Skip to content

Commit

Permalink
FIX Make change tracking work again for inline editable blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Feb 19, 2025
1 parent 4c38f21 commit 4b960ce
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 48 deletions.
20 changes: 10 additions & 10 deletions client/dist/js/bundle.js

Large diffs are not rendered by default.

46 changes: 8 additions & 38 deletions client/src/components/ElementEditor/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { inject } from 'lib/Injector';
import i18n from 'i18n';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { submit } from 'redux-form';
import { submit, isDirty } from 'redux-form';
import { loadElementFormStateName } from 'state/editor/loadElementFormStateName';
import { loadElementSchemaValue } from 'state/editor/loadElementSchemaValue';
import { publishBlockMutation } from 'state/editor/publishBlockMutation';
Expand All @@ -20,7 +20,7 @@ import { DragSource, DropTarget } from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';
import { elementDragSource, isOverTop } from 'lib/dragHelpers';
import * as toastsActions from 'state/toasts/ToastsActions';
import { addFormChanged, removeFormChanged } from 'state/unsavedForms/UnsavedFormsActions';
import getFormState from 'lib/getFormState';

export const ElementContext = createContext(null);

Expand All @@ -39,7 +39,6 @@ const Element = (props) => {
const [doPublishElementAfterSave, setDoPublishElementAfterSave] = useState(false);
const [ensureFormRendered, setEnsureFormRendered] = useState(false);
const [formHasRendered, setFormHasRendered] = useState(false);
const [doDispatchAddFormChanged, setDoDispatchAddFormChanged] = useState(false);
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
const [publishBlock] = useMutation(publishBlockMutation);

Expand All @@ -50,7 +49,7 @@ const Element = (props) => {
// which is confusing as the block still has unsaved changes, hence why we create
// this state variable to track this instead
// props.formDirty is either undefined (when pristine) or an object (when dirty)
const formDirty = typeof props.formDirty !== 'undefined';
const formDirty = typeof props.formDirty === 'undefined';
if (formDirty && !hasUnsavedChanges) {
setHasUnsavedChanges(true);
}
Expand Down Expand Up @@ -92,13 +91,6 @@ const Element = (props) => {
}
}, [justClickedPublishButton, formHasRendered]);

useEffect(() => {
if (doDispatchAddFormChanged) {
setDoDispatchAddFormChanged(false);
props.dispatchAddFormChanged();
}
}, [doDispatchAddFormChanged]);

const getNoTitle = () => i18n.inject(
i18n._t('ElementHeader.NOTITLE', 'Untitled {type} block'),
{ type: props.type.title }
Expand Down Expand Up @@ -143,18 +135,6 @@ const Element = (props) => {
showPublishedElementToast(wasError);
setDoPublishElement(false);
setDoPublishElementAfterSave(false);
// Ensure that formDirty becomes falsey after publishing
// We need to call at a later render rather than straight away or redux-form may override this
// and set the form state to dirty under certain conditions
// setTimeout is a hackish way to do this, though I'm not sure how else we can do this
// The core issue is that redux-form will detect changes when a form is hydrated for the first
// time under certain conditions, specifically during a behat test when trying to publish a closed
// block when presumably the apollo cache is empty (or something like that). This happens late and
// there are no hooks/callbacks available after this happens the input onchange handlers are fired
Promise.all(refetchElementalArea())
.then(() => {
setTimeout(() => props.dispatchRemoveFormChanged(), 250);
});
};

// Save action
Expand Down Expand Up @@ -337,10 +317,6 @@ const Element = (props) => {
if (props.type.inlineEditable) {
setPreviewExpanded(true);
}
// Ensure that formDirty remains truthy
// Note we need to call props.dispatchAddFormChanged() on the next render rather than straight away
// or it will get unset by code somewhere else, probably redux-form
setDoDispatchAddFormChanged(true);
// Don't accidentally auto publish the element once validation errors are fixed
if (doPublishElementAfterSave) {
setDoPublishElementAfterSave(false);
Expand Down Expand Up @@ -435,6 +411,7 @@ const Element = (props) => {
broken={type.broken}
onFormSchemaSubmitResponse={handleFormSchemaSubmitResponse}
onFormInit={() => handleFormInit(activeTab)}
formDirty={formDirty}
/>
</ElementContext.Provider>
</div>);
Expand Down Expand Up @@ -462,7 +439,10 @@ function mapStateToProps(state, ownProps) {

const tabSetName = tabSet && tabSet.id;
const uniqueFieldId = `element.${elementName}__${tabSetName}`;
const formDirty = state.unsavedForms.find((unsaved) => unsaved.name === `element.${elementName}`);
// const formDirty = state.unsavedForms.find((unsaved) => unsaved.name === `element.${elementName}`);

const formName = loadElementFormStateName(ownProps.element.id);
const formDirty = isDirty(`element.${formName}`, getFormState)(state);

// Find name of the active tab in the tab set
// Only defined once an element form is expanded for the first time
Expand Down Expand Up @@ -490,16 +470,6 @@ function mapDispatchToProps(dispatch, ownProps) {
// Perform a redux-form remote-submit
dispatch(submit(`element.${elementName}`));
},
dispatchAddFormChanged() {
// Ensures the form identifier is in unsavedForms in the global redux state
// This is used to derive the formDirty prop in mapStateToProps
dispatch(addFormChanged(`element.${elementName}`));
},
dispatchRemoveFormChanged() {
// Removes the form identifier from unsavedForms in the global redux store
// Opposite of beheaviour of dispatchAddFormChanged()
dispatch(removeFormChanged(`element.${elementName}`));
},
actions: {
toasts: bindActionCreators(toastsActions, dispatch),
},
Expand Down
8 changes: 8 additions & 0 deletions client/src/components/ElementEditor/ElementEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class ElementEditor extends PureComponent {

render() {
const {
fieldName,
formState,
ToolbarComponent,
ListComponent,
areaId,
Expand Down Expand Up @@ -104,6 +106,12 @@ class ElementEditor extends PureComponent {
sharedObject={sharedObject}
/>
<ElementDragPreview elementTypes={elementTypes} />
<input
name={fieldName}
type="hidden"
value={JSON.stringify(formState) || ''}
className="no-change-track"
/>
</div>
);
}
Expand Down

0 comments on commit 4b960ce

Please sign in to comment.