diff --git a/packages/core/admin/admin/src/components/FormInputs/Boolean.tsx b/packages/core/admin/admin/src/components/FormInputs/Boolean.tsx index ce244d30d3..296061dba5 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Boolean.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Boolean.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { Toggle, useComposedRefs, Field } from '@strapi/design-system'; import { useIntl } from 'react-intl'; @@ -40,4 +40,6 @@ const BooleanInput = forwardRef( } ); -export { BooleanInput }; +const MemoizedBooleanInput = memo(BooleanInput); + +export { MemoizedBooleanInput as BooleanInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Checkbox.tsx b/packages/core/admin/admin/src/components/FormInputs/Checkbox.tsx index 793681512c..3a927606e3 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Checkbox.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Checkbox.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { Checkbox, useComposedRefs, Field } from '@strapi/design-system'; @@ -31,4 +31,6 @@ const CheckboxInput = forwardRef( } ); -export { CheckboxInput }; +const MemoizedCheckboxInput = memo(CheckboxInput); + +export { MemoizedCheckboxInput as CheckboxInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Date.tsx b/packages/core/admin/admin/src/components/FormInputs/Date.tsx index fb64d61d04..8321b90ec1 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Date.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Date.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { DatePicker, useComposedRefs, Field } from '@strapi/design-system'; import { useIntl } from 'react-intl'; @@ -37,4 +37,6 @@ const DateInput = forwardRef( } ); -export { DateInput }; +const MemoizedDateInput = memo(DateInput); + +export { MemoizedDateInput as DateInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/DateTime.tsx b/packages/core/admin/admin/src/components/FormInputs/DateTime.tsx index e844ac9aae..3c99eb09ab 100644 --- a/packages/core/admin/admin/src/components/FormInputs/DateTime.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/DateTime.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { DateTimePicker, useComposedRefs, Field } from '@strapi/design-system'; import { useIntl } from 'react-intl'; @@ -37,4 +37,6 @@ const DateTimeInput = forwardRef( } ); -export { DateTimeInput }; +const MemoizedDateTimeInput = memo(DateTimeInput); + +export { MemoizedDateTimeInput as DateTimeInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Email.tsx b/packages/core/admin/admin/src/components/FormInputs/Email.tsx index 4d7698c633..0ce5adb4b2 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Email.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Email.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { TextInput, useComposedRefs, Field } from '@strapi/design-system'; @@ -7,7 +7,7 @@ import { useField } from '../Form'; import type { StringProps } from './types'; -export const EmailInput = forwardRef( +const EmailInput = forwardRef( ({ name, required, label, hint, labelAction, ...props }, ref) => { const field = useField(name); const fieldRef = useFocusInputField(name); @@ -32,3 +32,7 @@ export const EmailInput = forwardRef( ); } ); + +const MemoizedEmailInput = memo(EmailInput); + +export { MemoizedEmailInput as EmailInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Enumeration.tsx b/packages/core/admin/admin/src/components/FormInputs/Enumeration.tsx index 39f7575667..ade3bd39b8 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Enumeration.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Enumeration.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { SingleSelect, SingleSelectOption, useComposedRefs, Field } from '@strapi/design-system'; @@ -7,7 +7,7 @@ import { useField } from '../Form'; import { EnumerationProps } from './types'; -export const EnumerationInput = forwardRef( +const EnumerationInput = forwardRef( ({ name, required, label, hint, labelAction, options = [], ...props }, ref) => { const field = useField(name); const fieldRef = useFocusInputField(name); @@ -39,3 +39,7 @@ export const EnumerationInput = forwardRef( ); } ); + +const MemoizedEnumerationInput = memo(EnumerationInput); + +export { MemoizedEnumerationInput as EnumerationInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Json.tsx b/packages/core/admin/admin/src/components/FormInputs/Json.tsx index 4bf55ec8e4..0a4f2b2336 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Json.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Json.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { JSONInput as JSONInputImpl, @@ -12,7 +12,7 @@ import { useField } from '../Form'; import { InputProps } from './types'; -export const JsonInput = forwardRef( +const JsonInput = forwardRef( ({ name, required, label, hint, labelAction, ...props }, ref) => { const field = useField(name); const fieldRef = useFocusInputField(name); @@ -40,3 +40,7 @@ export const JsonInput = forwardRef( ); } ); + +const MemoizedJsonInput = memo(JsonInput); + +export { MemoizedJsonInput as JsonInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Number.tsx b/packages/core/admin/admin/src/components/FormInputs/Number.tsx index 4e2d68dabd..488bf4842c 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Number.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Number.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { NumberInput, useComposedRefs, Field } from '@strapi/design-system'; @@ -34,4 +34,6 @@ const NumberInputImpl = forwardRef( } ); -export { NumberInputImpl as NumberInput }; +const MemoizedNumberInput = memo(NumberInputImpl); + +export { MemoizedNumberInput as NumberInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Password.tsx b/packages/core/admin/admin/src/components/FormInputs/Password.tsx index bd6fb52dad..0664bfd4a0 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Password.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Password.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useState } from 'react'; +import { forwardRef, memo, useState } from 'react'; import { TextInput, useComposedRefs, Field } from '@strapi/design-system'; import { Eye, EyeStriked } from '@strapi/icons'; @@ -9,7 +9,7 @@ import { useField } from '../Form'; import type { StringProps } from './types'; -export const PasswordInput = forwardRef( +const PasswordInput = forwardRef( ({ name, required, label, hint, labelAction, ...props }, ref) => { const [showPassword, setShowPassword] = useState(false); const { formatMessage } = useIntl(); @@ -55,3 +55,7 @@ export const PasswordInput = forwardRef( ); } ); + +const MemoizedPasswordInput = memo(PasswordInput); + +export { MemoizedPasswordInput as PasswordInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Renderer.tsx b/packages/core/admin/admin/src/components/FormInputs/Renderer.tsx index 53751cd279..0992432d38 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Renderer.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Renderer.tsx @@ -93,4 +93,6 @@ const NotSupportedField = forwardRef( } ); -export { InputRenderer }; +const MemoizedInputRenderer = memo(InputRenderer); + +export { MemoizedInputRenderer as InputRenderer }; diff --git a/packages/core/admin/admin/src/components/FormInputs/String.tsx b/packages/core/admin/admin/src/components/FormInputs/String.tsx index 4798f905e7..2e77eaf2cb 100644 --- a/packages/core/admin/admin/src/components/FormInputs/String.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/String.tsx @@ -1,11 +1,11 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { TextInput, useComposedRefs, Field } from '@strapi/design-system'; import { useFocusInputField } from '../../hooks/useFocusInputField'; import { type InputProps, useField } from '../Form'; -export const StringInput = forwardRef( +const StringInput = forwardRef( ({ name, required, label, hint, labelAction, ...props }, ref) => { const field = useField(name); const fieldRef = useFocusInputField(name); @@ -28,3 +28,7 @@ export const StringInput = forwardRef( ); } ); + +const MemoizedStringInput = memo(StringInput); + +export { MemoizedStringInput as StringInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Textarea.tsx b/packages/core/admin/admin/src/components/FormInputs/Textarea.tsx index 8b5d319368..66cb3fa089 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Textarea.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Textarea.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { Textarea, useComposedRefs, Field } from '@strapi/design-system'; @@ -7,7 +7,7 @@ import { useField } from '../Form'; import type { StringProps } from './types'; -export const TextareaInput = forwardRef( +const TextareaInput = forwardRef( ({ name, required, label, hint, labelAction, ...props }, ref) => { const field = useField(name); const fieldRef = useFocusInputField(name); @@ -30,3 +30,7 @@ export const TextareaInput = forwardRef( ); } ); + +const MemoizedTextareaInput = memo(TextareaInput); + +export { MemoizedTextareaInput as TextareaInput }; diff --git a/packages/core/admin/admin/src/components/FormInputs/Time.tsx b/packages/core/admin/admin/src/components/FormInputs/Time.tsx index de3d8cd9c1..44c4b90c6d 100644 --- a/packages/core/admin/admin/src/components/FormInputs/Time.tsx +++ b/packages/core/admin/admin/src/components/FormInputs/Time.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { TimePicker, useComposedRefs, Field } from '@strapi/design-system'; import { useIntl } from 'react-intl'; @@ -36,4 +36,6 @@ const TimeInput = forwardRef( } ); -export { TimeInput }; +const MemoizedTimeInput = memo(TimeInput); + +export { MemoizedTimeInput as TimeInput }; diff --git a/packages/core/content-manager/admin/src/features/DocumentRBAC.tsx b/packages/core/content-manager/admin/src/features/DocumentRBAC.tsx index aa7cebf854..0369415798 100644 --- a/packages/core/content-manager/admin/src/features/DocumentRBAC.tsx +++ b/packages/core/content-manager/admin/src/features/DocumentRBAC.tsx @@ -104,12 +104,9 @@ const DocumentRBAC = ({ children, permissions }: DocumentRBACProps) => { .filter((field) => field.split('.').length > 1); if (fieldType === 'component') { - const componentOrDynamicZoneFields = componentFieldNames - // then map to give us the dot separate path as an array - .map((field) => field.split('.')); // check if the field name is within any of those arrays - return componentOrDynamicZoneFields.some((field) => { - return field.includes(fieldName); + return componentFieldNames.some((field) => { + return field.includes(name.join('.')); }); } diff --git a/packages/core/content-manager/admin/src/hooks/useContentTypeSchema.ts b/packages/core/content-manager/admin/src/hooks/useContentTypeSchema.ts index c5c05f8296..587a1632bc 100644 --- a/packages/core/content-manager/admin/src/hooks/useContentTypeSchema.ts +++ b/packages/core/content-manager/admin/src/hooks/useContentTypeSchema.ts @@ -26,32 +26,25 @@ const useContentTypeSchema = (model?: string) => { const { toggleNotification } = useNotification(); const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(); - const { components, contentType, contentTypes, error, isLoading, isFetching } = - useGetInitialDataQuery(undefined, { - selectFromResult: (res) => { - const contentType = res.data?.contentTypes.find((ct) => ct.uid === model); + const { data, error, isLoading, isFetching } = useGetInitialDataQuery(undefined); - const componentsByKey = res.data?.components.reduce( - (acc, component) => { - acc[component.uid] = component; + const { components, contentType, contentTypes } = React.useMemo(() => { + const contentType = data?.contentTypes.find((ct) => ct.uid === model); - return acc; - }, - {} - ); + const componentsByKey = data?.components.reduce((acc, component) => { + acc[component.uid] = component; - const components = extractContentTypeComponents(contentType?.attributes, componentsByKey); + return acc; + }, {}); - return { - isLoading: res.isLoading, - isFetching: res.isFetching, - error: res.error, - components: Object.keys(components).length === 0 ? undefined : components, - contentType, - contentTypes: res.data?.contentTypes ?? [], - }; - }, - }); + const components = extractContentTypeComponents(contentType?.attributes, componentsByKey); + + return { + components: Object.keys(components).length === 0 ? undefined : components, + contentType, + contentTypes: data?.contentTypes ?? [], + }; + }, [model, data]); React.useEffect(() => { if (error) { diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.tsx index e2dd25519f..503924e43f 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.tsx @@ -38,4 +38,6 @@ const BlocksInput = React.forwardRef<{ focus: () => void }, BlocksInputProps>( } ); -export { BlocksInput }; +const MemoizedBlocksInput = React.memo(BlocksInput); + +export { MemoizedBlocksInput as BlocksInput }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Component/Input.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Component/Input.tsx index e746237894..a1b0ef5ce5 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Component/Input.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Component/Input.tsx @@ -109,5 +109,7 @@ const ComponentInput = ({ ); }; -export { ComponentInput }; +const MemoizedComponentInput = React.memo(ComponentInput); + +export { MemoizedComponentInput as ComponentInput }; export type { ComponentInputProps }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/NotAllowed.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/NotAllowed.tsx index ebd00aac03..a67af166dc 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/NotAllowed.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/NotAllowed.tsx @@ -1,7 +1,6 @@ -import { TextInput } from '@strapi/design-system'; +import { Field, TextInput } from '@strapi/design-system'; import { EyeStriked } from '@strapi/icons'; import { useIntl } from 'react-intl'; -import { styled } from 'styled-components'; import type { InputProps } from '@strapi/admin/strapi-admin'; import type { Schema } from '@strapi/types'; @@ -19,26 +18,18 @@ const NotAllowedInput = ({ hint, label, required, name }: NotAllowedInputProps) }); return ( - } - type="text" - value="" - /> + + {label} + } + type="text" + value="" + /> + + ); }; -const StyledIcon = styled(EyeStriked)` - & > path { - fill: ${({ theme }) => theme.colors.neutral600}; - } -`; - export { NotAllowedInput }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Relations.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Relations.tsx index 96c86544c0..55a1f5f2a0 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Relations.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Relations.tsx @@ -1032,5 +1032,7 @@ const RelationItemPlaceholder = () => ( /> ); -export { RelationsField as RelationsInput, FlexWrapper, DisconnectButton, LinkEllipsis }; +const MemoizedRelationsField = React.memo(RelationsField); + +export { MemoizedRelationsField as RelationsInput, FlexWrapper, DisconnectButton, LinkEllipsis }; export type { RelationsFieldProps }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/UID.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/UID.tsx index 43a5587363..e74c8b604a 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/UID.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/UID.tsx @@ -322,5 +322,7 @@ const LoadingWrapper = styled(Flex)` animation: ${rotation} 2s infinite linear; `; -export { UIDInput }; +const MemoizedUIDInput = React.memo(UIDInput); + +export { MemoizedUIDInput as UIDInput }; export type { UIDInputProps }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.tsx index 8a0e61813b..28a0026ba2 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.tsx @@ -150,5 +150,7 @@ const Wysiwyg = React.forwardRef( } ); -export { Wysiwyg }; +const MemoizedWysiwyg = React.memo(Wysiwyg); + +export { MemoizedWysiwyg as Wysiwyg }; export type { WysiwygProps }; diff --git a/packages/core/content-manager/admin/src/pages/EditView/components/InputRenderer.tsx b/packages/core/content-manager/admin/src/pages/EditView/components/InputRenderer.tsx index 2bfe77a68f..11aaa5d3e4 100644 --- a/packages/core/content-manager/admin/src/pages/EditView/components/InputRenderer.tsx +++ b/packages/core/content-manager/admin/src/pages/EditView/components/InputRenderer.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { ReactNode, memo } from 'react'; import { useStrapiApp, @@ -228,5 +228,7 @@ const getMinMax = (attribute: Schema.Attribute.AnyAttribute) => { } }; +const MemoizedInputRenderer = memo(InputRenderer); + export type { InputRendererProps }; -export { InputRenderer, useFieldHint }; +export { MemoizedInputRenderer as InputRenderer, useFieldHint };