strapi-plugin-navigation 2.5.4 → 3.0.0-beta.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 (422) hide show
  1. package/README.md +21 -43
  2. package/admin/api/client.js +107 -0
  3. package/admin/api/index.js +1 -0
  4. package/admin/api/validators.js +248 -0
  5. package/admin/components/ConfirmationDialog/index.js +21 -0
  6. package/admin/components/Initializer.js +10 -0
  7. package/admin/components/RestartAlert/index.js +7 -0
  8. package/admin/components/TextArrayInput/index.js +18 -0
  9. package/admin/components/icons/index.js +1 -0
  10. package/admin/components/icons/navigation.js +9 -0
  11. package/admin/components/icons/pluginIcon.js +9 -0
  12. package/admin/index.js +48 -0
  13. package/admin/pages/App.js +10 -0
  14. package/admin/pages/HomePage/components/AdditionalFieldInput/index.js +58 -0
  15. package/admin/pages/HomePage/components/CollapseButton/index.js +15 -0
  16. package/admin/{src → pages/HomePage}/components/DragButton/index.js +9 -16
  17. package/admin/pages/HomePage/components/I18nCopyNavigationItems/index.js +9 -0
  18. package/admin/pages/HomePage/components/NavigationContentHeader/index.js +5 -0
  19. package/admin/pages/HomePage/components/NavigationHeader/hooks.js +14 -0
  20. package/admin/pages/HomePage/components/NavigationHeader/index.js +29 -0
  21. package/admin/pages/HomePage/components/NavigationHeader/styles.js +11 -0
  22. package/admin/pages/HomePage/components/NavigationItemForm/index.js +277 -0
  23. package/admin/pages/HomePage/components/NavigationItemForm/types.js +1 -0
  24. package/admin/pages/HomePage/components/NavigationItemForm/utils/form.js +105 -0
  25. package/admin/pages/HomePage/components/NavigationItemForm/utils/hooks.js +12 -0
  26. package/admin/pages/HomePage/components/NavigationItemForm/utils/properties.js +51 -0
  27. package/admin/pages/HomePage/components/NavigationItemList/Wrapper.js +21 -0
  28. package/admin/pages/HomePage/components/NavigationItemList/index.js +6 -0
  29. package/admin/pages/HomePage/components/NavigationItemListItem/ItemCardBadge/index.js +20 -0
  30. package/admin/pages/HomePage/components/NavigationItemListItem/ItemCardHeader/Wrapper.js +14 -0
  31. package/admin/pages/HomePage/components/NavigationItemListItem/ItemCardHeader/icons.js +6 -0
  32. package/admin/pages/HomePage/components/NavigationItemListItem/ItemCardHeader/index.js +19 -0
  33. package/admin/pages/HomePage/components/NavigationItemListItem/ItemCardRemovedOverlay/index.js +11 -0
  34. package/admin/pages/HomePage/components/NavigationItemListItem/Wrapper.js +38 -0
  35. package/admin/pages/HomePage/components/NavigationItemListItem/index.js +165 -0
  36. package/admin/pages/HomePage/components/NavigationItemPopup/NavigationItemPopupFooter.js +11 -0
  37. package/admin/pages/HomePage/components/NavigationItemPopup/NavigationItemPopupHeader.js +12 -0
  38. package/admin/pages/HomePage/components/NavigationItemPopup/index.js +34 -0
  39. package/admin/pages/HomePage/components/NavigationManager/AllNavigations/icons.js +5 -0
  40. package/admin/pages/HomePage/components/NavigationManager/AllNavigations/index.js +79 -0
  41. package/admin/pages/HomePage/components/NavigationManager/DeletionConfirm/index.js +25 -0
  42. package/admin/pages/HomePage/components/NavigationManager/ErrorDetails/index.js +29 -0
  43. package/admin/pages/HomePage/components/NavigationManager/Footer/index.js +6 -0
  44. package/admin/pages/HomePage/components/NavigationManager/Form/hooks.js +19 -0
  45. package/admin/pages/HomePage/components/NavigationManager/Form/index.js +26 -0
  46. package/admin/pages/HomePage/components/NavigationManager/NavigationUpdate/index.js +32 -0
  47. package/admin/pages/HomePage/components/NavigationManager/NewNavigation/index.js +35 -0
  48. package/admin/pages/HomePage/components/NavigationManager/PurgeCacheConfirm/index.js +25 -0
  49. package/admin/pages/HomePage/components/NavigationManager/index.js +236 -0
  50. package/admin/pages/HomePage/components/NavigationManager/types.js +1 -0
  51. package/admin/pages/HomePage/components/Search/index.js +58 -0
  52. package/admin/pages/HomePage/components/index.js +1 -0
  53. package/admin/pages/HomePage/hooks/index.js +165 -0
  54. package/admin/pages/HomePage/index.js +231 -0
  55. package/admin/pages/HomePage/utils/index.js +16 -0
  56. package/admin/pages/HomePage/utils/parsers.js +187 -0
  57. package/admin/pages/SettingsPage/common/const.js +1 -0
  58. package/admin/pages/SettingsPage/common/index.js +1 -0
  59. package/admin/pages/SettingsPage/components/CustomFieldForm/hooks/index.js +10 -0
  60. package/admin/pages/SettingsPage/components/CustomFieldForm/index.js +36 -0
  61. package/admin/pages/SettingsPage/components/CustomFieldModal/index.js +16 -0
  62. package/admin/pages/SettingsPage/components/CustomFieldTable/index.js +45 -0
  63. package/admin/pages/SettingsPage/hooks/index.js +111 -0
  64. package/admin/pages/SettingsPage/index.js +189 -0
  65. package/admin/pages/SettingsPage/types.js +1 -0
  66. package/admin/pages/SettingsPage/utils/index.js +25 -0
  67. package/admin/pluginId.js +1 -0
  68. package/admin/schemas/config.js +53 -0
  69. package/admin/schemas/content-type.js +14 -0
  70. package/admin/schemas/index.js +2 -0
  71. package/admin/{src/translations → translations}/en.json +7 -9
  72. package/admin/translations/index.js +15 -0
  73. package/admin/types.js +1 -0
  74. package/admin/utils/constants.js +1 -0
  75. package/admin/utils/getTranslation.js +4 -0
  76. package/admin/utils/permissions.js +16 -0
  77. package/admin/utils/prefixPluginTranslations.js +3 -0
  78. package/package.json +13 -11
  79. package/server/app-errors.js +20 -0
  80. package/server/bootstrap.js +13 -0
  81. package/server/cache/index.js +34 -15
  82. package/server/config/index.js +7 -5
  83. package/server/config/{setupStrategy.js → setup.js} +30 -26
  84. package/server/content-types/audience/index.js +0 -1
  85. package/server/content-types/audience/schema.js +0 -1
  86. package/server/content-types/index.js +4 -7
  87. package/server/content-types/navigation/index.js +0 -1
  88. package/server/content-types/navigation/lifecycles.js +1 -2
  89. package/server/content-types/navigation/schema.js +29 -32
  90. package/server/content-types/navigation-item/index.js +0 -1
  91. package/server/content-types/navigation-item/lifecycles.js +1 -2
  92. package/server/content-types/navigation-item/schema.js +51 -58
  93. package/server/controllers/admin.js +119 -158
  94. package/server/controllers/client.js +71 -60
  95. package/server/controllers/index.js +1 -3
  96. package/server/controllers/utils.js +22 -0
  97. package/{admin/src/hooks/useNavigationManager.js → server/controllers/validators.js} +23 -16
  98. package/server/destroy.js +3 -2
  99. package/{types/i18n.js → server/dtos/config.js} +0 -1
  100. package/server/{navigation → dtos}/index.js +3 -2
  101. package/server/dtos/navigation-item.js +2 -0
  102. package/{admin/src/pages/SettingsPage/types.js → server/dtos/navigation.js} +0 -1
  103. package/server/graphql/config.js +14 -16
  104. package/server/graphql/index.js +1 -2
  105. package/server/graphql/queries/index.js +8 -4
  106. package/server/graphql/queries/render-navigation-child.js +19 -8
  107. package/server/graphql/queries/render-navigation.js +30 -14
  108. package/server/graphql/resolvers-config.js +4 -2
  109. package/server/graphql/{setupStrategy.js → setup.js} +4 -5
  110. package/server/graphql/types/content-types-name-fields.js +10 -9
  111. package/server/graphql/types/content-types.js +15 -15
  112. package/server/graphql/types/create-navigation-item.js +16 -16
  113. package/server/graphql/types/create-navigation-related.js +7 -7
  114. package/server/graphql/types/create-navigation.js +6 -6
  115. package/server/graphql/types/index.js +35 -15
  116. package/server/graphql/types/navigation-config.js +8 -8
  117. package/server/graphql/types/navigation-details.js +2 -2
  118. package/server/graphql/types/navigation-item-additional-field-media.js +10 -10
  119. package/server/graphql/types/navigation-item-related-data.js +6 -6
  120. package/server/graphql/types/navigation-item-related.js +3 -3
  121. package/server/graphql/types/navigation-item.js +30 -27
  122. package/server/graphql/types/navigation-render-type.js +4 -5
  123. package/server/graphql/types/navigation.js +8 -8
  124. package/server/i18n/index.js +29 -20
  125. package/server/index.js +15 -8
  126. package/server/middlewares/index.js +3 -0
  127. package/server/permissions/index.js +10 -0
  128. package/{permissions.js → server/permissions/permissions.js} +0 -1
  129. package/server/permissions/setup.js +32 -0
  130. package/server/permissions.js +39 -0
  131. package/server/policies/index.js +3 -0
  132. package/server/register.js +6 -0
  133. package/server/repositories/audience.js +12 -0
  134. package/server/repositories/generic.js +20 -0
  135. package/server/repositories/index.js +11 -0
  136. package/server/repositories/navigation-item.js +51 -0
  137. package/server/repositories/navigation.js +65 -0
  138. package/server/routes/admin.js +86 -79
  139. package/server/routes/client.js +0 -1
  140. package/server/routes/index.js +0 -1
  141. package/server/schemas/config.js +68 -0
  142. package/server/schemas/content-type.js +140 -0
  143. package/{admin/src/pages/SettingsPage/common → server/schemas}/index.js +3 -2
  144. package/server/schemas/navigation.js +107 -0
  145. package/server/services/admin/admin.js +483 -0
  146. package/server/{content-types/navigations-items-related → services/admin}/index.js +2 -5
  147. package/{admin/src/pages/View/components/NavigationItemForm → server/services/admin}/types.js +0 -1
  148. package/server/services/admin/utils.js +84 -0
  149. package/server/services/client/client.js +397 -0
  150. package/server/services/client/index.js +7 -0
  151. package/{admin/src/pages/View/components/NavigationManager → server/services/client}/types.js +0 -1
  152. package/server/services/client/utils.js +88 -0
  153. package/server/services/common/common.js +307 -0
  154. package/server/services/common/index.js +7 -0
  155. package/{admin/src/components/AdditionalFieldInput → server/services/common}/types.js +0 -1
  156. package/server/services/common/utils.js +24 -0
  157. package/server/services/index.js +4 -6
  158. package/server/types.js +2 -0
  159. package/server/utils/constants.js +35 -0
  160. package/server/utils/functions.js +71 -299
  161. package/server/utils/index.js +1 -2
  162. package/strapi-admin.js +5 -8
  163. package/strapi-server.js +3 -7
  164. package/tsconfig.tsbuildinfo +1 -1
  165. package/admin/src/components/AdditionalFieldInput/index.d.ts +0 -5
  166. package/admin/src/components/AdditionalFieldInput/index.js +0 -99
  167. package/admin/src/components/AdditionalFieldInput/types.d.ts +0 -15
  168. package/admin/src/components/Alert/styles.d.ts +0 -2
  169. package/admin/src/components/Alert/styles.js +0 -14
  170. package/admin/src/components/CollapseButton/index.d.ts +0 -7
  171. package/admin/src/components/CollapseButton/index.js +0 -30
  172. package/admin/src/components/ConfirmationDialog/index.d.ts +0 -28
  173. package/admin/src/components/ConfirmationDialog/index.js +0 -34
  174. package/admin/src/components/DragButton/index.d.ts +0 -6
  175. package/admin/src/components/EmptyView/index.d.ts +0 -3
  176. package/admin/src/components/EmptyView/index.js +0 -30
  177. package/admin/src/components/Item/ItemCardBadge/index.d.ts +0 -3
  178. package/admin/src/components/Item/ItemCardBadge/index.js +0 -26
  179. package/admin/src/components/Item/ItemCardHeader/Wrapper.d.ts +0 -3
  180. package/admin/src/components/Item/ItemCardHeader/Wrapper.js +0 -21
  181. package/admin/src/components/Item/ItemCardHeader/icons.d.ts +0 -5
  182. package/admin/src/components/Item/ItemCardHeader/icons.js +0 -13
  183. package/admin/src/components/Item/ItemCardHeader/index.d.ts +0 -17
  184. package/admin/src/components/Item/ItemCardHeader/index.js +0 -38
  185. package/admin/src/components/Item/ItemCardRemovedOverlay/index.d.ts +0 -2
  186. package/admin/src/components/Item/ItemCardRemovedOverlay/index.js +0 -18
  187. package/admin/src/components/Item/Wrapper.d.ts +0 -3
  188. package/admin/src/components/Item/Wrapper.js +0 -43
  189. package/admin/src/components/Item/index.d.ts +0 -31
  190. package/admin/src/components/Item/index.js +0 -188
  191. package/admin/src/components/NavigationItemList/Wrapper.d.ts +0 -3
  192. package/admin/src/components/NavigationItemList/Wrapper.js +0 -26
  193. package/admin/src/components/NavigationItemList/index.d.ts +0 -36
  194. package/admin/src/components/NavigationItemList/index.js +0 -32
  195. package/admin/src/components/RestartAlert/index.d.ts +0 -3
  196. package/admin/src/components/RestartAlert/index.js +0 -13
  197. package/admin/src/components/Search/index.d.ts +0 -12
  198. package/admin/src/components/Search/index.js +0 -97
  199. package/admin/src/components/TextArrayInput/index.d.ts +0 -15
  200. package/admin/src/components/TextArrayInput/index.js +0 -45
  201. package/admin/src/components/icons/navigation.d.ts +0 -6
  202. package/admin/src/components/icons/navigation.js +0 -12
  203. package/admin/src/contexts/DataManagerContext.d.ts +0 -3
  204. package/admin/src/contexts/DataManagerContext.js +0 -6
  205. package/admin/src/hooks/useAllContentTypes.d.ts +0 -3
  206. package/admin/src/hooks/useAllContentTypes.js +0 -8
  207. package/admin/src/hooks/useDataManager.d.ts +0 -3
  208. package/admin/src/hooks/useDataManager.js +0 -10
  209. package/admin/src/hooks/useI18nCopyNavigationItemsModal.d.ts +0 -9
  210. package/admin/src/hooks/useI18nCopyNavigationItemsModal.js +0 -51
  211. package/admin/src/hooks/useNavigationConfig.d.ts +0 -10
  212. package/admin/src/hooks/useNavigationConfig.js +0 -54
  213. package/admin/src/hooks/useNavigationManager.d.ts +0 -6
  214. package/admin/src/index.d.ts +0 -14
  215. package/admin/src/index.js +0 -87
  216. package/admin/src/pages/App/index.d.ts +0 -3
  217. package/admin/src/pages/App/index.js +0 -43
  218. package/admin/src/pages/DataManagerProvider/actions.d.ts +0 -21
  219. package/admin/src/pages/DataManagerProvider/actions.js +0 -24
  220. package/admin/src/pages/DataManagerProvider/index.d.ts +0 -12
  221. package/admin/src/pages/DataManagerProvider/index.js +0 -382
  222. package/admin/src/pages/DataManagerProvider/init.d.ts +0 -3
  223. package/admin/src/pages/DataManagerProvider/init.js +0 -7
  224. package/admin/src/pages/DataManagerProvider/reducer.d.ts +0 -20
  225. package/admin/src/pages/DataManagerProvider/reducer.js +0 -132
  226. package/admin/src/pages/NoAccessPage/index.d.ts +0 -3
  227. package/admin/src/pages/NoAccessPage/index.js +0 -31
  228. package/admin/src/pages/SettingsPage/common/const.d.ts +0 -2
  229. package/admin/src/pages/SettingsPage/common/const.js +0 -5
  230. package/admin/src/pages/SettingsPage/common/index.d.ts +0 -2
  231. package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.d.ts +0 -12
  232. package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.js +0 -129
  233. package/admin/src/pages/SettingsPage/components/CustomFieldModal/index.d.ts +0 -12
  234. package/admin/src/pages/SettingsPage/components/CustomFieldModal/index.js +0 -20
  235. package/admin/src/pages/SettingsPage/components/CustomFieldTable/index.d.ts +0 -11
  236. package/admin/src/pages/SettingsPage/components/CustomFieldTable/index.js +0 -105
  237. package/admin/src/pages/SettingsPage/components/DisableI18nModal/index.d.ts +0 -23
  238. package/admin/src/pages/SettingsPage/components/DisableI18nModal/index.js +0 -86
  239. package/admin/src/pages/SettingsPage/index.d.ts +0 -3
  240. package/admin/src/pages/SettingsPage/index.js +0 -321
  241. package/admin/src/pages/SettingsPage/types.d.ts +0 -35
  242. package/admin/src/pages/SettingsPage/utils/form.d.ts +0 -20
  243. package/admin/src/pages/SettingsPage/utils/form.js +0 -37
  244. package/admin/src/pages/SettingsPage/utils/functions.d.ts +0 -3
  245. package/admin/src/pages/SettingsPage/utils/functions.js +0 -26
  246. package/admin/src/pages/View/components/I18nCopyNavigationItems/index.d.ts +0 -14
  247. package/admin/src/pages/View/components/I18nCopyNavigationItems/index.js +0 -15
  248. package/admin/src/pages/View/components/NavigationContentHeader/index.d.ts +0 -6
  249. package/admin/src/pages/View/components/NavigationContentHeader/index.js +0 -14
  250. package/admin/src/pages/View/components/NavigationHeader/index.d.ts +0 -14
  251. package/admin/src/pages/View/components/NavigationHeader/index.js +0 -92
  252. package/admin/src/pages/View/components/NavigationHeader/styles.d.ts +0 -2
  253. package/admin/src/pages/View/components/NavigationHeader/styles.js +0 -18
  254. package/admin/src/pages/View/components/NavigationItemForm/index.d.ts +0 -5
  255. package/admin/src/pages/View/components/NavigationItemForm/index.js +0 -470
  256. package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +0 -99
  257. package/admin/src/pages/View/components/NavigationItemForm/utils/form.d.ts +0 -28
  258. package/admin/src/pages/View/components/NavigationItemForm/utils/form.js +0 -123
  259. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.d.ts +0 -25
  260. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +0 -31
  261. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.d.ts +0 -5
  262. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +0 -20
  263. package/admin/src/pages/View/components/NavigationItemPopup/index.d.ts +0 -33
  264. package/admin/src/pages/View/components/NavigationItemPopup/index.js +0 -90
  265. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +0 -4
  266. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.js +0 -12
  267. package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.d.ts +0 -8
  268. package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.js +0 -151
  269. package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.d.ts +0 -8
  270. package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.js +0 -34
  271. package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.d.ts +0 -8
  272. package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.js +0 -53
  273. package/admin/src/pages/View/components/NavigationManager/Footer/index.d.ts +0 -24
  274. package/admin/src/pages/View/components/NavigationManager/Footer/index.js +0 -13
  275. package/admin/src/pages/View/components/NavigationManager/Form/index.d.ts +0 -19
  276. package/admin/src/pages/View/components/NavigationManager/Form/index.js +0 -103
  277. package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.d.ts +0 -8
  278. package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.js +0 -59
  279. package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.d.ts +0 -9
  280. package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.js +0 -62
  281. package/admin/src/pages/View/components/NavigationManager/PurgeCacheConfirm/index.d.ts +0 -8
  282. package/admin/src/pages/View/components/NavigationManager/PurgeCacheConfirm/index.js +0 -34
  283. package/admin/src/pages/View/components/NavigationManager/index.d.ts +0 -10
  284. package/admin/src/pages/View/components/NavigationManager/index.js +0 -203
  285. package/admin/src/pages/View/components/NavigationManager/types.d.ts +0 -44
  286. package/admin/src/pages/View/index.d.ts +0 -4
  287. package/admin/src/pages/View/index.js +0 -269
  288. package/admin/src/pages/View/utils/form.d.ts +0 -2
  289. package/admin/src/pages/View/utils/form.js +0 -16
  290. package/admin/src/pages/View/utils/index.d.ts +0 -2
  291. package/admin/src/pages/View/utils/index.js +0 -11
  292. package/admin/src/pages/View/utils/parsers.d.ts +0 -51
  293. package/admin/src/pages/View/utils/parsers.js +0 -272
  294. package/admin/src/pages/View/utils/types.d.ts +0 -3
  295. package/admin/src/pages/View/utils/types.js +0 -3
  296. package/admin/src/permissions.d.ts +0 -16
  297. package/admin/src/permissions.js +0 -13
  298. package/admin/src/pluginId.d.ts +0 -3
  299. package/admin/src/pluginId.js +0 -5
  300. package/admin/src/translations/index.d.ts +0 -15
  301. package/admin/src/translations/index.js +0 -21
  302. package/admin/src/utils/api.d.ts +0 -9
  303. package/admin/src/utils/api.js +0 -20
  304. package/admin/src/utils/enums.d.ts +0 -25
  305. package/admin/src/utils/enums.js +0 -30
  306. package/admin/src/utils/functions.d.ts +0 -16
  307. package/admin/src/utils/functions.js +0 -46
  308. package/admin/src/utils/index.d.ts +0 -4
  309. package/admin/src/utils/index.js +0 -20
  310. package/permissions.d.ts +0 -10
  311. package/server/bootstrap/index.d.ts +0 -4
  312. package/server/bootstrap/index.js +0 -50
  313. package/server/cache/index.d.ts +0 -2
  314. package/server/cache/serviceEnhancers.d.ts +0 -3
  315. package/server/cache/serviceEnhancers.js +0 -16
  316. package/server/cache/setupStrategy.d.ts +0 -3
  317. package/server/cache/setupStrategy.js +0 -38
  318. package/server/cache/types.d.ts +0 -11
  319. package/server/cache/types.js +0 -3
  320. package/server/cache/utils.d.ts +0 -11
  321. package/server/cache/utils.js +0 -19
  322. package/server/config/index.d.ts +0 -5
  323. package/server/config/setupStrategy.d.ts +0 -3
  324. package/server/content-types/audience/index.d.ts +0 -27
  325. package/server/content-types/audience/schema.d.ts +0 -25
  326. package/server/content-types/index.d.ts +0 -244
  327. package/server/content-types/navigation/index.d.ts +0 -59
  328. package/server/content-types/navigation/lifecycles.d.ts +0 -3
  329. package/server/content-types/navigation/schema.d.ts +0 -56
  330. package/server/content-types/navigation-item/index.d.ts +0 -111
  331. package/server/content-types/navigation-item/lifecycles.d.ts +0 -3
  332. package/server/content-types/navigation-item/schema.d.ts +0 -108
  333. package/server/content-types/navigations-items-related/index.d.ts +0 -51
  334. package/server/content-types/navigations-items-related/schema.d.ts +0 -49
  335. package/server/content-types/navigations-items-related/schema.js +0 -50
  336. package/server/controllers/admin.d.ts +0 -4
  337. package/server/controllers/client.d.ts +0 -4
  338. package/server/controllers/index.d.ts +0 -4
  339. package/server/destroy.d.ts +0 -3
  340. package/server/graphql/config.d.ts +0 -4
  341. package/server/graphql/index.d.ts +0 -2
  342. package/server/graphql/queries/index.d.ts +0 -3
  343. package/server/graphql/queries/render-navigation-child.d.ts +0 -15
  344. package/server/graphql/queries/render-navigation.d.ts +0 -21
  345. package/server/graphql/resolvers-config.d.ts +0 -10
  346. package/server/graphql/setupStrategy.d.ts +0 -3
  347. package/server/graphql/types/content-types-name-fields.d.ts +0 -6
  348. package/server/graphql/types/content-types.d.ts +0 -5
  349. package/server/graphql/types/create-navigation-item.d.ts +0 -5
  350. package/server/graphql/types/create-navigation-related.d.ts +0 -5
  351. package/server/graphql/types/create-navigation.d.ts +0 -5
  352. package/server/graphql/types/index.d.ts +0 -3
  353. package/server/graphql/types/navigation-config.d.ts +0 -5
  354. package/server/graphql/types/navigation-details.d.ts +0 -5
  355. package/server/graphql/types/navigation-item-additional-field-media.d.ts +0 -5
  356. package/server/graphql/types/navigation-item-related-data.d.ts +0 -5
  357. package/server/graphql/types/navigation-item-related.d.ts +0 -7
  358. package/server/graphql/types/navigation-item.d.ts +0 -6
  359. package/server/graphql/types/navigation-render-type.d.ts +0 -5
  360. package/server/graphql/types/navigation.d.ts +0 -5
  361. package/server/i18n/constant.d.ts +0 -2
  362. package/server/i18n/constant.js +0 -5
  363. package/server/i18n/errors.d.ts +0 -7
  364. package/server/i18n/errors.js +0 -14
  365. package/server/i18n/graphQLEnhancers.d.ts +0 -10
  366. package/server/i18n/graphQLEnhancers.js +0 -10
  367. package/server/i18n/index.d.ts +0 -8
  368. package/server/i18n/navigationSetupStrategy.d.ts +0 -3
  369. package/server/i18n/navigationSetupStrategy.js +0 -147
  370. package/server/i18n/serviceEnhancers.d.ts +0 -13
  371. package/server/i18n/serviceEnhancers.js +0 -156
  372. package/server/i18n/types.d.ts +0 -60
  373. package/server/i18n/types.js +0 -3
  374. package/server/i18n/utils.d.ts +0 -13
  375. package/server/i18n/utils.js +0 -33
  376. package/server/index.d.ts +0 -262
  377. package/server/navigation/index.d.ts +0 -2
  378. package/server/navigation/setupStrategy.d.ts +0 -3
  379. package/server/navigation/setupStrategy.js +0 -39
  380. package/server/register/index.d.ts +0 -3
  381. package/server/register/index.js +0 -4
  382. package/server/routes/admin.d.ts +0 -4
  383. package/server/routes/client.d.ts +0 -4
  384. package/server/routes/index.d.ts +0 -6
  385. package/server/services/admin.d.ts +0 -5
  386. package/server/services/admin.js +0 -347
  387. package/server/services/client.d.ts +0 -5
  388. package/server/services/client.js +0 -335
  389. package/server/services/common.d.ts +0 -5
  390. package/server/services/common.js +0 -385
  391. package/server/services/index.d.ts +0 -7
  392. package/server/utils/constant.d.ts +0 -27
  393. package/server/utils/constant.js +0 -43
  394. package/server/utils/functions.d.ts +0 -157
  395. package/server/utils/index.d.ts +0 -3
  396. package/strapi-admin.d.ts +0 -3
  397. package/strapi-server.d.ts +0 -262
  398. package/types/bootstrap.d.ts +0 -16
  399. package/types/bootstrap.js +0 -3
  400. package/types/config.d.ts +0 -27
  401. package/types/config.js +0 -3
  402. package/types/contentTypes.d.ts +0 -112
  403. package/types/contentTypes.js +0 -3
  404. package/types/controllers.d.ts +0 -65
  405. package/types/controllers.js +0 -5
  406. package/types/graphQL.d.ts +0 -3
  407. package/types/graphQL.js +0 -3
  408. package/types/i18n.d.ts +0 -9
  409. package/types/index.d.ts +0 -10
  410. package/types/index.js +0 -26
  411. package/types/lifecycle.d.ts +0 -22
  412. package/types/lifecycle.js +0 -3
  413. package/types/services.d.ts +0 -106
  414. package/types/services.js +0 -3
  415. package/types/utils.d.ts +0 -72
  416. package/types/utils.js +0 -41
  417. package/utils/InvalidParamNavigationError.d.ts +0 -4
  418. package/utils/InvalidParamNavigationError.js +0 -8
  419. package/utils/NavigationError.d.ts +0 -5
  420. package/utils/NavigationError.js +0 -11
  421. /package/admin/{src/translations → translations}/ca.json +0 -0
  422. /package/admin/{src/translations → translations}/fr.json +0 -0
