@mattisvensson/strapi-plugin-webatlas 0.9.6 → 0.10.0

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 (81) hide show
  1. package/README.md +24 -36
  2. package/dist/_chunks/{SettingTitle-77mvMRg_.mjs → SettingTitle-CdR3SVn_.mjs} +1 -1
  3. package/dist/_chunks/{SettingTitle-DLj_Wwqy.js → SettingTitle-RU1azFIM.js} +1 -1
  4. package/dist/_chunks/{de-C-uxto84.mjs → de-B5pRvs13.mjs} +13 -7
  5. package/dist/_chunks/{de-CGXL_3o_.js → de-CqU1FU8C.js} +13 -7
  6. package/dist/_chunks/{en-B1CHnIH7.mjs → en-BE-zzIv8.mjs} +13 -7
  7. package/dist/_chunks/{en-DWEd5BXK.js → en-C7I90FwV.js} +13 -7
  8. package/dist/_chunks/{index-DwaKIwAz.mjs → index-B07UVUOa.mjs} +387 -229
  9. package/dist/_chunks/{index-3pYLMhui.mjs → index-BmyxSosC.mjs} +3 -3
  10. package/dist/_chunks/{index-Dt-AXdaw.js → index-BucL4va6.js} +38 -82
  11. package/dist/_chunks/{index-BRKi-K-v.mjs → index-BvcX9hcc.mjs} +61 -24
  12. package/dist/_chunks/{index-COfk3YSm.js → index-BxpDM360.js} +386 -228
  13. package/dist/_chunks/{index-5OG4i6qO.mjs → index-CIM-JzLK.mjs} +38 -82
  14. package/dist/_chunks/{index-BWzalvVi.mjs → index-CNKWb8pn.mjs} +614 -320
  15. package/dist/_chunks/{index-VXuAEnpX.js → index-D-vJE_K8.js} +3 -3
  16. package/dist/_chunks/{index-BOtvXSPU.js → index-IRSCe8PX.js} +609 -315
  17. package/dist/_chunks/{index-DTsHvlTa.js → index-d09V61nm.js} +61 -24
  18. package/dist/admin/index.js +1 -1
  19. package/dist/admin/index.mjs +1 -1
  20. package/dist/admin/src/components/CMEditViewAside/NewPathInfo.d.ts +2 -0
  21. package/dist/admin/src/components/CMEditViewAside/OverrideCheckbox.d.ts +7 -0
  22. package/dist/admin/src/components/CMEditViewAside/Panel.d.ts +5 -0
  23. package/dist/admin/src/components/CMEditViewAside/PathInput.d.ts +11 -0
  24. package/dist/admin/src/components/CMEditViewAside/RouteStructure.d.ts +3 -0
  25. package/dist/admin/src/components/CMEditViewAside/UidPathDisplay.d.ts +4 -0
  26. package/dist/admin/src/components/PathInfo.d.ts +2 -3
  27. package/dist/admin/src/components/modals/externalItem/index.d.ts +1 -1
  28. package/dist/admin/src/components/modals/internalItem/ItemDetails.d.ts +13 -0
  29. package/dist/admin/src/components/modals/internalItem/internalItemCreate.d.ts +1 -1
  30. package/dist/admin/src/components/modals/internalItem/internalItemEdit.d.ts +1 -1
  31. package/dist/admin/src/components/modals/useModalSharedLogic.d.ts +1 -1
  32. package/dist/admin/src/components/modals/wrapperItem/index.d.ts +1 -1
  33. package/dist/admin/src/hooks/useApi.d.ts +4 -3
  34. package/dist/admin/src/pages/Navigation/RouteItem.d.ts +1 -15
  35. package/dist/admin/src/pages/Navigation/RouteItemBadge.d.ts +4 -0
  36. package/dist/admin/src/pages/Navigation/RouteItemIcon.d.ts +5 -0
  37. package/dist/admin/src/pages/Navigation/RouteItemMenu.d.ts +10 -0
  38. package/dist/admin/src/pages/Navigation/RouteItemStatus.d.ts +5 -0
  39. package/dist/admin/src/pages/Navigation/SortableRouteItem.d.ts +1 -1
  40. package/dist/admin/src/types/index.d.ts +3 -0
  41. package/dist/admin/src/types/modal.d.ts +56 -0
  42. package/dist/admin/src/types/navigation.d.ts +18 -0
  43. package/dist/admin/src/types/panel.d.ts +41 -0
  44. package/dist/admin/src/types/route.d.ts +1 -1
  45. package/dist/admin/src/utils/buildBreadcrumbString.d.ts +16 -0
  46. package/dist/admin/src/utils/createTempNavItemObject.d.ts +6 -8
  47. package/dist/admin/src/utils/duplicateCheck.d.ts +10 -4
  48. package/dist/admin/src/utils/findParentNavItem.d.ts +13 -0
  49. package/dist/admin/src/utils/index.d.ts +3 -2
  50. package/dist/server/index.js +630 -200
  51. package/dist/server/index.mjs +630 -200
  52. package/dist/server/src/content-types/index.d.ts +18 -0
  53. package/dist/server/src/content-types/route/index.d.ts +18 -0
  54. package/dist/server/src/content-types/route/schema.d.ts +18 -0
  55. package/dist/server/src/controllers/admin.d.ts +3 -2
  56. package/dist/server/src/controllers/index.d.ts +3 -2
  57. package/dist/server/src/index.d.ts +24 -4
  58. package/dist/server/src/migrations/001-canonical-path.d.ts +7 -0
  59. package/dist/server/src/migrations/index.d.ts +3 -0
  60. package/dist/server/src/services/admin.d.ts +3 -2
  61. package/dist/server/src/services/index.d.ts +3 -2
  62. package/dist/server/src/utils/buildCanonicalPath.d.ts +1 -0
  63. package/dist/server/src/utils/buildNavigationPath.d.ts +5 -0
  64. package/dist/server/src/utils/cascadeCanonicalPathUpdates.d.ts +1 -0
  65. package/dist/server/src/utils/getNonInternalRouteIds.d.ts +1 -0
  66. package/dist/server/src/utils/getRouteAncestors.d.ts +1 -0
  67. package/dist/server/src/utils/getRouteDescendants.d.ts +1 -0
  68. package/dist/server/src/utils/index.d.ts +10 -2
  69. package/dist/server/src/utils/navigationItemStructure.d.ts +27 -0
  70. package/dist/server/src/utils/routeHandler.d.ts +4 -2
  71. package/dist/server/src/utils/validateRouteDependencies.d.ts +4 -0
  72. package/dist/types/index.d.ts +0 -1
  73. package/dist/types/navigation.d.ts +13 -12
  74. package/dist/types/route.d.ts +7 -2
  75. package/dist/types/strapi.d.ts +1 -2
  76. package/dist/utils/index.d.ts +1 -2
  77. package/package.json +1 -1
  78. package/dist/admin/src/components/CMEditViewAside/Path.d.ts +0 -5
  79. package/dist/admin/src/utils/countChildren.d.ts +0 -2
  80. package/dist/types/modal.d.ts +0 -36
  81. package/dist/utils/getPath.d.ts +0 -1
@@ -7,7 +7,7 @@ const designSystem = require("@strapi/design-system");
7
7
  const React = require("react");
8
8
  const ReactDOM = require("react-dom");
9
9
  const reactIntl = require("react-intl");
10
- const index = require("./index-COfk3YSm.js");
10
+ const index = require("./index-BxpDM360.js");
11
11
  const admin = require("@strapi/strapi/admin");
12
12
  const FullLoader = require("./FullLoader-Cmsf8xS6.js");
13
13
  const symbols = require("@strapi/icons/symbols");
@@ -35,7 +35,7 @@ const useAllEntities = () => {
35
35
  return { entities, loading, error };
36
36
  };
