@strapi/admin 4.5.0-alpha.0 → 4.5.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.
- package/admin/src/StrapiApp.js +4 -12
- 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/TableRows/index.js +20 -15
- package/admin/src/content-manager/components/DynamicZone/components/Component/index.js +19 -9
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +50 -3
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +50 -9
- 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/RelationInput/RelationInput.js +95 -32
- 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 +33 -22
- package/admin/src/content-manager/components/RelationInputDataManager/utils/index.js +1 -0
- package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeRelations.js +10 -3
- package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeSearchResults.js +12 -0
- package/admin/src/content-manager/components/RelationInputDataManager/utils/select.js +34 -11
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +5 -0
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +23 -0
- package/admin/src/content-manager/hooks/useRelation/useRelation.js +17 -9
- 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/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 +80 -0
- package/admin/src/core/apis/index.js +1 -0
- package/admin/src/hooks/index.js +1 -0
- package/admin/src/hooks/useRegenerate/index.js +34 -0
- package/admin/src/pages/HomePage/SocialLinks.js +1 -1
- 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 +254 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +77 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormHead/index.js +85 -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 +215 -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/Users/ListPage/ModalForm/index.js +2 -2
- package/admin/src/permissions/defaultPermissions.js +2 -6
- package/admin/src/translations/ca.json +3 -1
- package/admin/src/translations/de.json +4 -1
- package/admin/src/translations/dk.json +3 -0
- package/admin/src/translations/en.json +22 -1
- package/admin/src/translations/es.json +156 -157
- package/admin/src/translations/fr.json +3 -0
- package/admin/src/translations/gu.json +608 -606
- package/admin/src/translations/hi.json +689 -687
- package/admin/src/translations/hu.json +2 -0
- package/admin/src/translations/id.json +2 -0
- package/admin/src/translations/it.json +2 -0
- package/admin/src/translations/ja.json +2 -0
- package/admin/src/translations/ko.json +2 -0
- package/admin/src/translations/ml.json +689 -687
- package/admin/src/translations/nl.json +3 -0
- package/admin/src/translations/pl.json +2 -0
- package/admin/src/translations/pt-BR.json +3 -0
- package/admin/src/translations/ru.json +489 -491
- package/admin/src/translations/sa.json +85 -82
- package/admin/src/translations/sk.json +3 -0
- package/admin/src/translations/sv.json +3 -0
- package/admin/src/translations/zh-Hans.json +4 -1
- package/admin/src/translations/zh.json +3 -0
- package/build/1856.d8f13391.chunk.js +173 -0
- package/build/{9311.7cc03f29.chunk.js → 1939.e3c87653.chunk.js} +108 -291
- package/build/{2077.c935ee42.chunk.js → 2077.31a2d91e.chunk.js} +4 -4
- package/build/{2912.a015078a.chunk.js → 2912.ab68a736.chunk.js} +8 -8
- package/build/4318.7d167b58.chunk.js +30 -0
- package/build/4715.44b1ef9b.chunk.js +386 -0
- package/build/{4982.05eda880.chunk.js → 4982.c2a311b7.chunk.js} +9 -9
- package/build/7379.d246dd38.chunk.js +1 -0
- package/build/{7841.91f793dc.chunk.js → 7841.4b67af3f.chunk.js} +8 -8
- package/build/{7866.1201afbd.chunk.js → 7866.5fbeb7e5.chunk.js} +10 -10
- package/build/{8380.8789ff76.chunk.js → 8380.9b53a31d.chunk.js} +7 -7
- package/build/{8549.133c4473.chunk.js → 8549.cf10b5d1.chunk.js} +4 -4
- package/build/8738.a30a2160.chunk.js +461 -0
- package/build/{9066.08049eb1.chunk.js → 9066.26faf397.chunk.js} +4 -4
- package/build/{9166.037339e0.chunk.js → 9166.8fcb3019.chunk.js} +5 -5
- package/build/{9420.43a86e7c.chunk.js → 9420.0fe11290.chunk.js} +6 -6
- package/build/962.8651ba3f.chunk.js +184 -0
- package/build/Admin-authenticatedApp.883449a5.chunk.js +80 -0
- package/build/{Admin_homePage.118926e0.chunk.js → Admin_homePage.4b2be829.chunk.js} +2 -2
- package/build/{Admin_profilePage.9d50ac44.chunk.js → Admin_profilePage.da32abbc.chunk.js} +1 -1
- package/build/{Admin_settingsPage.98a711e5.chunk.js → Admin_settingsPage.98e2a62b.chunk.js} +16 -16
- package/build/admin-app.a61d5c2e.chunk.js +112 -0
- package/build/admin-edit-roles-page.4dd6bcb9.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.a16899ae.chunk.js → ca-json.82df6eab.chunk.js} +1 -1
- package/build/content-manager.933dc286.chunk.js +1201 -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.a6e29716.chunk.js +145 -0
- package/build/{de-json.aa6026b3.chunk.js → de-json.0ad554eb.chunk.js} +1 -1
- package/build/{dk-json.fac2bcfb.chunk.js → dk-json.e195ea1a.chunk.js} +1 -1
- package/build/{email-settings-page.64037147.chunk.js → email-settings-page.bfe6227f.chunk.js} +4 -4
- package/build/en-json.1889403c.chunk.js +1 -0
- package/build/{es-json.d672e181.chunk.js → es-json.09f80f6e.chunk.js} +1 -1
- package/build/{fr-json.71a16175.chunk.js → fr-json.606d056b.chunk.js} +1 -1
- package/build/{gu-json.ca345cd1.chunk.js → gu-json.9881264f.chunk.js} +1 -1
- package/build/{hi-json.50c7e6d4.chunk.js → hi-json.83dcf48f.chunk.js} +1 -1
- package/build/{hu-json.e0521dcc.chunk.js → hu-json.6f328bce.chunk.js} +1 -1
- package/build/{i18n-settings-page.0b73785d.chunk.js → i18n-settings-page.18166125.chunk.js} +4 -4
- package/build/{id-json.4b1ff8d6.chunk.js → id-json.1f3c4303.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/{it-json.86bac220.chunk.js → it-json.494ac432.chunk.js} +1 -1
- package/build/{ja-json.4e44e36b.chunk.js → ja-json.6f262117.chunk.js} +1 -1
- package/build/{ko-json.1003756e.chunk.js → ko-json.36dc3b9a.chunk.js} +1 -1
- package/build/main.63e7ea0a.js +9338 -0
- package/build/{ml-json.c7774425.chunk.js → ml-json.9566bf9a.chunk.js} +1 -1
- package/build/{nl-json.f58ea235.chunk.js → nl-json.94c3a289.chunk.js} +1 -1
- package/build/{pl-json.fed96aba.chunk.js → pl-json.ccc6ef23.chunk.js} +1 -1
- package/build/{pt-BR-json.073799ab.chunk.js → pt-BR-json.744f024d.chunk.js} +1 -1
- package/build/{ru-json.7ad2cbbf.chunk.js → ru-json.d22ea13c.chunk.js} +1 -1
- package/build/{runtime~main.feeac6d3.js → runtime~main.3a5e1b07.js} +1 -1
- package/build/{sa-json.f0f704f0.chunk.js → sa-json.8fb1c04d.chunk.js} +1 -1
- package/build/{sk-json.a848961b.chunk.js → sk-json.6c7335d4.chunk.js} +1 -1
- package/build/sso-settings-page.9ceb0140.chunk.js +1 -0
- package/build/{sv-json.b038acbe.chunk.js → sv-json.2e589a7d.chunk.js} +1 -1
- package/build/{upload-settings.80ff0974.chunk.js → upload-settings.3d613216.chunk.js} +4 -4
- 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.f4051d92.chunk.js} +4 -4
- package/build/{webhook-edit-page.d2ea3351.chunk.js → webhook-edit-page.9e46fc3f.chunk.js} +1 -1
- package/build/{webhook-list-page.2775a683.chunk.js → webhook-list-page.a712ae40.chunk.js} +4 -4
- package/build/{zh-Hans-json.03d2bda1.chunk.js → zh-Hans-json.a4d7dc69.chunk.js} +1 -1
- package/build/{zh-json.3d0cc664.chunk.js → zh-json.66aa2ae1.chunk.js} +1 -1
- package/ee/server/controllers/user.js +5 -3
- package/package.json +9 -8
- 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/get-custom-app-config-file.js +5 -0
- package/build/1856.47226450.chunk.js +0 -173
- package/build/4715.58cd558f.chunk.js +0 -387
- package/build/7098.40dcd7bf.chunk.js +0 -1
- package/build/8851.e4ac62f2.chunk.js +0 -158
- package/build/Admin-authenticatedApp.e39f36c9.chunk.js +0 -80
- 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/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/en-json.0c69c7d7.chunk.js +0 -1
- package/build/main.b47db1a3.js +0 -9337
- package/build/sso-settings-page.445184e0.chunk.js +0 -1
- package/server/services/permission/engine-hooks.js +0 -82
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef, useState, useMemo, useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import styled
|
|
3
|
+
import styled from 'styled-components';
|
|
4
4
|
import { FixedSizeList as List } from 'react-window';
|
|
5
5
|
|
|
6
6
|
import { ReactSelect } from '@strapi/helper-plugin';
|
|
@@ -15,7 +15,6 @@ import { Tooltip } from '@strapi/design-system/Tooltip';
|
|
|
15
15
|
|
|
16
16
|
import Cross from '@strapi/icons/Cross';
|
|
17
17
|
import Refresh from '@strapi/icons/Refresh';
|
|
18
|
-
import Loader from '@strapi/icons/Loader';
|
|
19
18
|
|
|
20
19
|
import { Relation } from './components/Relation';
|
|
21
20
|
import { RelationItem } from './components/RelationItem';
|
|
@@ -39,19 +38,15 @@ const BoxEllipsis = styled(Box)`
|
|
|
39
38
|
}
|
|
40
39
|
`;
|
|
41
40
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
const DisconnectButton = styled.button`
|
|
42
|
+
svg path {
|
|
43
|
+
fill: ${({ theme }) => theme.colors.neutral500};
|
|
45
44
|
}
|
|
46
|
-
to {
|
|
47
|
-
transform: rotate(359deg);
|
|
48
|
-
}
|
|
49
|
-
`;
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
&:hover svg path,
|
|
47
|
+
&:focus svg path {
|
|
48
|
+
fill: ${({ theme }) => theme.colors.neutral600};
|
|
49
|
+
}
|
|
55
50
|
`;
|
|
56
51
|
|
|
57
52
|
const RelationInput = ({
|
|
@@ -64,6 +59,7 @@ const RelationInput = ({
|
|
|
64
59
|
label,
|
|
65
60
|
labelAction,
|
|
66
61
|
labelLoadMore,
|
|
62
|
+
labelDisconnectRelation,
|
|
67
63
|
loadingMessage,
|
|
68
64
|
onRelationAdd,
|
|
69
65
|
onRelationLoadMore,
|
|
@@ -84,6 +80,10 @@ const RelationInput = ({
|
|
|
84
80
|
const outerListRef = useRef();
|
|
85
81
|
const [overflow, setOverflow] = useState('');
|
|
86
82
|
|
|
83
|
+
const {
|
|
84
|
+
data: { pages },
|
|
85
|
+
} = searchResults;
|
|
86
|
+
|
|
87
87
|
const relations = useMemo(() => paginatedRelations.data.pages.flat(), [paginatedRelations]);
|
|
88
88
|
const totalNumberOfRelations = relations.length ?? 0;
|
|
89
89
|
|
|
@@ -102,12 +102,12 @@ const RelationInput = ({
|
|
|
102
102
|
|
|
103
103
|
const options = useMemo(
|
|
104
104
|
() =>
|
|
105
|
-
|
|
105
|
+
pages.flat().map((result) => ({
|
|
106
106
|
...result,
|
|
107
107
|
value: result.id,
|
|
108
108
|
label: result.mainField,
|
|
109
109
|
})),
|
|
110
|
-
[
|
|
110
|
+
[pages]
|
|
111
111
|
);
|
|
112
112
|
|
|
113
113
|
useEffect(() => {
|
|
@@ -143,6 +143,71 @@ const RelationInput = ({
|
|
|
143
143
|
};
|
|
144
144
|
}, [paginatedRelations, relations, numberOfRelationsToDisplay, totalNumberOfRelations]);
|
|
145
145
|
|
|
146
|
+
/**
|
|
147
|
+
* This code is being isolated because it's a hack to fix a placement bug in
|
|
148
|
+
* `react-select` where when the options prop is updated the position of the
|
|
149
|
+
* menu is not recalculated.
|
|
150
|
+
*/
|
|
151
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
152
|
+
|
|
153
|
+
const timeoutRef = useRef();
|
|
154
|
+
const previousOptions = useRef([]);
|
|
155
|
+
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
/**
|
|
158
|
+
* We only really want this effect to fire once when the options
|
|
159
|
+
* change from an empty array to an array with values.
|
|
160
|
+
* Otherwise, it'll fire when the infinite scrolling happens causing
|
|
161
|
+
* the menu to jump to the top all the time when loading more.
|
|
162
|
+
*/
|
|
163
|
+
if (options.length > 0 && previousOptions.current.length === 0) {
|
|
164
|
+
setIsMenuOpen((isCurrentlyOpened) => {
|
|
165
|
+
/**
|
|
166
|
+
* If we're currently open and the options changed
|
|
167
|
+
* we want to close and open to ensure the menu's
|
|
168
|
+
* position is correctly calculated
|
|
169
|
+
*/
|
|
170
|
+
if (isCurrentlyOpened) {
|
|
171
|
+
timeoutRef.current = setTimeout(() => {
|
|
172
|
+
setIsMenuOpen(true);
|
|
173
|
+
}, 10);
|
|
174
|
+
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return false;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return () => {
|
|
183
|
+
previousOptions.current = options || [];
|
|
184
|
+
};
|
|
185
|
+
}, [options]);
|
|
186
|
+
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
return () => {
|
|
189
|
+
/**
|
|
190
|
+
* If the component unmounts and a timer is set we should clear that timer
|
|
191
|
+
*/
|
|
192
|
+
if (timeoutRef.current) {
|
|
193
|
+
clearTimeout(timeoutRef.current);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}, []);
|
|
197
|
+
|
|
198
|
+
const handleMenuClose = () => {
|
|
199
|
+
setIsMenuOpen(false);
|
|
200
|
+
|
|
201
|
+
if (onSearchClose) {
|
|
202
|
+
onSearchClose();
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const handleMenuOpen = () => {
|
|
207
|
+
setIsMenuOpen(true);
|
|
208
|
+
onSearchOpen();
|
|
209
|
+
};
|
|
210
|
+
|
|
146
211
|
return (
|
|
147
212
|
<Field error={error} name={name} hint={description} id={id}>
|
|
148
213
|
<Relation
|
|
@@ -157,6 +222,7 @@ const RelationInput = ({
|
|
|
157
222
|
// position fixed doesn't update position on scroll
|
|
158
223
|
// react select doesn't update menu position on options change
|
|
159
224
|
menuPosition="absolute"
|
|
225
|
+
menuPlacement="auto"
|
|
160
226
|
components={{ Option }}
|
|
161
227
|
options={options}
|
|
162
228
|
isDisabled={disabled}
|
|
@@ -181,8 +247,9 @@ const RelationInput = ({
|
|
|
181
247
|
setValue(value);
|
|
182
248
|
onSearch(value);
|
|
183
249
|
}}
|
|
184
|
-
onMenuClose={
|
|
185
|
-
onMenuOpen={
|
|
250
|
+
onMenuClose={handleMenuClose}
|
|
251
|
+
onMenuOpen={handleMenuOpen}
|
|
252
|
+
menuIsOpen={isMenuOpen}
|
|
186
253
|
onMenuScrollToBottom={() => {
|
|
187
254
|
if (searchResults.hasNextPage) {
|
|
188
255
|
onSearchNextPage();
|
|
@@ -197,18 +264,10 @@ const RelationInput = ({
|
|
|
197
264
|
loadMore={
|
|
198
265
|
shouldDisplayLoadMoreButton && (
|
|
199
266
|
<TextButton
|
|
200
|
-
disabled={paginatedRelations.isLoading}
|
|
267
|
+
disabled={paginatedRelations.isLoading || paginatedRelations.isFetchingNextPage}
|
|
201
268
|
onClick={() => onRelationLoadMore()}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// TODO: To replace with loading prop on TextButton after DS release
|
|
205
|
-
<LoaderWrapper>
|
|
206
|
-
<Loader />
|
|
207
|
-
</LoaderWrapper>
|
|
208
|
-
) : (
|
|
209
|
-
<Refresh />
|
|
210
|
-
)
|
|
211
|
-
}
|
|
269
|
+
loading={paginatedRelations.isLoading || paginatedRelations.isFetchingNextPage}
|
|
270
|
+
startIcon={<Refresh />}
|
|
212
271
|
>
|
|
213
272
|
{labelLoadMore}
|
|
214
273
|
</TextButton>
|
|
@@ -234,19 +293,20 @@ const RelationInput = ({
|
|
|
234
293
|
disabled={disabled}
|
|
235
294
|
key={`relation-${name}-${id}`}
|
|
236
295
|
endAction={
|
|
237
|
-
<
|
|
296
|
+
<DisconnectButton
|
|
238
297
|
data-testid={`remove-relation-${id}`}
|
|
239
298
|
disabled={disabled}
|
|
240
299
|
type="button"
|
|
241
300
|
onClick={() => onRelationRemove(data[index])}
|
|
301
|
+
aria-label={labelDisconnectRelation}
|
|
242
302
|
>
|
|
243
303
|
<Icon width="12px" as={Cross} />
|
|
244
|
-
</
|
|
304
|
+
</DisconnectButton>
|
|
245
305
|
}
|
|
246
306
|
style={style}
|
|
247
307
|
>
|
|
248
308
|
<BoxEllipsis minWidth={0} paddingTop={1} paddingBottom={1} paddingRight={4}>
|
|
249
|
-
<Tooltip description={mainField ?? id}>
|
|
309
|
+
<Tooltip description={mainField ?? `${id}`}>
|
|
250
310
|
{href ? (
|
|
251
311
|
<LinkEllipsis to={href} disabled={disabled}>
|
|
252
312
|
{mainField ?? id}
|
|
@@ -300,6 +360,7 @@ const ReactQueryRelationResult = PropTypes.shape({
|
|
|
300
360
|
),
|
|
301
361
|
}),
|
|
302
362
|
hasNextPage: PropTypes.bool,
|
|
363
|
+
isFetchingNextPage: PropTypes.bool.isRequired,
|
|
303
364
|
isLoading: PropTypes.bool.isRequired,
|
|
304
365
|
isSuccess: PropTypes.bool.isRequired,
|
|
305
366
|
});
|
|
@@ -327,6 +388,7 @@ RelationInput.defaultProps = {
|
|
|
327
388
|
error: undefined,
|
|
328
389
|
labelAction: null,
|
|
329
390
|
labelLoadMore: null,
|
|
391
|
+
onSearchClose: undefined,
|
|
330
392
|
required: false,
|
|
331
393
|
relations: [],
|
|
332
394
|
searchResults: [],
|
|
@@ -340,6 +402,7 @@ RelationInput.propTypes = {
|
|
|
340
402
|
label: PropTypes.string.isRequired,
|
|
341
403
|
labelAction: PropTypes.element,
|
|
342
404
|
labelLoadMore: PropTypes.string,
|
|
405
|
+
labelDisconnectRelation: PropTypes.string.isRequired,
|
|
343
406
|
loadingMessage: PropTypes.func.isRequired,
|
|
344
407
|
name: PropTypes.string.isRequired,
|
|
345
408
|
numberOfRelationsToDisplay: PropTypes.number.isRequired,
|
|
@@ -348,7 +411,7 @@ RelationInput.propTypes = {
|
|
|
348
411
|
onRelationLoadMore: PropTypes.func.isRequired,
|
|
349
412
|
onSearch: PropTypes.func.isRequired,
|
|
350
413
|
onSearchNextPage: PropTypes.func.isRequired,
|
|
351
|
-
onSearchClose: PropTypes.func
|
|
414
|
+
onSearchClose: PropTypes.func,
|
|
352
415
|
onSearchOpen: PropTypes.func.isRequired,
|
|
353
416
|
placeholder: PropTypes.string.isRequired,
|
|
354
417
|
publicationStateTranslations: PropTypes.shape({
|
|
@@ -14,8 +14,8 @@ export const RelationItem = ({ children, disabled, endAction, style, ...props })
|
|
|
14
14
|
return (
|
|
15
15
|
<Box style={style} as="li">
|
|
16
16
|
<Flex
|
|
17
|
-
paddingTop={
|
|
18
|
-
paddingBottom={
|
|
17
|
+
paddingTop={2}
|
|
18
|
+
paddingBottom={2}
|
|
19
19
|
paddingLeft={4}
|
|
20
20
|
paddingRight={4}
|
|
21
21
|
hasRadius
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const RELATION_ITEM_HEIGHT =
|
|
1
|
+
export const RELATION_ITEM_HEIGHT = 50;
|
package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React, { memo, useEffect, useMemo } from 'react';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
|
+
import get from 'lodash/get';
|
|
4
5
|
|
|
5
|
-
import { useCMEditViewDataManager, NotAllowedInput
|
|
6
|
+
import { useCMEditViewDataManager, NotAllowedInput } from '@strapi/helper-plugin';
|
|
6
7
|
|
|
7
8
|
import { RelationInput } from '../RelationInput';
|
|
8
9
|
import { useRelation } from '../../hooks/useRelation';
|
|
9
|
-
import { connect, select, normalizeRelations } from './utils';
|
|
10
|
+
import { connect, select, normalizeRelations, normalizeSearchResults } from './utils';
|
|
10
11
|
import { PUBLICATION_STATES, RELATIONS_TO_DISPLAY, SEARCH_RESULTS_TO_DISPLAY } from './constants';
|
|
11
12
|
import { getTrad } from '../../utils';
|
|
12
13
|
|
|
13
|
-
export const
|
|
14
|
+
export const RelationInputDataManager = ({
|
|
15
|
+
componentId,
|
|
14
16
|
editable,
|
|
15
17
|
description,
|
|
16
18
|
intlLabel,
|
|
@@ -30,15 +32,13 @@ export const RelationInputDataManger = ({
|
|
|
30
32
|
const { formatMessage } = useIntl();
|
|
31
33
|
const { connectRelation, disconnectRelation, loadRelation, modifiedData, slug, initialData } =
|
|
32
34
|
useCMEditViewDataManager();
|
|
33
|
-
const [{ query }] = useQueryParams();
|
|
34
35
|
|
|
35
36
|
const { relations, search, searchFor } = useRelation(`${slug}-${name}-${initialData?.id ?? ''}`, {
|
|
36
37
|
relation: {
|
|
37
|
-
enabled: initialData
|
|
38
|
+
enabled: get(initialData, name)?.count !== 0 && !!endpoints.relation,
|
|
38
39
|
endpoint: endpoints.relation,
|
|
39
40
|
pageParams: {
|
|
40
41
|
...defaultParams,
|
|
41
|
-
locale: query?.plugins?.i18n?.locale,
|
|
42
42
|
pageSize: RELATIONS_TO_DISPLAY,
|
|
43
43
|
},
|
|
44
44
|
},
|
|
@@ -47,18 +47,18 @@ export const RelationInputDataManger = ({
|
|
|
47
47
|
endpoint: endpoints.search,
|
|
48
48
|
pageParams: {
|
|
49
49
|
...defaultParams,
|
|
50
|
-
entityId: isCreatingEntry ? undefined : initialData.id,
|
|
51
|
-
locale: query?.plugins?.i18n?.locale,
|
|
50
|
+
entityId: isCreatingEntry ? undefined : componentId ?? initialData.id,
|
|
52
51
|
pageSize: SEARCH_RESULTS_TO_DISPLAY,
|
|
53
52
|
},
|
|
54
53
|
},
|
|
55
54
|
});
|
|
56
55
|
|
|
56
|
+
const relationsFromModifiedData = get(modifiedData, name);
|
|
57
57
|
const stringifiedRelations = JSON.stringify(relations);
|
|
58
58
|
const normalizedRelations = useMemo(
|
|
59
59
|
() =>
|
|
60
60
|
normalizeRelations(relations, {
|
|
61
|
-
modifiedData:
|
|
61
|
+
modifiedData: relationsFromModifiedData,
|
|
62
62
|
mainFieldName: mainField.name,
|
|
63
63
|
shouldAddLink: shouldDisplayRelationLink,
|
|
64
64
|
targetModel,
|
|
@@ -117,11 +117,17 @@ export const RelationInputDataManger = ({
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
const handleSearch = (term) => {
|
|
120
|
-
searchFor(term, {
|
|
120
|
+
searchFor(term, {
|
|
121
|
+
idsToInclude: relationsFromModifiedData?.disconnect?.map((relation) => relation.id),
|
|
122
|
+
idsToOmit: relationsFromModifiedData?.connect?.map((relation) => relation.id),
|
|
123
|
+
});
|
|
121
124
|
};
|
|
122
125
|
|
|
123
126
|
const handleOpenSearch = () => {
|
|
124
|
-
searchFor('', {
|
|
127
|
+
searchFor('', {
|
|
128
|
+
idsToInclude: relationsFromModifiedData?.disconnect?.map((relation) => relation.id),
|
|
129
|
+
idsToOmit: relationsFromModifiedData?.connect?.map((relation) => relation.id),
|
|
130
|
+
});
|
|
125
131
|
};
|
|
126
132
|
|
|
127
133
|
const handleSearchMore = () => {
|
|
@@ -146,13 +152,17 @@ export const RelationInputDataManger = ({
|
|
|
146
152
|
})} ${initialData[name]?.count !== undefined ? `(${initialData[name].count})` : ''}`}
|
|
147
153
|
labelAction={labelAction}
|
|
148
154
|
labelLoadMore={
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
!isCreatingEntry
|
|
156
|
+
? formatMessage({
|
|
157
|
+
id: getTrad('relation.loadMore'),
|
|
158
|
+
defaultMessage: 'Load More',
|
|
159
|
+
})
|
|
160
|
+
: null
|
|
155
161
|
}
|
|
162
|
+
labelDisconnectRelation={formatMessage({
|
|
163
|
+
id: getTrad('relation.disconnect'),
|
|
164
|
+
defaultMessage: 'Remove',
|
|
165
|
+
})}
|
|
156
166
|
listHeight={320}
|
|
157
167
|
loadingMessage={() =>
|
|
158
168
|
formatMessage({
|
|
@@ -167,7 +177,6 @@ export const RelationInputDataManger = ({
|
|
|
167
177
|
onRelationLoadMore={() => handleRelationLoadMore()}
|
|
168
178
|
onSearch={(term) => handleSearch(term)}
|
|
169
179
|
onSearchNextPage={() => handleSearchMore()}
|
|
170
|
-
onSearchClose={() => {}}
|
|
171
180
|
onSearchOpen={handleOpenSearch}
|
|
172
181
|
placeholder={formatMessage(
|
|
173
182
|
placeholder || {
|
|
@@ -188,7 +197,7 @@ export const RelationInputDataManger = ({
|
|
|
188
197
|
}}
|
|
189
198
|
relations={normalizedRelations}
|
|
190
199
|
required={required}
|
|
191
|
-
searchResults={
|
|
200
|
+
searchResults={normalizeSearchResults(search, {
|
|
192
201
|
mainFieldName: mainField.name,
|
|
193
202
|
})}
|
|
194
203
|
size={size}
|
|
@@ -196,7 +205,8 @@ export const RelationInputDataManger = ({
|
|
|
196
205
|
);
|
|
197
206
|
};
|
|
198
207
|
|
|
199
|
-
|
|
208
|
+
RelationInputDataManager.defaultProps = {
|
|
209
|
+
componentId: undefined,
|
|
200
210
|
editable: true,
|
|
201
211
|
description: '',
|
|
202
212
|
labelAction: null,
|
|
@@ -205,7 +215,8 @@ RelationInputDataManger.defaultProps = {
|
|
|
205
215
|
required: false,
|
|
206
216
|
};
|
|
207
217
|
|
|
208
|
-
|
|
218
|
+
RelationInputDataManager.propTypes = {
|
|
219
|
+
componentId: PropTypes.number,
|
|
209
220
|
editable: PropTypes.bool,
|
|
210
221
|
description: PropTypes.string,
|
|
211
222
|
intlLabel: PropTypes.shape({
|
|
@@ -245,6 +256,6 @@ RelationInputDataManger.propTypes = {
|
|
|
245
256
|
}).isRequired,
|
|
246
257
|
};
|
|
247
258
|
|
|
248
|
-
const Memoized = memo(
|
|
259
|
+
const Memoized = memo(RelationInputDataManager);
|
|
249
260
|
|
|
250
261
|
export default connect(Memoized, select);
|
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,6 +22,14 @@ 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
|
{ modifiedData = {}, shouldAddLink = false, mainFieldName, targetModel }
|
|
@@ -31,7 +39,7 @@ export const normalizeRelations = (
|
|
|
31
39
|
data: {
|
|
32
40
|
pages:
|
|
33
41
|
[
|
|
34
|
-
...(relations?.data?.pages ?? []),
|
|
42
|
+
...(relations?.data?.pages.reverse() ?? []),
|
|
35
43
|
...(modifiedData?.connect ? [{ results: modifiedData.connect }] : []),
|
|
36
44
|
]
|
|
37
45
|
?.map((page) =>
|
|
@@ -44,7 +52,6 @@ export const normalizeRelations = (
|
|
|
44
52
|
)
|
|
45
53
|
.map((relation) =>
|
|
46
54
|
normalizeRelation(relation, {
|
|
47
|
-
modifiedData,
|
|
48
55
|
shouldAddLink,
|
|
49
56
|
mainFieldName,
|
|
50
57
|
targetModel,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { normalizeRelation } from './normalizeRelations';
|
|
2
|
+
|
|
3
|
+
export const normalizeSearchResults = (relations, { mainFieldName }) => {
|
|
4
|
+
return {
|
|
5
|
+
...relations,
|
|
6
|
+
data: {
|
|
7
|
+
pages: [...(relations?.data?.pages ?? [])]?.map((page) =>
|
|
8
|
+
page?.results.map((relation) => normalizeRelation(relation, { mainFieldName }))
|
|
9
|
+
),
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -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,42 @@ 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,
|
|
62
85
|
queryInfos: {
|
|
63
86
|
...queryInfos,
|
|
64
87
|
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,
|
|
@@ -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,
|
|
@@ -22,18 +22,23 @@ export const useRelation = (cacheKey, { relation, search }) => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const fetchSearch = async ({ pageParam = 1 }) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
try {
|
|
26
|
+
const { data } = await axiosInstance.get(search.endpoint, {
|
|
27
|
+
params: {
|
|
28
|
+
...(search.pageParams ?? {}),
|
|
29
|
+
...searchParams,
|
|
30
|
+
page: pageParam,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
return data;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
34
38
|
};
|
|
35
39
|
|
|
36
40
|
const relationsRes = useInfiniteQuery(['relation', cacheKey], fetchRelations, {
|
|
41
|
+
cacheTime: 0,
|
|
37
42
|
enabled: relation.enabled,
|
|
38
43
|
getNextPageParam(lastPage) {
|
|
39
44
|
// the API may send an empty 204 response
|
|
@@ -44,6 +49,9 @@ export const useRelation = (cacheKey, { relation, search }) => {
|
|
|
44
49
|
// eslint-disable-next-line consistent-return
|
|
45
50
|
return lastPage.pagination.page + 1;
|
|
46
51
|
},
|
|
52
|
+
select: (data) => ({
|
|
53
|
+
pages: data.pages.map((page) => ({ ...page, results: [...(page.results ?? [])].reverse() })),
|
|
54
|
+
}),
|
|
47
55
|
});
|
|
48
56
|
|
|
49
57
|
const searchRes = useInfiniteQuery(
|
|
@@ -65,7 +73,7 @@ export const useRelation = (cacheKey, { relation, search }) => {
|
|
|
65
73
|
const searchFor = (term, options = {}) => {
|
|
66
74
|
setSearchParams({
|
|
67
75
|
...options,
|
|
68
|
-
_q:
|
|
76
|
+
_q: term,
|
|
69
77
|
});
|
|
70
78
|
};
|
|
71
79
|
|