@@ -0,0 +1,111 @@
1
+ import { zodResolver } from '@hookform/resolvers/zod';
2
+ import { getFetchClient } from '@strapi/strapi/admin';
3
+ import { useMutation, useQuery } from '@tanstack/react-query';
4
+ import { useForm } from 'react-hook-form';
5
+ import { z } from 'zod';
6
+ import { getApiClient } from '../../../api';
7
+ import { configSchema } from '../../../schemas';
8
+ import { resolveGlobalLikeId } from '../utils';
9
+ export const useConfig = () => {
10
+ // TODO: Resolve useQuery issues to use useFetchClient
11
+ const fetch = getFetchClient();
12
+ const apiClient = getApiClient(fetch);
13
+ return useQuery({
14
+ queryKey: apiClient.readSettingsConfigIndex(),
15
+ queryFn() {
16
+ return apiClient.readSettingsConfig();
17
+ },
18
+ staleTime: 1000 * 60 * 5,
19
+ });
20
+ };
21
+ export const useRestart = () => {
22
+ const fetch = getFetchClient();
23
+ const apiClient = getApiClient(fetch);
24
+ return useMutation({
25
+ mutationFn: () => apiClient.restart(),
26
+ });
27
+ };
28
+ export const useRestoreConfig = () => {
29
+ const fetch = getFetchClient();
30
+ const apiClient = getApiClient(fetch);
31
+ return useMutation({
32
+ mutationFn: () => apiClient.restoreConfig(),
33
+ });
34
+ };
35
+ export const useContentTypes = () => {
36
+ const fetch = getFetchClient();
37
+ const apiClient = getApiClient(fetch);
38
+ return useQuery({
39
+ queryKey: apiClient.readContentTypeIndex(),
40
+ queryFn: () => apiClient.readContentType(),
41
+ staleTime: Infinity,
42
+ });
43
+ };
44
+ export const useSaveConfig = () => {
45
+ const fetch = getFetchClient();
46
+ const apiClient = getApiClient(fetch);
47
+ return useMutation({
48
+ mutationFn(data) {
49
+ return apiClient.updateConfig({
50
+ ...data,
51
+ contentTypesNameFields: Object.fromEntries(data.contentTypesNameFields.map(({ key, fields }) => [key, fields])),
52
+ contentTypesPopulate: Object.fromEntries(data.contentTypesPopulate.map(({ key, fields }) => [key, fields])),
53
+ pathDefaultFields: Object.fromEntries(data.pathDefaultFields.map(({ key, fields }) => [key, fields])),
54
+ additionalFields: data.audienceFieldChecked
55
+ ? [...data.additionalFields, 'audience']
56
+ : data.additionalFields,
57
+ gql: {
58
+ navigationItemRelated: data.contentTypes.map((uid) => {
59
+ return resolveGlobalLikeId(uid);
60
+ }),
61
+ },
62
+ });
63
+ },
64
+ });
65
+ };
66
+ export const uiFormSchema = configSchema.omit({ contentTypesNameFields: true }).extend({
67
+ audienceFieldChecked: z.boolean(),
68
+ contentTypesNameFields: z
69
+ .object({
70
+ key: z.string(),
71
+ fields: z.string().array(),
72
+ })
73
+ .array(),
74
+ contentTypesPopulate: z
75
+ .object({
76
+ key: z.string(),
77
+ fields: z.string().array(),
78
+ })
79
+ .array(),
80
+ pathDefaultFields: z
81
+ .object({
82
+ key: z.string(),
83
+ fields: z.string().array(),
84
+ })
85
+ .array(),
86
+ });
87
+ export const useSettingsForm = (config) => {
88
+ const form = useForm({
89
+ resolver: zodResolver(uiFormSchema),
90
+ values: config
91
+ ? {
92
+ ...config,
93
+ additionalFields: config.additionalFields.filter((field) => typeof field !== 'string'),
94
+ audienceFieldChecked: config.additionalFields.includes('audience'),
95
+ contentTypesNameFields: Object.entries(config.contentTypesNameFields).map(([key, fields]) => ({
96
+ key,
97
+ fields,
98
+ })),
99
+ contentTypesPopulate: Object.entries(config.contentTypesPopulate).map(([key, fields]) => ({
100
+ key,
101
+ fields,
102
+ })),
103
+ pathDefaultFields: Object.entries(config.pathDefaultFields).map(([key, fields]) => ({
104
+ key,
105
+ fields,
106
+ })),
107
+ }
108
+ : undefined,
109
+ });
110
+ return { form };
111
+ };
@@ -0,0 +1,189 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DesignSystemProvider, lightTheme } from '@strapi/design-system';
3
+ import { Check, Play, Typhoon } from '@strapi/icons';
4
+ import { Layouts, Page, useAuth } from '@strapi/strapi/admin';
5
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
+ import { useMemo, useState } from 'react';
7
+ import { useIntl } from 'react-intl';
8
+ import { Accordion, Box, Button, Field, Flex, Grid, MultiSelect, MultiSelectOption, NumberInput, Toggle, Typography, } from '@strapi/design-system';
9
+ import { isEmpty, sortBy } from 'lodash';
10
+ import { Controller } from 'react-hook-form';
11
+ import { ConfirmationDialog } from '../../components/ConfirmationDialog';
12
+ import { RestartAlert } from '../../components/RestartAlert';
13
+ import { getTrad } from '../../utils/getTranslation';
14
+ import pluginPermissions from '../../utils/permissions';
15
+ import CustomFieldModal from './components/CustomFieldModal';
16
+ import CustomFieldTable from './components/CustomFieldTable';
17
+ import { uiFormSchema, useConfig, useContentTypes, useRestart, useRestoreConfig, useSaveConfig, useSettingsForm, } from './hooks';
18
+ import { isContentTypeEligible } from './utils';
19
+ const BOX_DEFAULT_PROPS = {
20
+ background: 'neutral0',
21
+ hasRadius: true,
22
+ shadow: 'filterShadow',
23
+ padding: 6,
24
+ };
25
+ const queryClient = new QueryClient();
26
+ const Inner = () => {
27
+ const configQuery = useConfig();
28
+ const contentTypesQuery = useContentTypes();
29
+ const configSaveMutation = useSaveConfig();
30
+ const restoreMutation = useRestoreConfig();
31
+ const restartMutation = useRestart();
32
+ const { formatMessage } = useIntl();
33
+ const { form: { control, watch, setValue, getValues, handleSubmit }, } = useSettingsForm(configQuery.data);
34
+ const [contentTypeNameFieldsCurrent, contentTypesCurrent, additionalFields, preferCustomContentTypes,] = watch([
35
+ 'contentTypesNameFields',
36
+ 'contentTypes',
37
+ 'additionalFields',
38
+ 'preferCustomContentTypes',
39
+ ]);
40
+ const [restartStatus, setRestartStatus] = useState({ required: false });
41
+ const readPermissions = useAuth('SettingsPage', (state) => state.permissions);
42
+ const hasSettingsPermissions = useMemo(() => {
43
+ return !!readPermissions.find(({ action }) => action === pluginPermissions.settings[0].action);
44
+ }, [readPermissions]);
45
+ const hasSettingsReadPermissions = useMemo(() => {
46
+ return !!readPermissions.find(({ action }) => action === pluginPermissions.access[0].action);
47
+ }, [readPermissions]);
48
+ const isLoading = configQuery.isPending ||
49
+ contentTypesQuery.isPending ||
50
+ configSaveMutation.isPending ||
51
+ restartMutation.isPending ||
52
+ restoreMutation.isPending;
53
+ const [isCustomFieldModalOpen, setIsCustomFieldModalOpen] = useState(false);
54
+ const [isRestorePopupOpen, setIsRestorePopupOpen] = useState(false);
55
+ const [customFieldSelected, setCustomFieldSelected] = useState(null);
56
+ const handleOpenCustomFieldModal = (field) => {
57
+ setCustomFieldSelected(field);
58
+ setIsCustomFieldModalOpen(true);
59
+ };
60
+ const handleRemoveCustomField = (field) => {
61
+ const filteredFields = additionalFields.filter((f) => typeof f !== 'string' ? f.name !== field.name : true);
62
+ setValue('additionalFields', filteredFields);
63
+ setCustomFieldSelected(null);
64
+ setIsCustomFieldModalOpen(false);
65
+ };
66
+ const handleToggleCustomField = (current) => {
67
+ const next = { ...current, enabled: !current.enabled };
68
+ const nextAdditionalFields = additionalFields.map((field) => typeof field !== 'string' && current.name === field.name ? next : field);
69
+ setValue('additionalFields', nextAdditionalFields);
70
+ };
71
+ const handleSubmitCustomField = (next) => {
72
+ const hasFieldAlready = !!additionalFields.find((field) => typeof field !== 'string' ? field.name === next.name : false);
73
+ const nextAdditionalFields = hasFieldAlready
74
+ ? additionalFields.map((field) => typeof field !== 'string' && next.name === field.name ? next : field)
75
+ : [...additionalFields, next];
76
+ setValue('additionalFields', nextAdditionalFields);
77
+ setCustomFieldSelected(null);
78
+ setIsCustomFieldModalOpen(false);
79
+ };
80
+ const allContentTypes = !isLoading
81
+ ? sortBy(Object.values(contentTypesQuery.data ?? [])
82
+ .filter(({ uid }) => isContentTypeEligible(uid, {
83
+ allowedContentTypes: configQuery.data?.allowedContentTypes,
84
+ restrictedContentTypes: configQuery.data?.restrictedContentTypes,
85
+ preferCustomContentTypes,
86
+ contentTypes: contentTypesCurrent,
87
+ }))
88
+ .map((ct) => {
89
+ const type = contentTypesQuery.data?.find((_) => _.uid === ct.uid);
90
+ if (type) {
91
+ const { isDisplayed: available, kind } = type;
92
+ const isSingle = kind === 'singleType';
93
+ return {
94
+ ...ct,
95
+ available,
96
+ isSingle,
97
+ };
98
+ }
99
+ return ct;
100
+ }), (ct) => ct.info.displayName)
101
+ : [];
102
+ const onSubmit = (rawData) => {
103
+ const parsed = uiFormSchema.safeParse(rawData);
104
+ if (parsed.success) {
105
+ configSaveMutation.mutate(parsed.data, {
106
+ onSuccess() {
107
+ setRestartStatus({ required: true });
108
+ configSaveMutation.reset();
109
+ },
110
+ });
111
+ }
112
+ else {
113
+ console.warn('Invalid form data', parsed.error);
114
+ }
115
+ };
116
+ const onPopupClose = async (isConfirmed) => {
117
+ setIsRestorePopupOpen(false);
118
+ if (isConfirmed) {
119
+ restoreMutation.mutate();
120
+ setRestartStatus({ required: true });
121
+ }
122
+ };
123
+ const handleRestart = async () => {
124
+ restartMutation.mutate(undefined, {
125
+ onSuccess() {
126
+ setRestartStatus({ required: false });
127
+ },
128
+ onError() {
129
+ setRestartStatus({ required: false });
130
+ },
131
+ });
132
+ // TODO: Reload
133
+ window.location.reload();
134
+ };
135
+ const handleRestartDiscard = () => setRestartStatus({ required: false });
136
+ if (!hasSettingsPermissions) {
137
+ return _jsx(Page.NoPermissions, {});
138
+ }
139
+ if (isLoading) {
140
+ return _jsx(Page.Loading, {});
141
+ }
142
+ return (_jsxs(Layouts.Root, { children: [_jsxs(Page.Main, { children: [_jsx(Page.Title, { children: formatMessage(getTrad('pages.settings.header.title')) }), _jsx(Layouts.Header, { title: formatMessage(getTrad('pages.settings.header.title')), subtitle: formatMessage(getTrad('pages.settings.header.description')), primaryAction: hasSettingsReadPermissions ? (_jsx(Button, { startIcon: _jsx(Check, {}), disabled: restartStatus.required, onClick: handleSubmit(onSubmit), children: formatMessage(getTrad('pages.settings.actions.submit')) })) : null }), _jsx(Layouts.Content, { children: _jsxs(Flex, { direction: "column", gap: 4, children: [restartStatus.required && (_jsx(Box, { ...BOX_DEFAULT_PROPS, width: "100%", children: _jsx(RestartAlert, { closeLabel: formatMessage(getTrad('pages.settings.actions.restart.alert.cancel')), title: formatMessage(getTrad('pages.settings.actions.restart.alert.title')), action: _jsx(Box, { children: _jsx(Button, { onClick: handleRestart, startIcon: _jsx(Play, {}), children: formatMessage(getTrad('pages.settings.actions.restart')) }) }), onClose: handleRestartDiscard, children: _jsxs(_Fragment, { children: [_jsx(Box, { paddingBottom: 1, children: formatMessage(getTrad('pages.settings.actions.restart.alert.description')) }), restartStatus.reasons?.map((reason, i) => (_jsx(Box, { paddingBottom: 1, children: formatMessage(getTrad(`pages.settings.actions.restart.alert.reason.${reason}`)) }, i)))] }) }) })), _jsx(Box, { ...BOX_DEFAULT_PROPS, width: "100%", children: _jsxs(Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [_jsx(Typography, { variant: "delta", as: "h2", children: formatMessage(getTrad('pages.settings.general.title')) }), _jsx(Grid.Root, { gap: 4, width: "100%", children: _jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsxs(Grid.Root, { gap: 4, width: "100%", children: [_jsx(Grid.Item, { col: 4, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: "preferCustomContentTypes", render: ({ field: { name, value, onChange } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.preferCustomContentTypes.label')) }), _jsx(Toggle, { name: name, checked: value, onChange: ({ currentTarget: { checked }, }) => {
143
+ onChange(checked);
144
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required, width: "100%" }), _jsx(Field.Hint, { children: formatMessage(getTrad('pages.settings.form.preferCustomContentTypes.hint')) })] })) }) }), _jsx(Grid.Item, { col: 8, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: "contentTypes", render: ({ field: { name, value, onChange }, fieldState: { error } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.contentTypes.label')) }), _jsx(MultiSelect, { name: name, label: formatMessage(getTrad('pages.settings.form.contentTypes.label')), "aria-label": formatMessage(getTrad('pages.settings.form.contentTypes.label')), placeholder: formatMessage(getTrad('pages.settings.form.contentTypes.placeholder')), hint: formatMessage(getTrad('pages.settings.form.contentTypes.hint')), value: value, onChange: (value) => {
145
+ onChange(value);
146
+ const { contentTypesNameFields = [], contentTypesPopulate = [], pathDefaultFields, } = getValues();
147
+ const missingKeys = value.filter((key) => !contentTypesNameFields.find((nameFields) => nameFields.key === key)) ?? [];
148
+ const redundantKeys = contentTypesNameFields
149
+ .filter((nameFields) => !value.includes(nameFields.key) ||
150
+ nameFields.key === 'default')
151
+ .map(({ key }) => key) ?? [];
152
+ setValue('contentTypesNameFields', [
153
+ ...(contentTypesNameFields.filter(({ key }) => !redundantKeys.includes(key) || key === 'default') ?? []),
154
+ ...missingKeys.map((key) => ({ key, fields: [] })),
155
+ ], { shouldDirty: true, shouldTouch: true, shouldValidate: true });
156
+ setValue('contentTypesPopulate', [
157
+ ...(contentTypesPopulate.filter(({ key }) => !redundantKeys.includes(key) || key === 'default') ?? []),
158
+ ...missingKeys.map((key) => ({ key, fields: [] })),
159
+ ], { shouldDirty: true, shouldTouch: true, shouldValidate: true });
160
+ setValue('pathDefaultFields', [
161
+ ...(pathDefaultFields.filter(({ key }) => !redundantKeys.includes(key) || key === 'default') ?? []),
162
+ ...missingKeys.map((key) => ({ key, fields: [] })),
163
+ ], { shouldDirty: true, shouldTouch: true, shouldValidate: true });
164
+ }, disabled: restartStatus.required, error: !!error, withTags: true, width: "100%", children: allContentTypes.map((item) => (_jsx(MultiSelectOption, { value: item.uid, children: item.info.displayName }, item.uid))) })] })) }) }), _jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: contentTypesCurrent?.length ? (_jsx(Accordion.Root, { style: { width: '100%' }, children: contentTypeNameFieldsCurrent.map((nameFields, index) => {
165
+ const current = contentTypesQuery.data?.find(({ uid }) => uid === nameFields.key);
166
+ const attributeKeys = Object.keys(current?.attributes ?? {}).sort();
167
+ return current ? (_jsxs(Accordion.Item, { value: nameFields.key, children: [_jsx(Accordion.Header, { children: _jsx(Accordion.Trigger, { children: current?.info.displayName ??
168
+ formatMessage(getTrad('pages.settings.form.nameField.default')) }) }), _jsx(Accordion.Content, { children: _jsxs(Grid.Root, { gap: 4, padding: 2, children: [_jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: `contentTypesNameFields.${index}`, render: ({ field: { name, value, onChange }, fieldState: { error }, }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.nameField.label')) }), _jsx(MultiSelect, { name: name, placeholder: formatMessage(getTrad('pages.settings.form.nameField.placeholder')), value: value.fields, onChange: (fields) => onChange({
169
+ ...value,
170
+ fields,
171
+ }), disabled: restartStatus.required, error: !!error, withTags: true, children: attributeKeys.map((attribute) => (_jsx(MultiSelectOption, { value: attribute, children: attribute }, attribute))) }), _jsx(Field.Hint, { children: formatMessage(getTrad(`pages.settings.form.nameField.${isEmpty(value?.fields) ? 'empty' : 'hint'}`)) })] })) }) }), _jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: `contentTypesPopulate.${index - 1}`, render: ({ field: { name, value, onChange }, fieldState: { error }, }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.populate.label')) }), _jsx(MultiSelect, { width: "100%", name: name, placeholder: formatMessage(getTrad('pages.settings.form.populate.placeholder')), value: value?.fields ?? [], onChange: (fields) => onChange({
172
+ ...value,
173
+ fields,
174
+ }), disabled: restartStatus.required, error: !!error, withTags: true, children: attributeKeys.map((attribute) => (_jsx(MultiSelectOption, { value: attribute, children: attribute }, attribute))) }), _jsx(Field.Hint, { children: formatMessage(getTrad(`pages.settings.form.populate.${isEmpty(value?.fields) ? 'empty' : 'hint'}`)) })] })) }) }), _jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: `pathDefaultFields.${index - 1}`, render: ({ field: { name, value, onChange }, fieldState: { error }, }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.pathDefaultFields.label')) }), _jsx(MultiSelect, { name: name, width: "100%", placeholder: formatMessage(getTrad('pages.settings.form.pathDefaultFields.placeholder')), value: value?.fields ?? [], onChange: (fields) => onChange({
175
+ ...value,
176
+ fields,
177
+ }), disabled: restartStatus.required, error: !!error, withTags: true, children: attributeKeys.map((attribute) => (_jsx(MultiSelectOption, { value: attribute, children: attribute }, attribute))) }), _jsx(Field.Hint, { children: formatMessage(getTrad(`pages.settings.form.pathDefaultFields.${isEmpty(value?.fields) ? 'empty' : 'hint'}`)) })] })) }) })] }) })] }, nameFields.key)) : null;
178
+ }) })) : null })] }) }) })] }) }), _jsx(Box, { ...BOX_DEFAULT_PROPS, width: "100%", children: _jsxs(Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [_jsx(Typography, { variant: "delta", as: "h2", children: formatMessage(getTrad('pages.settings.additional.title')) }), _jsxs(Grid.Root, { gap: 4, width: "100%", children: [_jsx(Grid.Item, { col: 4, s: 12, xs: 12, children: _jsx(Box, { width: "100%", children: _jsx(Controller, { control: control, name: "allowedLevels", render: ({ field: { onChange, value, name } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.allowedLevels.label')) }), _jsx(NumberInput, { width: "100%", name: name, placeholder: formatMessage(getTrad('pages.settings.form.allowedLevels.placeholder')), onValueChange: (nextValue) => onChange(nextValue), value: value, disabled: restartStatus.required }), _jsx(Field.Hint, { children: formatMessage(getTrad('pages.settings.form.allowedLevels.hint')) })] })) }) }) }), _jsx(Grid.Item, { col: 4, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: "cascadeMenuAttached", render: ({ field: { name, value, onChange } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.cascadeMenuAttached.label')) }), _jsx(Toggle, { width: "100%", name: name, checked: value, onChange: ({ currentTarget: { checked }, }) => {
179
+ onChange(checked);
180
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required }), _jsx(Field.Hint, { children: formatMessage(getTrad('pages.settings.form.cascadeMenuAttached.hint')) })] })) }) }), _jsx(Grid.Item, { col: 4, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: "audienceFieldChecked", render: ({ field: { name, value, onChange } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.audience.label')) }), _jsx(Toggle, { name: name, checked: value, onChange: ({ currentTarget: { checked }, }) => {
181
+ onChange(checked);
182
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required, width: "100%" }), _jsx(Field.Hint, { children: formatMessage(getTrad('pages.settings.form.audience.hint')) })] })) }) }), configQuery.data?.isCachePluginEnabled && (_jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsx(Controller, { control: control, name: "isCacheEnabled", render: ({ field: { name, value, onChange } }) => (_jsxs(Field.Root, { width: "100%", children: [_jsx(Field.Label, { children: formatMessage(getTrad('pages.settings.form.cache.label')) }), _jsx(Toggle, { name: name, checked: value, onChange: ({ currentTarget: { checked }, }) => {
183
+ onChange(checked);
184
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required, width: "100%" }), _jsx(Field.Hint, { children: formatMessage(getTrad('pages.settings.form.cache.hint')) })] })) }) }))] })] }) }), _jsxs(Box, { ...BOX_DEFAULT_PROPS, width: "100%", gap: 2, direction: "column", alignItems: "flex-start", children: [_jsx(Typography, { variant: "delta", as: "h2", children: formatMessage(getTrad('pages.settings.customFields.title')) }), _jsx(Box, { padding: 1 }), _jsx(CustomFieldTable, { data: additionalFields, onOpenModal: handleOpenCustomFieldModal, onRemoveCustomField: handleRemoveCustomField, onToggleCustomField: handleToggleCustomField })] }), _jsx(Box, { ...BOX_DEFAULT_PROPS, width: "100%", children: _jsxs(Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [_jsx(Typography, { variant: "delta", as: "h2", children: formatMessage(getTrad('pages.settings.restoring.title')) }), _jsxs(Grid.Root, { gap: 4, width: "100%", children: [_jsx(Grid.Item, { col: 12, s: 12, xs: 12, children: _jsx(Typography, { children: formatMessage(getTrad('pages.settings.actions.restore.description')) }) }), _jsxs(Grid.Item, { col: 12, s: 12, xs: 12, children: [hasSettingsReadPermissions ? (_jsx(Button, { variant: "danger-light", startIcon: _jsx(Check, {}), onClick: () => setIsRestorePopupOpen(true), children: formatMessage(getTrad('pages.settings.actions.restore')) })) : null, _jsx(ConfirmationDialog, { isVisible: isRestorePopupOpen, header: formatMessage(getTrad('pages.settings.actions.restore.confirmation.header')), labelConfirm: formatMessage(getTrad('pages.settings.actions.restore.confirmation.confirm')), iconConfirm: _jsx(Typhoon, {}), onConfirm: () => onPopupClose(true), onCancel: () => onPopupClose(false), children: formatMessage(getTrad('pages.settings.actions.restore.confirmation.description')) })] })] })] }) })] }) })] }), isCustomFieldModalOpen && (_jsx(CustomFieldModal, { onClose: () => setIsCustomFieldModalOpen(false), onSubmit: handleSubmitCustomField, isOpen: isCustomFieldModalOpen, data: customFieldSelected }))] }));
185
+ };
186
+ export default function SettingsPage() {
187
+ queryClient.invalidateQueries();
188
+ return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(DesignSystemProvider, { locale: "en-GB", theme: lightTheme, children: _jsx(Inner, {}) }) }));
189
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import { capitalize } from 'lodash';
2
+ const UID_REGEX = /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i;
3
+ export const isContentTypeEligible = (uid = '', config = {}) => {
4
+ const { allowedContentTypes: baseAllowedContentTypes = [], restrictedContentTypes = [], contentTypes = [], preferCustomContentTypes = false, } = config;
5
+ const allowedContentTypes = preferCustomContentTypes
6
+ ? ['api::', ...contentTypes]
7
+ : baseAllowedContentTypes;
8
+ const isOneOfAllowedType = allowedContentTypes.filter((_) => uid.includes(_) || uid === _).length > 0;
9
+ const isNoneOfRestricted = restrictedContentTypes.filter((_) => uid.includes(_) || uid === _).length === 0;
10
+ return !!uid && isOneOfAllowedType && isNoneOfRestricted;
11
+ };
12
+ export const resolveGlobalLikeId = (uid = '') => {
13
+ const parse = (str) => str
14
+ .split('-')
15
+ .map((_) => capitalize(_))
16
+ .join('');
17
+ const [type, scope, contentTypeName] = splitTypeUid(uid);
18
+ if (type === 'api') {
19
+ return parse(contentTypeName);
20
+ }
21
+ return `${parse(scope)}${parse(contentTypeName)}`;
22
+ };
23
+ const splitTypeUid = (uid = '') => {
24
+ return uid.split(UID_REGEX).filter((s) => s && s.length > 0);
25
+ };
@@ -0,0 +1 @@
1
+ export const PLUGIN_ID = 'navigation';
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ const navigationCustomFieldBase = z.object({
3
+ name: z.string(),
4
+ label: z.string(),
5
+ required: z.boolean().optional(),
6
+ enabled: z.boolean().optional(),
7
+ });
8
+ const navigationItemCustomFieldSelect = navigationCustomFieldBase.extend({
9
+ type: z.literal('select'),
10
+ multi: z.boolean(),
11
+ options: z.array(z.string()),
12
+ });
13
+ const navigationItemCustomFieldPrimitive = navigationCustomFieldBase.extend({
14
+ type: z.enum(['boolean', 'string']),
15
+ multi: z.literal(false).optional(),
16
+ options: z.array(z.string()).max(0).optional(),
17
+ });
18
+ const navigationItemCustomFieldMedia = navigationCustomFieldBase.extend({
19
+ type: z.literal('media'),
20
+ multi: z.literal(false).optional(),
21
+ options: z.array(z.string()).max(0).optional(),
22
+ });
23
+ export const navigationItemCustomField = z.union([
24
+ navigationItemCustomFieldPrimitive,
25
+ navigationItemCustomFieldMedia,
26
+ navigationItemCustomFieldSelect,
27
+ ]);
28
+ export const navigationItemAdditionalField = z.union([
29
+ z.literal('audience'),
30
+ navigationItemCustomField,
31
+ ]);
32
+ export const configSchema = z.object({
33
+ additionalFields: z.array(navigationItemAdditionalField),
34
+ allowedLevels: z.number(),
35
+ availableAudience: z
36
+ .object({
37
+ id: z.number(),
38
+ name: z.string(),
39
+ key: z.string(),
40
+ })
41
+ .array(),
42
+ contentTypes: z.array(z.string()),
43
+ contentTypesNameFields: z.record(z.string(), z.array(z.string())),
44
+ contentTypesPopulate: z.record(z.string(), z.array(z.string())),
45
+ gql: z.object({
46
+ navigationItemRelated: z.array(z.string()),
47
+ }),
48
+ pathDefaultFields: z.record(z.string(), z.any()),
49
+ cascadeMenuAttached: z.boolean(),
50
+ preferCustomContentTypes: z.boolean(),
51
+ isCacheEnabled: z.boolean().optional(),
52
+ isCachePluginEnabled: z.boolean().optional(),
53
+ });
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ export const strapiContentTypeSchema = z.object({
3
+ uid: z.string(),
4
+ isDisplayed: z.boolean(),
5
+ apiID: z.string(),
6
+ kind: z.enum(['collectionType', 'singleType']),
7
+ info: z.object({
8
+ singularName: z.string(),
9
+ pluralName: z.string(),
10
+ displayName: z.string(),
11
+ description: z.string().optional(),
12
+ }),
13
+ attributes: z.record(z.string(), z.unknown()),
14
+ });
@@ -0,0 +1,2 @@
1
+ export * from './config';
2
+ export * from './content-type';
@@ -9,7 +9,6 @@
9
9
  "header.action.expandAll": "Expand All",