37
37
  function createTempNavItemObject({
38
- parentId,
38
+ actionItemParentId,
39
39
  entityRoute,
40
40
  selectedNavigation,
41
41
  navItemState,
@@ -44,6 +44,12 @@ function createTempNavItemObject({
44
44
  path,
45
45
  type = "internal"
46
46
  }) {
47
+ const clientModifications = {
48
+ type: "create",
49
+ route: entityRoute?.documentId ?? null,
50
+ parent: actionItemParentId ?? null,
51
+ navigation: selectedNavigation?.documentId ?? null
52
+ };
47
53
  const tempNavItem = {
48
54
  id: Math.floor(Math.random() * -1e6),
49
55
  // Temporary negative ID
@@ -53,25 +59,23 @@ function createTempNavItemObject({
53
59
  depth: 0,
54
60
  status: null,
55
61
  order: 0,
56
- parent: parentId ? { documentId: parentId } : null,
62
+ parent: actionItemParentId ? { documentId: actionItemParentId } : null,
57
63
  items: [],
58
- isNew: {
59
- route: entityRoute?.documentId ?? null,
60
- parent: parentId ?? null,
61
- navigation: selectedNavigation?.documentId ?? null
62
- },
64
+ clientModifications: { ...clientModifications },
65
+ initialClientModifications: { ...clientModifications },
63
66
  route: {
64
67
  active: navItemState.active || false,
65
68
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
66
69
  documentId: "",
67
70
  path: path?.value || "",
71
+ canonicalPath: "",
68
72
  id: 0,
69
73
  type,
70
74
  isOverride: navItemState.isOverride || false,
71
- relatedContentType: selectedContentType ? JSON.stringify(selectedContentType.contentType) : "",
75
+ relatedContentType: selectedContentType ? selectedContentType.contentType.uid : "",
72
76
  relatedDocumentId: selectedEntity ? selectedEntity.documentId : "",
73
77
  relatedId: selectedEntity ? selectedEntity.id : 0,
74
- slug: path?.value || "",
78
+ slug: path?.slug || "",
75
79
  title: navItemState.title || "",
76
80
  uidPath: path?.uidPath || "",
77
81
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -80,6 +84,56 @@ function createTempNavItemObject({
80
84
  };
81
85
  return tempNavItem;
82
86
  }
87
+ function findParentNavItem({
88
+ navigationItems,
89
+ targetItem,
90
+ onlyInternalItems = false
91
+ }) {
92
+ if (!navigationItems || !Array.isArray(navigationItems)) return null;
93
+ if (!targetItem || typeof targetItem.depth !== "number" || targetItem.depth <= 0) return null;
94
+ const targetIndex = navigationItems.findIndex(
95
+ (navItem) => navItem.documentId === targetItem.documentId
96
+ );
97
+ if (targetIndex === -1) return null;
98
+ for (let i = targetIndex - 1; i >= 0; i--) {
99
+ const candidate = navigationItems[i];
100
+ if (candidate.depth === 0) {
101
+ if (onlyInternalItems && candidate.route.type !== "internal") {
102
+ return null;
103
+ }
104
+ return candidate;
105
+ }
106
+ if (candidate.clientModifications?.type === "delete" || typeof candidate.depth === "number" && candidate.depth >= targetItem.depth || onlyInternalItems && candidate.route.type !== "internal") {
107
+ continue;
108
+ }
109
+ return candidate;
110
+ }
111
+ return null;
112
+ }
113
+ function buildBreadcrumbString({
114
+ navigationItems,
115
+ targetItem,
116
+ includeTarget = true
117
+ }) {
118
+ if (!navigationItems || !Array.isArray(navigationItems)) return null;
119
+ if (!targetItem || typeof targetItem.depth !== "number") return null;
120
+ if (targetItem.depth <= 0) return targetItem.route.title;
121
+ const targetIndex = navigationItems.findIndex(
122
+ (navItem) => navItem.documentId === targetItem.documentId
123
+ );
124
+ if (targetIndex === -1) return null;
125
+ const parts = [];
126
+ for (let i = targetIndex - 1; i >= 0; i--) {
127
+ const candidate = navigationItems[i];
128
+ if (candidate.clientModifications?.type === "delete") continue;
129
+ parts.unshift(candidate.route.title);
130
+ if (typeof candidate.depth === "number" && candidate.depth === 0) break;
131
+ }
132
+ if (includeTarget) {
133
+ parts.push(targetItem.route.title);
134
+ }
135
+ return parts.join(" > ");
136
+ }
83
137
  function EmptyBox({ msg }) {
84
138
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
85
139
  /* @__PURE__ */ jsxRuntime.jsx(symbols.EmptyDocuments, { width: "10rem", height: "6rem" }),
@@ -102,11 +156,17 @@ function Delete({ variant, item, onDelete }) {
102
156
  await deleteNavigation(item.documentId);
103
157
  onDelete(item);
104
158
  } else if (variant === "ItemDelete") {
105
- const editedItem = { ...item, deleted: true };
159
+ const editedItem = {
160
+ ...item,
161
+ clientModifications: {
162
+ ...item.clientModifications,
163
+ type: "delete"
164
+ }
165
+ };
106
166
  onDelete(editedItem);
107
167
  }
108
168
  } catch (err) {
109
- console.log(err);
169
+ strapi.log.error(err);
110
170
  }
111
171
  setModalType(closeModalState.current);
112
172
  };
@@ -243,7 +303,7 @@ function NavCreate() {
243
303
  navigate(`/plugins/${index.PLUGIN_ID}/navigation/${data.documentId}`);
244
304
  setModalType("");
245
305
  } catch (err) {
246
- console.log(err);
306
+ strapi.log.error(err);
247
307
  toggleNotification({
248
308
  type: "danger",
249
309
  message: formatMessage({
@@ -298,7 +358,7 @@ function NavEdit({ item, onEdit }) {
298
358
  setModalType("NavOverview");
299
359
  onEdit({ ...item, name, visible });
300
360
  } catch (err) {
301
- console.log(err);
361
+ strapi.log.error(err);
302
362
  toggleNotification({
303
363
  type: "danger",
304
364
  message: formatMessage({
@@ -439,12 +499,10 @@ function NavOverview({ navigations, setActionItem }) {
439
499
  }
440
500
  );
441
501
  }
442
- function itemStateReducer(navItemState, action) {
502
+ function navItemStateReducer(navItemState, action) {
443
503
  switch (action.type) {
444
504
  case "SET_TITLE":
445
505
  return { ...navItemState, title: action.payload };
446
- case "SET_SLUG":
447
- return { ...navItemState, slug: action.payload };
448
506
  case "SET_ACTIVE":
449
507
  return { ...navItemState, active: action.payload };
450
508
  case "SET_OVERRIDE":
@@ -458,14 +516,14 @@ function pathReducer(state, action) {
458
516
  case "DEFAULT":
459
517
  return {
460
518
  ...state,
461
- value: index.transformToUrl(action.payload),
519
+ value: action.payload,
462
520
  prevValue: state.value,
463
521
  needsUrlCheck: true
464
522
  };
465
523
  case "NO_URL_CHECK":
466
524
  return {
467
525
  ...state,
468
- value: index.transformToUrl(action.payload),
526
+ value: action.payload,
469
527
  prevValue: state.value,
470
528
  needsUrlCheck: false
471
529
  };
@@ -478,8 +536,14 @@ function pathReducer(state, action) {
478
536
  };
479
537
  case "RESET_URL_CHECK_FLAG":
480
538
  return { ...state, needsUrlCheck: false };
539
+ case "SET_REPLACEMENT":
540
+ return { ...state, replacement: action.payload };
481
541
  case "SET_UIDPATH":
482
542
  return { ...state, uidPath: action.payload };
543
+ case "SET_SLUG":
544
+ return { ...state, slug: action.payload };
545
+ case "SET_CANONICALPATH":
546
+ return { ...state, canonicalPath: action.payload };
483
547
  case "SET_INITIALPATH":
484
548
  return { ...state, initialPath: action.payload };
485
549
  default:
@@ -487,61 +551,64 @@ function pathReducer(state, action) {
487
551
  }
488
552
  }
489
553
  function useModalSharedLogic() {
490
- const [availableEntities, setAvailableEntities] = React.useState([]);
491
- const [selectedEntity, setSelectedEntity] = React.useState();
492
554
  const [selectedContentType, setSelectedContentType] = React.useState();
493
- const [entityRoute, setEntityRoute] = React.useState();
494
- const [replacement, setReplacement] = React.useState("");
495
555
  const [validationState, setValidationState] = React.useState("initial");
496
556
  const { entities } = useAllEntities();
497
- const { updateRoute, getRelatedRoute } = index.useApi();
498
557
  const { get } = admin.useFetchClient();
558
+ const availableEntities = React.useMemo(() => {
559
+ if (!entities) return [];
560
+ return entities;
561
+ }, [entities]);
499
562
  const initialState = React.useRef({
500
563
  title: "",
501
564
  slug: "",
502
565
  active: true,
503
- internal: true,
566
+ type: "internal",
504
567
  isOverride: false
505
568
  });
506
- const [navItemState, dispatchItemState] = React.useReducer(itemStateReducer, initialState.current);
507
- const [path, dispatchPath] = React.useReducer(pathReducer, { needsUrlCheck: false });
569
+ const [navItemState, dispatchNavItemState] = React.useReducer(navItemStateReducer, initialState.current);
570
+ const [path, dispatchPath] = React.useReducer(pathReducer, {
571
+ needsUrlCheck: false,
572
+ value: "",
573
+ prevValue: "",
574
+ slug: "",
575
+ replacement: null,
576
+ uidPath: "",
577
+ canonicalPath: "",
578
+ initialPath: ""
579
+ });
508
580
  const debouncedCheckUrl = React.useCallback(index.debounce(checkUrl, 500), []);
509
581
  const { modalType, setModalType } = React.useContext(ModalContext);
510
582
  const { selectedNavigation } = React.useContext(SelectedNavigationContext);
511
- async function checkUrl(url, routeDocumentId) {
583
+ async function checkUrl({
584
+ url,
585
+ routeDocumentId,
586
+ withoutTransform = false
587
+ }) {
512
588
  if (!url) return;
513
589
  setValidationState("checking");
514
- setReplacement("");
590
+ dispatchPath({ type: "SET_REPLACEMENT", payload: "" });
515
591
  try {
516
- const data = await index.duplicateCheck(get, url, routeDocumentId);
592
+ const data = await index.duplicateCheck({ fetchFunction: get, path: url, routeDocumentId, withoutTransform });
517
593
  if (!data || data === url) return;
518
594
  dispatchPath({ type: "NO_URL_CHECK", payload: data });
519
- setReplacement(data);
595
+ dispatchPath({ type: "SET_REPLACEMENT", payload: data });
520
596
  } catch (err) {
521
- console.log(err);
597
+ strapi.log.error(err);
522
598
  } finally {
523
599
  setValidationState("done");
524
600
  }
525
601
  }
526
- const modalSharedLogic2 = {
602
+ const modalSharedLogic = {
527
603
  availableEntities,
528
- setAvailableEntities,
529
- selectedEntity,
530
- setSelectedEntity,
531
604
  selectedContentType,
532
605
  setSelectedContentType,
533
- entityRoute,
534
- setEntityRoute,
535
606
  entities,
536
- updateRoute,
537
- getRelatedRoute,
538
- replacement,
539
- setReplacement,
540
607
  validationState,
541
608
  setValidationState,
542
609
  initialState,
543
610
  navItemState,
544
- dispatchItemState,
611
+ dispatchNavItemState,
545
612
  path,
546
613
  dispatchPath,
547
614
  debouncedCheckUrl,
@@ -549,7 +616,7 @@ function useModalSharedLogic() {
549
616
  setModalType,
550
617
  selectedNavigation
551
618
  };
552
- return modalSharedLogic2;
619
+ return modalSharedLogic;
553
620
  }
554
621
  function withModalSharedLogic(Component) {
555
622
  return function WrappedComponent(props) {
@@ -567,39 +634,39 @@ function ExternalItemComponent(props) {
567
634
  const {
568
635
  variant,
569
636
  navItemState,
570
- dispatchItemState,
637
+ dispatchNavItemState,
571
638
  path,
572
639
  dispatchPath,
573
640
  setModalType,
574
641
  selectedNavigation
575
642
  } = props;
576
- const parentId = isExternalCreateProps(props) ? props.parentId : void 0;
643
+ const actionItemParentId = isExternalCreateProps(props) ? props.actionItemParentId : void 0;
577
644
  const onCreate = isExternalCreateProps(props) ? props.onCreate : void 0;
578
645
  const onSave = isExternalEditProps(props) ? props.onSave : void 0;
579
646
  const item = isExternalEditProps(props) ? props.item : void 0;
580
647
  const { formatMessage } = reactIntl.useIntl();
581
648
  React.useEffect(() => {
582
649
  if (variant !== "ExternalEdit" || !item) return;
583
- dispatchItemState({ type: "SET_TITLE", payload: item.route.title });
584
- dispatchItemState({ type: "SET_ACTIVE", payload: item.route.active });
650
+ dispatchNavItemState({ type: "SET_TITLE", payload: item.route.title });
651
+ dispatchNavItemState({ type: "SET_ACTIVE", payload: item.route.active });
585
652
  dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: item.route.path });
586
- }, [variant, item, dispatchItemState, dispatchPath]);
653
+ }, [variant, item, dispatchNavItemState, dispatchPath]);
587
654
  const handleConfirm = async () => {
588
655
  try {
589
656
  if (!path || path.value?.trim() === "" || !navItemState.title || navItemState.title?.trim() === "" || !selectedNavigation) return;
590
657
  if (variant === "ExternalEdit" && item && onSave) {
591
658
  onSave({
592
659
  ...item,
593
- update: {
660
+ clientModifications: {
661
+ ...item.clientModifications,
662
+ type: "update",
594
663
  title: navItemState.title,
595
- path: path.value
596
- // internal: false,
597
- // active: navItemState.active,
664
+ slug: path.value
598
665
  }
599
666
  });
600
667
  } else if (onCreate) {
601
668
  const newItem = createTempNavItemObject({
602
- parentId,
669
+ actionItemParentId,
603
670
  entityRoute: null,
604
671
  selectedNavigation,
605
672
  navItemState,
@@ -612,7 +679,7 @@ function ExternalItemComponent(props) {
612
679
  }
613
680
  setModalType("");
614
681
  } catch (err) {
615
- console.log(err);
682
+ strapi.log.error(err);
616
683
  }
617
684
  };
618
685
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -642,7 +709,7 @@ function ExternalItemComponent(props) {
642
709
  }),
643
710
  name: "title",
644
711
  value: navItemState.title || "",
645
- onChange: (e) => dispatchItemState({ type: "SET_TITLE", payload: e.target.value }),
712
+ onChange: (e) => dispatchNavItemState({ type: "SET_TITLE", payload: e.target.value }),
646
713
  required: true
647
714
  }
648
715
  )
@@ -671,10 +738,79 @@ function ExternalItemComponent(props) {
671
738
  );
672
739
  }
673
740
  const ExternalItem = withModalSharedLogic(ExternalItemComponent);
674
- function ItemDetails({ navItemState, dispatchItemState, path, dispatchPath, validationState, replacement }) {
741
+ function Warning({ main, info }) {
742
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { variant: "warning", minWidth: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
743
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, children: [
744
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}),
745
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: main })
746
+ ] }),
747
+ info && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: info })
748
+ ] }) }) });
749
+ }
750
+ function ItemDetails({
751
+ navItemState,
752
+ dispatchNavItemState,
753
+ path,
754
+ dispatchPath,
755
+ validationState,
756
+ parentNavItem,
757
+ navigationItems,
758
+ navigations,
759
+ debouncedCheckUrl,
760
+ item,
761
+ route,
762
+ modalVariant
763
+ }) {
675
764
  const { formatMessage } = reactIntl.useIntl();
676
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
677
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
765
+ const breadcrumbString = React.useMemo(() => {
766
+ if (!navigationItems) return null;
767
+ const targetItem = item || parentNavItem;
768
+ if (!targetItem || typeof targetItem.depth !== "number") return null;
769
+ return buildBreadcrumbString({ navigationItems, targetItem, includeTarget: modalVariant === "create" });
770
+ }, [parentNavItem, navigationItems, item, modalVariant]);
771
+ const navigationWhereRouteExists = React.useMemo(() => {
772
+ if (!navigations || !route) return false;
773
+ return navigations.find((nav) => nav.items.some((r) => r.route.documentId === route.documentId || r.route.relatedContentType === route.relatedContentType && r.route.relatedDocumentId === route.relatedDocumentId));
774
+ }, [navigations, route, navigationItems]);
775
+ React.useEffect(() => {
776
+ if (path.needsUrlCheck && path.value) {
777
+ if (path.uidPath === path.value || path.initialPath === path.value) return;
778
+ debouncedCheckUrl({ url: path.value, routeDocumentId: route.documentId, withoutTransform: true });
779
+ dispatchPath({ type: "RESET_URL_CHECK_FLAG" });
780
+ }
781
+ }, [path.needsUrlCheck, route.documentId]);
782
+ React.useEffect(() => {
783
+ if (!path.slug) return;
784
+ const parentPath = parentNavItem?.clientModifications?.path || parentNavItem?.route.path || "";
785
+ const newPath = parentPath ? `${parentPath}/${path.slug}` : path.slug;
786
+ dispatchPath({ type: "DEFAULT", payload: newPath });
787
+ }, [path.slug, parentNavItem]);
788
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
789
+ path.canonicalPath !== path.value && /* @__PURE__ */ jsxRuntime.jsx(
790
+ Warning,
791
+ {
792
+ main: formatMessage({
793
+ id: index.getTranslation("modal.item.canonicalPathMismatch"),
794
+ defaultMessage: "Warning: Canonical Path does not match navigation path"
795
+ })
796
+ }
797
+ ),
798
+ navigationWhereRouteExists && /* @__PURE__ */ jsxRuntime.jsx(
799
+ Warning,
800
+ {
801
+ main: formatMessage({
802
+ id: index.getTranslation("modal.item.routeAlreadyUsed"),
803
+ defaultMessage: 'Warning: This route is already used in the navigation "{navigationName}"'
804
+ }, {
805
+ navigationName: navigationWhereRouteExists.name
806
+ }),
807
+ info: formatMessage({
808
+ id: index.getTranslation("modal.item.routeAlreadyUsed.info"),
809
+ defaultMessage: "Changing the path for this item will also update the path in the existing item."
810
+ })
811
+ }
812
+ ),
813
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { required: true, children: [
678
814
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
679
815
  id: index.getTranslation("modal.item.titleField.label"),
680
816
  defaultMessage: "Title"
@@ -682,17 +818,65 @@ function ItemDetails({ navItemState, dispatchItemState, path, dispatchPath, vali
682
818
  /* @__PURE__ */ jsxRuntime.jsx(
683
819
  designSystem.Field.Input,
684
820
  {
685
- placeholder: formatMessage({
686
- id: index.getTranslation("modal.item.titleField.placeholder"),
687
- defaultMessage: "e.g. About us"
688
- }),
689
821
  name: "title",
690
822
  value: navItemState?.title || "",
691
- onChange: (e) => dispatchItemState({ type: "SET_TITLE", payload: e.target.value }),
823
+ onChange: (e) => dispatchNavItemState({ type: "SET_TITLE", payload: e.target.value }),
692
824
  required: true
693
825
  }
694
826
  )
695
827
  ] }) }) }),
828
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
829
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Label, { children: [
830
+ formatMessage({
831
+ id: index.getTranslation("modal.item.canonicalPathField.label"),
832
+ defaultMessage: "Canonical Path"
833
+ }),
834
+ /* @__PURE__ */ jsxRuntime.jsx(index.Tooltip, { description: formatMessage({
835
+ id: index.getTranslation("modal.item.canonicalPathField.tooltip"),
836
+ defaultMessage: "Based on content hierarchy"
837
+ }) })
838
+ ] }),
839
+ /* @__PURE__ */ jsxRuntime.jsx(
840
+ designSystem.Field.Input,
841
+ {
842
+ name: "canonicalPath",
843
+ value: route.canonicalPath || "",
844
+ disabled: true
845
+ }
846
+ ),
847
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
848
+ ] }) }) }),
849
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { required: true, children: [
850
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
851
+ id: index.getTranslation("modal.item.slugField.label"),
852
+ defaultMessage: "Slug"
853
+ }) }),
854
+ /* @__PURE__ */ jsxRuntime.jsx(
855
+ designSystem.Field.Input,
856
+ {
857
+ name: "slug",
858
+ value: path.slug,
859
+ onChange: (e) => dispatchPath({ type: "SET_SLUG", payload: e.target.value }),
860
+ onBlur: (e) => {
861
+ dispatchPath({ type: "SET_SLUG", payload: e.target.value });
862
+ }
863
+ }
864
+ )
865
+ ] }) }) }),
866
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
867
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
868
+ id: index.getTranslation("modal.item.navigationPosition.label"),
869
+ defaultMessage: "Navigation Position"
870
+ }) }),
871
+ /* @__PURE__ */ jsxRuntime.jsx(
872
+ designSystem.Field.Input,
873
+ {
874
+ name: "navigationPosition",
875
+ value: breadcrumbString || "Root",
876
+ disabled: true
877
+ }
878
+ )
879
+ ] }) }) }),
696
880
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
697
881
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
698
882
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
@@ -702,110 +886,77 @@ function ItemDetails({ navItemState, dispatchItemState, path, dispatchPath, vali
702
886
  /* @__PURE__ */ jsxRuntime.jsx(
703
887
  designSystem.Field.Input,
704
888
  {
705
- required: true,
706
- placeholder: formatMessage({
707
- id: index.getTranslation("modal.item.pathField.placeholder"),
708
- defaultMessage: "e.g. about/"
709
- }),
710
- name: "slug",
711
- value: path?.value || "",
712
- onChange: (e) => dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: e.target.value }),
713
- onBlur: (e) => {
714
- if (e.target.value === path.prevValue) return;
715
- dispatchPath({ type: "DEFAULT", payload: e.target.value });
716
- }
889
+ name: "path",
890
+ value: path.value,
891
+ disabled: true
717
892
  }
718
893
  )
