@strapi/admin 4.5.4 → 4.6.0-alpha.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.
- package/admin/src/components/AuthenticatedApp/index.js +2 -13
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +1 -1
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +3 -39
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +1 -5
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +1 -8
- package/admin/src/content-manager/components/NonRepeatableComponent/index.js +0 -4
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +9 -4
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +1 -1
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +0 -4
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +1 -1
- package/admin/src/content-manager/components/Wysiwyg/Editor.js +1 -1
- package/admin/src/content-manager/hooks/useLazyComponents/index.js +15 -40
- package/admin/src/content-manager/sharedReducers/crudReducer/actions.js +0 -5
- package/admin/src/content-manager/sharedReducers/crudReducer/constants.js +0 -2
- package/admin/src/content-manager/sharedReducers/crudReducer/reducer.js +0 -7
- package/admin/src/core/utils/axiosInstance.js +2 -4
- package/admin/src/hooks/index.js +0 -1
- package/admin/src/hooks/useSettingsMenu/init.js +7 -0
- package/admin/src/pages/App/index.js +13 -20
- package/admin/src/pages/HomePage/SocialLinks.js +4 -4
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +3 -2
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/DynamicTable/TableRows/CellValue.js +19 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/DynamicTable/TableRows/index.js +65 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/ActionItem.js +25 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/index.js +76 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useFormatTimeStamp.js +24 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/index.js +84 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/utils/tableHeaders.js +37 -0
- package/admin/src/pages/SettingsPage/pages/AuditLogs/ProtectedListPage/index.js +12 -0
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +18 -23
- package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +11 -0
- package/admin/src/permissions/defaultPermissions.js +4 -0
- package/admin/src/translations/en.json +7 -0
- package/admin/src/translations/tr.json +5 -485
- package/admin/src/utils/index.js +0 -1
- package/build/{1233.802422fa.chunk.js → 1233.80b05d66.chunk.js} +61 -61
- package/build/1920.74a262e7.chunk.js +245 -0
- package/build/2438.61291207.chunk.js +2183 -0
- package/build/2517.9b4940f3.chunk.js +117 -0
- package/build/4306.f03c2b46.chunk.js +98 -0
- package/build/4318.7931eee7.chunk.js +30 -0
- package/build/{8176.e929d326.chunk.js → 4986.3820d11d.chunk.js} +3 -3
- package/build/{8633.43ec9042.chunk.js → 8633.8da5488a.chunk.js} +1 -1
- package/build/Admin-authenticatedApp.ac85652e.chunk.js +80 -0
- package/build/{Admin_homePage.8945f71a.chunk.js → Admin_homePage.54e33c2d.chunk.js} +5 -5
- package/build/{Admin_marketplace.ed754a4a.chunk.js → Admin_marketplace.8219fda6.chunk.js} +1 -1
- package/build/{Admin_profilePage.60ab80bb.chunk.js → Admin_profilePage.e9fcce92.chunk.js} +1 -1
- package/build/{Admin_settingsPage.6ef8acc9.chunk.js → Admin_settingsPage.d3f48e9e.chunk.js} +15 -15
- package/build/admin-app.77179e07.chunk.js +112 -0
- package/build/admin-audit-logs.334ee871.chunk.js +1 -0
- package/build/admin-edit-roles-page.23f15909.chunk.js +1 -0
- package/build/admin-edit-users.283b49ed.chunk.js +10 -0
- package/build/{admin-users.e64fb0f1.chunk.js → admin-users.a0748674.chunk.js} +1 -1
- package/build/content-manager.01e04e11.chunk.js +1200 -0
- package/build/content-type-builder-translation-tr-json.2e52bc60.chunk.js +1 -0
- package/build/content-type-builder.aa4ec633.chunk.js +145 -0
- package/build/email-settings-page.d44a57cb.chunk.js +15 -0
- package/build/email-translation-tr-json.87f2feb3.chunk.js +1 -0
- package/build/en-json.57917cb1.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/{main.71f24343.js → main.f31112a5.js} +371 -371
- package/build/runtime~main.81f05721.js +2 -0
- package/build/sso-settings-page.9f091262.chunk.js +1 -0
- package/build/tr-json.9c44ea0c.chunk.js +1 -0
- package/build/upload.a73936d9.chunk.js +64 -0
- package/build/users-advanced-settings-page.dc23bc56.chunk.js +13 -0
- package/build/users-email-settings-page.6541d372.chunk.js +28 -0
- package/build/users-permissions-translation-tr-json.cdc49a3c.chunk.js +1 -0
- package/build/users-providers-settings-page.e11a2f64.chunk.js +33 -0
- package/build/users-roles-settings-page.445e5e16.chunk.js +30 -0
- package/build/{webhook-edit-page.1215a6b7.chunk.js → webhook-edit-page.14ad1e6e.chunk.js} +1 -1
- package/package.json +11 -11
- package/server/controllers/admin.js +0 -2
- package/server/routes/admin.js +1 -1
- package/server/services/metrics.js +2 -5
- package/utils/get-plugins-path.js +3 -17
- package/admin/src/hooks/useFetchClient/index.js +0 -23
- package/admin/src/utils/fetchClient.js +0 -45
- package/admin/src/utils/getFetchClient.js +0 -10
- package/admin/src/utils/uniqueAdminHash.js +0 -22
- package/build/4306.df40a798.chunk.js +0 -98
- package/build/4318.9283c350.chunk.js +0 -30
- package/build/5057.195a59ff.chunk.js +0 -65
- package/build/8881.c693411a.chunk.js +0 -245
- package/build/9161.4a0ab137.chunk.js +0 -2119
- package/build/9279.6290c87a.chunk.js +0 -117
- package/build/Admin-authenticatedApp.0da578b8.chunk.js +0 -80
- package/build/admin-app.a3277e72.chunk.js +0 -112
- package/build/admin-edit-roles-page.f407538c.chunk.js +0 -1
- package/build/admin-edit-users.5547b126.chunk.js +0 -10
- package/build/content-manager.f9630c3b.chunk.js +0 -1197
- package/build/content-type-builder-translation-tr-json.949e22eb.chunk.js +0 -1
- package/build/content-type-builder.b132b5f4.chunk.js +0 -145
- package/build/email-settings-page.c6e62f6b.chunk.js +0 -15
- package/build/email-translation-tr-json.8aa034bb.chunk.js +0 -1
- package/build/en-json.7dd57947.chunk.js +0 -1
- package/build/i18n-translation-tr-json.34ca9d61.chunk.js +0 -1
- package/build/runtime~main.1115f82b.js +0 -2
- package/build/sso-settings-page.feed2f45.chunk.js +0 -1
- package/build/tr-json.eac8bd79.chunk.js +0 -1
- package/build/upload-translation-tr-json.b173223a.chunk.js +0 -1
- package/build/upload.74540aab.chunk.js +0 -64
- package/build/users-advanced-settings-page.0c0b8230.chunk.js +0 -13
- package/build/users-email-settings-page.3126ff8c.chunk.js +0 -28
- package/build/users-permissions-translation-tr-json.9bebc250.chunk.js +0 -1
- package/build/users-providers-settings-page.b7b602e2.chunk.js +0 -33
- package/build/users-roles-settings-page.ce5b582d.chunk.js +0 -30
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
fetchUserRoles,
|
|
21
21
|
} from './utils/api';
|
|
22
22
|
import checkLatestStrapiVersion from './utils/checkLatestStrapiVersion';
|
|
23
|
-
import { getFullName
|
|
23
|
+
import { getFullName } from '../../utils';
|
|
24
24
|
|
|
25
25
|
const strapiVersion = packageJSON.version;
|
|
26
26
|
|
|
@@ -31,7 +31,6 @@ const AuthenticatedApp = () => {
|
|
|
31
31
|
const userInfo = auth.getUserInfo();
|
|
32
32
|
const userName = get(userInfo, 'username') || getFullName(userInfo.firstname, userInfo.lastname);
|
|
33
33
|
const [userDisplayName, setUserDisplayName] = useState(userName);
|
|
34
|
-
const [userId, setUserId] = useState(null);
|
|
35
34
|
const { showReleaseNotification } = useConfigurations();
|
|
36
35
|
const [
|
|
37
36
|
{ data: appInfos, status },
|
|
@@ -72,15 +71,6 @@ const AuthenticatedApp = () => {
|
|
|
72
71
|
}
|
|
73
72
|
}, [userRoles, appInfos]);
|
|
74
73
|
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
const getUserId = async () => {
|
|
77
|
-
const userId = await hashAdminUserEmail(userInfo);
|
|
78
|
-
setUserId(userId);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
getUserId();
|
|
82
|
-
}, [userInfo]);
|
|
83
|
-
|
|
84
74
|
// We don't need to wait for the release query to be fetched before rendering the plugins
|
|
85
75
|
// however, we need the appInfos and the permissions
|
|
86
76
|
const shouldShowNotDependentQueriesLoader =
|
|
@@ -91,13 +81,12 @@ const AuthenticatedApp = () => {
|
|
|
91
81
|
const appInfosValue = useMemo(() => {
|
|
92
82
|
return {
|
|
93
83
|
...appInfos,
|
|
94
|
-
userId,
|
|
95
84
|
latestStrapiReleaseTag: tag_name,
|
|
96
85
|
setUserDisplayName,
|
|
97
86
|
shouldUpdateStrapi,
|
|
98
87
|
userDisplayName,
|
|
99
88
|
};
|
|
100
|
-
}, [appInfos, tag_name, shouldUpdateStrapi, userDisplayName
|
|
89
|
+
}, [appInfos, tag_name, shouldUpdateStrapi, userDisplayName]);
|
|
101
90
|
|
|
102
91
|
if (shouldShowLoader) {
|
|
103
92
|
return <LoadingIndicatorPage />;
|
|
@@ -111,7 +111,7 @@ const DynamicZoneComponent = ({
|
|
|
111
111
|
<StyledBox hasRadius>
|
|
112
112
|
<Accordion expanded={isOpen} onToggle={handleToggle} size="S" error={errorMessage}>
|
|
113
113
|
<AccordionToggle
|
|
114
|
-
startIcon={
|
|
114
|
+
startIcon={<FontAwesomeIcon icon={icon} />}
|
|
115
115
|
action={
|
|
116
116
|
<Stack horizontal spacing={0} expanded={isOpen}>
|
|
117
117
|
{showDownIcon && (
|
|
@@ -8,9 +8,7 @@ import set from 'lodash/set';
|
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
9
|
import { useIntl } from 'react-intl';
|
|
10
10
|
import { Prompt, Redirect } from 'react-router-dom';
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
import { Main } from '@strapi/design-system';
|
|
11
|
+
import { Main } from '@strapi/design-system/Main';
|
|
14
12
|
import {
|
|
15
13
|
LoadingIndicatorPage,
|
|
16
14
|
ContentManagerEditViewDataManagerContext,
|
|
@@ -22,13 +20,8 @@ import {
|
|
|
22
20
|
} from '@strapi/helper-plugin';
|
|
23
21
|
|
|
24
22
|
import { getTrad, removeKeyInObject } from '../../utils';
|
|
25
|
-
|
|
26
|
-
import selectCrudReducer from '../../sharedReducers/crudReducer/selectors';
|
|
27
|
-
|
|
28
23
|
import reducer, { initialState } from './reducer';
|
|
29
24
|
import { cleanData, createYupSchema, recursivelyFindPathsBasedOnCondition } from './utils';
|
|
30
|
-
import { clearSetModifiedDataOnly } from '../../sharedReducers/crudReducer/actions';
|
|
31
|
-
import { usePrev } from '../../hooks';
|
|
32
25
|
|
|
33
26
|
const EditViewDataManagerProvider = ({
|
|
34
27
|
allLayoutData,
|
|
@@ -68,9 +61,6 @@ const EditViewDataManagerProvider = ({
|
|
|
68
61
|
publishConfirmation,
|
|
69
62
|
} = reducerState;
|
|
70
63
|
|
|
71
|
-
const { setModifiedDataOnly } = useSelector(selectCrudReducer);
|
|
72
|
-
const reduxDispatch = useDispatch();
|
|
73
|
-
|
|
74
64
|
const toggleNotification = useNotification();
|
|
75
65
|
const { lockApp, unlockApp } = useOverlayBlocker();
|
|
76
66
|
|
|
@@ -154,18 +144,8 @@ const EditViewDataManagerProvider = ({
|
|
|
154
144
|
|
|
155
145
|
const { components } = allLayoutData;
|
|
156
146
|
|
|
157
|
-
const previousInitialValues = usePrev(initialValues);
|
|
158
|
-
|
|
159
147
|
useEffect(() => {
|
|
160
|
-
|
|
161
|
-
* Only fire this effect if the initialValues are different
|
|
162
|
-
* otherwise it's a fruitless effort no matter what happens.
|
|
163
|
-
*/
|
|
164
|
-
if (
|
|
165
|
-
initialValues &&
|
|
166
|
-
currentContentTypeLayout?.attributes &&
|
|
167
|
-
!isEqual(previousInitialValues, initialValues)
|
|
168
|
-
) {
|
|
148
|
+
if (initialValues && currentContentTypeLayout?.attributes) {
|
|
169
149
|
/**
|
|
170
150
|
* This will return an array of paths:
|
|
171
151
|
* ['many_to_one', 'one_to_many', 'one_to_one']
|
|
@@ -199,25 +179,9 @@ const EditViewDataManagerProvider = ({
|
|
|
199
179
|
componentPaths,
|
|
200
180
|
repeatableComponentPaths,
|
|
201
181
|
dynamicZonePaths,
|
|
202
|
-
setModifiedDataOnly,
|
|
203
182
|
});
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* TODO: This should be moved to a side-effect e.g. thunks
|
|
207
|
-
* something to consider for V5
|
|
208
|
-
*/
|
|
209
|
-
if (setModifiedDataOnly) {
|
|
210
|
-
reduxDispatch(clearSetModifiedDataOnly());
|
|
211
|
-
}
|
|
212
183
|
}
|
|
213
|
-
}, [
|
|
214
|
-
initialValues,
|
|
215
|
-
currentContentTypeLayout,
|
|
216
|
-
components,
|
|
217
|
-
setModifiedDataOnly,
|
|
218
|
-
reduxDispatch,
|
|
219
|
-
previousInitialValues,
|
|
220
|
-
]);
|
|
184
|
+
}, [initialValues, currentContentTypeLayout, components]);
|
|
221
185
|
|
|
222
186
|
const dispatchAddComponent = useCallback(
|
|
223
187
|
(type) =>
|
|
@@ -192,7 +192,6 @@ const reducer = (state, action) =>
|
|
|
192
192
|
componentPaths = [],
|
|
193
193
|
repeatableComponentPaths = [],
|
|
194
194
|
dynamicZonePaths = [],
|
|
195
|
-
setModifiedDataOnly,
|
|
196
195
|
} = action;
|
|
197
196
|
|
|
198
197
|
/**
|
|
@@ -244,10 +243,7 @@ const reducer = (state, action) =>
|
|
|
244
243
|
return acc;
|
|
245
244
|
}, data);
|
|
246
245
|
|
|
247
|
-
|
|
248
|
-
draftState.initialData = mergeDataWithPreparedRelations;
|
|
249
|
-
}
|
|
250
|
-
|
|
246
|
+
draftState.initialData = mergeDataWithPreparedRelations;
|
|
251
247
|
draftState.modifiedData = mergeDataWithPreparedRelations;
|
|
252
248
|
|
|
253
249
|
draftState.formErrors = {};
|
|
@@ -55,15 +55,8 @@ const recursivelyFindPathsBasedOnConditionSetup = (components, predicate = () =>
|
|
|
55
55
|
*
|
|
56
56
|
* NOTE: we don't need to know the path to the `array` because it's about data shape not about the actual data
|
|
57
57
|
*/
|
|
58
|
-
}).map((path) => {
|
|
59
|
-
return path.split(`${componentName}.`)[1];
|
|
60
|
-
});
|
|
58
|
+
}).map((path) => path.split(`${componentName}.`)[1]);
|
|
61
59
|
})
|
|
62
|
-
/**
|
|
63
|
-
* We filter because this will give you `dynamiczone.undefined` because the dynamic_zone component
|
|
64
|
-
* is not required to be returned in this circumstance.
|
|
65
|
-
*/
|
|
66
|
-
.filter((path) => Boolean(path))
|
|
67
60
|
.map((path) => `${key}.${path}`);
|
|
68
61
|
|
|
69
62
|
acc = [...acc, attributesInDynamicComponents];
|
|
@@ -9,7 +9,6 @@ import { Stack } from '@strapi/design-system/Stack';
|
|
|
9
9
|
import { useContentTypeLayout } from '../../hooks';
|
|
10
10
|
import FieldComponent from '../FieldComponent';
|
|
11
11
|
import Inputs from '../Inputs';
|
|
12
|
-
import useLazyComponents from '../../hooks/useLazyComponents';
|
|
13
12
|
|
|
14
13
|
const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, name }) => {
|
|
15
14
|
const { getComponentLayout } = useContentTypeLayout();
|
|
@@ -19,8 +18,6 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam
|
|
|
19
18
|
);
|
|
20
19
|
const fields = componentLayoutData.layouts.edit;
|
|
21
20
|
|
|
22
|
-
const { lazyComponentStore } = useLazyComponents();
|
|
23
|
-
|
|
24
21
|
return (
|
|
25
22
|
<Box
|
|
26
23
|
background={isFromDynamicZone ? '' : 'neutral100'}
|
|
@@ -70,7 +67,6 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam
|
|
|
70
67
|
metadatas={metadatas}
|
|
71
68
|
queryInfos={queryInfos}
|
|
72
69
|
size={size}
|
|
73
|
-
customFieldInputs={lazyComponentStore}
|
|
74
70
|
/>
|
|
75
71
|
</GridItem>
|
|
76
72
|
);
|
|
@@ -24,13 +24,18 @@ import { RELATION_ITEM_HEIGHT } from './constants';
|
|
|
24
24
|
import { usePrev } from '../../hooks';
|
|
25
25
|
|
|
26
26
|
const LinkEllipsis = styled(Link)`
|
|
27
|
-
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
text-overflow: ellipsis;
|
|
30
|
+
display: inherit;
|
|
31
|
+
`;
|
|
28
32
|
|
|
33
|
+
const BoxEllipsis = styled(Box)`
|
|
29
34
|
> span {
|
|
30
35
|
white-space: nowrap;
|
|
31
36
|
overflow: hidden;
|
|
32
37
|
text-overflow: ellipsis;
|
|
33
|
-
display:
|
|
38
|
+
display: inherit;
|
|
34
39
|
}
|
|
35
40
|
`;
|
|
36
41
|
|
|
@@ -317,7 +322,7 @@ const RelationInput = ({
|
|
|
317
322
|
}
|
|
318
323
|
style={style}
|
|
319
324
|
>
|
|
320
|
-
<
|
|
325
|
+
<BoxEllipsis minWidth={0} paddingTop={1} paddingBottom={1} paddingRight={4}>
|
|
321
326
|
<Tooltip description={mainField ?? `${id}`}>
|
|
322
327
|
{href ? (
|
|
323
328
|
<LinkEllipsis to={href} disabled={disabled}>
|
|
@@ -329,7 +334,7 @@ const RelationInput = ({
|
|
|
329
334
|
</Typography>
|
|
330
335
|
)}
|
|
331
336
|
</Tooltip>
|
|
332
|
-
</
|
|
337
|
+
</BoxEllipsis>
|
|
333
338
|
|
|
334
339
|
{publicationState && (
|
|
335
340
|
<Status variant={statusColor} showBullet={false} size="S">
|
package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js
CHANGED
|
@@ -40,7 +40,7 @@ export const RelationInputDataManager = ({
|
|
|
40
40
|
const { connectRelation, disconnectRelation, loadRelation, modifiedData, slug, initialData } =
|
|
41
41
|
useCMEditViewDataManager();
|
|
42
42
|
|
|
43
|
-
const relationsFromModifiedData = get(modifiedData, name
|
|
43
|
+
const relationsFromModifiedData = get(modifiedData, name) ?? [];
|
|
44
44
|
|
|
45
45
|
const currentLastPage = Math.ceil(get(initialData, name, []).length / RELATIONS_TO_DISPLAY);
|
|
46
46
|
|
|
@@ -21,7 +21,6 @@ import Preview from './Preview';
|
|
|
21
21
|
import DraggingSibling from './DraggingSibling';
|
|
22
22
|
import { CustomIconButton } from './IconButtonCustoms';
|
|
23
23
|
import { connect, select } from './utils';
|
|
24
|
-
import useLazyComponents from '../../../hooks/useLazyComponents';
|
|
25
24
|
|
|
26
25
|
const DragButton = styled.span`
|
|
27
26
|
display: flex;
|
|
@@ -178,8 +177,6 @@ const DraggedItem = ({
|
|
|
178
177
|
const accordionTitle = toString(displayedValue);
|
|
179
178
|
const accordionHasError = hasErrors ? 'error' : undefined;
|
|
180
179
|
|
|
181
|
-
const { lazyComponentStore } = useLazyComponents();
|
|
182
|
-
|
|
183
180
|
return (
|
|
184
181
|
<Box ref={refs ? refs.dropRef : null}>
|
|
185
182
|
{isDragging && <Preview />}
|
|
@@ -276,7 +273,6 @@ const DraggedItem = ({
|
|
|
276
273
|
// onBlur={hasErrors ? checkFormErrors : null}
|
|
277
274
|
queryInfos={queryInfos}
|
|
278
275
|
size={size}
|
|
279
|
-
customFieldInputs={lazyComponentStore}
|
|
280
276
|
/>
|
|
281
277
|
</GridItem>
|
|
282
278
|
);
|
|
@@ -103,7 +103,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
103
103
|
setIsCreatingEntry(true);
|
|
104
104
|
|
|
105
105
|
try {
|
|
106
|
-
const { data } = await axiosInstance
|
|
106
|
+
const { data } = await axiosInstance(getRequestUrl(`${slug}${searchToSend}`), {
|
|
107
107
|
cancelToken: source.token,
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -43,7 +43,7 @@ const Editor = ({
|
|
|
43
43
|
}, [editorRef, textareaRef, name, placeholder]);
|
|
44
44
|
|
|
45
45
|
useEffect(() => {
|
|
46
|
-
if (value && !editorRef.current.
|
|
46
|
+
if (value && !editorRef.current.state.focused) {
|
|
47
47
|
editorRef.current.setValue(value);
|
|
48
48
|
}
|
|
49
49
|
}, [editorRef, value]);
|
|
@@ -1,69 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import { useCustomFields } from '@strapi/helper-plugin';
|
|
3
3
|
|
|
4
|
-
const componentStore = new Map();
|
|
5
|
-
|
|
6
4
|
/**
|
|
7
5
|
* @description
|
|
8
6
|
* A hook to lazy load custom field components
|
|
9
7
|
* @param {Array.<string>} componentUids - The uids to look up components
|
|
10
8
|
* @returns object
|
|
11
9
|
*/
|
|
12
|
-
const useLazyComponents = (componentUids
|
|
13
|
-
const [lazyComponentStore, setLazyComponentStore] = useState(
|
|
14
|
-
const [loading, setLoading] = useState(
|
|
15
|
-
if (componentStore.size === 0 && componentUids.length > 0) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return false;
|
|
20
|
-
});
|
|
10
|
+
const useLazyComponents = (componentUids) => {
|
|
11
|
+
const [lazyComponentStore, setLazyComponentStore] = useState({});
|
|
12
|
+
const [loading, setLoading] = useState(true);
|
|
21
13
|
const customFieldsRegistry = useCustomFields();
|
|
22
14
|
|
|
23
15
|
useEffect(() => {
|
|
24
|
-
const setStore = (store) => {
|
|
25
|
-
setLazyComponentStore(store);
|
|
26
|
-
setLoading(false);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
16
|
const lazyLoadComponents = async (uids, components) => {
|
|
30
17
|
const modules = await Promise.all(components);
|
|
31
18
|
|
|
32
19
|
uids.forEach((uid, index) => {
|
|
33
|
-
|
|
20
|
+
if (!Object.keys(lazyComponentStore).includes(uid)) {
|
|
21
|
+
setLazyComponentStore({ ...lazyComponentStore, [uid]: modules[index].default });
|
|
22
|
+
}
|
|
34
23
|
});
|
|
35
|
-
|
|
36
|
-
setStore(Object.fromEntries(componentStore));
|
|
37
24
|
};
|
|
38
25
|
|
|
39
|
-
if (componentUids.length
|
|
40
|
-
|
|
41
|
-
* These uids are not in the component store therefore we need to get the components
|
|
42
|
-
*/
|
|
43
|
-
const newUids = componentUids.filter((uid) => !componentStore.get(uid));
|
|
44
|
-
|
|
45
|
-
const componentPromises = newUids.map((uid) => {
|
|
26
|
+
if (componentUids.length) {
|
|
27
|
+
const componentPromises = componentUids.map((uid) => {
|
|
46
28
|
const customField = customFieldsRegistry.get(uid);
|
|
47
29
|
|
|
48
30
|
return customField.components.Input();
|
|
49
31
|
});
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
lazyLoadComponents(newUids, componentPromises);
|
|
53
|
-
}
|
|
33
|
+
lazyLoadComponents(componentUids, componentPromises);
|
|
54
34
|
}
|
|
55
|
-
}, [componentUids, customFieldsRegistry, loading]);
|
|
56
35
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const cleanup = useCallback(() => {
|
|
62
|
-
componentStore.clear();
|
|
63
|
-
setLazyComponentStore({});
|
|
64
|
-
}, []);
|
|
36
|
+
if (componentUids.length === Object.keys(lazyComponentStore).length) {
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}
|
|
39
|
+
}, [componentUids, customFieldsRegistry, loading, lazyComponentStore]);
|
|
65
40
|
|
|
66
|
-
return { isLazyLoading: loading, lazyComponentStore
|
|
41
|
+
return { isLazyLoading: loading, lazyComponentStore };
|
|
67
42
|
};
|
|
68
43
|
|
|
69
44
|
export default useLazyComponents;
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
SET_DATA_STRUCTURES,
|
|
7
7
|
SET_STATUS,
|
|
8
8
|
SUBMIT_SUCCEEDED,
|
|
9
|
-
CLEAR_SET_MODIFIED_DATA_ONLY,
|
|
10
9
|
} from './constants';
|
|
11
10
|
|
|
12
11
|
export const getData = () => {
|
|
@@ -43,7 +42,3 @@ export const submitSucceeded = (data) => ({
|
|
|
43
42
|
type: SUBMIT_SUCCEEDED,
|
|
44
43
|
data,
|
|
45
44
|
});
|
|
46
|
-
|
|
47
|
-
export const clearSetModifiedDataOnly = () => ({
|
|
48
|
-
type: CLEAR_SET_MODIFIED_DATA_ONLY,
|
|
49
|
-
});
|
|
@@ -5,5 +5,3 @@ export const RESET_PROPS = 'ContentManager/CrudReducer/RESET_PROPS';
|
|
|
5
5
|
export const SET_DATA_STRUCTURES = 'ContentManager/CrudReducer/SET_DATA_STRUCTURES';
|
|
6
6
|
export const SET_STATUS = 'ContentManager/CrudReducer/SET_STATUS';
|
|
7
7
|
export const SUBMIT_SUCCEEDED = 'ContentManager/CrudReducer/SUBMIT_SUCCEEDED';
|
|
8
|
-
export const CLEAR_SET_MODIFIED_DATA_ONLY =
|
|
9
|
-
'ContentManager/CrudReducer/CLEAR_SET_MODIFIED_DATA_ONLY';
|
|
@@ -8,7 +8,6 @@ import produce from 'immer';
|
|
|
8
8
|
// to do any of this.
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
CLEAR_SET_MODIFIED_DATA_ONLY,
|
|
12
11
|
GET_DATA,
|
|
13
12
|
GET_DATA_SUCCEEDED,
|
|
14
13
|
INIT_FORM,
|
|
@@ -24,7 +23,6 @@ const crudInitialState = {
|
|
|
24
23
|
isLoading: true,
|
|
25
24
|
data: null,
|
|
26
25
|
status: 'resolved',
|
|
27
|
-
setModifiedDataOnly: false,
|
|
28
26
|
};
|
|
29
27
|
|
|
30
28
|
const crudReducer = (state = crudInitialState, action) =>
|
|
@@ -38,7 +36,6 @@ const crudReducer = (state = crudInitialState, action) =>
|
|
|
38
36
|
case GET_DATA_SUCCEEDED: {
|
|
39
37
|
draftState.isLoading = false;
|
|
40
38
|
draftState.data = action.data;
|
|
41
|
-
draftState.setModifiedDataOnly = action.setModifiedDataOnly ?? false;
|
|
42
39
|
break;
|
|
43
40
|
}
|
|
44
41
|
case INIT_FORM: {
|
|
@@ -69,10 +66,6 @@ const crudReducer = (state = crudInitialState, action) =>
|
|
|
69
66
|
draftState.data = action.data;
|
|
70
67
|
break;
|
|
71
68
|
}
|
|
72
|
-
case CLEAR_SET_MODIFIED_DATA_ONLY: {
|
|
73
|
-
draftState.setModifiedDataOnly = false;
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
69
|
default:
|
|
77
70
|
return draftState;
|
|
78
71
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import { auth
|
|
2
|
+
import { auth } from '@strapi/helper-plugin';
|
|
3
3
|
|
|
4
4
|
const instance = axios.create({
|
|
5
5
|
baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
|
|
@@ -33,6 +33,4 @@ instance.interceptors.response.use(
|
|
|
33
33
|
}
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
export default wrapper;
|
|
36
|
+
export default instance;
|
package/admin/src/hooks/index.js
CHANGED
|
@@ -10,4 +10,3 @@ export { default as usePermissionsDataManager } from './usePermissionsDataManage
|
|
|
10
10
|
export { default as useReleaseNotification } from './useReleaseNotification';
|
|
11
11
|
export { default as useThemeToggle } from './useThemeToggle';
|
|
12
12
|
export { default as useRegenerate } from './useRegenerate';
|
|
13
|
-
export { default as useFetchClient } from './useFetchClient';
|
|
@@ -24,6 +24,13 @@ const init = (initialState, { settings, shouldUpdateStrapi }) => {
|
|
|
24
24
|
id: 'permissions',
|
|
25
25
|
intlLabel: { id: 'Settings.permissions', defaultMessage: 'Administration Panel' },
|
|
26
26
|
links: [
|
|
27
|
+
{
|
|
28
|
+
intlLabel: { id: 'global.auditLogs', defaultMessage: 'Audit Logs' },
|
|
29
|
+
to: '/settings/audit-logs',
|
|
30
|
+
id: 'auditLogs',
|
|
31
|
+
isDisplayed: false,
|
|
32
|
+
permissions: adminPermissions.settings.auditLogs.main,
|
|
33
|
+
},
|
|
27
34
|
{
|
|
28
35
|
intlLabel: { id: 'global.roles', defaultMessage: 'Roles' },
|
|
29
36
|
to: '/settings/roles',
|
|
@@ -25,7 +25,7 @@ import NotFoundPage from '../NotFoundPage';
|
|
|
25
25
|
import UseCasePage from '../UseCasePage';
|
|
26
26
|
import { getUID } from './utils';
|
|
27
27
|
import routes from './utils/routes';
|
|
28
|
-
import { useConfigurations
|
|
28
|
+
import { useConfigurations } from '../../hooks';
|
|
29
29
|
|
|
30
30
|
const AuthenticatedApp = lazy(() =>
|
|
31
31
|
import(/* webpackChunkName: "Admin-authenticatedApp" */ '../../components/AuthenticatedApp')
|
|
@@ -35,12 +35,8 @@ function App() {
|
|
|
35
35
|
const toggleNotification = useNotification();
|
|
36
36
|
const { updateProjectSettings } = useConfigurations();
|
|
37
37
|
const { formatMessage } = useIntl();
|
|
38
|
-
const [{ isLoading, hasAdmin, uuid
|
|
39
|
-
isLoading: true,
|
|
40
|
-
hasAdmin: false,
|
|
41
|
-
});
|
|
38
|
+
const [{ isLoading, hasAdmin, uuid }, setState] = useState({ isLoading: true, hasAdmin: false });
|
|
42
39
|
const appInfo = useAppInfos();
|
|
43
|
-
const { get } = useFetchClient();
|
|
44
40
|
|
|
45
41
|
const authRoutes = useMemo(() => {
|
|
46
42
|
return makeUniqueRoutes(
|
|
@@ -84,29 +80,27 @@ function App() {
|
|
|
84
80
|
} = await axios.get(`${strapi.backendURL}/admin/init`);
|
|
85
81
|
|
|
86
82
|
updateProjectSettings({ menuLogo: prefixFileUrlWithBackendUrl(menuLogo) });
|
|
87
|
-
const deviceId = await getUID();
|
|
88
83
|
|
|
89
84
|
if (uuid) {
|
|
90
85
|
const {
|
|
91
86
|
data: { data: properties },
|
|
92
|
-
} = await get(
|
|
93
|
-
// NOTE: needed because the interceptors of the fetchClient redirect to /login when receive a 401 and it would end up in an infinite loop when the user doesn't have a session.
|
|
94
|
-
validateStatus: (status) => status < 500,
|
|
95
|
-
});
|
|
87
|
+
} = await axios.get(`${strapi.backendURL}/admin/telemetry-properties`);
|
|
96
88
|
|
|
97
89
|
setTelemetryProperties(properties);
|
|
98
90
|
|
|
99
91
|
try {
|
|
100
|
-
await
|
|
92
|
+
const deviceId = await getUID();
|
|
93
|
+
|
|
94
|
+
await fetch('https://analytics.strapi.io/track', {
|
|
101
95
|
method: 'POST',
|
|
102
96
|
body: JSON.stringify({
|
|
103
|
-
// This event is anonymous
|
|
104
97
|
event: 'didInitializeAdministration',
|
|
105
|
-
|
|
98
|
+
uuid,
|
|
106
99
|
deviceId,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
properties: {
|
|
101
|
+
...properties,
|
|
102
|
+
environment: appInfo.currentEnvironment,
|
|
103
|
+
},
|
|
110
104
|
}),
|
|
111
105
|
headers: {
|
|
112
106
|
'Content-Type': 'application/json',
|
|
@@ -117,7 +111,7 @@ function App() {
|
|
|
117
111
|
}
|
|
118
112
|
}
|
|
119
113
|
|
|
120
|
-
setState({ isLoading: false, hasAdmin, uuid
|
|
114
|
+
setState({ isLoading: false, hasAdmin, uuid });
|
|
121
115
|
} catch (err) {
|
|
122
116
|
toggleNotification({
|
|
123
117
|
type: 'warning',
|
|
@@ -136,9 +130,8 @@ function App() {
|
|
|
136
130
|
() => ({
|
|
137
131
|
uuid,
|
|
138
132
|
telemetryProperties,
|
|
139
|
-
deviceId,
|
|
140
133
|
}),
|
|
141
|
-
[uuid, telemetryProperties
|
|
134
|
+
[uuid, telemetryProperties]
|
|
142
135
|
);
|
|
143
136
|
|
|
144
137
|
if (isLoading) {
|
|
@@ -33,13 +33,13 @@ const StyledReddit = styled(Reddit)`
|
|
|
33
33
|
`;
|
|
34
34
|
const StyledStrapi = styled(Strapi)`
|
|
35
35
|
> path:first-child {
|
|
36
|
-
fill: #
|
|
36
|
+
fill: #8e75ff;
|
|
37
37
|
}
|
|
38
38
|
> path:nth-child(2) {
|
|
39
|
-
fill: #
|
|
39
|
+
fill: #8e75ff;
|
|
40
40
|
}
|
|
41
|
-
> path:nth-child(
|
|
42
|
-
fill: #
|
|
41
|
+
> path:nth-child(3) {
|
|
42
|
+
fill: #8e75ff;
|
|
43
43
|
}
|
|
44
44
|
`;
|
|
45
45
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '@strapi/helper-plugin';
|
|
13
13
|
import { Main } from '@strapi/design-system/Main';
|
|
14
14
|
import { Formik } from 'formik';
|
|
15
|
+
import { get } from 'lodash';
|
|
15
16
|
import { useRouteMatch, useHistory } from 'react-router-dom';
|
|
16
17
|
import { useQuery } from 'react-query';
|
|
17
18
|
import { formatAPIErrors } from '../../../../../utils';
|
|
@@ -204,12 +205,12 @@ const ApiTokenCreateView = () => {
|
|
|
204
205
|
if (err?.response?.data?.error?.message === MSG_ERROR_NAME_TAKEN) {
|
|
205
206
|
toggleNotification({
|
|
206
207
|
type: 'warning',
|
|
207
|
-
message: err
|
|
208
|
+
message: get(err, 'response.data.message', 'notification.error.tokennamenotunique'),
|
|
208
209
|
});
|
|
209
210
|
} else {
|
|
210
211
|
toggleNotification({
|
|
211
212
|
type: 'warning',
|
|
212
|
-
message: err
|
|
213
|
+
message: get(err, 'response.data.message', 'notification.error'),
|
|
213
214
|
});
|
|
214
215
|
}
|
|
215
216
|
unlockApp();
|
package/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/DynamicTable/TableRows/CellValue.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import useFormatTimeStamp from '../../hooks/useFormatTimeStamp';
|
|
3
|
+
|
|
4
|
+
const CellValue = ({ type, value }) => {
|
|
5
|
+
const formatTimeStamp = useFormatTimeStamp();
|
|
6
|
+
|
|
7
|
+
if (type === 'date') {
|
|
8
|
+
return formatTimeStamp(value);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return value || '-';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
CellValue.propTypes = {
|
|
15
|
+
type: PropTypes.string.isRequired,
|
|
16
|
+
value: PropTypes.any.isRequired,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default CellValue;
|