10
10
  "submit.cta.cancel": "Cancel",
11
11
  "submit.cta.save": "Save",
12
- "submit.cta.cache.purge": "Clear cache",
13
12
  "empty": "Your navigation is empty",
14
13
  "empty.cta": "Create first item",
15
14
  "popup.item.header.view": "View navigation item",
@@ -32,6 +31,9 @@
32
31
  "popup.item.form.type.external.label": "External source",
33
32
  "popup.item.form.type.wrapper.label": "Wrapper element",
34
33
  "popup.item.form.type.external.description": "Output path: {value}",
34
+ "popup.navigation.manage.button.purge": "Clear read cache",
35
+ "popup.navigation.manage.footer.button.purge": "Clear",
36
+ "popup.navigation.manage.purge.header": "This action will clear API read cache. This will result in brief slowdown of reads for navigations below.",
35
37
  "popup.item.form.audience.label": "Audience",
36
38
  "popup.item.form.audience.placeholder": "Select audience...",
37
39
  "popup.item.form.audience.empty": "There are no more audiences",
@@ -67,14 +69,10 @@
67
69
  "popup.navigation.manage.button.goBack": "Go back",
68
70
  "popup.navigation.manage.button.cancel": "Cancel",
69
71
  "popup.navigation.manage.button.delete": "Delete",
