Skip to content

Commit 4d5f333

Browse files
authored
fix: try and preserve Double and Long/Int64 types in the json editor COMPASS-8337 (#7119)
try and preserve Double and Long/Int64 types in the json editor
1 parent f7775a5 commit 4d5f333

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

packages/compass-crud/src/components/json-editor.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ const JSONEditor: React.FunctionComponent<JSONEditorProps> = ({
136136
}, []);
137137

138138
const onUpdate = useCallback(() => {
139-
doc.apply(HadronDocument.FromEJSON(value || ''));
139+
const newDoc = HadronDocument.FromEJSON(value || '');
140+
newDoc.preserveTypes(doc);
141+
doc.apply(newDoc);
140142
void replaceDocument?.(doc);
141143
}, [doc, replaceDocument, value]);
142144

packages/hadron-document/src/document.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,20 @@ export class Document extends EventEmitter<
9797
}
9898
}
9999

100+
preserveTypes(other: Document): void {
101+
const thisDoc = this.generateObject();
102+
103+
for (const key of Object.keys(thisDoc)) {
104+
const thisElement = this.get(key);
105+
const otherElement = other.get(key);
106+
if (!thisElement || !otherElement) {
107+
continue;
108+
}
109+
110+
thisElement.preserveType(otherElement);
111+
}
112+
}
113+
100114
/**
101115
* Generate the javascript object for this document.
102116
*

packages/hadron-document/src/element.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,46 @@ export class Element extends EventEmitter {
194194
this.currentValue = value;
195195
this.elements = undefined;
196196
} else {
197+
// if they are both integer types and equal if made the previous type, don't update.
197198
this.currentValue = value;
198199
}
199200
this.setValid();
200201
this._bubbleUp(ElementEvents.Edited, this);
201202
}
202203

204+
preserveType(otherElement: Element): void {
205+
switch (this.currentType) {
206+
case 'Object': {
207+
if (!this.elements) {
208+
return;
209+
}
210+
for (const child of this.elements) {
211+
const otherChild = otherElement.get(child.currentKey);
212+
if (!otherChild) {
213+
continue;
214+
}
215+
child.preserveType(otherChild);
216+
}
217+
break;
218+
}
219+
case 'Int32': {
220+
const otherType = otherElement.currentType;
221+
if (otherType === 'Double') {
222+
this.changeType('Double');
223+
}
224+
if (otherType === 'Int64') {
225+
this.changeType('Int64');
226+
}
227+
break;
228+
}
229+
default:
230+
// NOTE: Purposefully leaving Array elements alone because deciding
231+
// whether to turn on Int32 into a Double or Int64 or not is complex and
232+
// error-prone. Also leaving every other type alone.
233+
break;
234+
}
235+
}
236+
203237
changeType(newType: TypeCastTypes): void {
204238
if (newType === 'Object') {
205239
this._convertToEmptyObject();

packages/hadron-document/test/document.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,72 @@ describe('Document', function () {
23922392
);
23932393
});
23942394
});
2395+
2396+
describe('#preserveTypes', function () {
2397+
it('keeps unnecessary double type', function () {
2398+
const oldDoc = new Document({
2399+
number: new Double(1),
2400+
different: new Double(1),
2401+
sameArray: [new Double(1), new Double(2)],
2402+
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
2403+
object: {
2404+
number: new Double(1),
2405+
different: new Double(1),
2406+
},
2407+
});
2408+
const newDoc = new Document({
2409+
number: new Double(2),
2410+
different: new Long(1),
2411+
sameArray: [new Int32(1), new Double(2.2)],
2412+
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
2413+
object: {
2414+
number: new Int32(1),
2415+
different: new Long(3),
2416+
},
2417+
});
2418+
2419+
newDoc.preserveTypes(oldDoc);
2420+
2421+
expect(newDoc.get('number')?.currentType).to.equal('Double');
2422+
expect(newDoc.get('different')?.currentType).to.equal('Int64');
2423+
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
2424+
'Double'
2425+
);
2426+
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
2427+
'Int64'
2428+
);
2429+
});
2430+
2431+
it('keeps unnecessary long type', function () {
2432+
const oldDoc = new Document({
2433+
number: new Long(1),
2434+
different: new Long(1),
2435+
object: {
2436+
number: new Long(1),
2437+
different: new Long(1),
2438+
},
2439+
});
2440+
const newDoc = new Document({
2441+
number: new Int32(2),
2442+
different: new Double(1),
2443+
object: {
2444+
number: new Int32(1),
2445+
different: new Double(3),
2446+
},
2447+
});
2448+
2449+
newDoc.preserveTypes(oldDoc);
2450+
2451+
expect(newDoc.get('number')?.currentType).to.equal('Int64');
2452+
expect(newDoc.get('different')?.currentType).to.equal('Double');
2453+
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
2454+
'Int64'
2455+
);
2456+
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
2457+
'Double'
2458+
);
2459+
});
2460+
});
23952461
});
23962462

23972463
context('when a document is expanded/collapsed', function () {

0 commit comments

Comments
 (0)