@strapi/admin 4.9.0-exp.90df253ba90fd6879eb56a720a1f80d04ff745b8 → 4.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.js +14 -0
  3. package/admin/src/components/LocalesProvider/__mocks__/useLocalesProvider.js +7 -0
  4. package/admin/src/content-manager/components/DynamicZone/utils/select.js +1 -1
  5. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +3 -1
  6. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findAllAndReplace.js +10 -3
  7. package/admin/src/content-manager/components/FieldComponent/utils/select.js +2 -1
  8. package/admin/src/content-manager/components/InputUID/endActionStyle.js +4 -13
  9. package/admin/src/content-manager/components/InputUID/index.js +94 -71
  10. package/admin/src/content-manager/components/Inputs/utils/getInputType.js +1 -1
  11. package/admin/src/content-manager/components/Inputs/utils/select.js +1 -1
  12. package/admin/src/content-manager/hooks/useContentTypeLayout/index.js +1 -2
  13. package/admin/src/content-manager/hooks/useFetchContentTypeLayout/utils/formatLayouts.js +4 -1
  14. package/admin/src/content-manager/pages/App/index.js +2 -2
  15. package/admin/src/content-manager/pages/CollectionTypeRecursivePath/index.js +1 -2
  16. package/admin/src/content-manager/pages/EditSettingsView/init.js +3 -1
  17. package/admin/src/content-manager/pages/EditSettingsView/utils/createPossibleMainFieldsForModelsAndComponents.js +2 -4
  18. package/admin/src/content-manager/pages/EditView/DeleteLink/utils/select.js +1 -1
  19. package/admin/src/content-manager/pages/EditView/utils/createAttributesLayout.js +2 -1
  20. package/admin/src/content-manager/pages/EditView/utils/getFieldsActionMatchingPermissions.js +2 -1
  21. package/admin/src/content-manager/utils/checkIfAttributeIsDisplayable.js +1 -1
  22. package/admin/src/content-manager/utils/createDefaultForm.js +2 -2
  23. package/admin/src/content-manager/utils/formatLayoutToApi.js +2 -1
  24. package/admin/src/content-manager/utils/getFieldName.js +1 -1
  25. package/admin/src/content-manager/utils/mergeMetasWithSchema.js +1 -1
  26. package/admin/src/content-manager/utils/paths.js +1 -1
  27. package/admin/src/content-manager/utils/removePasswordFieldsFromData.js +1 -1
  28. package/admin/src/hooks/useConfigurations/__mocks__/index.js +7 -0
  29. package/admin/src/hooks/useRegenerate/index.js +12 -7
  30. package/admin/src/hooks/useSettingsForm/index.js +3 -3
  31. package/admin/src/hooks/useSettingsForm/reducer.js +3 -1
  32. package/admin/src/hooks/useSettingsMenu/reducer.js +1 -1
  33. package/admin/src/pages/AuthPage/components/Register/index.js +46 -38
  34. package/admin/src/pages/AuthPage/reducer.js +1 -1
  35. package/admin/src/pages/MarketplacePage/components/EmptyNpmPackageSearch/index.js +2 -2
  36. package/admin/src/pages/SettingsPage/components/Tokens/FormHead/index.js +4 -0
  37. package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +5 -3
  38. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +1 -1
  39. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +1 -1
  40. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +6 -8
  41. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/utils/createDefaultConditionsForm.js +1 -1
  42. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/utils/generateCheckboxesActions.js +2 -1
  43. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/utils/getRowLabelCheckboxeState.js +2 -1
  44. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/utils/getRowLabelCheckboxesState.js +1 -1
  45. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/reducer.js +6 -1
  46. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/utils/createDefaultCTFormFromLayout.js +5 -1
  47. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/utils/createDefaultPluginsFormFromLayout.js +1 -2
  48. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/utils/formatContentTypesPermissionToAPI.js +2 -2
  49. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/utils/updateConditionsToFalse.js +4 -1
  50. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/Permissions/utils/updateValues.js +1 -1
  51. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/utils/formatActions.js +1 -1
  52. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/utils/createArrayOfValues.js +2 -1
  53. package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +1 -1
  54. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +47 -5
  55. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +27 -5
  56. package/admin/src/pages/SettingsPage/pages/Users/ProtectedEditPage/index.js +2 -2
  57. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/utils/formatData.js +1 -7
  58. package/admin/src/permissions/index.js +1 -1
  59. package/admin/src/translations/en.json +1 -0
  60. package/admin/src/utils/getAttributesToDisplay.js +2 -4
  61. package/admin/src/utils/getExistingActions.js +1 -3
  62. package/admin/src/utils/sortLinks.js +1 -1
  63. package/build/1387.84b454d3.chunk.js +1 -0
  64. package/build/1657.45231968.chunk.js +168 -0
  65. package/build/3081.bcf9a12f.chunk.js +108 -0
  66. package/build/462.8fff7f3b.chunk.js +71 -0
  67. package/build/4628.20631dd1.chunk.js +1 -0
  68. package/build/5542.b8240e3f.chunk.js +70 -0
  69. package/build/5563.905daa13.chunk.js +79 -0
  70. package/build/6404.68405699.chunk.js +100 -0
  71. package/build/7259.b7d00cea.chunk.js +1 -0
  72. package/build/8694.6522968d.chunk.js +247 -0
  73. package/build/9347.058ddb22.chunk.js +1 -0
  74. package/build/Admin-authenticatedApp.a168aa38.chunk.js +79 -0
  75. package/build/Admin_InternalErrorPage.15c6bf07.chunk.js +1 -0
  76. package/build/Admin_homePage.da2181fe.chunk.js +73 -0
  77. package/build/Admin_marketplace.99e25059.chunk.js +31 -0
  78. package/build/Admin_pluginsPage.f6b52ee9.chunk.js +6 -0
  79. package/build/Admin_profilePage.9112cffc.chunk.js +15 -0
  80. package/build/Admin_settingsPage.cb63220f.chunk.js +79 -0
  81. package/build/Upload_ConfigureTheView.eaaec495.chunk.js +1 -0
  82. package/build/admin-app.8cde5b22.chunk.js +110 -0
  83. package/build/admin-edit-roles-page.4f1858e9.chunk.js +280 -0
  84. package/build/admin-edit-users.7e14d85f.chunk.js +10 -0
  85. package/build/admin-roles-list.97e198f9.chunk.js +31 -0
  86. package/build/admin-users.d02de059.chunk.js +34 -0
  87. package/build/api-tokens-create-page.97595e12.chunk.js +1 -0
  88. package/build/api-tokens-edit-page.cd36e30e.chunk.js +1 -0
  89. package/build/api-tokens-list-page.6757c7b9.chunk.js +16 -0
  90. package/build/audit-logs-settings-page.ca9a3c46.chunk.js +76 -0
  91. package/build/content-manager.ba088a66.chunk.js +1132 -0
  92. package/build/content-type-builder-list-view.9c2c020c.chunk.js +214 -0
  93. package/build/content-type-builder.fef159db.chunk.js +126 -0
  94. package/build/email-settings-page.1095e1ab.chunk.js +10 -0
  95. package/build/{en-json.01a88a30.chunk.js → en-json.b052667a.chunk.js} +1 -1
  96. package/build/{highlight.js.26ef649f.chunk.js → highlight.js.28a1547e.chunk.js} +2 -2
  97. package/build/i18n-settings-page.7d80aae0.chunk.js +60 -0
  98. package/build/index.html +1 -1
  99. package/build/main.0df5f5ca.js +2280 -0
  100. package/build/{runtime~main.a40b1b57.js → runtime~main.03cdff31.js} +2 -2
  101. package/build/sso-settings-page.1dd4886e.chunk.js +1 -0
  102. package/build/transfer-tokens-create-page.ec2ca215.chunk.js +1 -0
  103. package/build/transfer-tokens-edit-page.22bf28e5.chunk.js +1 -0
  104. package/build/transfer-tokens-list-page.cf8c77f2.chunk.js +16 -0
  105. package/build/upload-settings.945fdcfa.chunk.js +13 -0
  106. package/build/upload-translation-fr-json.baab9911.chunk.js +1 -0
  107. package/build/{upload-translation-th-json.3847dae0.chunk.js → upload-translation-th-json.98d35574.chunk.js} +1 -1
  108. package/build/upload.a86b1054.chunk.js +33 -0
  109. package/build/users-advanced-settings-page.5b5a9baa.chunk.js +8 -0
  110. package/build/users-email-settings-page.e5506eb4.chunk.js +23 -0
  111. package/build/users-providers-settings-page.e32089c2.chunk.js +28 -0
  112. package/build/users-roles-settings-page.9359e4d1.chunk.js +30 -0
  113. package/build/webhook-edit-page.213f0075.chunk.js +75 -0
  114. package/build/webhook-list-page.5beb2a5c.chunk.js +71 -0
  115. package/ee/server/bootstrap.js +3 -0
  116. package/ee/server/register.js +3 -2
  117. package/ee/server/services/audit-logs.js +75 -16
  118. package/ee/server/utils/persisted-tables.js +49 -0
  119. package/jest.config.front.js +1 -6
  120. package/package.json +27 -25
  121. package/server/middlewares/data-transfer.js +4 -1
  122. package/server/services/permission/permissions-manager/sanitize.js +2 -0
  123. package/webpack.config.js +1 -1
  124. package/build/2637.679b590b.chunk.js +0 -1
  125. package/build/4049.64715f20.chunk.js +0 -1
  126. package/build/5563.451e91ee.chunk.js +0 -30
  127. package/build/7112.2bf13da3.chunk.js +0 -14
  128. package/build/7259.7744297b.chunk.js +0 -1
  129. package/build/8469.853c822b.chunk.js +0 -1
  130. package/build/8580.b0dcf37c.chunk.js +0 -98
  131. package/build/9816.01ee964f.chunk.js +0 -2
  132. package/build/Admin-authenticatedApp.5aa08bf5.chunk.js +0 -79
  133. package/build/Admin_InternalErrorPage.4ad8b0df.chunk.js +0 -1
  134. package/build/Admin_homePage.1411fb7c.chunk.js +0 -68
  135. package/build/Admin_marketplace.0f6c8ee2.chunk.js +0 -22
  136. package/build/Admin_pluginsPage.15e3b0fd.chunk.js +0 -1
  137. package/build/Admin_profilePage.d2a8f9ab.chunk.js +0 -15
  138. package/build/Admin_settingsPage.489ec4eb.chunk.js +0 -9
  139. package/build/Upload_ConfigureTheView.34dde278.chunk.js +0 -1
  140. package/build/admin-app.4b313104.chunk.js +0 -112
  141. package/build/admin-edit-roles-page.3b196317.chunk.js +0 -216
  142. package/build/admin-edit-users.af3b0f15.chunk.js +0 -10
  143. package/build/admin-roles-list.0ad504a7.chunk.js +0 -2
  144. package/build/admin-users.af8c3123.chunk.js +0 -11
  145. package/build/api-tokens-create-page.2a6e22bd.chunk.js +0 -1
  146. package/build/api-tokens-edit-page.fa38cd63.chunk.js +0 -1
  147. package/build/api-tokens-list-page.93f24348.chunk.js +0 -16
  148. package/build/audit-logs-settings-page.7be97e82.chunk.js +0 -1
  149. package/build/content-manager.f530e141.chunk.js +0 -1139
  150. package/build/content-type-builder-list-view.cf38fe2f.chunk.js +0 -191
  151. package/build/content-type-builder.6ecd201d.chunk.js +0 -126
  152. package/build/email-settings-page.4bdbef9a.chunk.js +0 -3
  153. package/build/i18n-settings-page.2bb5be96.chunk.js +0 -1
  154. package/build/main.43b93ff3.js +0 -3843
  155. package/build/sso-settings-page.5a8588ef.chunk.js +0 -1
  156. package/build/transfer-tokens-create-page.a1f14bb1.chunk.js +0 -1
  157. package/build/transfer-tokens-edit-page.00ee1c74.chunk.js +0 -1
  158. package/build/transfer-tokens-list-page.ce37354b.chunk.js +0 -16
  159. package/build/upload-settings.0200561d.chunk.js +0 -1
  160. package/build/upload-translation-fr-json.84429734.chunk.js +0 -1
  161. package/build/upload.c7da1611.chunk.js +0 -13
  162. package/build/users-advanced-settings-page.c0cae03a.chunk.js +0 -1
  163. package/build/users-email-settings-page.a3c80419.chunk.js +0 -1
  164. package/build/users-providers-settings-page.5f86e45c.chunk.js +0 -1
  165. package/build/users-roles-settings-page.b02986df.chunk.js +0 -30
  166. package/build/webhook-edit-page.a2a2b7bb.chunk.js +0 -23
  167. package/build/webhook-list-page.029957a4.chunk.js +0 -1