70
- "popup.navigation.manage.button.purge": "Clear read cache",
71
- "popup.navigation.manage.footer.button.purge": "Clear",
72
- "popup.navigation.manage.purge.header": "This action will clear API read cache. This will result in brief slowdown of reads for navigations below.",
73
72
  "popup.navigation.manage.button.save": "Save",
74
73
  "popup.navigation.manage.button.edit": "Edit",
75
74
  "popup.navigation.manage.button.create": "Create",
76
75
  "popup.navigation.manage.delete.header": "Following navigations will be removed:",
77
- "popup.navigation.manage.header.CACHE_PURGE": "Read cache clear",
78
76
  "popup.navigation.manage.header.LIST": "All navigations",
79
77
  "popup.navigation.manage.header.CREATE": "New navigation",
80
78
  "popup.navigation.manage.header.DELETE": "Deleting",
@@ -98,6 +96,8 @@
98
96
  "pages.main.search.placeholder": "Type to start searching...",
99
97
  "pages.main.search.subLabel": "press ENTER to highlight next item",
100
98
  "pages.main.header.localization.select.placeholder": "Select locale",
99
+ "pages.settings.form.nameField.default": "Default",
100
+ "pages.settings.title": "Navigation settings",
101
101
  "pages.settings.general.title": "General settings",