719
894
  ] }),
720
- /* @__PURE__ */ jsxRuntime.jsx(index.PathInfo, { validationState, replacement })
895
+ /* @__PURE__ */ jsxRuntime.jsx(index.PathInfo, { validationState, replacement: path.replacement })
721
896
  ] }) })
722
- ] }) });
897
+ ] });
723
898
  }
724
899
  function ItemCreateComponent({
725
900
  availableEntities,
726
- setAvailableEntities,
727
- selectedEntity,
728
- setSelectedEntity,
729
901
  selectedContentType,
730
902
  setSelectedContentType,
731
- entityRoute,
732
- setEntityRoute,
733
- entities,
734
- getRelatedRoute,
735
- replacement,
736
903
  validationState,
737
- initialState,
738
904
  navItemState,
739
- dispatchItemState,
905
+ dispatchNavItemState,
740
906
  path,
741
907
  dispatchPath,
742
908
  debouncedCheckUrl,
743
909
  setModalType,
744
910
  selectedNavigation,
745
- parentId,
746
- onCreate
911
+ actionItemParent,
912
+ onCreate,
913
+ navigationItems,
914
+ navigations
747
915
  }) {
748
- const [loading, setLoading] = React.useState(false);
916
+ const [route, setRoute] = React.useState(null);
917
+ const [entity, setEntity] = React.useState(null);
749
918
  const [loadingRoute, setLoadingRoute] = React.useState(true);
750
919
  const { formatMessage } = reactIntl.useIntl();
751
- React.useEffect(() => {
752
- if (!entities) return;
753
- setAvailableEntities(entities);
754
- }, [entities]);
755
- React.useEffect(() => {
756
- if (path.needsUrlCheck && path.value) {
757
- if (path.uidPath === path.value || path.initialPath === path.value) return;
758
- debouncedCheckUrl(path.value, entityRoute?.documentId);
759
- dispatchPath({ type: "RESET_URL_CHECK_FLAG" });
760
- }
761
- }, [path.needsUrlCheck, entityRoute?.documentId]);
920
+ const { getRelatedRoute } = index.useApi();
762
921
  React.useEffect(() => {
763
922
  async function fetchRoute() {
764
- if (!selectedContentType?.contentType || !selectedEntity?.documentId) return setLoadingRoute(false);
923
+ if (!selectedContentType?.contentType || !entity?.documentId) return setLoadingRoute(false);
765
924
  setLoadingRoute(true);
766
925
  try {
767
- const route = await getRelatedRoute(selectedEntity.documentId);
768
- if (!route) throw new Error("No route found for the selected entity");
769
- dispatchPath({ type: "NO_URL_CHECK", payload: route.path });
770
- dispatchPath({ type: "SET_UIDPATH", payload: route.uidPath });
771
- dispatchPath({ type: "SET_INITIALPATH", payload: route.path });
772
- dispatchItemState({ type: "SET_TITLE", payload: route.title });
773
- dispatchItemState({ type: "SET_ACTIVE", payload: route.active });
774
- dispatchItemState({ type: "SET_OVERRIDE", payload: route.isOverride });
775
- initialState.current = {
776
- title: route.title,
777
- slug: route.path,
778
- active: route.active,
779
- isOverride: route.isOverride
780
- };
781
- setEntityRoute(route);
926
+ const relatedRoute = await getRelatedRoute(entity.documentId);
927
+ if (!relatedRoute) throw new Error("No route found for the selected entity");
928
+ dispatchPath({ type: "NO_URL_CHECK", payload: relatedRoute.path });
929
+ dispatchPath({ type: "SET_SLUG", payload: relatedRoute.slug });
930
+ dispatchPath({ type: "SET_INITIALPATH", payload: relatedRoute.path });
931
+ dispatchPath({ type: "SET_CANONICALPATH", payload: relatedRoute.canonicalPath });
932
+ dispatchNavItemState({ type: "SET_TITLE", payload: relatedRoute.title });
933
+ dispatchNavItemState({ type: "SET_ACTIVE", payload: relatedRoute.active });
934
+ dispatchNavItemState({ type: "SET_OVERRIDE", payload: relatedRoute.isOverride });
935
+ setRoute(relatedRoute);
782
936
  } catch (err) {
783
- console.log(err);
937
+ strapi.log.error(err);
784
938
  } finally {
785
939
  setLoadingRoute(false);
786
940
  }
787
941
  }
788
942
  fetchRoute();
789
- }, [selectedEntity]);
943
+ }, [entity]);
790
944
  const addItem = async () => {
791
945
  try {
792
- setLoading(true);
793
- if (!selectedContentType?.contentType || !selectedEntity?.documentId || !path || !path.value?.trim() || !navItemState.title || !navItemState.title?.trim() || !selectedNavigation || !entityRoute) return;
946
+ if (!selectedContentType?.contentType || !entity?.documentId || !path || !path.value?.trim() || !navItemState.title || !navItemState.title?.trim() || !selectedNavigation || !route) return;
794
947
  const newItem = createTempNavItemObject({
795
- parentId,
796
- entityRoute,
948
+ actionItemParentId: actionItemParent?.documentId,
949
+ entityRoute: route,
797
950
  selectedNavigation,
798
951
  navItemState,
799
- selectedEntity,
952
+ selectedEntity: entity,
800
953
  selectedContentType,
801
954
  path
802
955
  });
803
956
  onCreate(newItem);
804
957
  setModalType("");
805
958
  } catch (err) {
806
- console.log(err);
807
- } finally {
808
- setLoading(false);
959
+ strapi.log.error(err);
809
960
  }
810
961
  };
