From d6a63c23120e823a9bba9bb23ee4fa293f53d37b Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 5 Jul 2026 16:43:09 +1000 Subject: [PATCH] fix: don't emit a Delete op when clearing a field on a new row (#1751) --- src/dashboard/Data/Browser/Browser.react.js | 5 ++-- src/lib/tests/unsetField.test.js | 27 +++++++++++++++++++++ src/lib/unsetField.js | 11 +++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/lib/tests/unsetField.test.js create mode 100644 src/lib/unsetField.js diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index 57dfe57af3..c14ac3ff0c 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -49,6 +49,7 @@ import { ActionTypes as ConfigActionTypes } from 'lib/stores/ConfigStore'; import { getStore } from 'lib/stores/StoreManager'; import stringCompare from 'lib/stringCompare'; import subscribeTo from 'lib/subscribeTo'; +import unsetField from 'lib/unsetField'; import { withRouter } from 'lib/withRouter'; import FilterPreferencesManager from 'lib/FilterPreferencesManager'; import { prefersServerStorage } from 'lib/StoragePreferences'; @@ -1859,14 +1860,14 @@ class Browser extends DashboardView { return; } if (value === undefined) { - obj.unset(attr); + obj = unsetField(obj, attr, isNewObject || isEditCloneObj); } else { obj.set(attr, value); } if (isNewObject) { this.setState({ - isNewObject: obj, + newObject: obj, }); return; } diff --git a/src/lib/tests/unsetField.test.js b/src/lib/tests/unsetField.test.js new file mode 100644 index 0000000000..ec02258bc2 --- /dev/null +++ b/src/lib/tests/unsetField.test.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +jest.dontMock('../unsetField'); + +const unsetField = require('../unsetField').default; +const Parse = require('parse'); + +describe('unsetField', () => { + it('clears a field on an unsaved object without a Delete op', () => { + const obj = new Parse.Object('Test'); + obj.set('username', 'bob'); + obj.set('authData', {}); + const json = unsetField(obj, 'username', true)._getSaveJSON(); + expect(json.username).toBe(undefined); + expect(json.authData).toEqual({}); + }); + + it('keeps the Delete op when unsetting a field on a saved object', () => { + const obj = Parse.Object.fromJSON({ className: 'Test', objectId: 'abc', username: 'bob' }); + expect(unsetField(obj, 'username', false)._getSaveJSON().username).toEqual({ __op: 'Delete' }); + }); +}); diff --git a/src/lib/unsetField.js b/src/lib/unsetField.js new file mode 100644 index 0000000000..81a775cbc1 --- /dev/null +++ b/src/lib/unsetField.js @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +export default function unsetField(obj, attr, isUnsaved) { + obj.unset(attr); + return isUnsaved ? obj.clone() : obj; +}