102
102
  "pages.settings.additional.title": "Additional settings",
103
103
  "pages.settings.customFields.title": "Custom fields settings",
@@ -136,13 +136,11 @@
136
136
  "pages.settings.notification.submit.error": "Config update has failed",
137
137
  "pages.settings.notification.restore.error": "Config restore has failed",
138
138
  "pages.settings.notification.restart.error": "Failed to restart your application. Try to do it manually.",
139
- "pages.settings.form.preferCustomContentTypes.label": "Prefer custom content types",
140
- "pages.settings.form.preferCustomContentTypes.hint": "Prefer if to use only api:: prefixed content types",
141
139
  "pages.settings.form.cascadeMenuAttached.label": "Cascade menu attached",
142
140
  "pages.settings.form.cascadeMenuAttached.hint": "Disable if you don't want \"Menu attached\" to cascade on child items",
141
+ "pages.settings.form.preferCustomContentTypes.label": "Prefer custom content types",
142
+ "pages.settings.form.preferCustomContentTypes.hint": "Prefer if to use only api:: prefixed content types",
143
143
  "pages.settings.form.contentTypes.label": "Enable navigation for",
144
- "pages.settings.form.cache.label": "REST cache",
145
- "pages.settings.form.cache.hint": "Enable caching of client read requests",
146
144
  "pages.settings.form.i18n.label": "i18n",