811
962
  if (availableEntities && availableEntities.length === 0) {
@@ -828,11 +979,10 @@ function ItemCreateComponent({
828
979
  titleText: formatMessage({ id: index.getTranslation("modal.internalItem.titleText.create"), defaultMessage: "Add new navigation item" }),
829
980
  loadingText: formatMessage({ id: index.getTranslation("modal.internalItem.loadingText.create"), defaultMessage: "Creating" }),
830
981
  onConfirm: addItem,
831
- loading,
832
982
  modalToOpen: "",
833
983
  currentModalType: "ItemCreate",
834
984
  currentModalMode: "create",
835
- disabled: !selectedContentType?.contentType || !selectedEntity?.documentId || !path || !path.value?.trim() || !navItemState.title || !navItemState.title?.trim(),
985
+ disabled: !selectedContentType?.contentType || !entity?.documentId || !path || !path.value?.trim() || !path.slug?.trim() || !navItemState.title || !navItemState.title?.trim(),
836
986
  children: [
837
987
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
838
988
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
@@ -852,7 +1002,7 @@ function ItemCreateComponent({
852
1002
  const [contentType] = availableEntities.filter((group) => group.contentType.label === value);
853
1003
  if (contentType) {
854
1004
  setSelectedContentType(contentType);
855
- setSelectedEntity(null);
1005
+ setEntity(null);
856
1006
  }
857
1007
  },
858
1008
  disabled: availableEntities && availableEntities.length === 0,
@@ -868,39 +1018,40 @@ function ItemCreateComponent({
868
1018
  /* @__PURE__ */ jsxRuntime.jsx(
869
1019
  designSystem.SingleSelect,
870
1020
  {
871
- value: selectedEntity ? selectedEntity.id : "",
1021
+ value: entity ? entity.documentId : "",
872
1022
  placeholder: formatMessage({
873
1023
  id: index.getTranslation("modal.internalItem.entity.placeholder"),
874
1024
  defaultMessage: "Select an entity"
875
1025
  }),
876
1026
  onChange: (value) => {
877
1027
  const flatEntities = availableEntities.flatMap((group) => group.entities);
878
- const route = flatEntities.find((route2) => route2.id === Number(value));
879
- if (route) setSelectedEntity(route);
1028
+ const route2 = flatEntities.find((route3) => route3.documentId === value);
1029
+ if (route2) setEntity(route2);
880
1030
  },
881
1031
  disabled: !selectedContentType || selectedContentType?.entities && selectedContentType?.entities.length === 0,
882
1032
  children: selectedContentType && selectedContentType.entities?.map(
883
- (entity) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.SingleSelectOption, { value: entity.id, children: [
884
- entity.id,
885
- " - ",
886
- entity[selectedContentType.contentType.default]
887
- ] }, entity.id)
1033
+ (entity2) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: entity2.documentId, children: entity2[selectedContentType.contentType.default] }, entity2.id)
888
1034
  )
889
1035
  }
890
1036
  )
891
1037
  ] }) }) })