package/.eslintignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules/
2
+ .eslintrc.js
3
+ build/
4
+ admin/src/plugins.js
package/.eslintrc.js ADDED
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ root: true,
3
+ overrides: [
4
+ {
5
+ files: ['admin/**/*', 'ee/admin/**/*'],
6
+ extends: ['custom/front'],
7
+ },
8
+ {
9
+ files: ['**/*'],
10
+ excludedFiles: ['admin/**/*', 'ee/admin/**/*'],
11
+ extends: ['custom/back'],
12
+ },
13
+ ],
14
+ };
@@ -0,0 +1,7 @@
1
+ export default function useLocalesProvider() {
2
+ return {
3
+ changeLocale() {},
4
+ localeNames: { en: 'English' },
5
+ messages: ['test'],
6
+ };
7
+ }
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'react';
2
- import { get } from 'lodash';
2
+ import get from 'lodash/get';
3
3
  import { useCMEditViewDataManager } from '@strapi/helper-plugin';
4
4
 
5
5
  function useSelect(name) {
@@ -220,7 +220,9 @@ const reducer = (state, action) =>
220
220
 
221
221
  const findAllRelationsAndReplaceWithEmptyArray = findAllAndReplace(
222
222
  components,
223
- (value) => value.type === 'relation',
223
+ (value) => {
224
+ return value.type === 'relation';
225
+ },
224
226
  (_, { path }) => {
225
227
  if (state.modifiedData?.id === data.id && get(state.modifiedData, path)) {
226
228
  return get(state.modifiedData, path);
@@ -26,7 +26,11 @@ const findAllAndReplaceSetup = (components, predicate = () => false, replacement
26
26
  /**
27
27
  * @type {<TData extends object = object>(data: TData, attributes: Attributes, options?: { ignoreFalseyValues?: boolean}) => TData}
28
28
  */
29
- const findAllAndReplace = (data, attributes, { ignoreFalseyValues = false, path = [] } = {}) => {
29
+ const findAllAndReplace = (
30
+ data,
31
+ attributes,
32
+ { ignoreFalseyValues = false, path = [], parent = attributes } = {}
33
+ ) => {
30
34
  return Object.entries(attributes).reduce(
31
35
  (acc, [key, value]) => {
32
36
  if (
@@ -36,7 +40,7 @@ const findAllAndReplaceSetup = (components, predicate = () => false, replacement
36
40
  return acc;
37
41
  }
38
42
 
39
- if (predicate(value, { path: [...path, key], parent: acc })) {
43
+ if (predicate(value, { path: [...path, key], parent })) {
40
44
  acc[key] =
41
45
  typeof replacement === 'function'
42
46
  ? replacement(acc[key], { path: [...path, key], parent: acc })
@@ -46,16 +50,18 @@ const findAllAndReplaceSetup = (components, predicate = () => false, replacement
46
50
  if (value.type === 'component') {
47
51
  const componentAttributes = components[value.component].attributes;
48
52
 
49
- if (!value.repeatable) {
53
+ if (!value.repeatable && acc[key] && typeof acc[key] === 'object') {
50
54
  acc[key] = findAllAndReplace(acc[key], componentAttributes, {
51
55
  ignoreFalseyValues,
52
56
  path: [...path, key],
57
+ parent: attributes[key],
53
58
  });
54
59
  } else if (value.repeatable && Array.isArray(acc[key])) {
55
60
  acc[key] = acc[key].map((datum, index) => {
56
61
  const data = findAllAndReplace(datum, componentAttributes, {
57
62
  ignoreFalseyValues,
58
63
  path: [...path, key, index],
64
+ parent: attributes[key],
59
65
  });
60
66
 
61
67
  return data;
@@ -67,6 +73,7 @@ const findAllAndReplaceSetup = (components, predicate = () => false, replacement
67
73
  const data = findAllAndReplace(datum, componentAttributes, {
68
74
  ignoreFalseyValues,
69
75
  path: [...path, key, index],
76
+ parent: attributes[key],
70
77
  });
71
78
 
72
79
  return data;
@@ -1,5 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- import { get, take } from 'lodash';
2
+ import get from 'lodash/get';
3
+ import take from 'lodash/take';
3
4
  import { useCMEditViewDataManager } from '@strapi/helper-plugin';
4
5
 
5
6
  import { getFieldName } from '../../../utils';
@@ -1,9 +1,5 @@
1
1
  import styled, { keyframes } from 'styled-components';
2
- import { Box, Flex, FieldAction } from '@strapi/design-system';
3
-
4
- export const EndActionWrapper = styled(Box)`
5
- position: relative;
6
- `;
2
+ import { Flex, FieldAction } from '@strapi/design-system';
7
3
 
8
4
  export const FieldActionWrapper = styled(FieldAction)`
9
5
  svg {
@@ -22,18 +18,13 @@ export const FieldActionWrapper = styled(FieldAction)`
22
18
  `;
23
19
 
24
20
  export const TextValidation = styled(Flex)`
25
- position: absolute;
26
- right: ${({ theme }) => theme.spaces[6]};
27
- width: 100px;
28
- pointer-events: none;
29
-
30
21
  svg {
31
- margin-right: ${({ theme }) => theme.spaces[1]};
32
22
  height: ${12 / 16}rem;
33
23
  width: ${12 / 16}rem;
24
+
34
25
  path {
35
- fill: ${({ theme, notAvailable }) =>
36
- !notAvailable ? theme.colors.success600 : theme.colors.danger600};
26
+ fill: ${({ theme, available }) =>
27
+ available ? theme.colors.success600 : theme.colors.danger600};
37
28
  }
38
29
  }
39
30
  `;
@@ -1,19 +1,19 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { useCMEditViewDataManager, useFetchClient } from '@strapi/helper-plugin';
3
+ import {
4
+ useCMEditViewDataManager,
5
+ useFetchClient,
6
+ useNotification,
7
+ useAPIErrorHandler,
8
+ } from '@strapi/helper-plugin';
4
9
  import { useIntl } from 'react-intl';
5
- import get from 'lodash/get';
6
- import { TextInput, Typography } from '@strapi/design-system';
10
+ import { Flex, TextInput, Typography } from '@strapi/design-system';
7
11
  import { Refresh, CheckCircle, ExclamationMarkCircle, Loader } from '@strapi/icons';
12
+
8
13
  import { getRequestUrl } from '../../utils';
9
14
  import useDebounce from './useDebounce';
10
15
  import UID_REGEX from './regex';
11
- import {
12
- EndActionWrapper,
13
- FieldActionWrapper,
14
- TextValidation,
15
- LoadingWrapper,
16
- } from './endActionStyle';
16
+ import { FieldActionWrapper, TextValidation, LoadingWrapper } from './endActionStyle';
17
17
 
18
18
  const InputUID = ({
19
19
  attribute,
@@ -34,9 +34,11 @@ const InputUID = ({
34
34
  const [availability, setAvailability] = useState(null);
35
35
  const debouncedValue = useDebounce(value, 300);
36
36
  const generateUid = useRef();
37
+ const toggleNotification = useNotification();
38
+ const { formatAPIError } = useAPIErrorHandler();
37
39
  const initialValue = initialData[name];
38
40
  const { formatMessage } = useIntl();
39
- const createdAtName = get(layout, ['options', 'timestamps', 0]);
41
+ const createdAtName = layout?.options?.timestamps ?? 0;
40
42
  const isCreation = !initialData[createdAtName];
41
43
  const debouncedTargetFieldValue = useDebounce(modifiedData[attribute.targetField], 300);
42
44
  const [isCustomized, setIsCustomized] = useState(false);
@@ -59,72 +61,74 @@ const InputUID = ({
59
61
 
60
62
  generateUid.current = async (shouldSetInitialValue = false) => {
61
63
  setIsLoading(true);
62
- const requestURL = getRequestUrl('uid/generate');
64
+
63
65
  try {
64
66
  const {
65
67
  data: { data },
66
- } = await post(requestURL, {
68
+ } = await post(getRequestUrl('uid/generate'), {
67
69
  contentTypeUID,
68
70
  field: name,
69
71
  data: modifiedData,
70
72
  });
73
+
71
74
  onChange({ target: { name, value: data, type: 'text' } }, shouldSetInitialValue);
72
75
  setIsLoading(false);
73
- } catch (err) {
76
+ } catch (error) {
74
77
  setIsLoading(false);
78
+ toggleNotification({
79
+ type: 'warning',
80
+ message: formatAPIError(error),
81
+ });
75
82
  }
76
83
  };
77
84
 
78
85
  const checkAvailability = async () => {
79
- setIsLoading(true);
80
-
81
- const requestURL = getRequestUrl('uid/check-availability');
82
-
83
86
  if (!value) {
84
87
  return;
85
88
  }
86
89
 
90
+ setIsLoading(true);
91
+
87
92
  try {
88
- const { data } = await post(requestURL, {
93
+ const { data } = await post(getRequestUrl('uid/check-availability'), {
89
94
  contentTypeUID,
90
95
  field: name,
91
96
  value: value ? value.trim() : '',
92
97
  });
93
98
 
94
- setAvailability(data);
95
-
96
99
  setIsLoading(false);
97
- } catch (err) {
100
+ setAvailability(data);
101
+ } catch (error) {
98
102
  setIsLoading(false);
103
+ toggleNotification({
104
+ type: 'warning',
105
+ message: formatAPIError(error),
106
+ });
99
107
  }
100
108
  };
101
109
 
102
- // // FIXME: we need to find a better way to autofill the input when it is required.
110
+ // FIXME: we need to find a better way to autofill the input when it is required.
103
111
  useEffect(() => {
104
112
  if (!value && attribute.required) {
105
113
  generateUid.current(true);
106
114
  }
107
- // eslint-disable-next-line react-hooks/exhaustive-deps
108
- }, []);
115
+ }, [attribute.required, generateUid, value]);
109
116
 
110
117
  useEffect(() => {
111
- if (
112
- debouncedValue &&
113
- debouncedValue.trim().match(UID_REGEX) &&
114
- debouncedValue !== initialValue
115
- ) {
118
+ if (debouncedValue?.trim().match(UID_REGEX) && debouncedValue !== initialValue) {
116
119
  checkAvailability();
117
120
  }
121
+
118
122
  if (!debouncedValue) {
119
123
  setAvailability(null);
120
124
  }
121
125
  // eslint-disable-next-line react-hooks/exhaustive-deps
122
- }, [debouncedValue, initialValue]);
126
+ }, [initialValue, debouncedValue]);
123
127
 
124
128
  useEffect(() => {
125
129
  let timer;
126
130
 
127
- if (availability && availability.isAvailable) {
131
+ if (availability?.isAvailable) {
128
132
  timer = setTimeout(() => {
129
133
  setAvailability(null);
130
134
  }, 4000);
@@ -176,51 +180,70 @@ const InputUID = ({
176
180
  disabled={disabled}
177
181
  error={error}
178
182
  endAction={
179
- <EndActionWrapper>
180
- {availability && availability.isAvailable && !regenerateLabel && (
181
- <TextValidation alignItems="center" justifyContent="flex-end">
182
- <CheckCircle />
183
- <Typography textColor="success600" variant="pi">
184
- {formatMessage({
185
- id: 'content-manager.components.uid.available',
186
- defaultMessage: 'Available',
187
- })}
183
+ <Flex position="relative" gap={1}>
184
+ {availability && !regenerateLabel && (
185
+ <TextValidation
186
+ alignItems="center"
187
+ gap={1}
188
+ justifyContent="flex-end"
189
+ available={!!availability?.isAvailable}
190
+ data-not-here-outer
191
+ position="absolute"
192
+ pointerEvents="none"
193
+ right={6}
194
+ width="100px"
195
+ >
196
+ {availability?.isAvailable ? <CheckCircle /> : <ExclamationMarkCircle />}
197
+
198
+ <Typography
199
+ textColor={availability.isAvailable ? 'success600' : 'danger600'}
200
+ variant="pi"
201
+ >
202
+ {formatMessage(
203
+ availability.isAvailable
204
+ ? {
205
+ id: 'content-manager.components.uid.available',
206
+ defaultMessage: 'Available',
207
+ }
208
+ : {
209
+ id: 'content-manager.components.uid.unavailable',
210
+ defaultMessage: 'Unavailable',
211
+ }
212
+ )}
188
213
  </Typography>
189
214
  </TextValidation>
190
215
  )}
191
- {availability && !availability.isAvailable && !regenerateLabel && (
192
- <TextValidation notAvailable alignItems="center" justifyContent="flex-end">
193
- <ExclamationMarkCircle />
194
- <Typography textColor="danger600" variant="pi">
195
- {formatMessage({
196
- id: 'content-manager.components.uid.unavailable',
197
- defaultMessage: 'Unavailable',
216
+
217
+ {!disabled && (
218
+ <>
219
+ {regenerateLabel && (
220
+ <TextValidation alignItems="center" justifyContent="flex-end" gap={1}>
221
+ <Typography textColor="primary600" variant="pi">
222
+ {regenerateLabel}
223
+ </Typography>
224
+ </TextValidation>
225
+ )}
226
+
227
+ <FieldActionWrapper
228
+ onClick={() => generateUid.current()}
229
+ label={formatMessage({
230
+ id: 'content-manager.components.uid.regenerate',
231
+ defaultMessage: 'Regenerate',
198
232
  })}
199
- </Typography>
200
- </TextValidation>
201
- )}
202
- {regenerateLabel && (
203
- <TextValidation alignItems="center" justifyContent="flex-end">
204
- <Typography textColor="primary600" variant="pi">
205
- {regenerateLabel}
206
- </Typography>
207
- </TextValidation>
233
+ onMouseEnter={handleGenerateMouseEnter}
234
+ onMouseLeave={handleGenerateMouseLeave}
235
+ >
236
+ {isLoading ? (
237
+ <LoadingWrapper data-testid="loading-wrapper">
238
+ <Loader />
239
+ </LoadingWrapper>
240
+ ) : (
241
+ <Refresh />
242
+ )}
243
+ </FieldActionWrapper>
244
+ </>
208
245
  )}
209
- <FieldActionWrapper
210
- onClick={() => generateUid.current()}
211
- label="regenerate"
212
- onMouseEnter={handleGenerateMouseEnter}
213
- onMouseLeave={handleGenerateMouseLeave}
214
- >
215
- {isLoading ? (
216
- <LoadingWrapper>
217
- <Loader />
218
- </LoadingWrapper>
219
- ) : (
220
- <Refresh />
221
- )}
222
- </FieldActionWrapper>
223
- </EndActionWrapper>
246
+ </Flex>
224
247
  }
225
248
  hint={hint}
226
249
  label={label}
@@ -1,4 +1,4 @@
1
- import { toLower } from 'lodash';
1
+ import toLower from 'lodash/toLower';
2
2
 
3
3
  const getInputType = (type = '') => {
4
4
  switch (toLower(type)) {
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'react';
2
- import { get } from 'lodash';
2
+ import get from 'lodash/get';
3
3
  import { useCMEditViewDataManager } from '@strapi/helper-plugin';
4
4
 
5
5
  function useSelect(keys) {
@@ -1,5 +1,4 @@
1
1
  import { useCallback } from 'react';
2
- import { get } from 'lodash';
3
2
  import { useSelector } from 'react-redux';
4
3
  import selectLayout from '../../pages/EditViewLayoutManager/selectors';
5
4
 
@@ -8,7 +7,7 @@ const useContentTypeLayout = () => {
8
7
 
9
8
  const getComponentLayout = useCallback(
10
9
  (componentUid) => {
11
- return get(currentLayout, ['components', componentUid], {});
10
+ return currentLayout?.components?.[componentUid] ?? {};
12
11
  },
13
12
  [currentLayout]
14
13
  );
@@ -1,4 +1,7 @@
1
- import { cloneDeep, get, set } from 'lodash';
1
+ import cloneDeep from 'lodash/cloneDeep';
2
+ import get from 'lodash/get';
3
+ import set from 'lodash/set';
4
+
2
5
  import { mergeMetasWithSchema } from '../../../utils';
3
6
 
4
7
  const getRelationModel = (targetModel, models) => models.find((model) => model.uid === targetModel);
@@ -4,7 +4,7 @@ import { Switch, Route, useRouteMatch, Redirect, useLocation } from 'react-route
4
4
  import {
5
5
  CheckPagePermissions,
6
6
  LoadingIndicatorPage,
7
- NotFound,
7
+ AnErrorOccurred,
8
8
  useGuidedTour,
9
9
  } from '@strapi/helper-plugin';
10
10
  import { Layout, HeaderLayout, Main } from '@strapi/design-system';
@@ -104,7 +104,7 @@ const App = () => {
104
104
  <Route path="/content-manager/no-content-types">
105
105
  <NoContentType />
106
106
  </Route>
107
- <Route path="" component={NotFound} />
107
+ <Route path="" component={AnErrorOccurred} />
108
108
  </Switch>
109
109
  </ModelsContext.Provider>
110
110
  </Layout>
@@ -1,7 +1,6 @@
1
1
  import React, { memo, useMemo } from 'react';
2
2
  import { Switch, Route } from 'react-router-dom';
3
3
  import { ErrorBoundary } from 'react-error-boundary';
4
- import { get } from 'lodash';
5
4
  import PropTypes from 'prop-types';
6
5
  import { LoadingIndicatorPage, CheckPagePermissions } from '@strapi/helper-plugin';
7
6
  import permissions from '../../../permissions';
@@ -43,7 +42,7 @@ const CollectionTypeRecursivePath = ({
43
42
  return { rawContentTypeLayout, rawComponentsLayouts };
44
43
  }, [layout]);
45
44
 
46
- const uid = get(layout, ['contentType', 'uid'], null);
45
+ const uid = layout?.contentType?.uid ?? null;
47
46
 
48
47
  // This statement is needed in order to prevent the CollectionTypeFormWrapper effects clean up phase to be run twice.
49
48
  // What can happen is that when navigating from one entry to another the cleanup phase of the fetch data effect is run twice : once when
@@ -1,4 +1,6 @@
1
- import { cloneDeep, set } from 'lodash';
1
+ import cloneDeep from 'lodash/cloneDeep';
2
+ import set from 'lodash/set';
3
+
2
4
  import { createLayout, formatLayout } from './utils/layout';
3
5
 
4
6
  const init = (initialState, mainLayout, components) => {
@@ -1,8 +1,6 @@
1
- import { get } from 'lodash';
2
-
3
1
  const createPossibleMainFieldsForModelsAndComponents = (array) => {
4
2
  return array.reduce((acc, current) => {
5
- const attributes = get(current, ['attributes'], {});
3
+ const attributes = current?.attributes ?? {};
6
4
  const possibleMainFields = Object.keys(attributes).filter((attr) => {
7
5
  return ![
8
6
  'boolean',
@@ -14,7 +12,7 @@ const createPossibleMainFieldsForModelsAndComponents = (array) => {
14
12
  'relation',
15
13
  'text',
16
14
  'richtext',
17
- ].includes(get(attributes, [attr, 'type'], ''));
15
+ ].includes(attributes?.[attr]?.type ?? '');
18
16
  });
19
17
 
20
18
  acc[current.uid] = possibleMainFields;
@@ -1,4 +1,4 @@
1
- import { isEmpty } from 'lodash';
1
+ import isEmpty from 'lodash/isEmpty';
2
2
  import { useCMEditViewDataManager } from '@strapi/helper-plugin';
3
3
 
4
4
  function useSelect() {
@@ -1,4 +1,5 @@
1
- import { get, isEmpty } from 'lodash';
1
+ import get from 'lodash/get';
2
+ import isEmpty from 'lodash/isEmpty';
2
3
 
3
4
  const createAttributesLayout = (currentContentTypeLayoutData) => {
4
5
  if (!currentContentTypeLayoutData.layouts) {
@@ -1,4 +1,5 @@
1
- import { uniq, flatMap } from 'lodash';
1
+ import uniq from 'lodash/uniq';
2
+ import flatMap from 'lodash/flatMap';
2
3
  import { findMatchingPermissions } from '@strapi/helper-plugin';
3
4
 
4
5
  const getFieldsActionMatchingPermissions = (userPermissions, slug) => {
@@ -1,4 +1,4 @@
1
- import { toLower } from 'lodash';
1
+ import toLower from 'lodash/toLower';
2
2
 
3
3
  const checkIfAttributeIsDisplayable = (attribute) => {
4
4
  const type = attribute.type;
@@ -1,4 +1,4 @@
1
- import { get } from 'lodash';
1
+ import get from 'lodash/get';
2
2
 
3
3
  const createDefaultForm = (attributes, allComponentsSchema) => {
4
4
  return Object.keys(attributes).reduce((acc, current) => {
@@ -10,7 +10,7 @@ const createDefaultForm = (attributes, allComponentsSchema) => {
10
10
  }
11
11
 
12
12
  if (type === 'component') {
13
- const currentComponentSchema = get(allComponentsSchema, [component, 'attributes'], {});
13
+ const currentComponentSchema = allComponentsSchema?.[component]?.attributes ?? {};
14
14
  const currentComponentDefaultForm = createDefaultForm(
15
15
  currentComponentSchema,
16
16
  allComponentsSchema
@@ -1,4 +1,5 @@
1
- import { omit, get } from 'lodash';
1
+ import get from 'lodash/get';
2
+ import omit from 'lodash/omit';
2
3
 
3
4
  const formatLayoutToApi = ({ layouts, metadatas, ...rest }) => {
4
5
  const list = layouts.list.map((obj) => {
@@ -1,4 +1,4 @@
1
- import { isNaN } from 'lodash';
1
+ import isNaN from 'lodash/isNaN';
2
2
 
3
3
  const getFieldName = (stringName) =>
4
4
  stringName.split('.').filter((string) => isNaN(parseInt(string, 10)));
@@ -1,4 +1,4 @@
1
- import { set } from 'lodash';
1
+ import set from 'lodash/set';
2
2
 
3
3
  const mergeMetasWithSchema = (data, schemas, mainSchemaKey) => {
4
4
  const findSchema = (refUid) => schemas.find((obj) => obj.uid === refUid);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * This file is for all helpers related to `paths` in the CM.
3
3
  */
4
- import { get } from 'lodash';
4
+ import get from 'lodash/get';
5
5
 
6
6
  /**
7
7
  * This is typically used in circumstances where there are re-orderable pieces e.g. Dynamic Zones
@@ -1,4 +1,4 @@
1
- import { get } from 'lodash';
1
+ import get from 'lodash/get';
2
2
  import { getType, getOtherInfos } from '@strapi/helper-plugin';
3
3
 
4
4
  const removePasswordFieldsFromData = (data, contentTypeSchema, componentSchema) => {
@@ -0,0 +1,7 @@
1
+ export default function () {
2
+ return {
3
+ logos: {
4
+ auth: { custom: 'customAuthLogo.png', default: 'defaultAuthLogo.png' },
5
+ },
6
+ };
7
+ }
@@ -1,11 +1,11 @@
1
1
  import { useState } from 'react';
2
- import { get } from 'lodash';
3
- import { useFetchClient, useNotification } from '@strapi/helper-plugin';
2
+ import { useFetchClient, useNotification, useAPIErrorHandler } from '@strapi/helper-plugin';
4
3
 
5
- const useRegenerate = (url, id, onRegenerate) => {
4
+ const useRegenerate = (url, id, onRegenerate, onError) => {
6
5
  const [isLoadingConfirmation, setIsLoadingConfirmation] = useState(false);
7
6
  const toggleNotification = useNotification();
8
7
  const { post } = useFetchClient();
8
+ const { formatAPIError } = useAPIErrorHandler();
9
9
 
10
10
  const regenerateData = async () => {
11
11
  try {
@@ -18,10 +18,15 @@ const useRegenerate = (url, id, onRegenerate) => {
18
18
  onRegenerate(accessKey);
19
19
  } catch (error) {
20
20
  setIsLoadingConfirmation(false);
21
- toggleNotification({
22
- type: 'warning',
23
- message: get(error, 'response.data.message', 'notification.error'),
24
- });
21
+
22
+ if (onError) {
23
+ onError(error);
24
+ } else {
25
+ toggleNotification({
26
+ type: 'warning',
27
+ message: formatAPIError(error),
28
+ });
29
+ }
25
30
  }
26
31
  };
27
32
 
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useReducer } from 'react';
2
2
  import { request, useNotification, useOverlayBlocker } from '@strapi/helper-plugin';
3
- import { get, has, omit } from 'lodash';
3
+ import omit from 'lodash/omit';
4
4
  import { checkFormValidity, formatAPIErrors } from '../../utils';
5
5
  import { initialState, reducer } from './reducer';
6
6
  import init from './init';
@@ -102,9 +102,9 @@ const useSettingsForm = (endPoint, schema, cbSuccess, fieldsToPick) => {
102
102
  message: { id: 'notification.success.saved' },
103
103
  });
104
104
  } catch (err) {
105
- const data = get(err, 'response.payload', { data: {} });
105
+ const data = err?.response?.payload ?? { data: {} };
106
106
 
107
- if (has(data, 'data') && typeof data.data === 'string') {
107
+ if (!!data?.data && typeof data.data === 'string') {
108
108
  toggleNotification({
109
109
  type: 'warning',
110
110
  message: data.data,