147
145
  "pages.settings.form.i18n.hint": "Enable internationalisation",
148
146
  "pages.settings.form.i18n.hint.missingDefaultLocale": "Default locale missing!",
@@ -0,0 +1,15 @@
1
+ import { PLUGIN_ID } from '../pluginId';
2
+ import ca from './ca.json';
3
+ import en from './en.json';
4
+ import fr from './fr.json';
5
+ const trads = {
6
+ en,
7
+ fr,
8
+ ca,
9
+ };
10
+ export const getTradId = (msg) => `${PLUGIN_ID}.${msg}`;
11
+ export const getTrad = (msg, defaultMessage) => ({
12
+ id: getTradId(msg),
13
+ defaultMessage: defaultMessage ?? getTradId(msg),
14
+ });
15
+ export default trads;
package/admin/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export const RELATED_ITEM_SEPARATOR = '$';
@@ -0,0 +1,4 @@
1
+ import { PLUGIN_ID } from '../pluginId';
2
+ export { getTrad, getTradId } from '../translations';
3
+ const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
4
+ export { getTranslation };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+ const render = (uid) => {
3
+ return `plugin::navigation.${uid}`;
4
+ };
5
+ const navigation = {
6
+ read: 'read',
7
+ update: 'update',
8
+ settings: 'settings',
9
+ };
10
+ // This should be equal to admin side. Strapi push to make admin and server independent chunks.
11
+ const pluginPermissions = {
12
+ access: [{ action: render(navigation.read), subject: null }],
13
+ update: [{ action: render(navigation.update), subject: null }],
14
+ settings: [{ action: render(navigation.settings), subject: null }],
15
+ };
16
+ export default pluginPermissions;
@@ -0,0 +1,3 @@
1
+ export const prefixPluginTranslations = (input, pluginId) => {
2
+ return Object.fromEntries(Object.entries(input).map(([key, value]) => [[pluginId, key].join('.'), value]));
3
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-navigation",
3
- "version": "2.5.4",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "Strapi - Navigation plugin",
5
5
  "strapi": {
6
6
  "name": "navigation",
@@ -15,25 +15,27 @@
15
15
  "scripts": {},
16
16
  "types": "./types/index.d.ts",
17
17
  "dependencies": {
18
+ "@hookform/resolvers": "3.4.2",
19
+ "@paralleldrive/cuid2": "2.2.2",
18
20
  "@sindresorhus/slugify": "1.1.0",
19
- "@strapi/utils": "^4.25.11",
21
+ "@tanstack/react-query": "5.37.1",
20
22
  "lodash": "^4.17.21",
21
- "pluralize": "^8.0.0",
23
+ "pluralize": "8.0.0",
22
24
  "react": "^18.2.0",
25
+ "react-dnd": "^16.0.1",
26
+ "react-dnd-html5-backend": "^16.0.1",
23
27
  "react-dom": "^18.2.0",
24
- "react-router": "^5.3.4",
25
- "react-router-dom": "5.3.4",
26
- "react-intl": "6.4.1",
27
- "uuid": "^8.3.0"
28
+ "react-intl": "6.6.8",
29
+ "react-router-dom": "^6.22.3",
30
+ "uuid": "^10.0.0",
31
+ "zod": "3.22.5"
28
32
  },
29
33
  "devDependencies": {},
30
34
  "peerDependencies": {
31
- "@strapi/data-transfer": "4.25.11",
32
- "@strapi/strapi": "4.x",
35
+ "@strapi/strapi": "^5.0.0-rc.22",
33
36
  "react": "^17.0.0 || ^18.0.0",
34
37
  "react-dom": "^17.0.0 || ^18.0.0",
35
- "react-router-dom": "^5.2.0",
36
- "styled-components": "^5.2.1"
38
+ "styled-components": "^6.0.0"
37
39
  },
38
40
  "author": {
39
41
  "name": "VirtusLab",
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidParamNavigationError = exports.FillNavigationError = exports.NavigationError = void 0;
4
+ class NavigationError extends Error {
5
+ additionalInfo;
6
+ type = 'NavigationError';
7
+ constructor(message, additionalInfo) {
8
+ super(message);
9
+ this.additionalInfo = additionalInfo;
10
+ }
11
+ }
12
+ exports.NavigationError = NavigationError;
13
+ class FillNavigationError extends NavigationError {
14
+ type = 'FillNavigationError';
15
+ }
16
+ exports.FillNavigationError = FillNavigationError;
17
+ class InvalidParamNavigationError extends NavigationError {
18
+ type = 'InvalidParamNavigationError';
19
+ }
20
+ exports.InvalidParamNavigationError = InvalidParamNavigationError;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("./config");
4
+ const i18n_1 = require("./i18n");
5
+ const permissions_1 = require("./permissions");
6
+ const graphql_1 = require("./graphql");
7
+ const bootstrap = async (context) => {
8
+ await (0, config_1.configSetup)(context);
9
+ await (0, i18n_1.navigationSetup)(context);
10
+ await (0, permissions_1.setupPermissions)(context);
11
+ await (0, graphql_1.graphQLSetup)(context);
12
+ };
13
+ exports.default = bootstrap;