892
1038
  ] }),
893
- selectedEntity && selectedContentType && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1039
+ entity && selectedContentType && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
894
1040
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}) }),
895
- loadingRoute ? /* @__PURE__ */ jsxRuntime.jsx(FullLoader.FullLoader, { height: 50 }) : /* @__PURE__ */ jsxRuntime.jsx(
1041
+ loadingRoute || !route ? /* @__PURE__ */ jsxRuntime.jsx(FullLoader.FullLoader, { height: 50 }) : /* @__PURE__ */ jsxRuntime.jsx(
896
1042
  ItemDetails,
897
1043
  {
898
1044
  navItemState,
899
- dispatchItemState,
1045
+ dispatchNavItemState,
900
1046
  path,
901
1047
  dispatchPath,
902
1048
  validationState,
903
- replacement
1049
+ parentNavItem: actionItemParent,
1050
+ navigationItems,
1051
+ navigations,
1052
+ debouncedCheckUrl,
1053
+ route,
1054
+ modalVariant: "create"
904
1055
  }
905
1056
  )
906
1057
  ] })
@@ -6400,23 +6551,35 @@ function ItemEditComponent({
6400
6551
  selectedContentType,
6401
6552
  setSelectedContentType,
6402
6553
  entities,
6403
- replacement,
6404
6554
  validationState,
6405
6555
  initialState,
6406
6556
  navItemState,
6407
- dispatchItemState,
6557
+ dispatchNavItemState,
6408
6558
  path,
6409
6559
  dispatchPath,
6410
6560
  debouncedCheckUrl,
6411
6561
  setModalType,
6562
+ navigationItems,
6412
6563
  onEdit
6413
6564
  }) {
6414
6565
  const { formatMessage } = reactIntl.useIntl();
6566
+ const parentNavItem = React.useMemo(() => {
6567
+ return findParentNavItem({
6568
+ navigationItems,
6569
+ targetItem: item,
6570
+ onlyInternalItems: true
6571
+ });
6572
+ }, [navigationItems, item]);
6415
6573
  React.useEffect(() => {
6416
- dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: item.route.path });
6417
- dispatchItemState({ type: "SET_TITLE", payload: item.route.title });
6418
- dispatchItemState({ type: "SET_SLUG", payload: item.route.slug });
6419
- dispatchItemState({ type: "SET_ACTIVE", payload: item.route.active });
6574
+ const parentPath = parentNavItem?.clientModifications?.path || parentNavItem?.route.path || "";
6575
+ const initialPath = `${parentPath}/${item.route.slug}`;
6576
+ dispatchPath({ type: "DEFAULT", payload: initialPath });
6577
+ dispatchPath({ type: "SET_SLUG", payload: item.route.slug });
6578
+ dispatchPath({ type: "SET_INITIALPATH", payload: initialPath });
6579
+ dispatchPath({ type: "SET_CANONICALPATH", payload: item.route.canonicalPath });
6580
+ dispatchNavItemState({ type: "SET_TITLE", payload: item.route.title });
6581
+ dispatchNavItemState({ type: "SET_ACTIVE", payload: item.route.active });
6582
+ dispatchNavItemState({ type: "SET_OVERRIDE", payload: item.route.isOverride });
6420
6583
  const initialValues = {
6421
6584
  title: item.route.title,
6422
6585
  active: item.route.active,
@@ -6424,8 +6587,7 @@ function ItemEditComponent({
6424
6587
  slug: item.route.slug
6425
6588
  };
6426
6589
  initialState.current = initialValues;
6427
- dispatchPath({ type: "SET_INITIALPATH", payload: item.route.path });
6428
- }, []);
6590
+ }, [navigationItems, item, parentNavItem]);
6429
6591
  React.useEffect(() => {
6430
6592
  if (!entities) return;
6431
6593
  const contentType = entities.find((group) => group.contentType.uid === item.route.relatedContentType);
@@ -6434,38 +6596,27 @@ function ItemEditComponent({
6434
6596
  React.useEffect(() => {
6435
6597
  if (path.needsUrlCheck && path.value) {
6436
6598
  if (path.uidPath === path.value || path.initialPath === path.value) return;
6437
- debouncedCheckUrl(path.value, item.route.documentId);
6599
+ debouncedCheckUrl({ url: path.value, routeDocumentId: item.route.documentId });
6438
6600
  dispatchPath({ type: "RESET_URL_CHECK_FLAG" });
6439
6601
  }
6440
6602
  }, [path.needsUrlCheck, item.route.documentId]);
6441
- const debouncedValueEffect = React.useMemo(
6442
- () => index.debounce((path2) => {
6443
- dispatchPath({ type: "DEFAULT", payload: path2 });
6444
- }, 500),
6445
- []
6446
- );
6447
- const handlePathChange = (newPath) => {
6448
- if (newPath === path.prevValue) return;
6449
- dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: newPath });
6450
- if (newPath === "") return;
6451
- debouncedValueEffect(newPath);
6452
- };
6453
6603
  const updateItem = async () => {
6454
6604
  try {
6455
6605
  if (lodashExports.isEqual(navItemState, initialState.current) && path.value === path.initialPath) return;
6456
6606
  const isOverride = path.value !== item.route.path ? true : navItemState.isOverride;
6457
6607
  onEdit({
6458
6608
  ...item,
6459
- update: {
6609
+ clientModifications: {
6610
+ type: "update",
6460
6611
  title: navItemState.title,
6461
- slug: navItemState.slug,
6612
+ slug: path.slug,
6462
6613
  path: path.value,
6463
6614
  isOverride
6464
6615
  }
6465
6616
  });
6466
6617
  setModalType("");
6467
6618
  } catch (err) {
6468
- console.log(err);
6619
+ strapi.log.error(err);
6469
6620
  }
6470
6621
  };
6471
6622
  if (!selectedContentType) return null;
@@ -6510,53 +6661,25 @@ function ItemEditComponent({
6510
6661
  )
6511
6662
  ] }) }) })
6512
6663
  ] }),
6513
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}) }),
6514
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 8, children: [
6515
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, alignItems: "baseline", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
6516
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
6517
- id: index.getTranslation("modal.item.titleField.label"),
6518
- defaultMessage: "Title"
6519
- }) }),
6520
- /* @__PURE__ */ jsxRuntime.jsx(
6521
- designSystem.Field.Input,
6522
- {
6523
- placeholder: formatMessage({
6524
- id: index.getTranslation("modal.item.titleField.placeholder"),
6525
- defaultMessage: "e.g. About us"
6526
- }),
6527
- name: "title",
6528
- value: navItemState.title || "",
6529
- onChange: (e) => dispatchItemState({ type: "SET_TITLE", payload: e.target.value }),
6530
- required: true
6531
- }
6532
- )
6533
- ] }) }) }),
6534
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
6535
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
6536
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
6537
- id: index.getTranslation("modal.item.pathField.label"),
6538
- defaultMessage: "Path"
6539
- }) }),
6540
- /* @__PURE__ */ jsxRuntime.jsx(
6541
- designSystem.Field.Input,
6542
- {
6543
- placeholder: formatMessage({
6544
- id: index.getTranslation("modal.item.pathField.placeholder"),
6545
- defaultMessage: "e.g. about/"
6546
- }),
6547
- value: path.value || "",
6548
- onChange: (e) => handlePathChange(e.target.value),
6549
- onBlur: (e) => {
6550
- if (e.target.value === path.prevValue) return;
6551
- dispatchPath({ type: "DEFAULT", payload: e.target.value });
6552
- },
6553
- required: true
6554
- }
6555
- )
6556
- ] }),
6557
- /* @__PURE__ */ jsxRuntime.jsx(index.PathInfo, { validationState, replacement })
6558
- ] }) })
6559
- ] }) })
6664
+ item && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6665
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}) }),
6666
+ /* @__PURE__ */ jsxRuntime.jsx(
6667
+ ItemDetails,
6668
+ {
6669
+ navItemState,
6670
+ dispatchNavItemState,
6671
+ path,
6672
+ dispatchPath,
6673
+ validationState,
6674
+ parentNavItem,
6675
+ navigationItems,
6676
+ debouncedCheckUrl,
6677
+ item,
6678
+ route: item.route,
6679
+ modalVariant: "edit"
6680
+ }
6681
+ )
6682
+ ] })
6560
6683
  ]
