@strapi/content-manager 5.53.0 → 5.55.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 (138) hide show
  1. package/dist/admin/components/ActionsDrawer.js +17 -6
  2. package/dist/admin/components/ActionsDrawer.js.map +1 -1
  3. package/dist/admin/components/ActionsDrawer.mjs +19 -8
  4. package/dist/admin/components/ActionsDrawer.mjs.map +1 -1
  5. package/dist/admin/components/LeftMenu.js +131 -52
  6. package/dist/admin/components/LeftMenu.js.map +1 -1
  7. package/dist/admin/components/LeftMenu.mjs +133 -54
  8. package/dist/admin/components/LeftMenu.mjs.map +1 -1
  9. package/dist/admin/history/components/VersionsList.js +37 -43
  10. package/dist/admin/history/components/VersionsList.js.map +1 -1
  11. package/dist/admin/history/components/VersionsList.mjs +37 -43
  12. package/dist/admin/history/components/VersionsList.mjs.map +1 -1
  13. package/dist/admin/hooks/useContentManagerInitData.js +3 -2
  14. package/dist/admin/hooks/useContentManagerInitData.js.map +1 -1
  15. package/dist/admin/hooks/useContentManagerInitData.mjs +3 -2
  16. package/dist/admin/hooks/useContentManagerInitData.mjs.map +1 -1
  17. package/dist/admin/hooks/useDocumentActions.js +3 -1
  18. package/dist/admin/hooks/useDocumentActions.js.map +1 -1
  19. package/dist/admin/hooks/useDocumentActions.mjs +4 -2
  20. package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
  21. package/dist/admin/layout.js +2 -4
  22. package/dist/admin/layout.js.map +1 -1
  23. package/dist/admin/layout.mjs +2 -4
  24. package/dist/admin/layout.mjs.map +1 -1
  25. package/dist/admin/modules/app.js +3 -1
  26. package/dist/admin/modules/app.js.map +1 -1
  27. package/dist/admin/modules/app.mjs +3 -1
  28. package/dist/admin/modules/app.mjs.map +1 -1
  29. package/dist/admin/pages/EditView/EditViewPage.js +15 -20
  30. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  31. package/dist/admin/pages/EditView/EditViewPage.mjs +15 -20
  32. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  33. package/dist/admin/pages/EditView/components/DocumentActions.js +2 -0
  34. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  35. package/dist/admin/pages/EditView/components/DocumentActions.mjs +2 -0
  36. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  37. package/dist/admin/pages/EditView/components/EditorToolbarObserver.js +74 -7
  38. package/dist/admin/pages/EditView/components/EditorToolbarObserver.js.map +1 -1
  39. package/dist/admin/pages/EditView/components/EditorToolbarObserver.mjs +74 -7
  40. package/dist/admin/pages/EditView/components/EditorToolbarObserver.mjs.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +7 -2
  42. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
  43. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +7 -2
  44. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +59 -2
  46. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs +60 -3
  48. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js +4 -1
  50. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js.map +1 -1
  51. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs +4 -1
  52. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.mjs.map +1 -1
  53. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +4 -1
  54. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
  55. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs +4 -1
  56. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
  57. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js +2 -1
  58. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js.map +1 -1
  59. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs +2 -1
  60. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs.map +1 -1
  61. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +58 -1
  62. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  63. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +58 -2
  64. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  65. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js +25 -2
  66. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js.map +1 -1
  67. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs +5 -2
  68. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs.map +1 -1
  69. package/dist/admin/pages/EditView/components/InputRenderer.js +5 -1
  70. package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
  71. package/dist/admin/pages/EditView/components/InputRenderer.mjs +6 -2
  72. package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
  73. package/dist/admin/pages/ListView/ListViewPage.js +1 -0
  74. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  75. package/dist/admin/pages/ListView/ListViewPage.mjs +1 -0
  76. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  77. package/dist/admin/preview/components/InputPopover.js +64 -46
  78. package/dist/admin/preview/components/InputPopover.js.map +1 -1
  79. package/dist/admin/preview/components/InputPopover.mjs +66 -49
  80. package/dist/admin/preview/components/InputPopover.mjs.map +1 -1
  81. package/dist/admin/preview/hooks/usePreviewInputManager.js +23 -7
  82. package/dist/admin/preview/hooks/usePreviewInputManager.js.map +1 -1
  83. package/dist/admin/preview/hooks/usePreviewInputManager.mjs +25 -9
  84. package/dist/admin/preview/hooks/usePreviewInputManager.mjs.map +1 -1
  85. package/dist/admin/preview/pages/Preview.js +19 -0
  86. package/dist/admin/preview/pages/Preview.js.map +1 -1
  87. package/dist/admin/preview/pages/Preview.mjs +20 -1
  88. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  89. package/dist/admin/preview/utils/constants.js +9 -3
  90. package/dist/admin/preview/utils/constants.js.map +1 -1
  91. package/dist/admin/preview/utils/constants.mjs +9 -3
  92. package/dist/admin/preview/utils/constants.mjs.map +1 -1
  93. package/dist/admin/src/components/ActionsDrawer.d.ts +1 -0
  94. package/dist/admin/src/modules/app.d.ts +2 -0
  95. package/dist/admin/src/pages/EditView/components/EditorToolbarObserver.d.ts +2 -1
  96. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.d.ts +5 -1
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.d.ts +5 -0
  98. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +5 -0
  99. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.d.ts +2 -1
  100. package/dist/admin/src/pages/EditView/components/FormInputs/Relations/RelationModal.d.ts +14 -1
  101. package/dist/admin/src/preview/components/InputPopover.d.ts +2 -1
  102. package/dist/admin/src/preview/pages/Preview.d.ts +1 -0
  103. package/dist/admin/src/preview/utils/constants.d.ts +8 -1
  104. package/dist/admin/src/services/init.d.ts +1 -0
  105. package/dist/admin/src/utils/contentStructure.d.ts +59 -0
  106. package/dist/admin/utils/contentStructure.js +136 -0
  107. package/dist/admin/utils/contentStructure.js.map +1 -0
  108. package/dist/admin/utils/contentStructure.mjs +130 -0
  109. package/dist/admin/utils/contentStructure.mjs.map +1 -0
  110. package/dist/server/controllers/init.js +7 -2
  111. package/dist/server/controllers/init.js.map +1 -1
  112. package/dist/server/controllers/init.mjs +7 -2
  113. package/dist/server/controllers/init.mjs.map +1 -1
  114. package/dist/server/preview/controllers/previewScript.js +548 -22
  115. package/dist/server/services/content-structure.js +53 -0
  116. package/dist/server/services/content-structure.js.map +1 -0
  117. package/dist/server/services/content-structure.mjs +51 -0
  118. package/dist/server/services/content-structure.mjs.map +1 -0
  119. package/dist/server/services/index.js +2 -0
  120. package/dist/server/services/index.js.map +1 -1
  121. package/dist/server/services/index.mjs +2 -0
  122. package/dist/server/services/index.mjs.map +1 -1
  123. package/dist/server/src/controllers/index.d.ts +1 -1
  124. package/dist/server/src/controllers/init.d.ts +1 -1
  125. package/dist/server/src/controllers/init.d.ts.map +1 -1
  126. package/dist/server/src/index.d.ts +6 -1
  127. package/dist/server/src/index.d.ts.map +1 -1
  128. package/dist/server/src/services/content-structure.d.ts +8 -0
  129. package/dist/server/src/services/content-structure.d.ts.map +1 -0
  130. package/dist/server/src/services/index.d.ts +5 -0
  131. package/dist/server/src/services/index.d.ts.map +1 -1
  132. package/dist/server/src/utils/index.d.ts +2 -0
  133. package/dist/server/src/utils/index.d.ts.map +1 -1
  134. package/dist/server/utils/index.js.map +1 -1
  135. package/dist/server/utils/index.mjs.map +1 -1
  136. package/dist/shared/contracts/init.d.ts +2 -0
  137. package/dist/shared/contracts/init.d.ts.map +1 -1
  138. package/package.json +5 -5
@@ -92,6 +92,7 @@ const DrawerContentInner = styledComponents.styled(designSystem.ScrollArea)`
92
92
  `;
