@strapi/admin 4.5.0-beta.0 → 4.5.1

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 (264) hide show
  1. package/admin/src/StrapiApp.js +17 -6
  2. package/admin/src/assets/images/hot-air-balloon.png +0 -0
  3. package/admin/src/assets/images/icon_offline-cloud.svg +3 -3
  4. package/admin/src/assets/images/logo-strapi-2022.svg +7 -0
  5. package/admin/src/assets/images/upgrade-details.png +0 -0
  6. package/admin/src/content-manager/components/DynamicTable/CellContent/CellValue.js +1 -1
  7. package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +5 -4
  8. package/admin/src/content-manager/components/DynamicTable/CellContent/index.js +10 -0
  9. package/admin/src/content-manager/components/DynamicTable/index.js +21 -4
  10. package/admin/src/content-manager/components/DynamicZone/components/{AddComponentButton/index.js → AddComponentButton.js} +12 -6
  11. package/admin/src/content-manager/components/DynamicZone/components/{ComponentPicker/Category/ComponentCard/index.js → ComponentCard.js} +8 -19
  12. package/admin/src/content-manager/components/DynamicZone/components/{ComponentPicker/Category/index.js → ComponentCategory.js} +19 -18
  13. package/admin/src/content-manager/components/DynamicZone/components/{ComponentPicker/index.js → ComponentPicker.js} +36 -38
  14. package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +195 -0
  15. package/admin/src/content-manager/components/DynamicZone/components/{DzLabel/index.js → DynamicZoneLabel.js} +13 -5
  16. package/admin/src/content-manager/components/DynamicZone/index.js +35 -116
  17. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +103 -60
  18. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +169 -162
  19. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +70 -16
  20. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +52 -0
  21. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +2 -0
  22. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +72 -0
  23. package/admin/src/content-manager/components/FieldComponent/index.js +9 -2
  24. package/admin/src/content-manager/components/PreviewWysiwyg/index.js +1 -1
  25. package/admin/src/content-manager/components/RelationInput/RelationInput.js +80 -76
  26. package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +95 -63
  27. package/admin/src/content-manager/components/RelationInputDataManager/utils/diffRelations.js +24 -0
  28. package/admin/src/content-manager/components/RelationInputDataManager/utils/index.js +2 -1
  29. package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeRelations.js +8 -29
  30. package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeSearchResults.js +8 -4
  31. package/admin/src/content-manager/components/RelationInputDataManager/utils/select.js +1 -0
  32. package/admin/src/content-manager/components/RepeatableComponent/index.js +4 -3
  33. package/admin/src/content-manager/hooks/__test__/usePrev.test.js +26 -0
  34. package/admin/src/content-manager/hooks/index.js +1 -0
  35. package/admin/src/content-manager/hooks/useFetchContentTypeLayout/utils/formatLayouts.js +19 -48
  36. package/admin/src/content-manager/hooks/usePrev.js +14 -0
  37. package/admin/src/content-manager/hooks/useRelation/useRelation.js +100 -7
  38. package/admin/src/content-manager/pages/App/reducer.js +3 -0
  39. package/admin/src/content-manager/pages/ListSettingsView/components/DraggableCard.js +3 -3
  40. package/admin/src/content-manager/pages/ListSettingsView/components/Settings.js +2 -2
  41. package/admin/src/content-manager/pages/ListSettingsView/components/SortDisplayedFields.js +1 -1
  42. package/admin/src/core/apis/CustomFields.js +0 -1
  43. package/admin/src/core/store/configureStore.js +17 -2
  44. package/admin/src/favicon.png +0 -0
  45. package/admin/src/hooks/useFetchMarketplacePlugins/index.js +2 -2
  46. package/admin/src/hooks/useFetchMarketplacePlugins/utils/api.js +4 -2
  47. package/admin/src/hooks/useFetchMarketplaceProviders/index.js +3 -3
  48. package/admin/src/hooks/useFetchMarketplaceProviders/utils/api.js +5 -3
  49. package/admin/src/index.js +1 -0
  50. package/admin/src/pages/App/index.js +1 -1
  51. package/admin/src/pages/HomePage/assets/corner-ornament.svg +48 -0
  52. package/admin/src/pages/HomePage/index.js +4 -3
  53. package/admin/src/pages/MarketplacePage/components/NpmPackageCard/CardButton.js +110 -0
  54. package/admin/src/pages/MarketplacePage/components/NpmPackageCard/InstallPluginButton.js +32 -21
  55. package/admin/src/pages/MarketplacePage/components/NpmPackageCard/PackageStats.js +79 -0
  56. package/admin/src/pages/MarketplacePage/components/NpmPackageCard/index.js +28 -11
  57. package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/FilterSelect.js +42 -0
  58. package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/FiltersPopover.js +96 -0
  59. package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/index.js +107 -0
  60. package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +4 -0
  61. package/admin/src/pages/MarketplacePage/components/SortSelect/index.js +70 -0
  62. package/admin/src/pages/MarketplacePage/index.js +68 -8
  63. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +5 -4
  64. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +4 -3
  65. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormHead/index.js +6 -2
  66. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +1 -1
  67. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +5 -4
  68. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +1 -1
  69. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/index.js +7 -38
  70. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/options.js +31 -0
  71. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/index.js +32 -43
  72. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/index.js +1 -1
  73. package/admin/src/pages/SettingsPage/pages/Roles/ListPage/components/RoleRow/index.js +3 -1
  74. package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +2 -1
  75. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +2 -2
  76. package/admin/src/translations/ca.json +1 -1
  77. package/admin/src/translations/de.json +1 -1
  78. package/admin/src/translations/dk.json +1 -1
  79. package/admin/src/translations/en.json +21 -7
  80. package/admin/src/translations/es.json +1 -1
  81. package/admin/src/translations/fr.json +1 -1
  82. package/admin/src/translations/gu.json +1 -1
  83. package/admin/src/translations/he.json +1 -1
  84. package/admin/src/translations/hi.json +1 -1
  85. package/admin/src/translations/hu.json +1 -1
  86. package/admin/src/translations/id.json +1 -1
  87. package/admin/src/translations/it.json +1 -1
  88. package/admin/src/translations/ja.json +1 -1
  89. package/admin/src/translations/ko.json +1 -1
  90. package/admin/src/translations/ml.json +1 -1
  91. package/admin/src/translations/nl.json +1 -1
  92. package/admin/src/translations/no.json +1 -1
  93. package/admin/src/translations/pl.json +1 -1
  94. package/admin/src/translations/pt-BR.json +15 -15
  95. package/admin/src/translations/ru.json +1 -1
  96. package/admin/src/translations/sa.json +1 -1
  97. package/admin/src/translations/sk.json +1 -1
  98. package/admin/src/translations/sv.json +118 -86
  99. package/admin/src/translations/th.json +1 -1
  100. package/admin/src/translations/zh-Hans.json +1 -1
  101. package/admin/src/translations/zh.json +1 -1
  102. package/build/1856.db9f5782.chunk.js +174 -0
  103. package/build/2077.fed8c9c3.chunk.js +206 -0
  104. package/build/2912.fccb2c43.chunk.js +259 -0
  105. package/build/4318.5e670740.chunk.js +30 -0
  106. package/build/{9166.8fcb3019.chunk.js → 4610.7614b003.chunk.js} +22 -21
  107. package/build/4715.8e33d630.chunk.js +387 -0
  108. package/build/{4800.d09f1225.chunk.js → 4800.a6935af6.chunk.js} +1 -1
  109. package/build/4982.9e58ea3f.chunk.js +325 -0
  110. package/build/617f9c948fa79e6d73bd.png +0 -0
  111. package/build/6925.bb6dd64d.chunk.js +762 -0
  112. package/build/6d21938306785f176538.png +0 -0
  113. package/build/70674f63fc3904c20de0.svg +7 -0
  114. package/build/{7379.d246dd38.chunk.js → 7379.e972985f.chunk.js} +1 -1
  115. package/build/7692.31e83caa.chunk.js +470 -0
  116. package/build/7841.4804bd98.chunk.js +259 -0
  117. package/build/7866.6db2248d.chunk.js +505 -0
  118. package/build/7e9af4fb7e723fcebf1f.svg +48 -0
  119. package/build/8380.37126e0d.chunk.js +299 -0
  120. package/build/8549.5e5fb6b6.chunk.js +159 -0
  121. package/build/8738.5a02bffb.chunk.js +463 -0
  122. package/build/{9066.26faf397.chunk.js → 9066.5d980488.chunk.js} +5 -5
  123. package/build/9420.7addc099.chunk.js +505 -0
  124. package/build/9649.b6afc945.chunk.js +199 -0
  125. package/build/9d5d788027e86620c234.svg +5 -0
  126. package/build/Admin-authenticatedApp.c07d2a86.chunk.js +80 -0
  127. package/build/{Admin_homePage.4b2be829.chunk.js → Admin_homePage.26d32e30.chunk.js} +5 -4
  128. package/build/Admin_marketplace.444ff7b8.chunk.js +22 -0
  129. package/build/Admin_settingsPage.bf2234e1.chunk.js +178 -0
  130. package/build/admin-app.b157c10a.chunk.js +112 -0
  131. package/build/{admin-edit-roles-page.4dd6bcb9.chunk.js → admin-edit-roles-page.69d9fcb2.chunk.js} +1 -1
  132. package/build/ca-json.07ae0f2c.chunk.js +1 -0
  133. package/build/content-manager.f38edbb6.chunk.js +1202 -0
  134. package/build/content-type-builder-translation-pt-BR-json.6fe3b8d1.chunk.js +1 -0
  135. package/build/content-type-builder-translation-sv-json.6deff030.chunk.js +1 -0
  136. package/build/{content-type-builder.a6e29716.chunk.js → content-type-builder.16af63a6.chunk.js} +13 -13
  137. package/build/de-json.6b3e1894.chunk.js +1 -0
  138. package/build/dk-json.144c6a8e.chunk.js +1 -0
  139. package/build/{email-settings-page.bfe6227f.chunk.js → email-settings-page.91c925a5.chunk.js} +6 -6
  140. package/build/email-translation-en-json.ebad8943.chunk.js +1 -0
  141. package/build/en-json.4a269f6b.chunk.js +1 -0
  142. package/build/es-json.6d123a82.chunk.js +1 -0
  143. package/build/fr-json.28ab54cb.chunk.js +1 -0
  144. package/build/gu-json.9a50ea64.chunk.js +1 -0
  145. package/build/he-json.72f18790.chunk.js +1 -0
  146. package/build/hi-json.0301b7ba.chunk.js +1 -0
  147. package/build/hu-json.c4b641bb.chunk.js +1 -0
  148. package/build/{i18n-settings-page.18166125.chunk.js → i18n-settings-page.4ef64441.chunk.js} +5 -5
  149. package/build/id-json.86035797.chunk.js +1 -0
  150. package/build/index.html +1 -1
  151. package/build/it-json.bbdc8993.chunk.js +1 -0
  152. package/build/ja-json.1c9eeeec.chunk.js +1 -0
  153. package/build/ko-json.e1f66398.chunk.js +1 -0
  154. package/build/main.ca8b0ee3.js +9465 -0
  155. package/build/ml-json.963c889f.chunk.js +1 -0
  156. package/build/nl-json.2b8cc3a0.chunk.js +1 -0
  157. package/build/no-json.a58c28bd.chunk.js +1 -0
  158. package/build/pl-json.249626b3.chunk.js +1 -0
  159. package/build/pt-BR-json.2b72b1d6.chunk.js +1 -0
  160. package/build/ru-json.d7cfc2ff.chunk.js +1 -0
  161. package/build/runtime~main.ede9da1e.js +2 -0
  162. package/build/sa-json.44e95991.chunk.js +1 -0
  163. package/build/sk-json.7ba4b330.chunk.js +1 -0
  164. package/build/sv-json.fb1081ff.chunk.js +1 -0
  165. package/build/th-json.a67309b1.chunk.js +1 -0
  166. package/build/{upload-settings.3d613216.chunk.js → upload-settings.3f7ad973.chunk.js} +5 -5
  167. package/build/{users-advanced-settings-page.f4051d92.chunk.js → users-advanced-settings-page.6a838320.chunk.js} +5 -5
  168. package/build/users-permissions-translation-sv-json.d5d11648.chunk.js +1 -0
  169. package/build/{webhook-edit-page.9e46fc3f.chunk.js → webhook-edit-page.dc9442ce.chunk.js} +1 -1
  170. package/build/webhook-list-page.a110c462.chunk.js +134 -0
  171. package/build/zh-Hans-json.21617c24.chunk.js +1 -0
  172. package/build/zh-json.608aaf24.chunk.js +1 -0
  173. package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +3 -2
  174. package/env.js +1 -0
  175. package/package.json +18 -17
  176. package/scripts/build.js +11 -0
  177. package/server/content-types/api-token.js +1 -1
  178. package/utils/create-plugins-exclude-path.js +40 -0
  179. package/webpack.alias.js +0 -13
  180. package/webpack.config.js +4 -1
  181. package/admin/src/assets/images/banner_strapi-rocket.png +0 -0
  182. package/admin/src/assets/images/big-logo-home.png +0 -0
  183. package/admin/src/assets/images/homepage-logo.png +0 -0
  184. package/admin/src/assets/images/icon_made-by-strapi.svg +0 -5
  185. package/admin/src/assets/images/logo_strapi_auth.png +0 -0
  186. package/admin/src/assets/images/logo_strapi_auth_v4.png +0 -0
  187. package/admin/src/assets/images/logo_strapi_menu.png +0 -0
  188. package/admin/src/assets/images/oops.png +0 -0
  189. package/admin/src/content-manager/components/DynamicZone/components/Component/Rectangle.js +0 -19
  190. package/admin/src/content-manager/components/DynamicZone/components/Component/index.js +0 -191
  191. package/admin/src/content-manager/components/State/index.js +0 -37
  192. package/admin/src/content-manager/icons/Bold/index.js +0 -22
  193. package/admin/src/content-manager/icons/Code/index.js +0 -13
  194. package/admin/src/content-manager/icons/Cross/index.js +0 -28
  195. package/admin/src/content-manager/icons/Italic/index.js +0 -23
  196. package/admin/src/content-manager/icons/Link/index.js +0 -21
  197. package/admin/src/content-manager/icons/Media/index.js +0 -14
  198. package/admin/src/content-manager/icons/Na/index.js +0 -39
  199. package/admin/src/content-manager/icons/Ol/index.js +0 -13
  200. package/admin/src/content-manager/icons/Quote/index.js +0 -13
  201. package/admin/src/content-manager/icons/Striked/index.js +0 -24
  202. package/admin/src/content-manager/icons/Ul/index.js +0 -15
  203. package/admin/src/content-manager/icons/Underline/index.js +0 -22
  204. package/admin/src/favicon.ico +0 -0
  205. package/build/15026a3d58aeb2828134.png +0 -0
  206. package/build/1856.d8f13391.chunk.js +0 -173
  207. package/build/1939.e3c87653.chunk.js +0 -325
  208. package/build/2077.31a2d91e.chunk.js +0 -205
  209. package/build/2912.ab68a736.chunk.js +0 -258
  210. package/build/4318.7d167b58.chunk.js +0 -30
  211. package/build/4715.44b1ef9b.chunk.js +0 -386
  212. package/build/4982.c2a311b7.chunk.js +0 -324
  213. package/build/6925.f5c8b6fc.chunk.js +0 -761
  214. package/build/7841.4b67af3f.chunk.js +0 -258
  215. package/build/7866.5fbeb7e5.chunk.js +0 -504
  216. package/build/8380.9b53a31d.chunk.js +0 -284
  217. package/build/8549.cf10b5d1.chunk.js +0 -158
  218. package/build/8738.a30a2160.chunk.js +0 -461
  219. package/build/90f49a385afb000fb1d4.svg +0 -5
  220. package/build/9420.0fe11290.chunk.js +0 -504
  221. package/build/962.8651ba3f.chunk.js +0 -184
  222. package/build/Admin-authenticatedApp.883449a5.chunk.js +0 -80
  223. package/build/Admin_marketplace.82c0570b.chunk.js +0 -11
  224. package/build/Admin_settingsPage.98e2a62b.chunk.js +0 -178
  225. package/build/a6b842e0b6d2b61135d1.svg +0 -5
  226. package/build/admin-app.a61d5c2e.chunk.js +0 -112
  227. package/build/b997a22a2e0b87ef1fa2.ico +0 -0
  228. package/build/bd81ba6c07827282255d.png +0 -0
  229. package/build/c3de6118ef47086ad05c.png +0 -0
  230. package/build/ca-json.82df6eab.chunk.js +0 -1
  231. package/build/content-manager.933dc286.chunk.js +0 -1201
  232. package/build/content-type-builder-translation-pt-BR-json.d6c7fcc1.chunk.js +0 -1
  233. package/build/de-json.0ad554eb.chunk.js +0 -1
  234. package/build/dk-json.e195ea1a.chunk.js +0 -1
  235. package/build/email-translation-en-json.3d74ff95.chunk.js +0 -1
  236. package/build/en-json.1889403c.chunk.js +0 -1
  237. package/build/es-json.09f80f6e.chunk.js +0 -1
  238. package/build/fb376b132d18bf4522ca.png +0 -0
  239. package/build/fde9b1ad0670d29a2516.png +0 -0
  240. package/build/fr-json.606d056b.chunk.js +0 -1
  241. package/build/gu-json.9881264f.chunk.js +0 -1
  242. package/build/he-json.3b825d80.chunk.js +0 -1
  243. package/build/hi-json.83dcf48f.chunk.js +0 -1
  244. package/build/hu-json.6f328bce.chunk.js +0 -1
  245. package/build/id-json.1f3c4303.chunk.js +0 -1
  246. package/build/it-json.494ac432.chunk.js +0 -1
  247. package/build/ja-json.6f262117.chunk.js +0 -1
  248. package/build/ko-json.36dc3b9a.chunk.js +0 -1
  249. package/build/main.63e7ea0a.js +0 -9338
  250. package/build/ml-json.9566bf9a.chunk.js +0 -1
  251. package/build/nl-json.94c3a289.chunk.js +0 -1
  252. package/build/no-json.40386397.chunk.js +0 -1
  253. package/build/pl-json.ccc6ef23.chunk.js +0 -1
  254. package/build/pt-BR-json.744f024d.chunk.js +0 -1
  255. package/build/ru-json.d22ea13c.chunk.js +0 -1
  256. package/build/runtime~main.3a5e1b07.js +0 -2
  257. package/build/sa-json.8fb1c04d.chunk.js +0 -1
  258. package/build/sk-json.6c7335d4.chunk.js +0 -1
  259. package/build/sv-json.2e589a7d.chunk.js +0 -1
  260. package/build/th-json.72e8de3d.chunk.js +0 -1
  261. package/build/users-permissions-translation-sv-json.83c60841.chunk.js +0 -1
  262. package/build/webhook-list-page.a712ae40.chunk.js +0 -134
  263. package/build/zh-Hans-json.a4d7dc69.chunk.js +0 -1
  264. package/build/zh-json.66aa2ae1.chunk.js +0 -1