6561
6684
  }
6562
6685
  );
@@ -6572,40 +6695,37 @@ function WrapperItemComponent(props) {
6572
6695
  const {
6573
6696
  variant,
6574
6697
  navItemState,
6575
- dispatchItemState,
6698
+ dispatchNavItemState,
6576
6699
  dispatchPath,
6577
6700
  setModalType,
6578
6701
  selectedNavigation
6579
6702
  } = props;
6580
- const parentId = isWrapperCreateProps(props) ? props.parentId : void 0;
6703
+ const actionItemParentId = isWrapperCreateProps(props) ? props.actionItemParentId : void 0;
6581
6704
  const onCreate = isWrapperCreateProps(props) ? props.onCreate : void 0;
6582
6705
  const onSave = isWrapperEditProps(props) ? props.onSave : void 0;
6583
6706
  const item = isWrapperEditProps(props) ? props.item : void 0;
6584
6707
  const { formatMessage } = reactIntl.useIntl();
6585
6708
  React.useEffect(() => {
6586
6709
  if (variant !== "WrapperEdit" || !item) return;
6587
- dispatchItemState({ type: "SET_TITLE", payload: item.route.title });
6588
- dispatchItemState({ type: "SET_ACTIVE", payload: item.route.active });
6710
+ dispatchNavItemState({ type: "SET_TITLE", payload: item.route.title });
6711
+ dispatchNavItemState({ type: "SET_ACTIVE", payload: item.route.active });
6589
6712
  dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: item.route.path });
6590
6713
  }, []);
6591
6714
  const onConfirm = async () => {
6592
6715
  try {
6593
6716
  if (!navItemState.title || !selectedNavigation) return;
6594
- const data = {
6595
- title: navItemState.title,
6596
- active: navItemState.active,
6597
- type: "wrapper"
6598
- };
6599
6717
  if (variant === "WrapperEdit" && item && onSave) {
6600
6718
  onSave({
6601
6719
  ...item,
6602
- update: {
6603
- ...data
6720
+ clientModifications: {
6721
+ ...item.clientModifications,
6722
+ type: "update",
6723
+ title: navItemState.title
6604
6724
  }
6605
6725
  });
6606
6726
  } else if (onCreate) {
6607
6727
  const newItem = createTempNavItemObject({
6608
- parentId,
6728
+ actionItemParentId,
6609
6729
  entityRoute: null,
6610
6730
  selectedNavigation,
6611
6731
  navItemState,
@@ -6617,7 +6737,7 @@ function WrapperItemComponent(props) {
6617
6737
  }
6618
6738
  setModalType("");
6619
6739
  } catch (err) {
6620
- console.log(err);
6740
+ strapi.log.error(err);
6621
6741
  }
6622
6742
  };
6623
6743
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -6646,7 +6766,7 @@ function WrapperItemComponent(props) {
6646
6766
  }),
6647
6767
  name: "title",
6648
6768
  value: navItemState.title || "",
6649
- onChange: (e) => dispatchItemState({ type: "SET_TITLE", payload: e.target.value }),
6769
+ onChange: (e) => dispatchNavItemState({ type: "SET_TITLE", payload: e.target.value }),
6650
6770
  required: true
6651
6771
  }
6652
6772
  )
@@ -6689,7 +6809,98 @@ function getMaxDepth({ previousItem, maxDepthValue }) {
6689
6809
  function getDragDepth(offset, indentationWidth2) {
6690
6810
  return Math.round(offset / indentationWidth2);
6691
6811
  }
6692
- function RouteIcon({ type, color = "neutral800" }) {
6812
+ function RouteItemMenu({
6813
+ item,
6814
+ depth,
6815
+ maxDepth,
6816
+ handleEdit,
6817
+ handleAddChildren,
6818
+ handleDelete,
6819
+ handleRestore
6820
+ }) {
6821
+ const { formatMessage } = reactIntl.useIntl();
6822
+ const viewEntityTo = item.route.relatedContentType && item.route.relatedDocumentId ? `/content-manager/collection-types/${item.route.relatedContentType}/${item.route.relatedDocumentId}` : null;
6823
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.SimpleMenu, { label: "Item actions", tag: designSystem.IconButton, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {}), children: [
6824
+ (item.clientModifications?.type === "delete" || item.clientModifications?.type === "update") && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleRestore(), children: formatMessage({
6825
+ id: index.getTranslation("restore.metadata"),
6826
+ defaultMessage: "Restore Metadata"
6827
+ }) }) }),
6828
+ item.clientModifications?.type !== "delete" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6829
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleEdit(), children: formatMessage({
6830
+ id: index.getTranslation("edit"),
6831
+ defaultMessage: "Edit"
6832
+ }) }),
6833
+ item.route.type === "internal" && viewEntityTo && /* @__PURE__ */ jsxRuntime.jsx(
6834
+ designSystem.MenuItem,
6835
+ {
6836
+ isLink: true,
6837
+ as: reactRouterDom.Link,
6838
+ to: viewEntityTo,
6839
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
6840
+ id: index.getTranslation("navigation.page.navItem.viewEntity"),
6841
+ defaultMessage: "View Entity"
6842
+ }) })
6843
+ }
6844
+ ),
6845
+ depth !== void 0 && depth < maxDepth && /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleAddChildren(), children: formatMessage({
6846
+ id: index.getTranslation("navigation.page.navItem.addChildren"),
6847
+ defaultMessage: "Add children"
6848
+ }) }),
6849
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleDelete(), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: formatMessage({
6850
+ id: index.getTranslation("delete"),
6851
+ defaultMessage: "Delete"
6852
+ }) }) })
6853
+ ] })
6854
+ ] });
6855
+ }
6856
+ function RouteItemStatus({
6857
+ item,
6858
+ isUpdated = false
6859
+ }) {
6860
+ if (!item) return null;
6861
+ const { formatMessage } = reactIntl.useIntl();
6862
+ if (item.clientModifications?.type === "create")
6863
+ return /* @__PURE__ */ jsxRuntime.jsx(
6864
+ designSystem.Badge,
6865
+ {
6866
+ backgroundColor: "success100",
6867
+ textColor: "success600",
6868
+ borderColor: "success200",
6869
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: formatMessage({
6870
+ id: index.getTranslation("new"),
6871
+ defaultMessage: "New"
6872
+ }) })
6873
+ }
6874
+ );
6875
+ if (item.clientModifications?.type === "update" || isUpdated)
6876
+ return /* @__PURE__ */ jsxRuntime.jsx(
6877
+ designSystem.Badge,
6878
+ {
6879
+ backgroundColor: "warning100",
6880
+ textColor: "warning600",
6881
+ borderColor: "warning200",
6882
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: formatMessage({
6883
+ id: index.getTranslation("updated"),
6884
+ defaultMessage: "Updated"
6885
+ }) })
6886
+ }
6887
+ );
6888
+ if (item.clientModifications?.type === "delete")
6889
+ return /* @__PURE__ */ jsxRuntime.jsx(
6890
+ designSystem.Badge,
6891
+ {
6892
+ backgroundColor: "danger100",
6893
+ textColor: "danger600",
6894
+ borderColor: "danger200",
6895
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: formatMessage({
6896
+ id: index.getTranslation("deleted"),
6897
+ defaultMessage: "Deleted"
6898
+ }) })
6899
+ }
6900
+ );
6901
+ return null;
6902
+ }
6903
+ function RouteItemIcon({ type, color = "neutral800" }) {
6693
6904
  switch (type) {
6694
6905
  case "external":
6695
6906
  return /* @__PURE__ */ jsxRuntime.jsx(icons.ExternalLink, { color });
@@ -6701,20 +6912,8 @@ function RouteIcon({ type, color = "neutral800" }) {
6701
6912
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "16px", height: "16px" });
6702
6913
  }
6703
6914
  }