93
93
  const Root = ({ children, hasContent = false, hasSideNav = false })=>{
94
94
  const [isOpen, setIsOpen] = React__namespace.useState(false);
95
+ const [headerRef, { height: headerHeight }] = designSystem.useMeasure();
95
96
  // Close drawer when there's no content
96
97
  React__namespace.useEffect(()=>{
97
98
  if (!hasContent) {
@@ -100,16 +101,24 @@ const Root = ({ children, hasContent = false, hasSideNav = false })=>{
100
101
  }, [
101
102
  hasContent
102
103
  ]);
103
- return /*#__PURE__*/ jsxRuntime.jsx(ActionsDrawerProvider, {
104
+ return /*#__PURE__*/ jsxRuntime.jsxs(ActionsDrawerProvider, {
104
105
  isOpen: isOpen,
105
106
  setIsOpen: setIsOpen,
106
107
  hasContent: hasContent,
107
108
  hasSideNav: hasSideNav,
108
- children: /*#__PURE__*/ jsxRuntime.jsx(DrawerContainer, {
109
- $hasSideNav: hasSideNav,
110
- $isOpen: isOpen,
111
- children: children
112
- })
109
+ headerRef: headerRef,
110
+ children: [
111
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
112
+ height: `${headerHeight}px`,
113
+ shrink: 0,
114
+ "data-testid": "actions-drawer-spacer"
115
+ }),
116
+ /*#__PURE__*/ jsxRuntime.jsx(DrawerContainer, {
117
+ $hasSideNav: hasSideNav,
118
+ $isOpen: isOpen,
119
+ children: children
120
+ })
121
+ ]
113
122
  });
114
123
  };
115
124
  /* -------------------------------------------------------------------------------------------------
@@ -135,11 +144,13 @@ const Header = ({ children })=>{
135
144
  const isOpen = ctx?.isOpen ?? false;
136
145
  const hasContent = ctx?.hasContent ?? false;
137
146
  const setIsOpen = ctx?.setIsOpen;
147
+ const headerRef = ctx?.headerRef;
138
148
  const { formatMessage } = reactIntl.useIntl();
139
149
  const toggleOpen = ()=>{
140
150
  setIsOpen?.((prev)=>!prev);
141
151
  };
142
152
  return /*#__PURE__*/ jsxRuntime.jsx(DrawerContent, {
153
+ ref: headerRef,
143
154
  background: "neutral0",
144
155
  children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
145
156
  paddingTop: 3,
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsDrawer.js","sources":["../../../admin/src/components/ActionsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { WIDTH_SIDE_NAVIGATION, createContext } from '@strapi/admin/strapi-admin';\nimport { Portal, Flex, Box, ScrollArea, IconButton } from '@strapi/design-system';\nimport { CaretDown, CaretUp } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/**\n * ActionsDrawer is a component used in the content manager edit view page and content history page.\n * It's a sticky banner that can expand to reveal more actions. It's used only in mobile and tablet.\n *\n * A similar component is currently in development in the design-system but it's not ready yet.\n * Using the Panels for the edit view page brought some complexity and for the moment, we decided to go with this custom implementation.\n *\n * @TODO: Replace this component with the one in the design-system when it's ready.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ActionsDrawerContextValue {\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n hasContent: boolean;\n hasSideNav: boolean;\n}\n\nconst [ActionsDrawerProvider, useActionsDrawer] = createContext<ActionsDrawerContextValue | null>(\n 'ActionsDrawer',\n null\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Styled Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DrawerContainer = styled(Portal)<{ $hasSideNav: boolean; $isOpen: boolean }>`\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: ${({ $isOpen }) => ($isOpen ? 4 : 2)};\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-end;\n\n ${({ theme }) => theme.breakpoints.medium} {\n z-index: 2;\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst DrawerOverlay = styled(Box)<{ $isOpen: boolean; $hasSideNav: boolean }>`\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n opacity: ${({ $isOpen }) => ($isOpen ? 1 : 0)};\n pointer-events: ${({ $isOpen }) => ($isOpen ? 'auto' : 'none')};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst ToggleButton = styled(IconButton)`\n padding: 0;\n border: none;\n background: ${({ theme }) => theme.colors.neutral200};\n width: 3.2rem;\n height: 3.2rem;\n border-radius: 1.6rem;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst DrawerContent = styled(Flex)`\n flex-direction: column;\n align-items: stretch;\n position: relative;\n z-index: 1;\n pointer-events: auto;\n`;\n\nconst DrawerContentInner = styled(ScrollArea)<{ $isOpen: boolean }>`\n max-height: ${({ $isOpen }) =>\n $isOpen\n ? 'calc(100vh - 25rem)' // 25rem is arbitrary, to be able to see a bit of the content behind (navigation and header)\n : '0'};\n overflow: hidden;\n transition: max-height ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n z-index: 1;\n pointer-events: auto;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasContent?: boolean;\n hasSideNav?: boolean;\n}\n\nconst Root = ({ children, hasContent = false, hasSideNav = false }: RootProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n // Close drawer when there's no content\n React.useEffect(() => {\n if (!hasContent) {\n setIsOpen(false);\n }\n }, [hasContent]);\n\n return (\n <ActionsDrawerProvider\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n hasContent={hasContent}\n hasSideNav={hasSideNav}\n >\n <DrawerContainer $hasSideNav={hasSideNav} $isOpen={isOpen}>\n {children}\n </DrawerContainer>\n </ActionsDrawerProvider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Overlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst Overlay = () => {\n const ctx = useActionsDrawer('ActionsDrawer.Overlay', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const hasSideNav = ctx?.hasSideNav ?? false;\n const setIsOpen = ctx?.setIsOpen;\n\n if (!hasContent) {\n return null;\n }\n\n return (\n <DrawerOverlay\n $isOpen={isOpen}\n $hasSideNav={hasSideNav}\n onClick={() => setIsOpen?.(false)}\n data-testid=\"actions-drawer-overlay\"\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Header\n * -----------------------------------------------------------------------------------------------*/\n\ninterface HeaderProps {\n children: React.ReactNode;\n}\n\nconst Header = ({ children }: HeaderProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Header', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const setIsOpen = ctx?.setIsOpen;\n const { formatMessage } = useIntl();\n\n const toggleOpen = () => {\n setIsOpen?.((prev: boolean) => !prev);\n };\n\n return (\n <DrawerContent background=\"neutral0\">\n <Flex\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n gap={3}\n borderStyle=\"solid\"\n borderWidth={isOpen ? '1px 0' : '1px 0 0 0'}\n borderColor=\"neutral150\"\n >\n <Flex flex={1} gap={2} alignItems=\"center\" overflow=\"hidden\">\n {children}\n </Flex>\n {hasContent && (\n <ToggleButton\n onClick={toggleOpen}\n label={\n isOpen\n ? formatMessage({\n id: 'content-manager.actions-drawer.close',\n defaultMessage: 'Close more actions',\n })\n : formatMessage({\n id: 'content-manager.actions-drawer.open',\n defaultMessage: 'Open more actions',\n })\n }\n >\n {isOpen ? <CaretUp fill=\"neutral600\" /> : <CaretDown fill=\"neutral600\" />}\n </ToggleButton>\n )}\n </Flex>\n </DrawerContent>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ContentProps {\n children: React.ReactNode;\n}\n\nconst Content = ({ children }: ContentProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Content', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n\n return (\n <DrawerContentInner $isOpen={isOpen}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n justifyContent=\"flex-start\"\n padding={{ initial: 4, large: 0 }}\n background=\"neutral0\"\n >\n {children}\n </Flex>\n </DrawerContentInner>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nconst ActionsDrawer = {\n Root,\n Overlay,\n Header,\n Content,\n};\n\nexport { ActionsDrawer, useActionsDrawer };\n"],"names":["ActionsDrawerProvider","useActionsDrawer","createContext","DrawerContainer","styled","Portal","$isOpen","theme","breakpoints","medium","$hasSideNav","WIDTH_SIDE_NAVIGATION","DrawerOverlay","Box","props","motion","timings","easings","easeInOutQuad","ToggleButton","IconButton","colors","neutral200","DrawerContent","Flex","DrawerContentInner","ScrollArea","Root","children","hasContent","hasSideNav","isOpen","setIsOpen","React","useState","useEffect","_jsx","Overlay","ctx","s","onClick","data-testid","Header","formatMessage","useIntl","toggleOpen","prev","background","_jsxs","paddingTop","paddingBottom","paddingLeft","paddingRight","gap","borderStyle","borderWidth","borderColor","flex","alignItems","overflow","label","id","defaultMessage","CaretUp","fill","CaretDown","Content","direction","justifyContent","padding","initial","large","ActionsDrawer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,CAACA,qBAAAA,EAAuBC,gBAAAA,CAAiB,GAAGC,0BAChD,eAAA,EACA,IAAA;AAGF;;AAEkG,qGAElG,MAAMC,eAAAA,GAAkBC,uBAAAA,CAAOC,mBAAAA,CAAmD;;;;;AAKvE,WAAA,EAAE,CAAC,EAAEC,OAAO,EAAE,GAAMA,OAAAA,GAAU,IAAI,CAAA,CAAG;;;;;;EAM9C,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;AAElC,UAAA,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,WAAAA,GAAcC,oCAAwB,CAAA,CAAG;;AAE3E,CAAC;AAED,MAAMC,aAAAA,GAAgBR,uBAAAA,CAAOS,gBAAAA,CAAgD;;;;;;;sBAOvD,EAAE,CAACC,KAAAA,GAAUA,KAAAA,CAAMP,KAAK,CAACQ,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IAChE,EAAE,CAACF,KAAAA,GAAUA,KAAAA,CAAMP,KAAK,CAACQ,MAAM,CAACE,OAAO,CAACC,aAAa,CAAC;AAC/C,WAAA,EAAE,CAAC,EAAEZ,OAAO,EAAE,GAAMA,OAAAA,GAAU,IAAI,CAAA,CAAG;AAC9B,kBAAA,EAAE,CAAC,EAAEA,OAAO,EAAE,GAAMA,OAAAA,GAAU,SAAS,MAAA,CAAQ;;EAE/D,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;AAClC,UAAA,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,WAAAA,GAAcC,oCAAwB,CAAA,CAAG;;AAE3E,CAAC;AAED,MAAMQ,YAAAA,GAAef,uBAAAA,CAAOgB,uBAAAA,CAAW;;;cAGzB,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAAA,CAAMc,MAAM,CAACC,UAAU,CAAC;;;;;;;AAOvD,CAAC;AAED,MAAMC,aAAAA,GAAgBnB,uBAAAA,CAAOoB,iBAAAA,CAAK;;;;;;AAMlC,CAAC;AAED,MAAMC,kBAAAA,GAAqBrB,uBAAAA,CAAOsB,uBAAAA,CAAiC;AACrD,cAAA,EAAE,CAAC,EAAEpB,OAAO,EAAE,GACxBA,OAAAA,GACI;OACA,GAAA,CAAI;;yBAEa,EAAE,CAACQ,KAAAA,GAAUA,KAAAA,CAAMP,KAAK,CAACQ,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IACnE,EAAE,CAACF,KAAAA,GAAUA,KAAAA,CAAMP,KAAK,CAACQ,MAAM,CAACE,OAAO,CAACC,aAAa,CAAC;;;AAG1D,CAAC;AAYD,MAAMS,IAAAA,GAAO,CAAC,EAAEC,QAAQ,EAAEC,aAAa,KAAK,EAAEC,UAAAA,GAAa,KAAK,EAAa,GAAA;AAC3E,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAAA,CAAU,GAAGC,gBAAAA,CAAMC,QAAQ,CAAC,KAAA,CAAA;;AAG3CD,IAAAA,gBAAAA,CAAME,SAAS,CAAC,IAAA;AACd,QAAA,IAAI,CAACN,UAAAA,EAAY;YACfG,SAAAA,CAAU,KAAA,CAAA;AACZ,QAAA;IACF,CAAA,EAAG;AAACH,QAAAA;AAAW,KAAA,CAAA;AAEf,IAAA,qBACEO,cAAA,CAACpC,qBAAAA,EAAAA;QACC+B,MAAAA,EAAQA,MAAAA;QACRC,SAAAA,EAAWA,SAAAA;QACXH,UAAAA,EAAYA,UAAAA;QACZC,UAAAA,EAAYA,UAAAA;AAEZ,QAAA,QAAA,gBAAAM,cAAA,CAACjC,eAAAA,EAAAA;YAAgBO,WAAAA,EAAaoB,UAAAA;YAAYxB,OAAAA,EAASyB,MAAAA;AAChDH,YAAAA,QAAAA,EAAAA;;;AAIT,CAAA;AAEA;;AAEkG,qGAElG,MAAMS,OAAAA,GAAU,IAAA;AACd,IAAA,MAAMC,GAAAA,GAAMrC,gBAAAA,CAAiB,uBAAA,EAAyB,CAACsC,IAAMA,CAAAA,EAAG,KAAA,CAAA;IAChE,MAAMR,MAAAA,GAASO,KAAKP,MAAAA,IAAU,KAAA;IAC9B,MAAMF,UAAAA,GAAaS,KAAKT,UAAAA,IAAc,KAAA;IACtC,MAAMC,UAAAA,GAAaQ,KAAKR,UAAAA,IAAc,KAAA;AACtC,IAAA,MAAME,YAAYM,GAAAA,EAAKN,SAAAA;AAEvB,IAAA,IAAI,CAACH,UAAAA,EAAY;QACf,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,qBACEO,cAAA,CAACxB,aAAAA,EAAAA;QACCN,OAAAA,EAASyB,MAAAA;QACTrB,WAAAA,EAAaoB,UAAAA;AACbU,QAAAA,OAAAA,EAAS,IAAMR,SAAAA,GAAY,KAAA,CAAA;QAC3BS,aAAAA,EAAY;;AAGlB,CAAA;AAUA,MAAMC,MAAAA,GAAS,CAAC,EAAEd,QAAQ,EAAe,GAAA;AACvC,IAAA,MAAMU,GAAAA,GAAMrC,gBAAAA,CAAiB,sBAAA,EAAwB,CAACsC,IAAMA,CAAAA,EAAG,KAAA,CAAA;IAC/D,MAAMR,MAAAA,GAASO,KAAKP,MAAAA,IAAU,KAAA;IAC9B,MAAMF,UAAAA,GAAaS,KAAKT,UAAAA,IAAc,KAAA;AACtC,IAAA,MAAMG,YAAYM,GAAAA,EAAKN,SAAAA;IACvB,MAAM,EAAEW,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,MAAMC,UAAAA,GAAa,IAAA;QACjBb,SAAAA,GAAY,CAACc,OAAkB,CAACA,IAAAA,CAAAA;AAClC,IAAA,CAAA;AAEA,IAAA,qBACEV,cAAA,CAACb,aAAAA,EAAAA;QAAcwB,UAAAA,EAAW,UAAA;AACxB,QAAA,QAAA,gBAAAC,eAAA,CAACxB,iBAAAA,EAAAA;YACCyB,UAAAA,EAAY,CAAA;YACZC,aAAAA,EAAe,CAAA;YACfC,WAAAA,EAAa,CAAA;YACbC,YAAAA,EAAc,CAAA;YACdC,GAAAA,EAAK,CAAA;YACLC,WAAAA,EAAY,OAAA;AACZC,YAAAA,WAAAA,EAAaxB,SAAS,OAAA,GAAU,WAAA;YAChCyB,WAAAA,EAAY,YAAA;;8BAEZpB,cAAA,CAACZ,iBAAAA,EAAAA;oBAAKiC,IAAAA,EAAM,CAAA;oBAAGJ,GAAAA,EAAK,CAAA;oBAAGK,UAAAA,EAAW,QAAA;oBAASC,QAAAA,EAAS,QAAA;AACjD/B,oBAAAA,QAAAA,EAAAA;;AAEFC,gBAAAA,UAAAA,kBACCO,cAAA,CAACjB,YAAAA,EAAAA;oBACCqB,OAAAA,EAASK,UAAAA;AACTe,oBAAAA,KAAAA,EACE7B,SACIY,aAAAA,CAAc;wBACZkB,EAAAA,EAAI,sCAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA,CAAA,GACAnB,aAAAA,CAAc;wBACZkB,EAAAA,EAAI,qCAAA;wBACJC,cAAAA,EAAgB;AAClB,qBAAA,CAAA;AAGL/B,oBAAAA,QAAAA,EAAAA,MAAAA,iBAASK,cAAA,CAAC2B,aAAAA,EAAAA;wBAAQC,IAAAA,EAAK;uCAAkB5B,cAAA,CAAC6B,eAAAA,EAAAA;wBAAUD,IAAAA,EAAK;;;;;;AAMtE,CAAA;AAUA,MAAME,OAAAA,GAAU,CAAC,EAAEtC,QAAQ,EAAgB,GAAA;AACzC,IAAA,MAAMU,GAAAA,GAAMrC,gBAAAA,CAAiB,uBAAA,EAAyB,CAACsC,IAAMA,CAAAA,EAAG,KAAA,CAAA;IAChE,MAAMR,MAAAA,GAASO,KAAKP,MAAAA,IAAU,KAAA;AAE9B,IAAA,qBACEK,cAAA,CAACX,kBAAAA,EAAAA;QAAmBnB,OAAAA,EAASyB,MAAAA;AAC3B,QAAA,QAAA,gBAAAK,cAAA,CAACZ,iBAAAA,EAAAA;YACC2C,SAAAA,EAAU,QAAA;YACVT,UAAAA,EAAW,SAAA;YACXU,cAAAA,EAAe,YAAA;YACfC,OAAAA,EAAS;gBAAEC,OAAAA,EAAS,CAAA;gBAAGC,KAAAA,EAAO;AAAE,aAAA;YAChCxB,UAAAA,EAAW,UAAA;AAEVnB,YAAAA,QAAAA,EAAAA;;;AAIT,CAAA;AAEA;;AAEkG,2GAE5F4C,aAAAA,GAAgB;AACpB7C,IAAAA,IAAAA;AACAU,IAAAA,OAAAA;AACAK,IAAAA,MAAAA;AACAwB,IAAAA;AACF;;;;;"}
1
+ {"version":3,"file":"ActionsDrawer.js","sources":["../../../admin/src/components/ActionsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { WIDTH_SIDE_NAVIGATION, createContext } from '@strapi/admin/strapi-admin';\nimport { Portal, Flex, Box, ScrollArea, IconButton, useMeasure } from '@strapi/design-system';\nimport { CaretDown, CaretUp } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/**\n * ActionsDrawer is a component used in the content manager edit view page and content history page.\n * It's a sticky banner that can expand to reveal more actions. It's used only in mobile and tablet.\n *\n * A similar component is currently in development in the design-system but it's not ready yet.\n * Using the Panels for the edit view page brought some complexity and for the moment, we decided to go with this custom implementation.\n *\n * @TODO: Replace this component with the one in the design-system when it's ready.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ActionsDrawerContextValue {\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n hasContent: boolean;\n hasSideNav: boolean;\n headerRef: (element: HTMLDivElement) => void;\n}\n\nconst [ActionsDrawerProvider, useActionsDrawer] = createContext<ActionsDrawerContextValue | null>(\n 'ActionsDrawer',\n null\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Styled Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DrawerContainer = styled(Portal)<{ $hasSideNav: boolean; $isOpen: boolean }>`\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: ${({ $isOpen }) => ($isOpen ? 4 : 2)};\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-end;\n\n ${({ theme }) => theme.breakpoints.medium} {\n z-index: 2;\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst DrawerOverlay = styled(Box)<{ $isOpen: boolean; $hasSideNav: boolean }>`\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n opacity: ${({ $isOpen }) => ($isOpen ? 1 : 0)};\n pointer-events: ${({ $isOpen }) => ($isOpen ? 'auto' : 'none')};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst ToggleButton = styled(IconButton)`\n padding: 0;\n border: none;\n background: ${({ theme }) => theme.colors.neutral200};\n width: 3.2rem;\n height: 3.2rem;\n border-radius: 1.6rem;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst DrawerContent = styled(Flex)`\n flex-direction: column;\n align-items: stretch;\n position: relative;\n z-index: 1;\n pointer-events: auto;\n`;\n\nconst DrawerContentInner = styled(ScrollArea)<{ $isOpen: boolean }>`\n max-height: ${({ $isOpen }) =>\n $isOpen\n ? 'calc(100vh - 25rem)' // 25rem is arbitrary, to be able to see a bit of the content behind (navigation and header)\n : '0'};\n overflow: hidden;\n transition: max-height ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n z-index: 1;\n pointer-events: auto;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasContent?: boolean;\n hasSideNav?: boolean;\n}\n\nconst Root = ({ children, hasContent = false, hasSideNav = false }: RootProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [headerRef, { height: headerHeight }] = useMeasure<HTMLDivElement>();\n\n // Close drawer when there's no content\n React.useEffect(() => {\n if (!hasContent) {\n setIsOpen(false);\n }\n }, [hasContent]);\n\n return (\n <ActionsDrawerProvider\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n hasContent={hasContent}\n hasSideNav={hasSideNav}\n headerRef={headerRef}\n >\n <Box height={`${headerHeight}px`} shrink={0} data-testid=\"actions-drawer-spacer\" />\n <DrawerContainer $hasSideNav={hasSideNav} $isOpen={isOpen}>\n {children}\n </DrawerContainer>\n </ActionsDrawerProvider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Overlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst Overlay = () => {\n const ctx = useActionsDrawer('ActionsDrawer.Overlay', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const hasSideNav = ctx?.hasSideNav ?? false;\n const setIsOpen = ctx?.setIsOpen;\n\n if (!hasContent) {\n return null;\n }\n\n return (\n <DrawerOverlay\n $isOpen={isOpen}\n $hasSideNav={hasSideNav}\n onClick={() => setIsOpen?.(false)}\n data-testid=\"actions-drawer-overlay\"\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Header\n * -----------------------------------------------------------------------------------------------*/\n\ninterface HeaderProps {\n children: React.ReactNode;\n}\n\nconst Header = ({ children }: HeaderProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Header', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const setIsOpen = ctx?.setIsOpen;\n const headerRef = ctx?.headerRef;\n const { formatMessage } = useIntl();\n\n const toggleOpen = () => {\n setIsOpen?.((prev: boolean) => !prev);\n };\n\n return (\n <DrawerContent ref={headerRef} background=\"neutral0\">\n <Flex\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n gap={3}\n borderStyle=\"solid\"\n borderWidth={isOpen ? '1px 0' : '1px 0 0 0'}\n borderColor=\"neutral150\"\n >\n <Flex flex={1} gap={2} alignItems=\"center\" overflow=\"hidden\">\n {children}\n </Flex>\n {hasContent && (\n <ToggleButton\n onClick={toggleOpen}\n label={\n isOpen\n ? formatMessage({\n id: 'content-manager.actions-drawer.close',\n defaultMessage: 'Close more actions',\n })\n : formatMessage({\n id: 'content-manager.actions-drawer.open',\n defaultMessage: 'Open more actions',\n })\n }\n >\n {isOpen ? <CaretUp fill=\"neutral600\" /> : <CaretDown fill=\"neutral600\" />}\n </ToggleButton>\n )}\n </Flex>\n </DrawerContent>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ContentProps {\n children: React.ReactNode;\n}\n\nconst Content = ({ children }: ContentProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Content', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n\n return (\n <DrawerContentInner $isOpen={isOpen}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n justifyContent=\"flex-start\"\n padding={{ initial: 4, large: 0 }}\n background=\"neutral0\"\n >\n {children}\n </Flex>\n </DrawerContentInner>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nconst ActionsDrawer = {\n Root,\n Overlay,\n Header,\n Content,\n};\n\nexport { ActionsDrawer, useActionsDrawer };\n"],"names":["ActionsDrawerProvider","useActionsDrawer","createContext","DrawerContainer","styled","Portal","$isOpen","theme","breakpoints","medium","$hasSideNav","WIDTH_SIDE_NAVIGATION","DrawerOverlay","Box","props","motion","timings","easings","easeInOutQuad","ToggleButton","IconButton","colors","neutral200","DrawerContent","Flex","DrawerContentInner","ScrollArea","Root","children","hasContent","hasSideNav","isOpen","setIsOpen","React","useState","headerRef","height","headerHeight","useMeasure","useEffect","_jsxs","_jsx","shrink","data-testid","Overlay","ctx","s","onClick","Header","formatMessage","useIntl","toggleOpen","prev","ref","background","paddingTop","paddingBottom","paddingLeft","paddingRight","gap","borderStyle","borderWidth","borderColor","flex","alignItems","overflow","label","id","defaultMessage","CaretUp","fill","CaretDown","Content","direction","justifyContent","padding","initial","large","ActionsDrawer"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { createContext, WIDTH_SIDE_NAVIGATION } from '@strapi/admin/strapi-admin';
4
- import { Portal, Box, IconButton, Flex, ScrollArea } from '@strapi/design-system';
4
+ import { Portal, Box, IconButton, Flex, ScrollArea, useMeasure } from '@strapi/design-system';
5
5
  import { CaretUp, CaretDown } from '@strapi/icons';
6
6
  import { useIntl } from 'react-intl';
7
7
  import { styled } from 'styled-components';
@@ -70,6 +70,7 @@ const DrawerContentInner = styled(ScrollArea)`
70
70
  `;
71
71
  const Root = ({ children, hasContent = false, hasSideNav = false })=>{
72
72
  const [isOpen, setIsOpen] = React.useState(false);
73
+ const [headerRef, { height: headerHeight }] = useMeasure();
73
74
  // Close drawer when there's no content
74
75
  React.useEffect(()=>{
75
76
  if (!hasContent) {
@@ -78,16 +79,24 @@ const Root = ({ children, hasContent = false, hasSideNav = false })=>{
78
79
  }, [
79
80
  hasContent
80
81
  ]);
81
- return /*#__PURE__*/ jsx(ActionsDrawerProvider, {
82
+ return /*#__PURE__*/ jsxs(ActionsDrawerProvider, {
82
83
  isOpen: isOpen,
83
84
  setIsOpen: setIsOpen,
84
85
  hasContent: hasContent,
85
86
  hasSideNav: hasSideNav,
86
- children: /*#__PURE__*/ jsx(DrawerContainer, {
87
- $hasSideNav: hasSideNav,
88
- $isOpen: isOpen,
89
- children: children
90
- })
87
+ headerRef: headerRef,
88
+ children: [
89
+ /*#__PURE__*/ jsx(Box, {
90
+ height: `${headerHeight}px`,
91
+ shrink: 0,
92
+ "data-testid": "actions-drawer-spacer"
93
+ }),
94
+ /*#__PURE__*/ jsx(DrawerContainer, {
95
+ $hasSideNav: hasSideNav,
96
+ $isOpen: isOpen,
97
+ children: children
98
+ })
99
+ ]
91
100
  });
92
101
  };
93
102
  /* -------------------------------------------------------------------------------------------------
@@ -113,11 +122,13 @@ const Header = ({ children })=>{
113
122
  const isOpen = ctx?.isOpen ?? false;
114
123
  const hasContent = ctx?.hasContent ?? false;
115
124
  const setIsOpen = ctx?.setIsOpen;
125
+ const headerRef = ctx?.headerRef;
116
126
  const { formatMessage } = useIntl();
117
127
  const toggleOpen = ()=>{
118
128
  setIsOpen?.((prev)=>!prev);
119
129
  };
120
130
  return /*#__PURE__*/ jsx(DrawerContent, {
131
+ ref: headerRef,
121
132
  background: "neutral0",
122
133
  children: /*#__PURE__*/ jsxs(Flex, {
123
134
  paddingTop: 3,
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsDrawer.mjs","sources":["../../../admin/src/components/ActionsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { WIDTH_SIDE_NAVIGATION, createContext } from '@strapi/admin/strapi-admin';\nimport { Portal, Flex, Box, ScrollArea, IconButton } from '@strapi/design-system';\nimport { CaretDown, CaretUp } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/**\n * ActionsDrawer is a component used in the content manager edit view page and content history page.\n * It's a sticky banner that can expand to reveal more actions. It's used only in mobile and tablet.\n *\n * A similar component is currently in development in the design-system but it's not ready yet.\n * Using the Panels for the edit view page brought some complexity and for the moment, we decided to go with this custom implementation.\n *\n * @TODO: Replace this component with the one in the design-system when it's ready.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ActionsDrawerContextValue {\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n hasContent: boolean;\n hasSideNav: boolean;\n}\n\nconst [ActionsDrawerProvider, useActionsDrawer] = createContext<ActionsDrawerContextValue | null>(\n 'ActionsDrawer',\n null\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Styled Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DrawerContainer = styled(Portal)<{ $hasSideNav: boolean; $isOpen: boolean }>`\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: ${({ $isOpen }) => ($isOpen ? 4 : 2)};\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-end;\n\n ${({ theme }) => theme.breakpoints.medium} {\n z-index: 2;\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst DrawerOverlay = styled(Box)<{ $isOpen: boolean; $hasSideNav: boolean }>`\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n opacity: ${({ $isOpen }) => ($isOpen ? 1 : 0)};\n pointer-events: ${({ $isOpen }) => ($isOpen ? 'auto' : 'none')};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst ToggleButton = styled(IconButton)`\n padding: 0;\n border: none;\n background: ${({ theme }) => theme.colors.neutral200};\n width: 3.2rem;\n height: 3.2rem;\n border-radius: 1.6rem;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst DrawerContent = styled(Flex)`\n flex-direction: column;\n align-items: stretch;\n position: relative;\n z-index: 1;\n pointer-events: auto;\n`;\n\nconst DrawerContentInner = styled(ScrollArea)<{ $isOpen: boolean }>`\n max-height: ${({ $isOpen }) =>\n $isOpen\n ? 'calc(100vh - 25rem)' // 25rem is arbitrary, to be able to see a bit of the content behind (navigation and header)\n : '0'};\n overflow: hidden;\n transition: max-height ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n z-index: 1;\n pointer-events: auto;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasContent?: boolean;\n hasSideNav?: boolean;\n}\n\nconst Root = ({ children, hasContent = false, hasSideNav = false }: RootProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n // Close drawer when there's no content\n React.useEffect(() => {\n if (!hasContent) {\n setIsOpen(false);\n }\n }, [hasContent]);\n\n return (\n <ActionsDrawerProvider\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n hasContent={hasContent}\n hasSideNav={hasSideNav}\n >\n <DrawerContainer $hasSideNav={hasSideNav} $isOpen={isOpen}>\n {children}\n </DrawerContainer>\n </ActionsDrawerProvider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Overlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst Overlay = () => {\n const ctx = useActionsDrawer('ActionsDrawer.Overlay', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const hasSideNav = ctx?.hasSideNav ?? false;\n const setIsOpen = ctx?.setIsOpen;\n\n if (!hasContent) {\n return null;\n }\n\n return (\n <DrawerOverlay\n $isOpen={isOpen}\n $hasSideNav={hasSideNav}\n onClick={() => setIsOpen?.(false)}\n data-testid=\"actions-drawer-overlay\"\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Header\n * -----------------------------------------------------------------------------------------------*/\n\ninterface HeaderProps {\n children: React.ReactNode;\n}\n\nconst Header = ({ children }: HeaderProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Header', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const setIsOpen = ctx?.setIsOpen;\n const { formatMessage } = useIntl();\n\n const toggleOpen = () => {\n setIsOpen?.((prev: boolean) => !prev);\n };\n\n return (\n <DrawerContent background=\"neutral0\">\n <Flex\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n gap={3}\n borderStyle=\"solid\"\n borderWidth={isOpen ? '1px 0' : '1px 0 0 0'}\n borderColor=\"neutral150\"\n >\n <Flex flex={1} gap={2} alignItems=\"center\" overflow=\"hidden\">\n {children}\n </Flex>\n {hasContent && (\n <ToggleButton\n onClick={toggleOpen}\n label={\n isOpen\n ? formatMessage({\n id: 'content-manager.actions-drawer.close',\n defaultMessage: 'Close more actions',\n })\n : formatMessage({\n id: 'content-manager.actions-drawer.open',\n defaultMessage: 'Open more actions',\n })\n }\n >\n {isOpen ? <CaretUp fill=\"neutral600\" /> : <CaretDown fill=\"neutral600\" />}\n </ToggleButton>\n )}\n </Flex>\n </DrawerContent>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ContentProps {\n children: React.ReactNode;\n}\n\nconst Content = ({ children }: ContentProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Content', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n\n return (\n <DrawerContentInner $isOpen={isOpen}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n justifyContent=\"flex-start\"\n padding={{ initial: 4, large: 0 }}\n background=\"neutral0\"\n >\n {children}\n </Flex>\n </DrawerContentInner>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nconst ActionsDrawer = {\n Root,\n Overlay,\n Header,\n Content,\n};\n\nexport { ActionsDrawer, useActionsDrawer };\n"],"names":["ActionsDrawerProvider","useActionsDrawer","createContext","DrawerContainer","styled","Portal","$isOpen","theme","breakpoints","medium","$hasSideNav","WIDTH_SIDE_NAVIGATION","DrawerOverlay","Box","props","motion","timings","easings","easeInOutQuad","ToggleButton","IconButton","colors","neutral200","DrawerContent","Flex","DrawerContentInner","ScrollArea","Root","children","hasContent","hasSideNav","isOpen","setIsOpen","React","useState","useEffect","_jsx","Overlay","ctx","s","onClick","data-testid","Header","formatMessage","useIntl","toggleOpen","prev","background","_jsxs","paddingTop","paddingBottom","paddingLeft","paddingRight","gap","borderStyle","borderWidth","borderColor","flex","alignItems","overflow","label","id","defaultMessage","CaretUp","fill","CaretDown","Content","direction","justifyContent","padding","initial","large","ActionsDrawer"],"mappings":"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"}
1
+ {"version":3,"file":"ActionsDrawer.mjs","sources":["../../../admin/src/components/ActionsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { WIDTH_SIDE_NAVIGATION, createContext } from '@strapi/admin/strapi-admin';\nimport { Portal, Flex, Box, ScrollArea, IconButton, useMeasure } from '@strapi/design-system';\nimport { CaretDown, CaretUp } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/**\n * ActionsDrawer is a component used in the content manager edit view page and content history page.\n * It's a sticky banner that can expand to reveal more actions. It's used only in mobile and tablet.\n *\n * A similar component is currently in development in the design-system but it's not ready yet.\n * Using the Panels for the edit view page brought some complexity and for the moment, we decided to go with this custom implementation.\n *\n * @TODO: Replace this component with the one in the design-system when it's ready.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ActionsDrawerContextValue {\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n hasContent: boolean;\n hasSideNav: boolean;\n headerRef: (element: HTMLDivElement) => void;\n}\n\nconst [ActionsDrawerProvider, useActionsDrawer] = createContext<ActionsDrawerContextValue | null>(\n 'ActionsDrawer',\n null\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Styled Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DrawerContainer = styled(Portal)<{ $hasSideNav: boolean; $isOpen: boolean }>`\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: ${({ $isOpen }) => ($isOpen ? 4 : 2)};\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: flex-end;\n\n ${({ theme }) => theme.breakpoints.medium} {\n z-index: 2;\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst DrawerOverlay = styled(Box)<{ $isOpen: boolean; $hasSideNav: boolean }>`\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n opacity: ${({ $isOpen }) => ($isOpen ? 1 : 0)};\n pointer-events: ${({ $isOpen }) => ($isOpen ? 'auto' : 'none')};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: ${({ $hasSideNav }) => ($hasSideNav ? WIDTH_SIDE_NAVIGATION : 0)};\n }\n`;\n\nconst ToggleButton = styled(IconButton)`\n padding: 0;\n border: none;\n background: ${({ theme }) => theme.colors.neutral200};\n width: 3.2rem;\n height: 3.2rem;\n border-radius: 1.6rem;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst DrawerContent = styled(Flex)`\n flex-direction: column;\n align-items: stretch;\n position: relative;\n z-index: 1;\n pointer-events: auto;\n`;\n\nconst DrawerContentInner = styled(ScrollArea)<{ $isOpen: boolean }>`\n max-height: ${({ $isOpen }) =>\n $isOpen\n ? 'calc(100vh - 25rem)' // 25rem is arbitrary, to be able to see a bit of the content behind (navigation and header)\n : '0'};\n overflow: hidden;\n transition: max-height ${(props) => props.theme.motion.timings['200']}\n ${(props) => props.theme.motion.easings.easeInOutQuad};\n z-index: 1;\n pointer-events: auto;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface RootProps {\n children: React.ReactNode;\n hasContent?: boolean;\n hasSideNav?: boolean;\n}\n\nconst Root = ({ children, hasContent = false, hasSideNav = false }: RootProps) => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [headerRef, { height: headerHeight }] = useMeasure<HTMLDivElement>();\n\n // Close drawer when there's no content\n React.useEffect(() => {\n if (!hasContent) {\n setIsOpen(false);\n }\n }, [hasContent]);\n\n return (\n <ActionsDrawerProvider\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n hasContent={hasContent}\n hasSideNav={hasSideNav}\n headerRef={headerRef}\n >\n <Box height={`${headerHeight}px`} shrink={0} data-testid=\"actions-drawer-spacer\" />\n <DrawerContainer $hasSideNav={hasSideNav} $isOpen={isOpen}>\n {children}\n </DrawerContainer>\n </ActionsDrawerProvider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Overlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst Overlay = () => {\n const ctx = useActionsDrawer('ActionsDrawer.Overlay', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const hasSideNav = ctx?.hasSideNav ?? false;\n const setIsOpen = ctx?.setIsOpen;\n\n if (!hasContent) {\n return null;\n }\n\n return (\n <DrawerOverlay\n $isOpen={isOpen}\n $hasSideNav={hasSideNav}\n onClick={() => setIsOpen?.(false)}\n data-testid=\"actions-drawer-overlay\"\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Header\n * -----------------------------------------------------------------------------------------------*/\n\ninterface HeaderProps {\n children: React.ReactNode;\n}\n\nconst Header = ({ children }: HeaderProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Header', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n const hasContent = ctx?.hasContent ?? false;\n const setIsOpen = ctx?.setIsOpen;\n const headerRef = ctx?.headerRef;\n const { formatMessage } = useIntl();\n\n const toggleOpen = () => {\n setIsOpen?.((prev: boolean) => !prev);\n };\n\n return (\n <DrawerContent ref={headerRef} background=\"neutral0\">\n <Flex\n paddingTop={3}\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n gap={3}\n borderStyle=\"solid\"\n borderWidth={isOpen ? '1px 0' : '1px 0 0 0'}\n borderColor=\"neutral150\"\n >\n <Flex flex={1} gap={2} alignItems=\"center\" overflow=\"hidden\">\n {children}\n </Flex>\n {hasContent && (\n <ToggleButton\n onClick={toggleOpen}\n label={\n isOpen\n ? formatMessage({\n id: 'content-manager.actions-drawer.close',\n defaultMessage: 'Close more actions',\n })\n : formatMessage({\n id: 'content-manager.actions-drawer.open',\n defaultMessage: 'Open more actions',\n })\n }\n >\n {isOpen ? <CaretUp fill=\"neutral600\" /> : <CaretDown fill=\"neutral600\" />}\n </ToggleButton>\n )}\n </Flex>\n </DrawerContent>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ContentProps {\n children: React.ReactNode;\n}\n\nconst Content = ({ children }: ContentProps) => {\n const ctx = useActionsDrawer('ActionsDrawer.Content', (s) => s, false);\n const isOpen = ctx?.isOpen ?? false;\n\n return (\n <DrawerContentInner $isOpen={isOpen}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n justifyContent=\"flex-start\"\n padding={{ initial: 4, large: 0 }}\n background=\"neutral0\"\n >\n {children}\n </Flex>\n </DrawerContentInner>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ActionsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nconst ActionsDrawer = {\n Root,\n Overlay,\n Header,\n Content,\n};\n\nexport { ActionsDrawer, useActionsDrawer };\n"],"names":["ActionsDrawerProvider","useActionsDrawer","createContext","DrawerContainer","styled","Portal","$isOpen","theme","breakpoints","medium","$hasSideNav","WIDTH_SIDE_NAVIGATION","DrawerOverlay","Box","props","motion","timings","easings","easeInOutQuad","ToggleButton","IconButton","colors","neutral200","DrawerContent","Flex","DrawerContentInner","ScrollArea","Root","children","hasContent","hasSideNav","isOpen","setIsOpen","React","useState","headerRef","height","headerHeight","useMeasure","useEffect","_jsxs","_jsx","shrink","data-testid","Overlay","ctx","s","onClick","Header","formatMessage","useIntl","toggleOpen","prev","ref","background","paddingTop","paddingBottom","paddingLeft","paddingRight","gap","borderStyle","borderWidth","borderColor","flex","alignItems","overflow","label","id","defaultMessage","CaretUp","fill","CaretDown","Content","direction","justifyContent","padding","initial","large","ActionsDrawer"],"mappings":"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"}
@@ -8,6 +8,7 @@ var reactIntl = require('react-intl');
8
8
  var reactRouterDom = require('react-router-dom');
9
9
  var useContentManagerInitData = require('../hooks/useContentManagerInitData.js');
10
10
  var hooks = require('../modules/hooks.js');
11
+ var contentStructure = require('../utils/contentStructure.js');
11
12
  var translations = require('../utils/translations.js');
12
13
 
13
14
  function _interopNamespace(e) {
@@ -30,8 +31,18 @@ function _interopNamespace(e) {
30
31
 
31
32
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
32
33
 
34
+ const COLLAPSED_FOLDERS_KEY = 'STRAPI_CM_COLLAPSED_FOLDERS';
35
+ const getFolderToken = (sectionId, folderId)=>`${sectionId}/${folderId}`;
36
+ const collectFolderTokens = (sectionId, groups, tokens)=>{
37
+ for (const group of groups){
38
+ tokens.add(getFolderToken(sectionId, group.id));
39
+ const childGroups = group.children.filter((child)=>child.type === 'group');
40
+ collectFolderTokens(sectionId, childGroups, tokens);
41
+ }
42
+ };
33
43
  const LeftMenu = ({ isFullPage = false })=>{
34
44
  const [search, setSearch] = React__namespace.useState('');
45
+ const [storedCollapsedFolders, setStoredCollapsedFolders] = strapiAdmin.useScopedPersistentState(COLLAPSED_FOLDERS_KEY, []);
35
46
  const { formatMessage, locale } = reactIntl.useIntl();
36
47
  const { search: locationSearch } = reactRouterDom.useLocation();
37
48
  const i18nLocale = new URLSearchParams(locationSearch).get('plugins[i18n][locale]');
@@ -39,56 +50,54 @@ const LeftMenu = ({ isFullPage = false })=>{
39
50
  const { isLoading } = useContentManagerInitData.useContentManagerInitData();
40
51
  const collectionTypeLinks = hooks.useTypedSelector((state)=>state['content-manager'].app.collectionTypeLinks);
41
52
  const singleTypeLinks = hooks.useTypedSelector((state)=>state['content-manager'].app.singleTypeLinks);
53
+ const contentStructure$1 = hooks.useTypedSelector((state)=>state['content-manager'].app.contentStructure);
42
54
  const { contains } = designSystem.useFilter(locale, {
43
55
  sensitivity: 'base'
44
56
  });
45
57
  const formatter = designSystem.useCollator(locale, {
46
58
  sensitivity: 'base'
47
59
  });
48
- const menu = React__namespace.useMemo(()=>[
49
- {
50
- id: 'collectionTypes',
51
- title: formatMessage({
52
- id: translations.getTranslation('components.LeftMenu.collection-types'),
53
- defaultMessage: 'Collection Types'
54
- }),
55
- searchable: true,
56
- links: collectionTypeLinks
57
- },
58
- {
59
- id: 'singleTypes',
60
- title: formatMessage({
61
- id: translations.getTranslation('components.LeftMenu.single-types'),
62
- defaultMessage: 'Single Types'
63
- }),
64
- searchable: true,
65
- links: singleTypeLinks
66
- }
67
- ].map((section)=>({
68
- ...section,
69
- links: section.links/**
70
- * Filter by the search value
71
- */ .filter((link)=>contains(link.title, search.trim()))/**
72
- * Sort correctly using the language
73
- */ .sort((a, b)=>formatter.compare(a.title, b.title))/**
74
- * Apply the formated strings to the links from react-intl
75
- */ .map((link)=>{
76
- return {
77
- ...link,
78
- title: formatMessage({
79
- id: link.title,
80
- defaultMessage: link.title
81
- })
82
- };
83
- })
84
- })), [
60
+ const compareLinks = React__namespace.useCallback((a, b)=>{
61
+ return formatter.compare(a.title, b.title);
62
+ }, [
63
+ formatter
64
+ ]);
65
+ const collectionTypesLabel = formatMessage({
66
+ id: translations.getTranslation('components.LeftMenu.collection-types'),
67
+ defaultMessage: 'Collection Types'
68
+ });
69
+ const singleTypesLabel = formatMessage({
70
+ id: translations.getTranslation('components.LeftMenu.single-types'),
71
+ defaultMessage: 'Single Types'
72
+ });
73
+ const sections = React__namespace.useMemo(()=>{
74
+ const collectionTypesSection = contentStructure.buildContentStructureSection({
75
+ id: 'collectionTypes',
76
+ groups: contentStructure$1?.collectionTypes ?? [],
77
+ title: collectionTypesLabel,
78
+ links: collectionTypeLinks,
79
+ compareLinks
80
+ });
81
+ const singleTypesSection = contentStructure.buildContentStructureSection({
82
+ id: 'singleTypes',
83
+ groups: contentStructure$1?.singleTypes ?? [],
84
+ title: singleTypesLabel,
85
+ links: singleTypeLinks,
86
+ compareLinks
87
+ });
88
+ return [
89
+ collectionTypesSection,
90
+ singleTypesSection
91
+ ];
92
+ }, [
93
+ collectionTypesLabel,
85
94
  collectionTypeLinks,
86
- search,
95
+ singleTypesLabel,
96
+ contentStructure$1,
87
97
  singleTypeLinks,
88
- contains,
89
- formatMessage,
90
- formatter
98
+ compareLinks
91
99
  ]);
100
+ const trimmedSearch = search.trim();
92
101
  const handleClear = ()=>{
93
102
  setSearch('');
94
103
  };
@@ -99,6 +108,64 @@ const LeftMenu = ({ isFullPage = false })=>{
99
108
  id: translations.getTranslation('header.name'),
100
109
  defaultMessage: 'Content Manager'
101
110
  });
111
+ const formatLinkTitle = (link)=>formatMessage({
112
+ id: link.title,
113
+ defaultMessage: link.title
114
+ });
115
+ const linkTo = (link)=>({
116
+ pathname: link.to,
117
+ search: i18nLocale ? `?plugins[i18n][locale]=${i18nLocale}` : ''
118
+ });
119
+ const collapsedFolderTokens = Array.isArray(storedCollapsedFolders) ? storedCollapsedFolders : [];
120
+ const knownFolderTokens = React__namespace.useMemo(()=>{
121
+ if (!contentStructure$1) {
122
+ return null;
123
+ }
124
+ try {
125
+ const tokens = new Set();
126
+ collectFolderTokens('collectionTypes', contentStructure$1.collectionTypes, tokens);
127
+ collectFolderTokens('singleTypes', contentStructure$1.singleTypes, tokens);
128
+ return tokens;
129
+ } catch {
130
+ return null;
131
+ }
132
+ }, [
133
+ contentStructure$1
134
+ ]);
135
+ const handleFolderToggle = (token, open)=>{
136
+ setStoredCollapsedFolders((previous)=>{
137
+ const collapsed = Array.isArray(previous) ? previous : [];
138
+ const pruned = knownFolderTokens ? collapsed.filter((storedToken)=>knownFolderTokens.has(storedToken)) : collapsed;
139
+ if (open) {
140
+ return pruned.filter((storedToken)=>storedToken !== token);
141
+ }
142
+ if (pruned.includes(token)) {
143
+ return pruned;
144
+ }
145
+ return [
146
+ ...pruned,
147
+ token
148
+ ];
149
+ });
150
+ };
151
+ const renderMenuItem = (node, depth, sectionId)=>{
152
+ if (node.type === 'link') {
153
+ return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
154
+ label: formatLinkTitle(node.link),
155
+ to: linkTo(node.link),
156
+ depth: depth,
157
+ bulleted: true
158
+ }, node.link.uid);
159
+ }
160
+ const token = getFolderToken(sectionId, node.id);
161
+ return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Folder, {
162
+ label: node.name,
163
+ depth: depth,
164
+ open: !collapsedFolderTokens.includes(token),
165
+ onToggle: (open)=>handleFolderToggle(token, open),
166
+ children: node.children.map((child)=>renderMenuItem(child, depth + 1, sectionId))
167
+ }, node.id);
168
+ };
102
169
  // Show loading state while data is being fetched
103
170
  if (isLoading) {
104
171
  return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.SubNav.Main, {
@@ -169,19 +236,31 @@ const LeftMenu = ({ isFullPage = false })=>{
169
236
  }),
170
237
  /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Content, {
171
238
  children: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Sections, {
172
- children: menu.map((section)=>{
239
+ children: sections.map((section)=>{
240
+ const matches = trimmedSearch ? contentStructure.filterTreeLinks({
241
+ nodes: section.tree,
242
+ matchLink: (link)=>{
243
+ return contains(formatLinkTitle(link), trimmedSearch) || contains(link.uid, trimmedSearch);
244
+ },
245
+ matchFolderName: (name)=>{
246
+ return contains(name, trimmedSearch);
247
+ }
248
+ }).sort((a, b)=>compareLinks(a.link, b.link)) : null;
249
+ const count = matches ? matches.length : contentStructure.countTreeLinks(section.tree);
250
+ const sectionItems = matches ? matches.map(({ link, path })=>/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
251
+ label: formatLinkTitle(link),
252
+ to: linkTo(link),
253
+ bulleted: true,
254
+ endAction: path.length > 0 ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
255
+ variant: "pi",
256
+ textColor: "neutral500",
257
+ children: path.join(' / ')
258
+ }) : undefined
259
+ }, link.uid)) : section.tree.map((node)=>renderMenuItem(node, 0, section.id));
173
260
  return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Section, {
174
261
  label: section.title,
175
- badgeLabel: section.links.length.toString(),
176
- children: section.links.map((link)=>{
177
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
178
- to: {
179
- pathname: link.to,
180
- search: i18nLocale ? `?plugins[i18n][locale]=${i18nLocale}` : ''
181
- },
182
- label: link.title
183
- }, link.uid);
184
- })
262
+ badgeLabel: count.toString(),
263
+ children: sectionItems
185
264
  }, section.id);
186
265
  })
187
266
  })
@@ -1 +1 @@
1
- {"version":3,"file":"LeftMenu.js","sources":["../../../admin/src/components/LeftMenu.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { SubNav } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Searchbar,\n useCollator,\n useFilter,\n Divider,\n Loader,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { useLocation } from 'react-router-dom';\n\nimport { useContentManagerInitData } from '../hooks/useContentManagerInitData';\nimport { useTypedSelector } from '../modules/hooks';\nimport { getTranslation } from '../utils/translations';\n\nconst LeftMenu = ({ isFullPage = false }: { isFullPage?: boolean }) => {\n const [search, setSearch] = React.useState('');\n const { formatMessage, locale } = useIntl();\n const { search: locationSearch } = useLocation();\n const i18nLocale = new URLSearchParams(locationSearch).get('plugins[i18n][locale]');\n\n // Initialize Content Manager data to ensure links are available\n const { isLoading } = useContentManagerInitData();\n\n const collectionTypeLinks = useTypedSelector(\n (state) => state['content-manager'].app.collectionTypeLinks\n );\n\n const singleTypeLinks = useTypedSelector((state) => state['content-manager'].app.singleTypeLinks);\n\n const { contains } = useFilter(locale, {\n sensitivity: 'base',\n });\n\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const menu = React.useMemo(\n () =>\n [\n {\n id: 'collectionTypes',\n title: formatMessage({\n id: getTranslation('components.LeftMenu.collection-types'),\n defaultMessage: 'Collection Types',\n }),\n searchable: true,\n links: collectionTypeLinks,\n },\n {\n id: 'singleTypes',\n title: formatMessage({\n id: getTranslation('components.LeftMenu.single-types'),\n defaultMessage: 'Single Types',\n }),\n searchable: true,\n links: singleTypeLinks,\n },\n ].map((section) => ({\n ...section,\n links: section.links\n /**\n * Filter by the search value\n */\n .filter((link) => contains(link.title, search.trim()))\n /**\n * Sort correctly using the language\n */\n .sort((a, b) => formatter.compare(a.title, b.title))\n /**\n * Apply the formated strings to the links from react-intl\n */\n .map((link) => {\n return {\n ...link,\n title: formatMessage({ id: link.title, defaultMessage: link.title }),\n };\n }),\n })),\n [collectionTypeLinks, search, singleTypeLinks, contains, formatMessage, formatter]\n );\n\n const handleClear = () => {\n setSearch('');\n };\n\n const handleChangeSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearch(event.target.value);\n };\n\n const label = formatMessage({\n id: getTranslation('header.name'),\n defaultMessage: 'Content Manager',\n });\n\n // Show loading state while data is being fetched\n if (isLoading) {\n return (\n <SubNav.Main aria-label={label} isFullPage={isFullPage}>\n <SubNav.Header label={label} />\n <Divider />\n <Flex padding={4} justifyContent=\"center\">\n <Loader />\n </Flex>\n </SubNav.Main>\n );\n }\n\n const searchBar = (\n <Flex\n paddingLeft={{\n initial: 3,\n large: 5,\n }}\n paddingRight={{\n initial: 3,\n large: 5,\n }}\n paddingTop={5}\n paddingBottom={{ initial: 1, large: 0 }}\n gap={3}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <Searchbar\n value={search}\n onChange={handleChangeSearch}\n onClear={handleClear}\n placeholder={formatMessage({\n id: 'search.placeholder',\n defaultMessage: 'Search',\n })}\n size=\"S\"\n // eslint-disable-next-line react/no-children-prop\n children={undefined}\n name={'search_contentType'}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n />\n </Flex>\n );\n\n return (\n <SubNav.Main aria-label={label} isFullPage={isFullPage}>\n <SubNav.Header label={label} />\n <Divider />\n <Box\n position={isFullPage ? 'sticky' : 'static'}\n top={isFullPage ? '0px' : undefined}\n zIndex={isFullPage ? 2 : undefined}\n background={isFullPage ? 'neutral100' : 'neutral0'}\n >\n {searchBar}\n </Box>\n <SubNav.Content>\n <SubNav.Sections>\n {menu.map((section) => {\n return (\n <SubNav.Section\n key={section.id}\n label={section.title}\n badgeLabel={section.links.length.toString()}\n >\n {section.links.map((link) => {\n return (\n <SubNav.Link\n key={link.uid}\n to={{\n pathname: link.to,\n search: i18nLocale ? `?plugins[i18n][locale]=${i18nLocale}` : '',\n }}\n label={link.title}\n />\n );\n })}\n </SubNav.Section>\n );\n })}\n </SubNav.Sections>\n </SubNav.Content>\n </SubNav.Main>\n );\n};\n\nexport { LeftMenu };\n"],"names":["LeftMenu","isFullPage","search","setSearch","React","useState","formatMessage","locale","useIntl","locationSearch","useLocation","i18nLocale","URLSearchParams","get","isLoading","useContentManagerInitData","collectionTypeLinks","useTypedSelector","state","app","singleTypeLinks","contains","useFilter","sensitivity","formatter","useCollator","menu","useMemo","id","title","getTranslation","defaultMessage","searchable","links","map","section","filter","link","trim","sort","a","b","compare","handleClear","handleChangeSearch","event","target","value","label","_jsxs","SubNav","Main","aria-label","_jsx","Header","Divider","Flex","padding","justifyContent","Loader","searchBar","paddingLeft","initial","large","paddingRight","paddingTop","paddingBottom","gap","direction","alignItems","Searchbar","onChange","onClear","placeholder","size","children","undefined","name","clearLabel","Box","position","top","zIndex","background","Content","Sections","Section","badgeLabel","length","toString","Link","to","pathname","uid"],"mappings":"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"}
1
+ {"version":3,"file":"LeftMenu.js","sources":["../../../admin/src/components/LeftMenu.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { SubNav, useScopedPersistentState } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Searchbar,\n Typography,\n useCollator,\n useFilter,\n Divider,\n Loader,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { useLocation } from 'react-router-dom';\n\nimport { useContentManagerInitData } from '../hooks/useContentManagerInitData';\nimport { useTypedSelector } from '../modules/hooks';\nimport {\n countTreeLinks,\n buildContentStructureSection,\n filterTreeLinks,\n type LinkTreeNode,\n} from '../utils/contentStructure';\nimport { getTranslation } from '../utils/translations';\n\nimport type { ContentManagerLink } from '../hooks/useContentManagerInitData';\nimport type { Modules } from '@strapi/types';\n\nconst COLLAPSED_FOLDERS_KEY = 'STRAPI_CM_COLLAPSED_FOLDERS';\n\ntype SectionId = Modules.ContentStructure.ContentStructureSectionKey;\n\nconst getFolderToken = (sectionId: SectionId, folderId: string) => `${sectionId}/${folderId}`;\n\nconst collectFolderTokens = (\n sectionId: SectionId,\n groups: Modules.ContentStructure.ResolvedGroupNode[],\n tokens: Set<string>\n) => {\n for (const group of groups) {\n tokens.add(getFolderToken(sectionId, group.id));\n\n const childGroups = group.children.filter(\n (child): child is Modules.ContentStructure.ResolvedGroupNode => child.type === 'group'\n );\n\n collectFolderTokens(sectionId, childGroups, tokens);\n }\n};\n\nconst LeftMenu = ({ isFullPage = false }: { isFullPage?: boolean }) => {\n const [search, setSearch] = React.useState('');\n const [storedCollapsedFolders, setStoredCollapsedFolders] = useScopedPersistentState<string[]>(\n COLLAPSED_FOLDERS_KEY,\n []\n );\n const { formatMessage, locale } = useIntl();\n const { search: locationSearch } = useLocation();\n const i18nLocale = new URLSearchParams(locationSearch).get('plugins[i18n][locale]');\n\n // Initialize Content Manager data to ensure links are available\n const { isLoading } = useContentManagerInitData();\n\n const collectionTypeLinks = useTypedSelector(\n (state) => state['content-manager'].app.collectionTypeLinks\n );\n\n const singleTypeLinks = useTypedSelector((state) => state['content-manager'].app.singleTypeLinks);\n\n const contentStructure = useTypedSelector(\n (state) => state['content-manager'].app.contentStructure\n );\n\n const { contains } = useFilter(locale, {\n sensitivity: 'base',\n });\n\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const compareLinks = React.useCallback(\n (a: ContentManagerLink, b: ContentManagerLink) => {\n return formatter.compare(a.title, b.title);\n },\n [formatter]\n );\n\n const collectionTypesLabel = formatMessage({\n id: getTranslation('components.LeftMenu.collection-types'),\n defaultMessage: 'Collection Types',\n });\n\n const singleTypesLabel = formatMessage({\n id: getTranslation('components.LeftMenu.single-types'),\n defaultMessage: 'Single Types',\n });\n\n const sections = React.useMemo(() => {\n const collectionTypesSection = buildContentStructureSection({\n id: 'collectionTypes',\n groups: contentStructure?.collectionTypes ?? [],\n title: collectionTypesLabel,\n links: collectionTypeLinks,\n compareLinks,\n });\n\n const singleTypesSection = buildContentStructureSection({\n id: 'singleTypes',\n groups: contentStructure?.singleTypes ?? [],\n title: singleTypesLabel,\n links: singleTypeLinks,\n compareLinks,\n });\n\n return [collectionTypesSection, singleTypesSection];\n }, [\n collectionTypesLabel,\n collectionTypeLinks,\n singleTypesLabel,\n contentStructure,\n singleTypeLinks,\n compareLinks,\n ]);\n\n const trimmedSearch = search.trim();\n\n const handleClear = () => {\n setSearch('');\n };\n\n const handleChangeSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearch(event.target.value);\n };\n\n const label = formatMessage({\n id: getTranslation('header.name'),\n defaultMessage: 'Content Manager',\n });\n\n const formatLinkTitle = (link: ContentManagerLink) =>\n formatMessage({ id: link.title, defaultMessage: link.title });\n\n const linkTo = (link: ContentManagerLink) => ({\n pathname: link.to,\n search: i18nLocale ? `?plugins[i18n][locale]=${i18nLocale}` : '',\n });\n\n const collapsedFolderTokens = Array.isArray(storedCollapsedFolders) ? storedCollapsedFolders : [];\n\n const knownFolderTokens = React.useMemo(() => {\n if (!contentStructure) {\n return null;\n }\n\n try {\n const tokens = new Set<string>();\n\n collectFolderTokens('collectionTypes', contentStructure.collectionTypes, tokens);\n collectFolderTokens('singleTypes', contentStructure.singleTypes, tokens);\n\n return tokens;\n } catch {\n return null;\n }\n }, [contentStructure]);\n\n const handleFolderToggle = (token: string, open: boolean) => {\n setStoredCollapsedFolders((previous) => {\n const collapsed = Array.isArray(previous) ? previous : [];\n\n const pruned = knownFolderTokens\n ? collapsed.filter((storedToken) => knownFolderTokens.has(storedToken))\n : collapsed;\n\n if (open) {\n return pruned.filter((storedToken) => storedToken !== token);\n }\n\n if (pruned.includes(token)) {\n return pruned;\n }\n\n return [...pruned, token];\n });\n };\n\n const renderMenuItem = (\n node: LinkTreeNode,\n depth: number,\n sectionId: SectionId\n ): React.ReactNode => {\n if (node.type === 'link') {\n return (\n <SubNav.Link\n label={formatLinkTitle(node.link)}\n to={linkTo(node.link)}\n key={node.link.uid}\n depth={depth}\n bulleted\n />\n );\n }\n\n const token = getFolderToken(sectionId, node.id);\n\n return (\n <SubNav.Folder\n key={node.id}\n label={node.name}\n depth={depth}\n open={!collapsedFolderTokens.includes(token)}\n onToggle={(open) => handleFolderToggle(token, open)}\n >\n {node.children.map((child) => renderMenuItem(child, depth + 1, sectionId))}\n </SubNav.Folder>\n );\n };\n\n // Show loading state while data is being fetched\n if (isLoading) {\n return (\n <SubNav.Main aria-label={label} isFullPage={isFullPage}>\n <SubNav.Header label={label} />\n <Divider />\n <Flex padding={4} justifyContent=\"center\">\n <Loader />\n </Flex>\n </SubNav.Main>\n );\n }\n\n const searchBar = (\n <Flex\n paddingLeft={{\n initial: 3,\n large: 5,\n }}\n paddingRight={{\n initial: 3,\n large: 5,\n }}\n paddingTop={5}\n paddingBottom={{ initial: 1, large: 0 }}\n gap={3}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <Searchbar\n value={search}\n onChange={handleChangeSearch}\n onClear={handleClear}\n placeholder={formatMessage({\n id: 'search.placeholder',\n defaultMessage: 'Search',\n })}\n size=\"S\"\n // eslint-disable-next-line react/no-children-prop\n children={undefined}\n name={'search_contentType'}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n />\n </Flex>\n );\n\n return (\n <SubNav.Main aria-label={label} isFullPage={isFullPage}>\n <SubNav.Header label={label} />\n <Divider />\n <Box\n position={isFullPage ? 'sticky' : 'static'}\n top={isFullPage ? '0px' : undefined}\n zIndex={isFullPage ? 2 : undefined}\n background={isFullPage ? 'neutral100' : 'neutral0'}\n >\n {searchBar}\n </Box>\n <SubNav.Content>\n <SubNav.Sections>\n {sections.map((section) => {\n const matches = trimmedSearch\n ? filterTreeLinks({\n nodes: section.tree,\n matchLink: (link) => {\n return (\n contains(formatLinkTitle(link), trimmedSearch) ||\n contains(link.uid, trimmedSearch)\n );\n },\n matchFolderName: (name) => {\n return contains(name, trimmedSearch);\n },\n }).sort((a, b) => compareLinks(a.link, b.link))\n : null;\n\n const count = matches ? matches.length : countTreeLinks(section.tree);\n\n const sectionItems = matches\n ? matches.map(({ link, path }) => (\n <SubNav.Link\n label={formatLinkTitle(link)}\n to={linkTo(link)}\n key={link.uid}\n bulleted\n endAction={\n path.length > 0 ? (\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {path.join(' / ')}\n </Typography>\n ) : undefined\n }\n />\n ))\n : section.tree.map((node) => renderMenuItem(node, 0, section.id));\n\n return (\n <SubNav.Section key={section.id} label={section.title} badgeLabel={count.toString()}>\n {sectionItems}\n </SubNav.Section>\n );\n })}\n </SubNav.Sections>\n </SubNav.Content>\n </SubNav.Main>\n );\n};\n\nexport { LeftMenu };\n"],"names":["COLLAPSED_FOLDERS_KEY","getFolderToken","sectionId","folderId","collectFolderTokens","groups","tokens","group","add","id","childGroups","children","filter","child","type","LeftMenu","isFullPage","search","setSearch","React","useState","storedCollapsedFolders","setStoredCollapsedFolders","useScopedPersistentState","formatMessage","locale","useIntl","locationSearch","useLocation","i18nLocale","URLSearchParams","get","isLoading","useContentManagerInitData","collectionTypeLinks","useTypedSelector","state","app","singleTypeLinks","contentStructure","contains","useFilter","sensitivity","formatter","useCollator","compareLinks","useCallback","a","b","compare","title","collectionTypesLabel","getTranslation","defaultMessage","singleTypesLabel","sections","useMemo","collectionTypesSection","buildContentStructureSection","collectionTypes","links","singleTypesSection","singleTypes","trimmedSearch","trim","handleClear","handleChangeSearch","event","target","value","label","formatLinkTitle","link","linkTo","pathname","to","collapsedFolderTokens","Array","isArray","knownFolderTokens","Set","handleFolderToggle","token","open","previous","collapsed","pruned","storedToken","has","includes","renderMenuItem","node","depth","_jsx","SubNav","Link","bulleted","uid","Folder","name","onToggle","map","_jsxs","Main","aria-label","Header","Divider","Flex","padding","justifyContent","Loader","searchBar","paddingLeft","initial","large","paddingRight","paddingTop","paddingBottom","gap","direction","alignItems","Searchbar","onChange","onClear","placeholder","size","undefined","clearLabel","Box","position","top","zIndex","background","Content","Sections","section","matches","filterTreeLinks","nodes","tree","matchLink","matchFolderName","sort","count","length","countTreeLinks","sectionItems","path","endAction","Typography","variant","textColor","join","Section","badgeLabel","toString"],"mappings":"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"}