@strapi/admin 4.5.0-alpha.0 → 4.5.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.
- package/admin/src/StrapiApp.js +21 -18
- package/admin/src/assets/images/hot-air-balloon.png +0 -0
- package/admin/src/assets/images/icon_offline-cloud.svg +3 -3
- package/admin/src/assets/images/logo-strapi-2022.svg +7 -0
- package/admin/src/assets/images/upgrade-details.png +0 -0
- package/admin/src/components/Providers/index.js +14 -10
- package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +24 -0
- package/admin/src/content-manager/components/DynamicTable/CellContent/CellValue.js +1 -1
- package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +5 -4
- package/admin/src/content-manager/components/DynamicTable/CellContent/index.js +10 -0
- package/admin/src/content-manager/components/DynamicTable/TableRows/index.js +20 -15
- package/admin/src/content-manager/components/DynamicTable/index.js +21 -4
- package/admin/src/content-manager/components/DynamicZone/components/Component/index.js +19 -9
- package/admin/src/content-manager/components/DynamicZone/index.js +6 -2
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +153 -63
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +180 -132
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +70 -16
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +52 -0
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +2 -0
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +72 -0
- package/admin/src/content-manager/components/FieldComponent/index.js +9 -2
- package/admin/src/content-manager/components/FieldTypeIcon/index.js +31 -1
- package/admin/src/content-manager/components/Inputs/index.js +36 -14
- package/admin/src/content-manager/components/NonRepeatableComponent/index.js +2 -0
- package/admin/src/content-manager/components/PreviewWysiwyg/index.js +1 -1
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +163 -96
- package/admin/src/content-manager/components/RelationInput/components/RelationItem.js +2 -2
- package/admin/src/content-manager/components/RelationInput/constants.js +1 -1
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +116 -73
- package/admin/src/content-manager/components/RelationInputDataManager/utils/diffRelations.js +24 -0
- package/admin/src/content-manager/components/RelationInputDataManager/utils/index.js +3 -1
- package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeRelations.js +17 -31
- package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeSearchResults.js +16 -0
- package/admin/src/content-manager/components/RelationInputDataManager/utils/select.js +35 -11
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +5 -0
- package/admin/src/content-manager/components/RepeatableComponent/index.js +4 -3
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +23 -0
- package/admin/src/content-manager/hooks/__test__/usePrev.test.js +26 -0
- package/admin/src/content-manager/hooks/index.js +1 -0
- package/admin/src/content-manager/hooks/useFetchContentTypeLayout/utils/formatLayouts.js +19 -48
- package/admin/src/content-manager/hooks/usePrev.js +14 -0
- package/admin/src/content-manager/hooks/useRelation/useRelation.js +116 -15
- package/admin/src/content-manager/pages/App/reducer.js +3 -0
- package/admin/src/content-manager/pages/EditSettingsView/components/FormModal.js +7 -2
- package/admin/src/content-manager/pages/EditSettingsView/index.js +2 -1
- package/admin/src/content-manager/pages/EditView/Header/index.js +118 -50
- package/admin/src/content-manager/pages/EditView/Header/utils/select.js +4 -0
- package/admin/src/content-manager/pages/EditView/index.js +102 -93
- package/admin/src/content-manager/pages/ListSettingsView/components/DraggableCard.js +3 -3
- package/admin/src/content-manager/pages/ListSettingsView/components/Settings.js +2 -2
- package/admin/src/content-manager/pages/ListSettingsView/components/SortDisplayedFields.js +1 -1
- package/admin/src/content-manager/pages/ListView/index.js +24 -15
- package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +14 -2
- package/admin/src/contexts/ApiTokenPermissions/index.js +24 -0
- package/admin/src/core/apis/CustomFields.js +79 -0
- package/admin/src/core/apis/index.js +1 -0
- package/admin/src/core/store/configureStore.js +17 -2
- package/admin/src/favicon.png +0 -0
- package/admin/src/hooks/index.js +1 -0
- package/admin/src/hooks/useFetchMarketplacePlugins/index.js +2 -2
- package/admin/src/hooks/useFetchMarketplacePlugins/utils/api.js +4 -2
- package/admin/src/hooks/useFetchMarketplaceProviders/index.js +3 -3
- package/admin/src/hooks/useFetchMarketplaceProviders/utils/api.js +5 -3
- package/admin/src/hooks/useRegenerate/index.js +34 -0
- package/admin/src/index.js +1 -0
- package/admin/src/pages/App/index.js +1 -1
- package/admin/src/pages/HomePage/SocialLinks.js +1 -1
- package/admin/src/pages/HomePage/assets/corner-ornament.svg +48 -0
- package/admin/src/pages/HomePage/index.js +3 -2
- package/admin/src/pages/MarketplacePage/components/NpmPackageCard/CardButton.js +110 -0
- package/admin/src/pages/MarketplacePage/components/NpmPackageCard/InstallPluginButton.js +32 -21
- package/admin/src/pages/MarketplacePage/components/NpmPackageCard/PackageStats.js +79 -0
- package/admin/src/pages/MarketplacePage/components/NpmPackageCard/index.js +28 -11
- package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/FilterSelect.js +41 -0
- package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/FiltersPopover.js +96 -0
- package/admin/src/pages/MarketplacePage/components/NpmPackagesFilters/index.js +106 -0
- package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +4 -0
- package/admin/src/pages/MarketplacePage/components/SortSelect/index.js +70 -0
- package/admin/src/pages/MarketplacePage/index.js +68 -8
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js +56 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js +41 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js +72 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js +30 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +150 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContenTypesSection/index.js +37 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +255 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +78 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormHead/index.js +89 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +40 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +68 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +216 -197
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +13 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +72 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/getDateOfExpiration.js +16 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/index.js +5 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +2 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +36 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +63 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +1 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +19 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +3 -36
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +13 -11
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +3 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/utils/tableHeaders.js +8 -8
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ProtectedEditView/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/index.js +7 -38
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/options.js +31 -0
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/index.js +32 -43
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Roles/ListPage/components/RoleRow/index.js +3 -1
- package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +2 -1
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +2 -2
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +2 -2
- package/admin/src/permissions/defaultPermissions.js +2 -6
- package/admin/src/translations/ca.json +4 -2
- package/admin/src/translations/de.json +5 -2
- package/admin/src/translations/dk.json +4 -1
- package/admin/src/translations/en.json +38 -3
- package/admin/src/translations/es.json +157 -158
- package/admin/src/translations/fr.json +4 -1
- package/admin/src/translations/gu.json +608 -606
- package/admin/src/translations/he.json +1 -1
- package/admin/src/translations/hi.json +689 -687
- package/admin/src/translations/hu.json +3 -1
- package/admin/src/translations/id.json +3 -1
- package/admin/src/translations/it.json +3 -1
- package/admin/src/translations/ja.json +3 -1
- package/admin/src/translations/ko.json +3 -1
- package/admin/src/translations/ml.json +689 -687
- package/admin/src/translations/nl.json +4 -1
- package/admin/src/translations/no.json +1 -1
- package/admin/src/translations/pl.json +3 -1
- package/admin/src/translations/pt-BR.json +4 -1
- package/admin/src/translations/ru.json +489 -491
- package/admin/src/translations/sa.json +86 -83
- package/admin/src/translations/sk.json +4 -1
- package/admin/src/translations/sv.json +4 -1
- package/admin/src/translations/th.json +1 -1
- package/admin/src/translations/zh-Hans.json +5 -2
- package/admin/src/translations/zh.json +4 -1
- package/build/1856.172d5fa0.chunk.js +174 -0
- package/build/2077.058590f4.chunk.js +206 -0
- package/build/2912.2c42c07b.chunk.js +259 -0
- package/build/4318.5e670740.chunk.js +30 -0
- package/build/4715.22747b59.chunk.js +387 -0
- package/build/{4800.d09f1225.chunk.js → 4800.a6935af6.chunk.js} +1 -1
- package/build/4982.1b75ddb1.chunk.js +325 -0
- package/build/617f9c948fa79e6d73bd.png +0 -0
- package/build/6d21938306785f176538.png +0 -0
- package/build/70674f63fc3904c20de0.svg +7 -0
- package/build/7379.d246dd38.chunk.js +1 -0
- package/build/7692.a36fb2c2.chunk.js +470 -0
- package/build/7841.c50e9509.chunk.js +259 -0
- package/build/7866.ba215f99.chunk.js +505 -0
- package/build/7e9af4fb7e723fcebf1f.svg +48 -0
- package/build/8380.e53e7207.chunk.js +299 -0
- package/build/8549.832ed79d.chunk.js +159 -0
- package/build/8738.0fe8a61e.chunk.js +463 -0
- package/build/{9066.08049eb1.chunk.js → 9066.eaf76ff3.chunk.js} +5 -5
- package/build/{9166.037339e0.chunk.js → 9166.90876521.chunk.js} +16 -15
- package/build/{9420.43a86e7c.chunk.js → 9420.5292d1d2.chunk.js} +38 -37
- package/build/9649.468667d9.chunk.js +199 -0
- package/build/9d5d788027e86620c234.svg +5 -0
- package/build/{Admin-authenticatedApp.e39f36c9.chunk.js → Admin-authenticatedApp.c4f68103.chunk.js} +3 -3
- package/build/{Admin_homePage.118926e0.chunk.js → Admin_homePage.26d32e30.chunk.js} +6 -5
- package/build/Admin_marketplace.32375885.chunk.js +22 -0
- package/build/{Admin_profilePage.9d50ac44.chunk.js → Admin_profilePage.da32abbc.chunk.js} +1 -1
- package/build/Admin_settingsPage.bf2234e1.chunk.js +178 -0
- package/build/admin-app.9049056c.chunk.js +112 -0
- package/build/admin-edit-roles-page.69d9fcb2.chunk.js +1 -0
- package/build/{admin-users.97a08630.chunk.js → admin-users.d71f198a.chunk.js} +3 -3
- package/build/api-tokens-create-page.93dd0689.chunk.js +1 -0
- package/build/api-tokens-edit-page.b0adac81.chunk.js +1 -0
- package/build/api-tokens-list-page.bb36535f.chunk.js +16 -0
- package/build/ca-json.07ae0f2c.chunk.js +1 -0
- package/build/content-manager.ff998bed.chunk.js +1204 -0
- package/build/content-type-builder-list-view.5b3cd768.chunk.js +194 -0
- package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +1 -0
- package/build/content-type-builder-translation-sv-json.6deff030.chunk.js +1 -0
- package/build/content-type-builder.16af63a6.chunk.js +145 -0
- package/build/de-json.6b3e1894.chunk.js +1 -0
- package/build/dk-json.144c6a8e.chunk.js +1 -0
- package/build/{email-settings-page.64037147.chunk.js → email-settings-page.c3469093.chunk.js} +6 -6
- package/build/en-json.4a269f6b.chunk.js +1 -0
- package/build/es-json.6d123a82.chunk.js +1 -0
- package/build/fr-json.28ab54cb.chunk.js +1 -0
- package/build/gu-json.9a50ea64.chunk.js +1 -0
- package/build/he-json.72f18790.chunk.js +1 -0
- package/build/hi-json.0301b7ba.chunk.js +1 -0
- package/build/hu-json.c4b641bb.chunk.js +1 -0
- package/build/{i18n-settings-page.0b73785d.chunk.js → i18n-settings-page.46d894ff.chunk.js} +5 -5
- package/build/id-json.86035797.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/it-json.bbdc8993.chunk.js +1 -0
- package/build/ja-json.1c9eeeec.chunk.js +1 -0
- package/build/ko-json.e1f66398.chunk.js +1 -0
- package/build/main.91328e7a.js +9381 -0
- package/build/ml-json.963c889f.chunk.js +1 -0
- package/build/nl-json.2b8cc3a0.chunk.js +1 -0
- package/build/no-json.a58c28bd.chunk.js +1 -0
- package/build/pl-json.249626b3.chunk.js +1 -0
- package/build/pt-BR-json.7852f808.chunk.js +1 -0
- package/build/ru-json.d7cfc2ff.chunk.js +1 -0
- package/build/runtime~main.c9c319c0.js +2 -0
- package/build/sa-json.44e95991.chunk.js +1 -0
- package/build/sk-json.7ba4b330.chunk.js +1 -0
- package/build/sso-settings-page.9ceb0140.chunk.js +1 -0
- package/build/sv-json.8e5a7911.chunk.js +1 -0
- package/build/th-json.a67309b1.chunk.js +1 -0
- package/build/{upload-settings.80ff0974.chunk.js → upload-settings.53b690f3.chunk.js} +5 -5
- package/build/{upload-translation-en-json.004a86c1.chunk.js → upload-translation-en-json.86da7b0a.chunk.js} +1 -1
- package/build/{users-advanced-settings-page.a02f4806.chunk.js → users-advanced-settings-page.3f4ee86e.chunk.js} +5 -5
- package/build/{webhook-edit-page.d2ea3351.chunk.js → webhook-edit-page.dc9442ce.chunk.js} +2 -2
- package/build/webhook-list-page.02191138.chunk.js +134 -0
- package/build/zh-Hans-json.21617c24.chunk.js +1 -0
- package/build/zh-json.608aaf24.chunk.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +3 -2
- package/ee/server/controllers/user.js +5 -3
- package/env.js +1 -0
- package/package.json +13 -11
- package/scripts/build.js +11 -0
- package/server/bootstrap.js +19 -1
- package/server/config/admin-actions.js +20 -0
- package/server/content-types/api-token-permission.js +36 -0
- package/server/content-types/api-token.js +25 -1
- package/server/content-types/index.js +1 -0
- package/server/controllers/admin.js +3 -0
- package/server/controllers/api-token.js +24 -1
- package/server/controllers/content-api.js +15 -0
- package/server/controllers/index.js +1 -0
- package/server/controllers/user.js +3 -2
- package/server/routes/api-tokens.js +11 -0
- package/server/routes/content-api.js +20 -0
- package/server/routes/index.js +2 -0
- package/server/services/api-token.js +309 -29
- package/server/services/constants.js +10 -0
- package/server/services/permission/engine.js +36 -226
- package/server/services/permission.js +4 -1
- package/server/strategies/admin.js +7 -1
- package/server/strategies/api-token.js +72 -11
- package/server/validation/api-tokens.js +12 -2
- package/utils/create-plugins-exclude-path.js +40 -0
- package/utils/get-custom-app-config-file.js +5 -0
- package/webpack.alias.js +0 -13
- package/webpack.config.js +4 -1
- package/admin/src/assets/images/banner_strapi-rocket.png +0 -0
- package/admin/src/assets/images/big-logo-home.png +0 -0
- package/admin/src/assets/images/homepage-logo.png +0 -0
- package/admin/src/assets/images/icon_made-by-strapi.svg +0 -5
- package/admin/src/assets/images/logo_strapi_auth.png +0 -0
- package/admin/src/assets/images/logo_strapi_auth_v4.png +0 -0
- package/admin/src/assets/images/logo_strapi_menu.png +0 -0
- package/admin/src/assets/images/oops.png +0 -0
- package/admin/src/content-manager/components/State/index.js +0 -37
- package/admin/src/favicon.ico +0 -0
- package/build/15026a3d58aeb2828134.png +0 -0
- package/build/1856.47226450.chunk.js +0 -173
- package/build/2077.c935ee42.chunk.js +0 -205
- package/build/2912.a015078a.chunk.js +0 -258
- package/build/4715.58cd558f.chunk.js +0 -387
- package/build/4982.05eda880.chunk.js +0 -324
- package/build/7098.40dcd7bf.chunk.js +0 -1
- package/build/7841.91f793dc.chunk.js +0 -258
- package/build/7866.1201afbd.chunk.js +0 -504
- package/build/8380.8789ff76.chunk.js +0 -284
- package/build/8549.133c4473.chunk.js +0 -158
- package/build/8851.e4ac62f2.chunk.js +0 -158
- package/build/90f49a385afb000fb1d4.svg +0 -5
- package/build/9311.7cc03f29.chunk.js +0 -508
- package/build/Admin_marketplace.82c0570b.chunk.js +0 -11
- package/build/Admin_settingsPage.98a711e5.chunk.js +0 -178
- package/build/a6b842e0b6d2b61135d1.svg +0 -5
- package/build/admin-app.4f7618a9.chunk.js +0 -112
- package/build/admin-edit-roles-page.554ba3fa.chunk.js +0 -1
- package/build/api-tokens-create-page.4c262d6e.chunk.js +0 -1
- package/build/api-tokens-edit-page.10a9d368.chunk.js +0 -1
- package/build/api-tokens-list-page.442c9f3c.chunk.js +0 -15
- package/build/b997a22a2e0b87ef1fa2.ico +0 -0
- package/build/bd81ba6c07827282255d.png +0 -0
- package/build/c3de6118ef47086ad05c.png +0 -0
- package/build/ca-json.a16899ae.chunk.js +0 -1
- package/build/content-manager.7d57c9d1.chunk.js +0 -1200
- package/build/content-type-builder-list-view.8cc534e0.chunk.js +0 -194
- package/build/content-type-builder-translation-en-json.201bfb78.chunk.js +0 -1
- package/build/content-type-builder.684df7a4.chunk.js +0 -142
- package/build/de-json.aa6026b3.chunk.js +0 -1
- package/build/dk-json.fac2bcfb.chunk.js +0 -1
- package/build/en-json.0c69c7d7.chunk.js +0 -1
- package/build/es-json.d672e181.chunk.js +0 -1
- package/build/fb376b132d18bf4522ca.png +0 -0
- package/build/fde9b1ad0670d29a2516.png +0 -0
- package/build/fr-json.71a16175.chunk.js +0 -1
- package/build/gu-json.ca345cd1.chunk.js +0 -1
- package/build/he-json.3b825d80.chunk.js +0 -1
- package/build/hi-json.50c7e6d4.chunk.js +0 -1
- package/build/hu-json.e0521dcc.chunk.js +0 -1
- package/build/id-json.4b1ff8d6.chunk.js +0 -1
- package/build/it-json.86bac220.chunk.js +0 -1
- package/build/ja-json.4e44e36b.chunk.js +0 -1
- package/build/ko-json.1003756e.chunk.js +0 -1
- package/build/main.b47db1a3.js +0 -9337
- package/build/ml-json.c7774425.chunk.js +0 -1
- package/build/nl-json.f58ea235.chunk.js +0 -1
- package/build/no-json.40386397.chunk.js +0 -1
- package/build/pl-json.fed96aba.chunk.js +0 -1
- package/build/pt-BR-json.073799ab.chunk.js +0 -1
- package/build/ru-json.7ad2cbbf.chunk.js +0 -1
- package/build/runtime~main.feeac6d3.js +0 -2
- package/build/sa-json.f0f704f0.chunk.js +0 -1
- package/build/sk-json.a848961b.chunk.js +0 -1
- package/build/sso-settings-page.445184e0.chunk.js +0 -1
- package/build/sv-json.b038acbe.chunk.js +0 -1
- package/build/th-json.72e8de3d.chunk.js +0 -1
- package/build/webhook-list-page.2775a683.chunk.js +0 -134
- package/build/zh-Hans-json.03d2bda1.chunk.js +0 -1
- package/build/zh-json.3d0cc664.chunk.js +0 -1
- package/server/services/permission/engine-hooks.js +0 -82
package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
1
2
|
import PropTypes from 'prop-types';
|
|
2
|
-
import React, { memo,
|
|
3
|
+
import React, { memo, useMemo } from 'react';
|
|
3
4
|
import { useIntl } from 'react-intl';
|
|
5
|
+
import get from 'lodash/get';
|
|
6
|
+
import pick from 'lodash/pick';
|
|
4
7
|
|
|
5
|
-
import { useCMEditViewDataManager, NotAllowedInput
|
|
8
|
+
import { useCMEditViewDataManager, NotAllowedInput } from '@strapi/helper-plugin';
|
|
6
9
|
|
|
7
10
|
import { RelationInput } from '../RelationInput';
|
|
11
|
+
|
|
8
12
|
import { useRelation } from '../../hooks/useRelation';
|
|
9
|
-
|
|
10
|
-
import { PUBLICATION_STATES, RELATIONS_TO_DISPLAY, SEARCH_RESULTS_TO_DISPLAY } from './constants';
|
|
13
|
+
|
|
11
14
|
import { getTrad } from '../../utils';
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
import { PUBLICATION_STATES, RELATIONS_TO_DISPLAY, SEARCH_RESULTS_TO_DISPLAY } from './constants';
|
|
17
|
+
import { connect, select, normalizeSearchResults, diffRelations, normalizeRelation } from './utils';
|
|
18
|
+
|
|
19
|
+
export const RelationInputDataManager = ({
|
|
20
|
+
error,
|
|
21
|
+
componentId,
|
|
22
|
+
isComponentRelation,
|
|
14
23
|
editable,
|
|
15
24
|
description,
|
|
16
25
|
intlLabel,
|
|
@@ -30,61 +39,42 @@ export const RelationInputDataManger = ({
|
|
|
30
39
|
const { formatMessage } = useIntl();
|
|
31
40
|
const { connectRelation, disconnectRelation, loadRelation, modifiedData, slug, initialData } =
|
|
32
41
|
useCMEditViewDataManager();
|
|
33
|
-
|
|
42
|
+
|
|
43
|
+
const relationsFromModifiedData = get(modifiedData, name) ?? [];
|
|
44
|
+
|
|
45
|
+
const currentLastPage = Math.ceil(get(initialData, name, []).length / RELATIONS_TO_DISPLAY);
|
|
34
46
|
|
|
35
47
|
const { relations, search, searchFor } = useRelation(`${slug}-${name}-${initialData?.id ?? ''}`, {
|
|
48
|
+
name,
|
|
36
49
|
relation: {
|
|
37
|
-
enabled:
|
|
50
|
+
enabled: !!endpoints.relation,
|
|
38
51
|
endpoint: endpoints.relation,
|
|
52
|
+
pageGoal: currentLastPage,
|
|
39
53
|
pageParams: {
|
|
40
54
|
...defaultParams,
|
|
41
|
-
locale: query?.plugins?.i18n?.locale,
|
|
42
55
|
pageSize: RELATIONS_TO_DISPLAY,
|
|
43
56
|
},
|
|
57
|
+
onLoad: loadRelation,
|
|
58
|
+
normalizeArguments: {
|
|
59
|
+
mainFieldName: mainField.name,
|
|
60
|
+
shouldAddLink: shouldDisplayRelationLink,
|
|
61
|
+
targetModel,
|
|
62
|
+
},
|
|
44
63
|
},
|
|
45
64
|
|
|
46
65
|
search: {
|
|
47
66
|
endpoint: endpoints.search,
|
|
48
67
|
pageParams: {
|
|
49
68
|
...defaultParams,
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
// eslint-disable-next-line no-nested-ternary
|
|
70
|
+
entityId: isCreatingEntry ? undefined : isComponentRelation ? componentId : initialData.id,
|
|
52
71
|
pageSize: SEARCH_RESULTS_TO_DISPLAY,
|
|
53
72
|
},
|
|
54
73
|
},
|
|
55
74
|
});
|
|
56
75
|
|
|
57
|
-
const stringifiedRelations = JSON.stringify(relations);
|
|
58
|
-
const normalizedRelations = useMemo(
|
|
59
|
-
() =>
|
|
60
|
-
normalizeRelations(relations, {
|
|
61
|
-
modifiedData: modifiedData?.[name],
|
|
62
|
-
mainFieldName: mainField.name,
|
|
63
|
-
shouldAddLink: shouldDisplayRelationLink,
|
|
64
|
-
targetModel,
|
|
65
|
-
}),
|
|
66
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
-
[
|
|
68
|
-
stringifiedRelations,
|
|
69
|
-
modifiedData,
|
|
70
|
-
name,
|
|
71
|
-
mainField.name,
|
|
72
|
-
shouldDisplayRelationLink,
|
|
73
|
-
targetModel,
|
|
74
|
-
]
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
if (relations.status === 'success') {
|
|
79
|
-
loadRelation({
|
|
80
|
-
target: { name, value: normalizedRelations.data.pages.flat() },
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
84
|
-
}, [loadRelation, relations.status, stringifiedRelations, name]);
|
|
85
|
-
|
|
86
76
|
const isMorph = useMemo(() => relationType.toLowerCase().includes('morph'), [relationType]);
|
|
87
|
-
const
|
|
77
|
+
const toOneRelation = [
|
|
88
78
|
'oneWay',
|
|
89
79
|
'oneToOne',
|
|
90
80
|
'manyToOne',
|
|
@@ -104,24 +94,37 @@ export const RelationInputDataManger = ({
|
|
|
104
94
|
return !editable;
|
|
105
95
|
}, [isMorph, isCreatingEntry, editable, isFieldAllowed, isFieldReadable]);
|
|
106
96
|
|
|
107
|
-
const
|
|
108
|
-
|
|
97
|
+
const handleRelationConnect = (relation) => {
|
|
98
|
+
/**
|
|
99
|
+
* Any relation being added to the store should be normalized so it has it's link.
|
|
100
|
+
*/
|
|
101
|
+
const normalizedRelation = normalizeRelation(relation, {
|
|
102
|
+
mainFieldName: mainField.name,
|
|
103
|
+
shouldAddLink: shouldDisplayRelationLink,
|
|
104
|
+
targetModel,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
connectRelation({ name, value: normalizedRelation, toOneRelation });
|
|
109
108
|
};
|
|
110
109
|
|
|
111
|
-
const
|
|
112
|
-
disconnectRelation({
|
|
110
|
+
const handleRelationDisconnect = (relation) => {
|
|
111
|
+
disconnectRelation({ name, id: relation.id });
|
|
113
112
|
};
|
|
114
113
|
|
|
115
114
|
const handleRelationLoadMore = () => {
|
|
116
115
|
relations.fetchNextPage();
|
|
117
116
|
};
|
|
118
117
|
|
|
119
|
-
const handleSearch = (term) => {
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
const handleSearch = (term = '') => {
|
|
119
|
+
const [connected, disconnected] = diffRelations(
|
|
120
|
+
relationsFromModifiedData,
|
|
121
|
+
get(initialData, name)
|
|
122
|
+
);
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
searchFor(term, {
|
|
125
|
+
idsToInclude: disconnected,
|
|
126
|
+
idsToOmit: connected,
|
|
127
|
+
});
|
|
125
128
|
};
|
|
126
129
|
|
|
127
130
|
const handleSearchMore = () => {
|
|
@@ -132,43 +135,70 @@ export const RelationInputDataManger = ({
|
|
|
132
135
|
(!isFieldAllowed && isCreatingEntry) ||
|
|
133
136
|
(!isCreatingEntry && !isFieldAllowed && !isFieldReadable)
|
|
134
137
|
) {
|
|
135
|
-
return <NotAllowedInput intlLabel={intlLabel} labelAction={labelAction} />;
|
|
138
|
+
return <NotAllowedInput name={name} intlLabel={intlLabel} labelAction={labelAction} />;
|
|
136
139
|
}
|
|
137
140
|
|
|
141
|
+
/**
|
|
142
|
+
* How to calculate the total number of relations even if you don't
|
|
143
|
+
* have them all loaded in the browser.
|
|
144
|
+
*
|
|
145
|
+
* 1. The `infiniteQuery` gives you the total number of relations in the pagination result.
|
|
146
|
+
* 2. You can diff the length of the browserState vs the fetchedServerState to determine if you've
|
|
147
|
+
* either added or removed relations.
|
|
148
|
+
* 3. Add them together, if you've removed relations you'll get a negative number and it'll
|
|
149
|
+
* actually subtract from the total number on the server (regardless of how many you fetched).
|
|
150
|
+
*/
|
|
151
|
+
const browserRelationsCount = relationsFromModifiedData.length;
|
|
152
|
+
const serverRelationsCount = (get(initialData, name) ?? []).length;
|
|
153
|
+
const realServerRelationsCount = relations.data?.pages[0]?.pagination?.total ?? 0;
|
|
154
|
+
/**
|
|
155
|
+
* _IF_ theres no relations data and the browserCount is the same as serverCount you can therefore assume
|
|
156
|
+
* that the browser count is correct because we've just _made_ this entry and the in-component hook is now fetching.
|
|
157
|
+
*/
|
|
158
|
+
const totalRelations =
|
|
159
|
+
!relations.data && browserRelationsCount === serverRelationsCount
|
|
160
|
+
? browserRelationsCount
|
|
161
|
+
: browserRelationsCount - serverRelationsCount + realServerRelationsCount;
|
|
162
|
+
|
|
138
163
|
return (
|
|
139
164
|
<RelationInput
|
|
165
|
+
error={error}
|
|
140
166
|
description={description}
|
|
141
167
|
disabled={isDisabled}
|
|
142
168
|
id={name}
|
|
143
169
|
label={`${formatMessage({
|
|
144
170
|
id: intlLabel.id,
|
|
145
171
|
defaultMessage: intlLabel.defaultMessage,
|
|
146
|
-
})} ${
|
|
172
|
+
})} ${totalRelations > 0 ? `(${totalRelations})` : ''}`}
|
|
147
173
|
labelAction={labelAction}
|
|
148
174
|
labelLoadMore={
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
175
|
+
!isCreatingEntry
|
|
176
|
+
? formatMessage({
|
|
177
|
+
id: getTrad('relation.loadMore'),
|
|
178
|
+
defaultMessage: 'Load More',
|
|
179
|
+
})
|
|
180
|
+
: null
|
|
155
181
|
}
|
|
182
|
+
labelDisconnectRelation={formatMessage({
|
|
183
|
+
id: getTrad('relation.disconnect'),
|
|
184
|
+
defaultMessage: 'Remove',
|
|
185
|
+
})}
|
|
156
186
|
listHeight={320}
|
|
157
|
-
loadingMessage={(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
})
|
|
162
|
-
}
|
|
187
|
+
loadingMessage={formatMessage({
|
|
188
|
+
id: getTrad('relation.isLoading'),
|
|
189
|
+
defaultMessage: 'Relations are loading',
|
|
190
|
+
})}
|
|
163
191
|
name={name}
|
|
192
|
+
noRelationsMessage={formatMessage({
|
|
193
|
+
id: getTrad('relation.notAvailable'),
|
|
194
|
+
defaultMessage: 'No relations available',
|
|
195
|
+
})}
|
|
164
196
|
numberOfRelationsToDisplay={RELATIONS_TO_DISPLAY}
|
|
165
|
-
|
|
166
|
-
|
|
197
|
+
onRelationConnect={(relation) => handleRelationConnect(relation)}
|
|
198
|
+
onRelationDisconnect={(relation) => handleRelationDisconnect(relation)}
|
|
167
199
|
onRelationLoadMore={() => handleRelationLoadMore()}
|
|
168
200
|
onSearch={(term) => handleSearch(term)}
|
|
169
201
|
onSearchNextPage={() => handleSearchMore()}
|
|
170
|
-
onSearchClose={() => {}}
|
|
171
|
-
onSearchOpen={handleOpenSearch}
|
|
172
202
|
placeholder={formatMessage(
|
|
173
203
|
placeholder || {
|
|
174
204
|
id: getTrad('relation.add'),
|
|
@@ -186,9 +216,16 @@ export const RelationInputDataManger = ({
|
|
|
186
216
|
defaultMessage: 'Published',
|
|
187
217
|
}),
|
|
188
218
|
}}
|
|
189
|
-
relations={
|
|
219
|
+
relations={pick(
|
|
220
|
+
{ ...relations, data: relationsFromModifiedData },
|
|
221
|
+
'data',
|
|
222
|
+
'hasNextPage',
|
|
223
|
+
'isFetchingNextPage',
|
|
224
|
+
'isLoading',
|
|
225
|
+
'isSuccess'
|
|
226
|
+
)}
|
|
190
227
|
required={required}
|
|
191
|
-
searchResults={
|
|
228
|
+
searchResults={normalizeSearchResults(search, {
|
|
192
229
|
mainFieldName: mainField.name,
|
|
193
230
|
})}
|
|
194
231
|
size={size}
|
|
@@ -196,17 +233,22 @@ export const RelationInputDataManger = ({
|
|
|
196
233
|
);
|
|
197
234
|
};
|
|
198
235
|
|
|
199
|
-
|
|
236
|
+
RelationInputDataManager.defaultProps = {
|
|
237
|
+
componentId: undefined,
|
|
200
238
|
editable: true,
|
|
239
|
+
error: undefined,
|
|
201
240
|
description: '',
|
|
202
241
|
labelAction: null,
|
|
242
|
+
isComponentRelation: false,
|
|
203
243
|
isFieldAllowed: true,
|
|
204
244
|
placeholder: null,
|
|
205
245
|
required: false,
|
|
206
246
|
};
|
|
207
247
|
|
|
208
|
-
|
|
248
|
+
RelationInputDataManager.propTypes = {
|
|
249
|
+
componentId: PropTypes.number,
|
|
209
250
|
editable: PropTypes.bool,
|
|
251
|
+
error: PropTypes.string,
|
|
210
252
|
description: PropTypes.string,
|
|
211
253
|
intlLabel: PropTypes.shape({
|
|
212
254
|
id: PropTypes.string.isRequired,
|
|
@@ -215,6 +257,7 @@ RelationInputDataManger.propTypes = {
|
|
|
215
257
|
}).isRequired,
|
|
216
258
|
labelAction: PropTypes.element,
|
|
217
259
|
isCreatingEntry: PropTypes.bool.isRequired,
|
|
260
|
+
isComponentRelation: PropTypes.bool,
|
|
218
261
|
isFieldAllowed: PropTypes.bool,
|
|
219
262
|
isFieldReadable: PropTypes.bool.isRequired,
|
|
220
263
|
mainField: PropTypes.shape({
|
|
@@ -235,7 +278,7 @@ RelationInputDataManger.propTypes = {
|
|
|
235
278
|
targetModel: PropTypes.string.isRequired,
|
|
236
279
|
queryInfos: PropTypes.shape({
|
|
237
280
|
defaultParams: PropTypes.shape({
|
|
238
|
-
|
|
281
|
+
locale: PropTypes.string,
|
|
239
282
|
}),
|
|
240
283
|
endpoints: PropTypes.shape({
|
|
241
284
|
relation: PropTypes.string,
|
|
@@ -245,6 +288,6 @@ RelationInputDataManger.propTypes = {
|
|
|
245
288
|
}).isRequired,
|
|
246
289
|
};
|
|
247
290
|
|
|
248
|
-
const Memoized = memo(
|
|
291
|
+
const Memoized = memo(RelationInputDataManager);
|
|
249
292
|
|
|
250
293
|
export default connect(Memoized, select);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Array<{id: string}>} browserStateRelations
|
|
3
|
+
* @param {Array<{id: string}>} serverStateRelations
|
|
4
|
+
* @returns {[connected: string[], disconnected: string[]]} – the connected and disconnected relations ids
|
|
5
|
+
*/
|
|
6
|
+
export const diffRelations = (browserStateRelations = [], serverStateRelations = []) => {
|
|
7
|
+
const connected = browserStateRelations.reduce((acc, relation) => {
|
|
8
|
+
if (!serverStateRelations.find((oldRelation) => oldRelation.id === relation.id)) {
|
|
9
|
+
return [...acc, relation.id];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return acc;
|
|
13
|
+
}, []);
|
|
14
|
+
|
|
15
|
+
const disconnected = serverStateRelations.reduce((acc, relation) => {
|
|
16
|
+
if (!browserStateRelations.find((oldRelation) => oldRelation.id === relation.id)) {
|
|
17
|
+
return [...acc, relation.id];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return acc;
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
return [connected, disconnected];
|
|
24
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { default as connect } from './connect';
|
|
2
2
|
export { default as select } from './select';
|
|
3
|
-
export { normalizeRelations } from './normalizeRelations';
|
|
3
|
+
export { normalizeRelations, normalizeRelation } from './normalizeRelations';
|
|
4
|
+
export { normalizeSearchResults } from './normalizeSearchResults';
|
|
5
|
+
export { diffRelations } from './diffRelations';
|
package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeRelations.js
CHANGED
|
@@ -2,7 +2,7 @@ import { getRelationLink } from './getRelationLink';
|
|
|
2
2
|
|
|
3
3
|
import { PUBLICATION_STATES } from '../constants';
|
|
4
4
|
|
|
5
|
-
const normalizeRelation = (relation, { shouldAddLink, mainFieldName, targetModel }) => {
|
|
5
|
+
export const normalizeRelation = (relation, { shouldAddLink, mainFieldName, targetModel }) => {
|
|
6
6
|
const nextRelation = { ...relation };
|
|
7
7
|
|
|
8
8
|
if (shouldAddLink) {
|
|
@@ -22,37 +22,23 @@ const normalizeRelation = (relation, { shouldAddLink, mainFieldName, targetModel
|
|
|
22
22
|
return nextRelation;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
/*
|
|
26
|
+
* Applies some transformations to existing and new relations in order to display them correctly
|
|
27
|
+
* relations: raw relations data coming from useRelations
|
|
28
|
+
* shouldAddLink: comes from generateRelationQueryInfos, if true we display a link to the relation (TO FIX: explanation)
|
|
29
|
+
* mainFieldName: name of the main field inside the relation (e.g. text field), if no displayable main field exists (e.g. date field) we use the id of the entry
|
|
30
|
+
* targetModel: the model on which the relation is based on, used to create an URL link
|
|
31
|
+
*/
|
|
32
|
+
|
|
25
33
|
export const normalizeRelations = (
|
|
26
34
|
relations,
|
|
27
|
-
{
|
|
35
|
+
{ shouldAddLink = false, mainFieldName, targetModel } = {}
|
|
28
36
|
) => {
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
]
|
|
37
|
-
?.map((page) =>
|
|
38
|
-
page?.results
|
|
39
|
-
.filter(
|
|
40
|
-
(relation) =>
|
|
41
|
-
!modifiedData?.disconnect?.find(
|
|
42
|
-
(disconnectRelation) => disconnectRelation.id === relation.id
|
|
43
|
-
)
|
|
44
|
-
)
|
|
45
|
-
.map((relation) =>
|
|
46
|
-
normalizeRelation(relation, {
|
|
47
|
-
modifiedData,
|
|
48
|
-
shouldAddLink,
|
|
49
|
-
mainFieldName,
|
|
50
|
-
targetModel,
|
|
51
|
-
})
|
|
52
|
-
)
|
|
53
|
-
.filter(Boolean)
|
|
54
|
-
)
|
|
55
|
-
?.filter((page) => page.length > 0) ?? [],
|
|
56
|
-
},
|
|
57
|
-
};
|
|
37
|
+
return [...relations].map((relation) =>
|
|
38
|
+
normalizeRelation(relation, {
|
|
39
|
+
shouldAddLink,
|
|
40
|
+
mainFieldName,
|
|
41
|
+
targetModel,
|
|
42
|
+
})
|
|
43
|
+
);
|
|
58
44
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { normalizeRelation } from './normalizeRelations';
|
|
2
|
+
|
|
3
|
+
export const normalizeSearchResults = (relations, { mainFieldName }) => {
|
|
4
|
+
const { data } = relations;
|
|
5
|
+
const { pages = [] } = data ?? {};
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
...relations,
|
|
9
|
+
data: pages
|
|
10
|
+
.map((page) =>
|
|
11
|
+
page?.results.map((relation) => normalizeRelation(relation, { mainFieldName }))
|
|
12
|
+
)
|
|
13
|
+
.filter(Boolean)
|
|
14
|
+
.flat(),
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
+
import get from 'lodash/get';
|
|
2
3
|
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
|
|
3
4
|
|
|
4
5
|
import { getRequestUrl } from '../../../utils';
|
|
5
6
|
|
|
6
|
-
function useSelect({
|
|
7
|
+
function useSelect({
|
|
8
|
+
componentUid,
|
|
9
|
+
isUserAllowedToEditField,
|
|
10
|
+
isUserAllowedToReadField,
|
|
11
|
+
name,
|
|
12
|
+
queryInfos,
|
|
13
|
+
}) {
|
|
7
14
|
const {
|
|
8
15
|
isCreatingEntry,
|
|
9
16
|
createActionAllowedFields,
|
|
@@ -11,7 +18,6 @@ function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name, q
|
|
|
11
18
|
updateActionAllowedFields,
|
|
12
19
|
slug,
|
|
13
20
|
initialData,
|
|
14
|
-
isSingleType,
|
|
15
21
|
} = useCMEditViewDataManager();
|
|
16
22
|
|
|
17
23
|
const isFieldAllowed = useMemo(() => {
|
|
@@ -40,25 +46,43 @@ function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name, q
|
|
|
40
46
|
return allowedFields.includes(name);
|
|
41
47
|
}, [isCreatingEntry, isUserAllowedToReadField, name, readActionAllowedFields]);
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
const fieldNameKeys = name.split('.');
|
|
50
|
+
let componentId;
|
|
51
|
+
|
|
52
|
+
if (componentUid) {
|
|
53
|
+
componentId = get(initialData, fieldNameKeys.slice(0, -1))?.id;
|
|
54
|
+
}
|
|
46
55
|
|
|
56
|
+
// /content-manager/relations/[model]/[id]/[field-name]
|
|
57
|
+
const relationFetchEndpoint = useMemo(() => {
|
|
47
58
|
if (isCreatingEntry) {
|
|
48
59
|
return null;
|
|
49
60
|
}
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
if (componentUid) {
|
|
63
|
+
// repeatable components and dz are dynamically created
|
|
64
|
+
// if no componentId exists in initialData it means that the user just created it
|
|
65
|
+
// there then are no relations to request
|
|
66
|
+
return componentId
|
|
67
|
+
? getRequestUrl(`relations/${componentUid}/${componentId}/${fieldNameKeys.at(-1)}`)
|
|
68
|
+
: null;
|
|
69
|
+
}
|
|
55
70
|
|
|
56
|
-
|
|
71
|
+
return getRequestUrl(`relations/${slug}/${initialData.id}/${name.split('.').at(-1)}`);
|
|
72
|
+
}, [isCreatingEntry, componentUid, slug, initialData.id, name, componentId, fieldNameKeys]);
|
|
73
|
+
|
|
74
|
+
// /content-manager/relations/[model]/[field-name]
|
|
57
75
|
const relationSearchEndpoint = useMemo(() => {
|
|
76
|
+
if (componentUid) {
|
|
77
|
+
return getRequestUrl(`relations/${componentUid}/${name.split('.').at(-1)}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
58
80
|
return getRequestUrl(`relations/${slug}/${name.split('.').at(-1)}`);
|
|
59
|
-
}, [slug, name]);
|
|
81
|
+
}, [componentUid, slug, name]);
|
|
60
82
|
|
|
61
83
|
return {
|
|
84
|
+
componentId,
|
|
85
|
+
isComponentRelation: Boolean(componentUid),
|
|
62
86
|
queryInfos: {
|
|
63
87
|
...queryInfos,
|
|
64
88
|
endpoints: {
|
|
@@ -44,6 +44,7 @@ const DragButton = styled.span`
|
|
|
44
44
|
|
|
45
45
|
const DraggedItem = ({
|
|
46
46
|
componentFieldName,
|
|
47
|
+
componentUid,
|
|
47
48
|
// Errors are retrieved from the AccordionGroupCustom cloneElement
|
|
48
49
|
hasErrorMessage,
|
|
49
50
|
hasErrors,
|
|
@@ -265,11 +266,13 @@ const DraggedItem = ({
|
|
|
265
266
|
return (
|
|
266
267
|
<GridItem key={keys} col={size} s={12} xs={12}>
|
|
267
268
|
<Inputs
|
|
269
|
+
componentUid={componentUid}
|
|
268
270
|
fieldSchema={fieldSchema}
|
|
269
271
|
keys={keys}
|
|
270
272
|
metadatas={metadatas}
|
|
271
273
|
// onBlur={hasErrors ? checkFormErrors : null}
|
|
272
274
|
queryInfos={queryInfos}
|
|
275
|
+
size={size}
|
|
273
276
|
/>
|
|
274
277
|
</GridItem>
|
|
275
278
|
);
|
|
@@ -286,6 +289,7 @@ const DraggedItem = ({
|
|
|
286
289
|
};
|
|
287
290
|
|
|
288
291
|
DraggedItem.defaultProps = {
|
|
292
|
+
componentUid: undefined,
|
|
289
293
|
isDraggingSibling: false,
|
|
290
294
|
isOpen: false,
|
|
291
295
|
setIsDraggingSibling() {},
|
|
@@ -294,6 +298,7 @@ DraggedItem.defaultProps = {
|
|
|
294
298
|
|
|
295
299
|
DraggedItem.propTypes = {
|
|
296
300
|
componentFieldName: PropTypes.string.isRequired,
|
|
301
|
+
componentUid: PropTypes.string,
|
|
297
302
|
hasErrorMessage: PropTypes.bool.isRequired,
|
|
298
303
|
hasErrors: PropTypes.bool.isRequired,
|
|
299
304
|
isDraggingSibling: PropTypes.bool,
|
|
@@ -48,7 +48,7 @@ const RepeatableComponent = ({
|
|
|
48
48
|
const [collapseToOpen, setCollapseToOpen] = useState('');
|
|
49
49
|
const [isDraggingSibling, setIsDraggingSibling] = useState(false);
|
|
50
50
|
const [, drop] = useDrop({ accept: ItemTypes.COMPONENT });
|
|
51
|
-
const { getComponentLayout } = useContentTypeLayout();
|
|
51
|
+
const { getComponentLayout, components } = useContentTypeLayout();
|
|
52
52
|
const componentLayoutData = useMemo(
|
|
53
53
|
() => getComponentLayout(componentUid),
|
|
54
54
|
[componentUid, getComponentLayout]
|
|
@@ -73,7 +73,7 @@ const RepeatableComponent = ({
|
|
|
73
73
|
if (componentValueLength < max) {
|
|
74
74
|
const shouldCheckErrors = hasMinError;
|
|
75
75
|
|
|
76
|
-
addRepeatableComponentToField(name,
|
|
76
|
+
addRepeatableComponentToField(name, componentLayoutData, components, shouldCheckErrors);
|
|
77
77
|
|
|
78
78
|
setCollapseToOpen(nextTempKey);
|
|
79
79
|
} else if (componentValueLength >= max) {
|
|
@@ -84,8 +84,9 @@ const RepeatableComponent = ({
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}, [
|
|
87
|
+
components,
|
|
87
88
|
addRepeatableComponentToField,
|
|
88
|
-
|
|
89
|
+
componentLayoutData,
|
|
89
90
|
componentValueLength,
|
|
90
91
|
hasMinError,
|
|
91
92
|
isReadOnly,
|
|
@@ -234,6 +234,28 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
234
234
|
queryClient,
|
|
235
235
|
]
|
|
236
236
|
);
|
|
237
|
+
|
|
238
|
+
const onDraftRelationCheck = useCallback(async () => {
|
|
239
|
+
try {
|
|
240
|
+
trackUsageRef.current('willCheckDraftRelations');
|
|
241
|
+
|
|
242
|
+
const endPoint = getRequestUrl(`${slug}/actions/numberOfDraftRelations`);
|
|
243
|
+
dispatch(setStatus('draft-relation-check-pending'));
|
|
244
|
+
|
|
245
|
+
const numberOfDraftRelations = await axiosInstance.get(endPoint);
|
|
246
|
+
trackUsageRef.current('didCheckDraftRelations');
|
|
247
|
+
|
|
248
|
+
dispatch(setStatus('resolved'));
|
|
249
|
+
|
|
250
|
+
return numberOfDraftRelations.data.data;
|
|
251
|
+
} catch (err) {
|
|
252
|
+
displayErrors(err);
|
|
253
|
+
dispatch(setStatus('resolved'));
|
|
254
|
+
|
|
255
|
+
return Promise.reject(err);
|
|
256
|
+
}
|
|
257
|
+
}, [displayErrors, slug, dispatch]);
|
|
258
|
+
|
|
237
259
|
const onPublish = useCallback(async () => {
|
|
238
260
|
try {
|
|
239
261
|
trackUsageRef.current('willPublishEntry');
|
|
@@ -337,6 +359,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
337
359
|
onDelete,
|
|
338
360
|
onDeleteSucceeded,
|
|
339
361
|
onPost,
|
|
362
|
+
onDraftRelationCheck,
|
|
340
363
|
onPublish,
|
|
341
364
|
onPut,
|
|
342
365
|
onUnpublish,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { renderHook } from '@testing-library/react-hooks';
|
|
2
|
+
|
|
3
|
+
import { usePrev } from '../usePrev';
|
|
4
|
+
|
|
5
|
+
describe('usePrev', () => {
|
|
6
|
+
const setup = () => renderHook(({ state }) => usePrev(state), { initialProps: { state: 0 } });
|
|
7
|
+
|
|
8
|
+
it('should return undefined on initial render', () => {
|
|
9
|
+
const { result } = setup();
|
|
10
|
+
|
|
11
|
+
expect(result.current).toBeUndefined();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should always return previous state after each update', () => {
|
|
15
|
+
const { result, rerender } = setup();
|
|
16
|
+
|
|
17
|
+
rerender({ state: 2 });
|
|
18
|
+
expect(result.current).toBe(0);
|
|
19
|
+
|
|
20
|
+
rerender({ state: 4 });
|
|
21
|
+
expect(result.current).toBe(2);
|
|
22
|
+
|
|
23
|
+
rerender({ state: 6 });
|
|
24
|
+
expect(result.current).toBe(4);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -5,3 +5,4 @@ export { default as useLayoutDnd } from './useLayoutDnd';
|
|
|
5
5
|
export { default as usePluginsQueryParams } from './usePluginsQueryParams';
|
|
6
6
|
export { default as useSyncRbac } from './useSyncRbac';
|
|
7
7
|
export { default as useWysiwyg } from './useWysiwyg';
|
|
8
|
+
export { usePrev } from './usePrev';
|