6704
- const RouteItem = React.forwardRef(({
6705
- item,
6706
- setParentId,
6707
- setActionItem,
6708
- setNavigationItems,
6709
- ghost,
6710
- depth,
6711
- maxDepth,
6712
- style,
6713
- wrapperRef,
6714
- handleProps
6715
- }, ref) => {
6716
- if (!item || !item.route) return null;
6717
- const { setModalType } = React.useContext(ModalContext);
6915
+ function RouteItemBadge({ item }) {
6916
+ if (item.route.type !== "internal" || !item.status) return null;
6718
6917
  const { formatMessage } = reactIntl.useIntl();
6719
6918
  const itemStatusOptions = {
6720
6919
  published: {
@@ -6722,25 +6921,119 @@ const RouteItem = React.forwardRef(({
6722
6921
  id: index.getTranslation("published"),
6723
6922
  defaultMessage: "Published"
6724
6923
  }),
6725
- variant: "primary"
6924
+ backgroundColor: "success100",
6925
+ textColor: "success600",
6926
+ borderColor: "success200"
6726
6927
  },
6727
6928
  draft: {
6728
6929
  status: formatMessage({
6729
6930
  id: index.getTranslation("draft"),
6730
6931
  defaultMessage: "Draft"
6731
6932
  }),
6732
- variant: "secondary"
6933
+ backgroundColor: "secondary100",
6934
+ textColor: "secondary600",
6935
+ borderColor: "secondary200"
6733
6936
  },
6734
6937
  modified: {
6735
6938
  status: formatMessage({
6736
6939
  id: index.getTranslation("modified"),
6737
6940
  defaultMessage: "Modified"
6738
6941
  }),
6739
- variant: "alternative"
6942
+ backgroundColor: "alternative100",
6943
+ textColor: "alternative600",
6944
+ borderColor: "alternative200"
6740
6945
  }
6741
6946
  };
6947
+ return /* @__PURE__ */ jsxRuntime.jsx(
6948
+ designSystem.Badge,
6949
+ {
6950
+ backgroundColor: itemStatusOptions[item.status].backgroundColor,
6951
+ textColor: itemStatusOptions[item.status].textColor,
6952
+ borderColor: itemStatusOptions[item.status].borderColor,
6953
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: itemStatusOptions[item.status].status })
6954
+ }
6955
+ );
6956
+ }
6957
+ const RouteItem = React.forwardRef(({
6958
+ item,
6959
+ initialItem,
6960
+ setActionItemParent,
6961
+ setActionItem,
6962
+ setNavigationItems,
6963
+ ghost,
6964
+ depth,
6965
+ maxDepth,
6966
+ style,
6967
+ wrapperRef,
6968
+ handleProps,
6969
+ navigationItems
6970
+ }, ref) => {
6971
+ const { setModalType } = React.useContext(ModalContext);
6972
+ const parentNavItem = React.useMemo(() => findParentNavItem({
6973
+ navigationItems,
6974
+ targetItem: item,
6975
+ onlyInternalItems: true
6976
+ }), [navigationItems, item]);
6977
+ const hasStructureChanges = React.useMemo(() => {
6978
+ if (!initialItem) return false;
6979
+ return initialItem.order !== item.order || initialItem.depth !== item.depth;
6980
+ }, [initialItem, item.order, item.depth]);
6981
+ const isUpdated = item.clientModifications?.type === "update" || hasStructureChanges;
6982
+ const itemPath = React.useMemo(() => {
6983
+ if (!item.route) return "";
6984
+ if (item.route.type !== "internal") return item.route.path;
6985
+ const parentPath = parentNavItem ? `${parentNavItem.clientModifications?.path || parentNavItem.route.path}/` : "";
6986
+ const itemSlug = item.clientModifications?.slug || item.route.slug;
6987
+ return `${parentPath}${itemSlug}`;
6988
+ }, [item, parentNavItem, isUpdated]);
6989
+ const updateNavItem = (navItems) => {
6990
+ if (!navItems) return navItems;
6991
+ return navItems.map((navItem) => {
6992
+ if (navItem.documentId === item.documentId) {
6993
+ if (navItem.clientModifications?.path === itemPath) {
6994
+ return navItem;
6995
+ }
6996
+ return {
6997
+ ...navItem,
6998
+ clientModifications: navItem.clientModifications ? {
6999
+ ...navItem.clientModifications,
7000
+ path: itemPath
7001
+ } : {
7002
+ type: "update",
7003
+ path: itemPath,
7004
+ autoGenerated: true
7005
+ }
7006
+ };
7007
+ }
7008
+ return navItem;
7009
+ });
7010
+ };
7011
+ const removeNavItemModifications = (navItems) => {
7012
+ if (!navItems) return navItems;
7013
+ return navItems.map((navItem) => {
7014
+ if (navItem.documentId === item.documentId) {
7015
+ const { clientModifications, ...rest } = navItem;
7016
+ return rest;
7017
+ }
7018
+ return navItem;
7019
+ });
7020
+ };
7021
+ React.useEffect(() => {
7022
+ if (item.route?.type !== "internal") return;
7023
+ const shouldSyncPath = item.clientModifications?.path !== itemPath && (item.clientModifications?.type === "update" || itemPath !== item.route.path);
7024
+ if (shouldSyncPath) {
7025
+ setNavigationItems(updateNavItem);
7026
+ }
7027
+ }, [itemPath, item.documentId, item.route?.type, item.route?.path, item.clientModifications?.type, item.clientModifications?.path, setNavigationItems]);
7028
+ React.useEffect(() => {
7029
+ if (item.route?.type !== "internal") return;
7030
+ const canBeRemoved = item.clientModifications?.autoGenerated && item.route.path === itemPath && !hasStructureChanges;
7031
+ if (canBeRemoved) {
7032
+ setNavigationItems(removeNavItemModifications);
7033
+ }
7034
+ }, [itemPath, item.documentId, item.route?.type, item.route?.path, item.clientModifications?.autoGenerated, hasStructureChanges, setNavigationItems]);
6742
7035
  const handleAddChildren = () => {
6743
- setParentId(item.documentId);
7036
+ setActionItemParent(item);
6744
7037
  setModalType("ItemCreate");
6745
7038
  };
6746
7039
  const handleEdit = () => {
@@ -6758,8 +7051,8 @@ const RouteItem = React.forwardRef(({
6758
7051
  setNavigationItems(
6759
7052
  (navItems) => navItems?.map((navItem) => {
6760
7053
  if (navItem.documentId === item.documentId) {
6761
- delete navItem.update;
6762
- delete navItem.deleted;
7054
+ const { clientModifications: _, ...rest } = navItem;
7055
+ return navItem.initialClientModifications ? { ...rest, clientModifications: navItem.initialClientModifications } : rest;
6763
7056
  }
6764
7057
  return navItem;
6765
7058
  })
@@ -6767,9 +7060,10 @@ const RouteItem = React.forwardRef(({
6767
7060
  };
6768
7061
  const elStyle = {
6769
7062
  marginLeft: depth !== void 0 ? depth * 48 : 0,
6770
- opacity: ghost || item.deleted ? 0.5 : 1,
7063
+ opacity: ghost || item.clientModifications?.type === "delete" ? 0.5 : 1,
6771
7064
  ...style
6772
7065
  };
7066
+ if (!item || !item.route) return null;
6773
7067
  return /* @__PURE__ */ jsxRuntime.jsx(
6774
7068
  designSystem.Box,
6775
7069
  {
@@ -6778,8 +7072,8 @@ const RouteItem = React.forwardRef(({
6778
7072
  children: /* @__PURE__ */ jsxRuntime.jsx(
6779
7073
  designSystem.Box,
6780
7074
  {
6781
- background: item.route?.active ? "neutral0" : "neutral100",
6782
- borderColor: "neutral150",
7075
+ background: "neutral0",
7076
+ borderColor: item.clientModifications?.type === "delete" ? "danger500" : "neutral150",
6783
7077
  hasRadius: true,
6784
7078
  paddingBottom: 4,
6785
7079
  paddingLeft: 4,
@@ -6798,49 +7092,30 @@ const RouteItem = React.forwardRef(({
6798
7092
  background: "neutral150"
6799
7093
  }
6800
7094
  ),
6801
- /* @__PURE__ */ jsxRuntime.jsx(RouteIcon, { type: item.route.type }),
7095
+ /* @__PURE__ */ jsxRuntime.jsx(RouteItemIcon, { type: item.route.type }),
6802
7096
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
6803
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: item.update?.title ? item.update.title : item.route.title }),
6804
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral400", children: [
6805
- item.route.type === "internal" && "/",
6806
- item.update?.path ? item.update.path : item.route.path
7097
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: item.clientModifications?.title ? item.clientModifications.title : item.route.title }),
7098
+ itemPath && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral400", children: [
7099
+ "/",
7100
+ itemPath
6807
7101
  ] })
6808
7102
  ] }),
6809
- item.isNew && !item.deleted && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { variant: "alternative", size: "S", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: formatMessage({
6810
- id: index.getTranslation("new"),
6811
- defaultMessage: "New"
6812
- }) }) }),
6813
- item.update && !item.deleted && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { variant: "alternative", size: "S", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: formatMessage({
6814
- id: index.getTranslation("updated"),
6815
- defaultMessage: "Updated"
6816
- }) }) }),
6817
- item.deleted && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { size: "S", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "danger500", children: formatMessage({
6818
- id: index.getTranslation("deleted"),
6819
- defaultMessage: "Deleted"
6820
- }) }) })
7103
+ /* @__PURE__ */ jsxRuntime.jsx(RouteItemStatus, { item, isUpdated: hasStructureChanges })
6821
7104
  ] }),