@@ -10,8 +10,7 @@ import { basename, createHook } from './core/utils';
10
10
  import configureStore from './core/store/configureStore';
11
11
  import { customFields, Plugin } from './core/apis';
12
12
  import App from './pages/App';
13
- import AuthLogo from './assets/images/logo_strapi_auth_v4.png';
14
- import MenuLogo from './assets/images/logo_strapi_menu.png';
13
+ import Logo from './assets/images/logo-strapi-2022.svg';
15
14
  import Providers from './components/Providers';
16
15
  import languageNativeNames from './translations/languageNativeNames';
17
16
  import {
@@ -21,7 +20,7 @@ import {
21
20
  MUTATE_SINGLE_TYPES_LINKS,
22
21
  } from './exposedHooks';
23
22
  import injectionZones from './injectionZones';
24
- import favicon from './favicon.ico';
23
+ import favicon from './favicon.png';
25
24
  import localStorageKey from './components/LanguageProvider/utils/localStorageKey';
26
25
 
27
26
  class StrapiApp {
@@ -29,10 +28,10 @@ class StrapiApp {
29
28
  this.customConfigurations = adminConfig.config;
30
29
  this.customBootstrapConfiguration = adminConfig.bootstrap;
31
30
  this.configurations = {
32
- authLogo: AuthLogo,
31
+ authLogo: Logo,
33
32
  head: { favicon },
34
33
  locales: ['en'],
35
- menuLogo: MenuLogo,
34
+ menuLogo: Logo,
36
35
  notifications: { releases: true },
37
36
  themes: { light: lightTheme, dark: darkTheme },
38
37
  translations: {},
@@ -227,7 +226,19 @@ class StrapiApp {
227
226
  }
228
227
 
229
228
  if (this.customConfigurations?.theme) {
230
- merge(this.configurations.themes.light, this.customConfigurations.theme);
229
+ const darkTheme = this.customConfigurations.theme.dark;
230
+ const lightTheme = this.customConfigurations.theme.light;
231
+
232
+ if (!darkTheme && !lightTheme) {
233
+ console.warn(
234
+ `[deprecated] In future versions, Strapi will stop supporting this theme customization syntax. The theme configuration accepts a light and a dark key to customize each theme separately. See https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#theme-extension.`
235
+ );
236
+ merge(this.configurations.themes.light, this.customConfigurations.theme);
237
+ }
238
+
239
+ if (lightTheme) merge(this.configurations.themes.light, lightTheme);
240
+
241
+ if (darkTheme) merge(this.configurations.themes.dark, darkTheme);
231
242
  }
232
243
 
233
244
  if (this.customConfigurations?.notifications?.releases !== undefined) {
@@ -1,5 +1,5 @@
1
1
  <svg width="88" height="88" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <rect x="0.5" y="0.5" width="87" height="87" rx="43.5" fill="#F0F0FF"/>
3
- <path d="M34.0469 39.2969H30C27.4479 39.2969 25.2604 40.2448 23.4375 42.1406C21.6146 43.9635 20.7031 46.151 20.7031 48.7031C20.7031 51.2552 21.6146 53.4427 23.4375 55.2656C25.2604 57.0885 27.4479 58 30 58H52.75L34.0469 39.2969ZM23 28.25L25.9531 25.2969L65 64.3438L62.0469 67.2969L57.3438 62.7031H30C26.1354 62.7031 22.8177 61.3542 20.0469 58.6562C17.349 55.8854 16 52.5677 16 48.7031C16 44.9115 17.3125 41.6667 19.9375 38.9688C22.5625 36.2708 25.7344 34.849 29.4531 34.7031L23 28.25ZM61.1719 39.4062C64.1615 39.625 66.7135 40.8646 68.8281 43.125C70.9427 45.3125 72 47.9375 72 51C72 55.0104 70.3594 58.1823 67.0781 60.5156L63.6875 57.125C66.0938 55.8125 67.2969 53.7708 67.2969 51C67.2969 49.1042 66.6042 47.4635 65.2188 46.0781C63.8333 44.6927 62.1927 44 60.2969 44H56.7969V42.7969C56.7969 39.224 55.5573 36.1979 53.0781 33.7188C50.599 31.2396 47.5729 30 44 30C41.9583 30 39.9896 30.474 38.0938 31.4219L34.5938 28.0312C37.4375 26.2083 40.5729 25.2969 44 25.2969C47.9375 25.2969 51.5833 26.6823 54.9375 29.4531C58.3646 32.224 60.4427 35.5417 61.1719 39.4062Z" fill="#4945FF"/>
4
- <rect x="0.5" y="0.5" width="87" height="87" rx="43.5" stroke="#D9D8FF"/>
2
+ <rect x=".5" y=".5" width="87" height="87" rx="43.5" fill="#F0F0FF"/>
3
+ <path d="M34 39.3h-4c-2.6 0-4.7 1-6.6 2.8a9 9 0 0 0-2.7 6.6 9 9 0 0 0 2.7 6.6A9 9 0 0 0 30 58h22.8L34 39.3Zm-11-11 3-3 39 39-3 3-4.7-4.6H30a13.8 13.8 0 0 1-14-14c0-3.8 1.3-7 4-9.7 2.6-2.7 5.7-4.2 9.5-4.3L23 28.2Zm38.2 11.1c3 .2 5.5 1.5 7.6 3.7A11 11 0 0 1 72 51c0 4-1.6 7.2-5 9.5l-3.3-3.4a6.5 6.5 0 0 0 3.6-6.1c0-1.9-.7-3.5-2-5-1.5-1.3-3.1-2-5-2h-3.5v-1.2c0-3.6-1.2-6.6-3.7-9a13 13 0 0 0-15-2.3L34.6 28a17 17 0 0 1 20.3 1.5c3.5 2.7 5.5 6 6.3 10Z" fill="#4945FF"/>
4
+ <rect x=".5" y=".5" width="87" height="87" rx="43.5" stroke="#D9D8FF"/>
5
5
  </svg>
@@ -0,0 +1,7 @@
1
+ <svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M39 282c0-118 0-176.9 36.6-213.5C112.2 32 171.1 32 288.9 32h221.2c117.8 0 176.7 0 213.3 36.6C760 105.2 760 164.1 760 281.9v221.2c0 117.8 0 176.7-36.6 213.3C686.8 753 627.9 753 510.1 753H288.9c-117.8 0-176.7 0-213.3-36.6C39 679.8 39 620.9 39 503.1V281.9Z" fill="#4945FF"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M536.4 250.7H293.7v123.8h123.8v123.7h123.8V255.5c0-2.6-2.2-4.8-4.9-4.8Z" fill="#fff"/>
4
+ <path fill="#fff" d="M412.7 374.5h4.8v4.8h-4.8z"/>
5
+ <path d="M293.8 374.5h119c2.6 0 4.8 2.1 4.8 4.8v119h-119a4.8 4.8 0 0 1-4.8-4.9v-119Z" fill="#9593FF"/>
6
+ <path d="M417.5 498.2h123.8L421.6 618a2.4 2.4 0 0 1-4-1.7v-118ZM293.8 374.5h-118a2.4 2.4 0 0 1-1.7-4.1l119.7-119.7v123.8Z" fill="#9593FF"/>
7
+ </svg>
@@ -32,7 +32,7 @@ const CellValue = ({ type, value }) => {
32
32
  formattedValue = formatNumber(value, {
33
33
  // Should be kept in sync with the corresponding value
34
34
  // in the design-system/NumberInput: https://github.com/strapi/design-system/blob/main/packages/strapi-design-system/src/NumberInput/NumberInput.js#L53
35
- maximumFractionDigits: 21,
35
+ maximumFractionDigits: 20,
36
36
  });
37
37
  }
38
38
 
@@ -31,9 +31,10 @@ const fetchRelation = async (endPoint, notifyStatus) => {
31
31
  const RelationMultiple = ({ fieldSchema, metadatas, name, entityId, value, contentType }) => {
32
32
  const { formatMessage } = useIntl();
33
33
  const { notifyStatus } = useNotifyAT();
34
- const relationFetchEndpoint = useMemo(() => {
35
- return getRequestUrl(`collection-types/${contentType.uid}/${entityId}/${name.split('.')[0]}`);
36
- }, [entityId, name, contentType]);
34
+ const relationFetchEndpoint = useMemo(
35
+ () => getRequestUrl(`relations/${contentType.uid}/${entityId}/${name.split('.')[0]}`),
36
+ [entityId, name, contentType]
37
+ );
37
38
  const [isOpen, setIsOpen] = useState(false);
38
39
 
39
40
  const Label = (
@@ -106,7 +107,7 @@ const RelationMultiple = ({ fieldSchema, metadatas, name, entityId, value, conte
106
107
  defaultMessage: 'This relation contains more entities than displayed',
107
108
  })}
108
109
  >
109
- <Typography>...</Typography>
110
+ <Typography>…</Typography>
110
111
  </MenuItem>
111
112
  )}
112
113
  </>
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import { Typography } from '@strapi/design-system/Typography';
5
+ import { Tooltip } from '@strapi/design-system/Tooltip';
5
6
  import Media from './Media';
6
7
  import MultipleMedias from './MultipleMedias';
7
8
  import RelationMultiple from './RelationMultiple';
@@ -55,6 +56,15 @@ const CellContent = ({ content, fieldSchema, metadatas, name, rowId, contentType
55
56
 
56
57
  return <SingleComponent value={content} metadatas={metadatas} />;
57
58
 
59
+ case 'string':
60
+ return (
61
+ <Tooltip description={content}>
62
+ <TypographyMaxWidth ellipsis textColor="neutral800">
63
+ <CellValue type={type} value={content} />
64
+ </TypographyMaxWidth>
65
+ </Tooltip>
66
+ );
67
+
58
68
  default:
59
69
  return (
60
70
  <TypographyMaxWidth ellipsis textColor="neutral800">
@@ -3,15 +3,22 @@ import PropTypes from 'prop-types';
3
3
  import { useIntl } from 'react-intl';
4
4
  import { DynamicTable as Table, useStrapiApp } from '@strapi/helper-plugin';
5
5
  import { useSelector } from 'react-redux';
6
- import isEmpty from 'lodash/isEmpty';
6
+ import styled from 'styled-components';
7
+
8
+ import { Status } from '@strapi/design-system/Status';
9
+ import { Typography } from '@strapi/design-system/Typography';
10
+
7
11
  import { INJECT_COLUMN_IN_TABLE } from '../../../exposedHooks';
8
12
  import { selectDisplayedHeaders } from '../../pages/ListView/selectors';
9
13
  import { getTrad } from '../../utils';
10
- import State from '../State';
11
14
  import TableRows from './TableRows';
12
15
  import ConfirmDialogDeleteAll from './ConfirmDialogDeleteAll';
13
16
  import ConfirmDialogDelete from './ConfirmDialogDelete';
14
17
 
18
+ const StyledStatus = styled(Status)`
19
+ width: min-content;
20
+ `;
21
+
15
22
  const DynamicTable = ({
16
23
  canCreate,
17
24
  canDelete,
@@ -87,9 +94,19 @@ const DynamicTable = ({
87
94
  sortable: true,
88
95
  },
89
96
  cellFormatter(cellData) {
90
- const isPublished = !isEmpty(cellData.publishedAt);
97
+ const isPublished = cellData.publishedAt;
98
+ const variant = isPublished ? 'success' : 'secondary';
91
99
 
92
- return <State isPublished={isPublished} />;
100
+ return (
101
+ <StyledStatus showBullet={false} variant={variant} size="S">
102
+ <Typography fontWeight="bold" textColor={`${variant}700`}>
103
+ {formatMessage({
104
+ id: getTrad(`containers.List.${isPublished ? 'published' : 'draft'}`),
105
+ defaultMessage: isPublished ? 'Published' : 'Draft',
106
+ })}
107
+ </Typography>
108
+ </StyledStatus>
109
+ );
93
110
  },
94
111
  },
95
112
  ];
@@ -13,7 +13,8 @@ import { BaseButton } from '@strapi/design-system/BaseButton';
13
13
  import { Box } from '@strapi/design-system/Box';
14
14
  import { Flex } from '@strapi/design-system/Flex';
15
15
  import { Typography } from '@strapi/design-system/Typography';
16
- import { getTrad } from '../../../../utils';
16
+
17
+ import { getTrad } from '../../../utils';
17
18
 
18
19
  const StyledAddIcon = styled(PlusCircle)`
19
20
  transform: ${({ $isOpen }) => ($isOpen ? 'rotate(45deg)' : 'rotate(0deg)')};
@@ -142,17 +143,22 @@ const AddComponentButton = ({
142
143
  };
143
144
 
144
145
  AddComponentButton.defaultProps = {
146
+ hasError: false,
147
+ hasMaxError: false,
148
+ hasMinError: false,
149
+ isDisabled: false,
150
+ isOpen: false,
145
151
  label: '',
146
152
  missingComponentNumber: 0,
147
153
  };
148
154
 
149
155
  AddComponentButton.propTypes = {
150
156
  label: PropTypes.string,
151
- hasError: PropTypes.bool.isRequired,
152
- hasMaxError: PropTypes.bool.isRequired,
153
- hasMinError: PropTypes.bool.isRequired,
154
- isDisabled: PropTypes.bool.isRequired,
155
- isOpen: PropTypes.bool.isRequired,
157
+ hasError: PropTypes.bool,
158
+ hasMaxError: PropTypes.bool,
159
+ hasMinError: PropTypes.bool,
160
+ isDisabled: PropTypes.bool,
161
+ isOpen: PropTypes.bool,
156
162
  missingComponentNumber: PropTypes.number,
157
163
  name: PropTypes.string.isRequired,
158
164
  onClick: PropTypes.func.isRequired,
@@ -6,13 +6,13 @@
6
6
 
7
7
  import React from 'react';
8
8
  import PropTypes from 'prop-types';
9
+ import styled from 'styled-components';
10
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
+
9
12
  import { Box } from '@strapi/design-system/Box';
10
13
  import { Typography } from '@strapi/design-system/Typography';
11
14
  import { Stack } from '@strapi/design-system/Stack';
12
15
  import { pxToRem } from '@strapi/helper-plugin';
13
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
14
- import styled from 'styled-components';
15
- import { useIntl } from 'react-intl';
16
16
 
17
17
  const StyledFontAwesomeIcon = styled(FontAwesomeIcon)`
18
18
  width: ${pxToRem(32)} !important;
@@ -53,19 +53,14 @@ const ComponentBox = styled(Box)`
53
53
  }
54
54
  `;
55
55
 
56
- function ComponentCard({ componentUid, intlLabel, icon, onClick }) {
57
- const { formatMessage } = useIntl();
58
- const handleClick = () => {
59
- onClick(componentUid);
60
- };
61
-
56
+ export default function ComponentCard({ children, icon, onClick }) {
62
57
  return (
63
- <button type="button" onClick={handleClick}>
58
+ <button type="button" onClick={onClick}>
64
59
  <ComponentBox borderRadius="borderRadius">
65
60
  <Stack spacing={1} style={{ justifyContent: 'center', alignItems: 'center' }}>
66
- <StyledFontAwesomeIcon icon={icon} />
61
+ <StyledFontAwesomeIcon data-testid="component-card-icon" icon={icon} />
67
62
  <Typography variant="pi" fontWeight="bold" textColor="neutral600">
68
- {formatMessage(intlLabel)}
63
+ {children}
69
64
  </Typography>
70
65
  </Stack>
71
66
  </ComponentBox>
@@ -79,13 +74,7 @@ ComponentCard.defaultProps = {
79
74
  };
80
75
 
81
76
  ComponentCard.propTypes = {
82
- componentUid: PropTypes.string.isRequired,
83
- intlLabel: PropTypes.shape({
84
- id: PropTypes.string.isRequired,
85
- defaultMessage: PropTypes.string.isRequired,
86
- }).isRequired,
77
+ children: PropTypes.node.isRequired,
87
78
  icon: PropTypes.string,
88
79
  onClick: PropTypes.func,
89
80
  };
90
-
91
- export default ComponentCard;
@@ -4,6 +4,7 @@ import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-sys
4
4
  import { Box } from '@strapi/design-system/Box';
5
5
  import styled from 'styled-components';
6
6
  import { useIntl } from 'react-intl';
7
+
7
8
  import ComponentCard from './ComponentCard';
8
9
 
9
10
  const Grid = styled.div`
@@ -12,7 +13,7 @@ const Grid = styled.div`
12
13
  grid-gap: ${({ theme }) => theme.spaces[1]};
13
14
  `;
14
15
 
15
- const Category = ({ category, components, isOdd, isOpen, onAddComponent, onToggle }) => {
16
+ const ComponentCategory = ({ category, components, variant, isOpen, onAddComponent, onToggle }) => {
16
17
  const { formatMessage } = useIntl();
17
18
 
18
19
  const handleToggle = () => {
@@ -22,24 +23,18 @@ const Category = ({ category, components, isOdd, isOpen, onAddComponent, onToggl
22
23
  return (
23
24
  <Accordion expanded={isOpen} onToggle={handleToggle} size="S">
24
25
  <AccordionToggle
25
- variant={isOdd ? 'primary' : 'secondary'}
26
+ variant={variant}
26
27
  title={formatMessage({ id: category, defaultMessage: category })}
27
28
  togglePosition="left"
28
29
  />
29
30
  <AccordionContent>
30
31
  <Box paddingTop={4} paddingBottom={4} paddingLeft={3} paddingRight={3}>
31
32
  <Grid>
32
- {components.map(({ componentUid, info: { displayName, icon } }) => {
33
- return (
34
- <ComponentCard
35
- key={componentUid}
36
- componentUid={componentUid}
37
- intlLabel={{ id: displayName, defaultMessage: displayName }}
38
- icon={icon}
39
- onClick={onAddComponent}
40
- />
41
- );
42
- })}
33
+ {components.map(({ componentUid, info: { displayName, icon } }) => (
34
+ <ComponentCard key={componentUid} icon={icon} onClick={onAddComponent(componentUid)}>
35
+ {formatMessage({ id: displayName, defaultMessage: displayName })}
36
+ </ComponentCard>
37
+ ))}
43
38
  </Grid>
44
39
  </Box>
45
40
  </AccordionContent>
@@ -47,13 +42,19 @@ const Category = ({ category, components, isOdd, isOpen, onAddComponent, onToggl
47
42
  );
48
43
  };
49
44
 
50
- Category.propTypes = {
45
+ ComponentCategory.defaultProps = {
46
+ components: [],
47
+ isOpen: false,
48
+ variant: 'primary',
49
+ };
50
+
51
+ ComponentCategory.propTypes = {
51
52
  category: PropTypes.string.isRequired,
52
- components: PropTypes.array.isRequired,
53
- isOdd: PropTypes.bool.isRequired,
54
- isOpen: PropTypes.bool.isRequired,
53
+ components: PropTypes.array,
54
+ isOpen: PropTypes.bool,
55
55
  onAddComponent: PropTypes.func.isRequired,
56
56
  onToggle: PropTypes.func.isRequired,
57
+ variant: PropTypes.oneOf(['primary', 'secondary']),
57
58
  };
58
59
 
59
- export default Category;
60
+ export default ComponentCategory;
@@ -1,4 +1,4 @@
1
- import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
2
  import groupBy from 'lodash/groupBy';
3
3
  import PropTypes from 'prop-types';
4
4
  import { useIntl } from 'react-intl';
@@ -6,9 +6,11 @@ import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable';
6
6
  import { Box } from '@strapi/design-system/Box';
7
7
  import { Flex } from '@strapi/design-system/Flex';
8
8
  import { Typography } from '@strapi/design-system/Typography';
9
- import { getTrad } from '../../../../utils';
10
- import { useContentTypeLayout } from '../../../../hooks';
11
- import Category from './Category';
9
+
10
+ import { getTrad } from '../../../utils';
11
+ import { useContentTypeLayout } from '../../../hooks';
12
+
13
+ import ComponentCategory from './ComponentCategory';
12
14
 
13
15
  const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
14
16
  const { formatMessage } = useIntl();
@@ -32,27 +34,22 @@ const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
32
34
  }, [components, getComponentLayout]);
33
35
 
34
36
  useEffect(() => {
35
- if (isOpen && dynamicComponentCategories.length) {
37
+ if (isOpen && dynamicComponentCategories.length > 0) {
36
38
  setCategoryToOpen(dynamicComponentCategories[0].category);
37
39
  }
38
40
  }, [isOpen, dynamicComponentCategories]);
39
41
 
40
- const handleAddComponentToDz = useCallback(
41
- (componentUid) => {
42
- onClickAddComponent(componentUid);
43
- setCategoryToOpen('');
44
- },
45
- [onClickAddComponent]
46
- );
47
-
48
- const handleClickToggle = useCallback(
49
- (categoryName) => {
50
- const nextCategoryToOpen = categoryToOpen === categoryName ? '' : categoryName;
42
+ const handleAddComponentToDz = (componentUid) => () => {
43
+ onClickAddComponent(componentUid);
44
+ setCategoryToOpen('');
45
+ };
51
46
 
52
- setCategoryToOpen(nextCategoryToOpen);
53
- },
54
- [categoryToOpen]
55
- );
47
+ /**
48
+ * @type {(categoryName: string) => void}
49
+ */
50
+ const handleClickToggle = (categoryName) => {
51
+ setCategoryToOpen((currentCat) => (currentCat === categoryName ? '' : categoryName));
52
+ };
56
53
 
57
54
  if (!isOpen) {
58
55
  return null;
@@ -80,21 +77,17 @@ const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
80
77
  </Flex>
81
78
  <Box paddingTop={2}>
82
79
  <KeyboardNavigable attributeName="data-strapi-accordion-toggle">
83
- {dynamicComponentCategories.map(({ category, components }, index) => {
84
- return (
85
- <Category
86
- key={category}
87
- category={category}
88
- components={components}
89
- isOdd={index % 2 === 1}
90
- isOpen={category === categoryToOpen}
91
- // TODO?
92
- // isFirst={index === 0}
93
- onAddComponent={handleAddComponentToDz}
94
- onToggle={handleClickToggle}
95
- />
96
- );
97
- })}
80
+ {dynamicComponentCategories.map(({ category, components }, index) => (
81
+ <ComponentCategory
82
+ key={category}
83
+ category={category}
84
+ components={components}
85
+ onAddComponent={handleAddComponentToDz}
86
+ isOpen={category === categoryToOpen}
87
+ onToggle={handleClickToggle}
88
+ variant={index % 2 === 1 ? 'primary' : 'secondary'}
89
+ />
90
+ ))}
98
91
  </KeyboardNavigable>
99
92
  </Box>
100
93
  </Box>
@@ -102,10 +95,15 @@ const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
102
95
  );
103
96
  };
104
97
 
98
+ ComponentPicker.defaultProps = {
99
+ components: [],
100
+ isOpen: false,
101
+ };
102
+
105
103
  ComponentPicker.propTypes = {
106
- components: PropTypes.array.isRequired,
107
- isOpen: PropTypes.bool.isRequired,
104
+ components: PropTypes.array,
105
+ isOpen: PropTypes.bool,
108
106
  onClickAddComponent: PropTypes.func.isRequired,
109
107
  };
110
108
 
111
- export default memo(ComponentPicker);
109
+ export default ComponentPicker;
@@ -0,0 +1,195 @@
1
+ import React, { useMemo, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from 'styled-components';
4
+ import { useIntl } from 'react-intl';
5
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
+ import get from 'lodash/get';
7
+
8
+ import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
9
+ import { IconButton } from '@strapi/design-system/IconButton';
10
+ import { Box } from '@strapi/design-system/Box';
11
+ import { Flex } from '@strapi/design-system/Flex';
12
+ import { Stack } from '@strapi/design-system/Stack';
13
+
14
+ import { useCMEditViewDataManager } from '@strapi/helper-plugin';
15
+
16
+ import Trash from '@strapi/icons/Trash';
17
+ import ArrowDown from '@strapi/icons/ArrowDown';
18
+ import ArrowUp from '@strapi/icons/ArrowUp';
19
+
20
+ import { useContentTypeLayout } from '../../../hooks';
21
+ import { getTrad } from '../../../utils';
22
+
23
+ import FieldComponent from '../../FieldComponent';
24
+
25
+ const IconButtonCustom = styled(IconButton)`
26
+ background-color: transparent;
27
+
28
+ svg path {
29
+ fill: ${({ theme, expanded }) =>
30
+ expanded ? theme.colors.primary600 : theme.colors.neutral600};
31
+ }
32
+ `;
33
+
34
+ const StyledBox = styled(Box)`
35
+ > div:first-child {
36
+ box-shadow: ${({ theme }) => theme.shadows.tableShadow};
37
+ }
38
+ `;
39
+
40
+ const AccordionContentRadius = styled(Box)`
41
+ border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
42
+ `;
43
+
44
+ const Rectangle = styled(Box)`
45
+ width: ${({ theme }) => theme.spaces[2]};
46
+ height: ${({ theme }) => theme.spaces[4]};
47
+ `;
48
+
49
+ const DynamicZoneComponent = ({
50
+ componentUid,
51
+ formErrors,
52
+ index,
53
+ isFieldAllowed,
54
+ onMoveComponentDownClick,
55
+ onMoveComponentUpClick,
56
+ name,
57
+ onRemoveComponentClick,
58
+ showDownIcon,
59
+ showUpIcon,
60
+ }) => {
61
+ const [isOpen, setIsOpen] = useState(true);
62
+ const { formatMessage } = useIntl();
63
+ const { getComponentLayout } = useContentTypeLayout();
64
+ const { modifiedData } = useCMEditViewDataManager();
65
+ const { icon, friendlyName, mainValue } = useMemo(() => {
66
+ const componentLayoutData = getComponentLayout(componentUid);
67
+
68
+ const {
69
+ info: { icon, displayName },
70
+ } = componentLayoutData;
71
+
72
+ const mainFieldKey = get(componentLayoutData, ['settings', 'mainField'], 'id');
73
+
74
+ const mainField = get(modifiedData, [name, index, mainFieldKey]) ?? '';
75
+
76
+ const displayedValue = mainFieldKey === 'id' ? '' : mainField.trim();
77
+
78
+ const mainValue = displayedValue.length > 0 ? ` - ${displayedValue}` : displayedValue;
79
+
80
+ return { friendlyName: displayName, icon, mainValue };
81
+ }, [componentUid, getComponentLayout, modifiedData, name, index]);
82
+
83
+ const fieldsErrors = Object.keys(formErrors).filter((errorKey) => {
84
+ const errorKeysArray = errorKey.split('.');
85
+
86
+ if (`${errorKeysArray[0]}.${errorKeysArray[1]}` === `${name}.${index}`) {
87
+ return true;
88
+ }
89
+
90
+ return false;
91
+ });
92
+
93
+ let errorMessage;
94
+
95
+ if (fieldsErrors.length > 0) {
96
+ errorMessage = formatMessage({
97
+ id: getTrad('components.DynamicZone.error-message'),
98
+ defaultMessage: 'The component contains error(s)',
99
+ });
100
+ }
101
+
102
+ const handleToggle = () => {
103
+ setIsOpen((s) => !s);
104
+ };
105
+
106
+ return (
107
+ <Box>
108
+ <Flex justifyContent="center">
109
+ <Rectangle background="neutral200" />
110
+ </Flex>
111
+ <StyledBox hasRadius>
112
+ <Accordion expanded={isOpen} onToggle={handleToggle} size="S" error={errorMessage}>
113
+ <AccordionToggle
114
+ startIcon={<FontAwesomeIcon icon={icon} />}
115
+ action={
116
+ <Stack horizontal spacing={0} expanded={isOpen}>
117
+ {showDownIcon && (
118
+ <IconButtonCustom
119
+ noBorder
120
+ label={formatMessage({
121
+ id: getTrad('components.DynamicZone.move-down-label'),
122
+ defaultMessage: 'Move component down',
123
+ })}
124
+ onClick={onMoveComponentDownClick}
125
+ icon={<ArrowDown />}
126
+ />
127
+ )}
128
+ {showUpIcon && (
129
+ <IconButtonCustom
130
+ noBorder
131
+ label={formatMessage({
132
+ id: getTrad('components.DynamicZone.move-up-label'),
133
+ defaultMessage: 'Move component up',
134
+ })}
135
+ onClick={onMoveComponentUpClick}
136
+ icon={<ArrowUp />}
137
+ />
138
+ )}
139
+ {isFieldAllowed && (
140
+ <IconButtonCustom
141
+ noBorder
142
+ label={formatMessage(
143
+ {
144
+ id: getTrad('components.DynamicZone.delete-label'),
145
+ defaultMessage: 'Delete {name}',
146
+ },
147
+ { name: friendlyName }
148
+ )}
149
+ onClick={onRemoveComponentClick}
150
+ icon={<Trash />}
151
+ />
152
+ )}
153
+ </Stack>
154
+ }
155
+ title={`${friendlyName}${mainValue}`}
156
+ togglePosition="left"
157
+ />
158
+ <AccordionContent>
159
+ <AccordionContentRadius background="neutral0">
160
+ <FieldComponent
161
+ componentUid={componentUid}
162
+ icon={icon}
163
+ name={`${name}.${index}`}
164
+ isFromDynamicZone
165
+ />
166
+ </AccordionContentRadius>
167
+ </AccordionContent>
168
+ </Accordion>
169
+ </StyledBox>
170
+ </Box>
171
+ );
172
+ };
173
+
174
+ DynamicZoneComponent.defaultProps = {
175
+ formErrors: {},
176
+ index: 0,
177
+ isFieldAllowed: true,
178
+ showDownIcon: true,
179
+ showUpIcon: true,
180
+ };
181
+
182
+ DynamicZoneComponent.propTypes = {
183
+ componentUid: PropTypes.string.isRequired,
184
+ formErrors: PropTypes.object,
185
+ index: PropTypes.number,
186
+ isFieldAllowed: PropTypes.bool,
187
+ name: PropTypes.string.isRequired,
188
+ onMoveComponentDownClick: PropTypes.func.isRequired,
189
+ onMoveComponentUpClick: PropTypes.func.isRequired,
190
+ onRemoveComponentClick: PropTypes.func.isRequired,
191
+ showDownIcon: PropTypes.bool,
192
+ showUpIcon: PropTypes.bool,
193
+ };
194
+
195
+ export default DynamicZoneComponent;