From 9a82fd933c5b0772c0e114b393f0af70d57b2c64 Mon Sep 17 00:00:00 2001 From: Felix Gnass Date: Tue, 25 Feb 2025 13:59:47 +0100 Subject: [PATCH 1/4] fix(#7414): don't call getAsset inside render --- .../Collection/Entries/EntryCard.js | 16 ++++++++++--- .../src/withFileControl.js | 23 ++++++++++++++----- .../src/ImagePreview.js | 15 ++++++++++-- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/decap-cms-core/src/components/Collection/Entries/EntryCard.js b/packages/decap-cms-core/src/components/Collection/Entries/EntryCard.js index 01e0027d7069..15fc07721c73 100644 --- a/packages/decap-cms-core/src/components/Collection/Entries/EntryCard.js +++ b/packages/decap-cms-core/src/components/Collection/Entries/EntryCard.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import styled from '@emotion/styled'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; @@ -81,7 +81,7 @@ const CardBody = styled.div` } `; -const CardImage = styled.div` +const StyledImage = styled.div` background-image: url(${props => props.src}); background-position: center center; background-size: cover; @@ -89,6 +89,16 @@ const CardImage = styled.div` height: 150px; `; +function CardImage({ getAsset, value, field }) { + const [asset, setAsset] = useState(null); + + useEffect(() => { + setAsset(value ? getAsset(value, field) : null); + }, [value, field, getAsset]); + + return asset ? : null; +} + function EntryCard({ path, summary, @@ -117,7 +127,7 @@ function EntryCard({ {collectionLabel ? {collectionLabel} : null} {summary} - {image ? : null} + {image ? : null} ); diff --git a/packages/decap-cms-widget-file/src/withFileControl.js b/packages/decap-cms-widget-file/src/withFileControl.js index 024b9195dbc3..404dac613cd3 100644 --- a/packages/decap-cms-widget-file/src/withFileControl.js +++ b/packages/decap-cms-widget-file/src/withFileControl.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; @@ -61,8 +61,19 @@ const StyledImage = styled.img` object-fit: contain; `; -function Image(props) { - return ; +function Image({ value, field, getAsset }) { + const [asset, setAsset] = useState(null); + + useEffect(() => { + if (value) { + const newAsset = getAsset(value, field); + setAsset(newAsset); + } else { + setAsset(null); + } + }, [value, field, getAsset]); + + return asset ? : null; } function SortableImageButtons({ onRemove, onReplace }) { @@ -89,7 +100,7 @@ function SortableImage(props) { return (
- + { const { getAsset, value, field } = this.props; const items = valueListToSortableArray(value); + if (isMultiple(value)) { return ( - + ); }; diff --git a/packages/decap-cms-widget-image/src/ImagePreview.js b/packages/decap-cms-widget-image/src/ImagePreview.js index b74e0ca44837..918d03b07de8 100644 --- a/packages/decap-cms-widget-image/src/ImagePreview.js +++ b/packages/decap-cms-widget-image/src/ImagePreview.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import { List } from 'immutable'; @@ -11,7 +11,18 @@ const StyledImage = styled(({ src }) => ; + const [asset, setAsset] = useState(null); + + useEffect(() => { + if (value) { + const newAsset = getAsset(value, field); + setAsset(newAsset); + } else { + setAsset(null); + } + }, [value, field, getAsset]); + + return asset ? : null; } function ImagePreviewContent(props) { From b7e96ed4f861907e62f39259cdb62439f860f31d Mon Sep 17 00:00:00 2001 From: Felix Gnass Date: Tue, 25 Feb 2025 14:00:14 +0100 Subject: [PATCH 2/4] fix: field prop must be a map --- packages/decap-cms-widget-object/src/ObjectPreview.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/decap-cms-widget-object/src/ObjectPreview.js b/packages/decap-cms-widget-object/src/ObjectPreview.js index f9015fc0f8c3..63bb386eec59 100644 --- a/packages/decap-cms-widget-object/src/ObjectPreview.js +++ b/packages/decap-cms-widget-object/src/ObjectPreview.js @@ -1,5 +1,5 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; import { WidgetPreviewContainer } from 'decap-cms-ui-default'; function ObjectPreview({ field }) { @@ -11,7 +11,7 @@ function ObjectPreview({ field }) { } ObjectPreview.propTypes = { - field: PropTypes.node, + field: ImmutablePropTypes.map, }; export default ObjectPreview; From d258d099c4c28e385289bb524259c7f168d67a07 Mon Sep 17 00:00:00 2001 From: Felix Gnass Date: Tue, 25 Feb 2025 14:01:55 +0100 Subject: [PATCH 3/4] fix: disable visual editing --- dev-test/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-test/config.yml b/dev-test/config.yml index 6eac43f98db9..2f57fc63337d 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -18,7 +18,7 @@ collections: # A list of collections the CMS should be able to edit summary: '{{title}} -- {{year}}/{{month}}/{{day}}' create: true # Allow users to create new documents in this collection editor: - visualEditing: true + visualEditing: false view_filters: - label: Posts With Index field: title From a7cd190911c30eac7e0e4ddc0f904ab981027284 Mon Sep 17 00:00:00 2001 From: Yan <61414485+yanthomasdev@users.noreply.github.com> Date: Fri, 8 May 2026 13:45:35 -0300 Subject: [PATCH 4/4] fix: merge issue --- .../decap-cms-widget-image/src/ImagePreview.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/decap-cms-widget-image/src/ImagePreview.js b/packages/decap-cms-widget-image/src/ImagePreview.js index 918d03b07de8..f34f90636b94 100644 --- a/packages/decap-cms-widget-image/src/ImagePreview.js +++ b/packages/decap-cms-widget-image/src/ImagePreview.js @@ -14,15 +14,23 @@ function StyledImageAsset({ getAsset, value, field }) { const [asset, setAsset] = useState(null); useEffect(() => { - if (value) { - const newAsset = getAsset(value, field); - setAsset(newAsset); - } else { + if (!value) { setAsset(null); + return; } + + if (typeof File !== 'undefined' && value instanceof File) { + const objectUrl = URL.createObjectURL(value); + setAsset(objectUrl); + + return () => URL.revokeObjectURL(objectUrl); + } + + const newAsset = getAsset(value, field); + setAsset(newAsset); }, [value, field, getAsset]); - return asset ? : null; + return asset ? : null; } function ImagePreviewContent(props) {