6822
7105
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "row", gap: 4, children: [
6823
- item.route.type === "internal" && item.status && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { variant: itemStatusOptions[item.status].variant, size: "S", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: itemStatusOptions[item.status].status }) }),
6824
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.SimpleMenu, { label: "Item actions", tag: designSystem.IconButton, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {}), children: [
6825
- !item.deleted && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6826
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleEdit(), children: formatMessage({
6827
- id: index.getTranslation("edit"),
6828
- defaultMessage: "Edit"
6829
- }) }),
6830
- depth !== void 0 && depth < maxDepth && /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleAddChildren(), children: formatMessage({
6831
- id: index.getTranslation("navigation.page.navItem.addChildren"),
6832
- defaultMessage: "Add children"
6833
- }) }),
6834
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleDelete(), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: formatMessage({
6835
- id: index.getTranslation("delete"),
6836
- defaultMessage: "Delete"
6837
- }) }) })
6838
- ] }),
6839
- (item.deleted || item.update) && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: () => handleRestore(), children: formatMessage({
6840
- id: index.getTranslation("restore"),
6841
- defaultMessage: "Restore"
6842
- }) }) })
6843
- ] })
7106
+ /* @__PURE__ */ jsxRuntime.jsx(RouteItemBadge, { item }),
7107
+ /* @__PURE__ */ jsxRuntime.jsx(
7108
+ RouteItemMenu,
7109
+ {
7110
+ item,
7111
+ depth,
7112
+ maxDepth,
7113
+ handleEdit,
7114
+ handleAddChildren,
7115
+ handleDelete,
7116
+ handleRestore
7117
+ }
7118
+ )
6844
7119
  ] })
6845
7120
  ] })
6846
7121
  }
@@ -7909,7 +8184,7 @@ const Navigation = () => {
7909
8184
  const [navigationItems, setNavigationItems] = React.useState();
7910
8185
  const initialNavigationItemsRef = React.useRef(null);
7911
8186
  const [actionItem, setActionItem] = React.useState();
7912
- const [parentId, setParentId] = React.useState();
8187
+ const [actionItemParent, setActionItemParent] = React.useState(null);
7913
8188
  const { getNavigation, updateNavigationItemStructure } = index.useApi();
7914
8189
  const [isSavingNavigation, setIsSavingNavigation] = React.useState(false);
7915
8190
  const [loading, setLoading] = React.useState(true);
@@ -7939,7 +8214,7 @@ const Navigation = () => {
7939
8214
  const { data: data2 } = await get(`/content-manager/collection-types/${ct}/${id}`);
7940
8215
  return { ...item, status: data2.data.status };
7941
8216
  } catch (err) {
7942
- console.error(err);
8217
+ strapi.log.error(err);
7943
8218
  return item;
7944
8219
  }
7945
8220
  })
@@ -7963,7 +8238,7 @@ const Navigation = () => {
7963
8238
  cachedNavigations.current = updatedNavigations;
7964
8239
  switchNavigation(selectedNav, updatedNavigations);
7965
8240
  } catch (error) {
7966
- console.error("Error fetching navigations: ", error);
8241
+ strapi.log.error("Error fetching navigations: ", error);
7967
8242
  toggleNotification({
7968
8243
  type: "danger",
7969
8244
  message: formatMessage({
@@ -8005,17 +8280,27 @@ const Navigation = () => {
8005
8280
  React.useEffect(() => {
8006
8281
  if (modalType === "NavOverview" || modalType === "") {
8007
8282
  setActionItem(void 0);
8008
- setParentId(void 0);
8283
+ setActionItemParent(null);
8009
8284
  }
8010
8285
  }, [modalType]);
8286
+ React.useEffect(() => {
8287
+ if (!selectedNavigation || !navigationItems) return;
8288
+ setNavigations(navigations.map((nav) => {
8289
+ if (nav.documentId !== selectedNavigation.documentId) return nav;
8290
+ return {
8291
+ ...nav,
8292
+ items: navigationItems
8293
+ };
8294
+ }));
8295
+ }, [setNavigations, navigationItems, selectedNavigation]);
8011
8296
  React.useEffect(() => {
8012
8297
  if (!activeId || !navigationItems) return;
8013
8298
  const item = navigationItems.find(({ id }) => id === activeId);
8014
8299
  setActiveItem(item);
8015
8300
  }, [navigationItems, activeId]);
8016
8301
  function handleSoftAddedItem(newItem) {
8017
- if (newItem.isNew?.parent) {
8018
- const parentIndex = navigationItems?.findIndex((item) => item.documentId === newItem.isNew?.parent);
8302
+ if (newItem.clientModifications?.parent) {
8303
+ const parentIndex = navigationItems?.findIndex((item) => item.documentId === newItem.clientModifications?.parent);
8019
8304
  if (parentIndex !== void 0 && parentIndex >= 0) {
8020
8305
  const parentDepth = navigationItems ? navigationItems[parentIndex].depth || 0 : 0;
8021
8306
  newItem.depth = parentDepth + 1;
@@ -8043,7 +8328,7 @@ const Navigation = () => {
8043
8328
  })
8044
8329
  });
8045
8330
  } catch (e) {
8046
- console.error(e);
8331
+ strapi.log.error(e);
8047
8332
  toggleNotification({
8048
8333
  type: "danger",
8049
8334
  message: formatMessage({
@@ -8145,28 +8430,34 @@ const Navigation = () => {
8145
8430
  onDragCancel: () => handleDragCancel(),
8146
8431
  measuring,
8147
8432
  children: /* @__PURE__ */ jsxRuntime.jsxs(sortable.SortableContext, { items: navigationItems, strategy: sortable.verticalListSortingStrategy, children: [
8148
- navigationItems.map((item, index2) => config?.navigation.maxDepth && /* @__PURE__ */ jsxRuntime.jsx(
8149
- SortableRouteItem,
8150
- {
8151
- item,
8152
- setParentId,
8153
- setActionItem,
8154
- setNavigationItems,
8155
- indentationWidth,
8156
- depth: item.id === activeId && projected ? projected.depth : item.depth,
8157
- maxDepth: config.navigation.maxDepth
8158
- },
8159
- item.documentId || index2
8160
- )),
8433
+ navigationItems.map((item, index2) => {
8434
+ const initialItem = initialNavigationItemsRef.current?.find((i) => i.documentId === item.documentId);
8435
+ return config?.navigation.maxDepth && /* @__PURE__ */ jsxRuntime.jsx(
8436
+ SortableRouteItem,
8437
+ {
8438
+ item,
8439
+ initialItem,
8440
+ setActionItemParent,
8441
+ setActionItem,
8442
+ setNavigationItems,
8443
+ indentationWidth,
8444
+ depth: item.id === activeId && projected ? projected.depth : item.depth,
8445
+ maxDepth: config.navigation.maxDepth,
8446
+ navigationItems
8447
+ },
8448
+ item.documentId || index2
8449
+ );
8450
+ }),
8161
8451
  ReactDOM.createPortal(
8162
8452
  /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { children: activeId && activeItem ? config?.navigation.maxDepth && /* @__PURE__ */ jsxRuntime.jsx(
8163
8453
  SortableRouteItem,
8164
8454
  {
8165
8455
  item: activeItem,
8166
- setParentId,
8456
+ setActionItemParent,
8167
8457
  setActionItem,
8168
8458
  setNavigationItems,
8169
- maxDepth: config.navigation.maxDepth
8459
+ maxDepth: config.navigation.maxDepth,
8460
+ navigationItems
8170
8461
  }
8171
8462
  ) : null }),
8172
8463
  document.body
@@ -8226,7 +8517,9 @@ const Navigation = () => {
8226
8517
  modalType === "ItemCreate" && /* @__PURE__ */ jsxRuntime.jsx(
8227
8518
  ItemCreate,
8228
8519
  {
8229
- parentId,
8520
+ actionItemParent,
8521
+ navigationItems: navigationItems || [],
8522
+ navigations,
8230
8523
  onCreate: (newItem) => {
8231
8524
  handleSoftAddedItem(newItem);
8232
8525
  }
@@ -8248,6 +8541,7 @@ const Navigation = () => {
8248
8541
  ItemEdit,
8249
8542
  {
8250
8543
  item: actionItem,
8544
+ navigationItems: navigationItems || [],
8251
8545
  onEdit: (editedItem) => {
8252
8546
  setNavigationItems(
8253
8547
  (items) => items?.map((item) => item.id === editedItem.id ? editedItem : item)
@@ -8259,7 +8553,7 @@ const Navigation = () => {
8259
8553
  ExternalItem,
8260
8554
  {
8261
8555
  variant: modalType,
8262
- parentId,
8556
+ actionItemParentId: actionItemParent?.documentId,
8263
8557
  onCreate: (newItem) => {
8264
8558
  handleSoftAddedItem(newItem);
8265
8559
  }
@@ -8281,7 +8575,7 @@ const Navigation = () => {
8281
8575
  WrapperItem,
8282
8576
  {
8283
8577
  variant: modalType,
8284
- parentId,
8578
+ actionItemParentId: actionItemParent?.documentId,
8285
8579
  onCreate: (newItem) => {
8286
8580
  handleSoftAddedItem(newItem);
8287
8581
  }