Skip to content

Commit 299d56e

Browse files
committed
Fix loading full value of truncated data when editing multi str field (Fixes #302)
1 parent e8b1069 commit 299d56e

File tree

4 files changed

+87
-67
lines changed

4 files changed

+87
-67
lines changed

shared/studio/components/dataEditor/editor.tsx

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useEffect, useRef} from "react";
2-
import {action, makeObservable, observable} from "mobx";
2+
import {action, makeObservable, observable, runInAction} from "mobx";
33

44
import cn from "@edgedb/common/utils/classNames";
55

@@ -33,40 +33,54 @@ export class DataEditorState {
3333
) {
3434
makeObservable(this);
3535

36-
if (isEditorValue) {
37-
this.value = value;
36+
const _init = (_value: any) =>
37+
runInAction(() => {
38+
if (isEditorValue) {
39+
this.value = _value;
40+
} else {
41+
this.value =
42+
_value != null
43+
? isMulti
44+
? _value.map((val: any) => valueToEditorValue(val, type))
45+
: valueToEditorValue(_value, type)
46+
: isRequired
47+
? isMulti
48+
? []
49+
: newPrimitiveValue(type)[0]
50+
: null;
51+
}
52+
53+
this.hasError =
54+
this.value === null
55+
? false
56+
: isMulti
57+
? (this.value as EditorValue[]).some(
58+
(v: any) => !isEditorValueValid(v, type)
59+
)
60+
: !isEditorValueValid(this.value, type);
61+
62+
this.loaded = true;
63+
});
64+
65+
if (value instanceof Promise) {
66+
value.then((_value) => _init(_value));
3867
} else {
39-
this.value =
40-
value != null
41-
? isMulti
42-
? value.map((val: any) => valueToEditorValue(val, type))
43-
: valueToEditorValue(value, type)
44-
: isRequired
45-
? isMulti
46-
? []
47-
: newPrimitiveValue(type)[0]
48-
: null;
68+
_init(value);
4969
}
50-
51-
this.hasError =
52-
this.value === null
53-
? false
54-
: isMulti
55-
? (this.value as EditorValue[]).some(
56-
(v: any) => !isEditorValueValid(v, type)
57-
)
58-
: !isEditorValueValid(this.value, type);
5970
}
6071

72+
@observable
73+
loaded = false;
74+
6175
isEdited = false;
6276

63-
@observable.ref value: EditorValue | null;
77+
@observable.ref value: EditorValue | null = null;
6478
@action setValue(val: EditorValue | null) {
6579
this.value = val;
6680
this.isEdited = true;
6781
}
6882

69-
@observable hasError: boolean;
83+
@observable hasError: boolean = false;
7084
@action setError(err: boolean) {
7185
this.hasError = err;
7286
}

shared/studio/tabs/dataview/dataInspector.tsx

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,8 @@ const GridCell = observer(function GridCell({
391391
field.type === ObjectFieldType.property &&
392392
edits.activePropertyEdit?.cellId === cellId
393393
) {
394-
return cellEditState?.value === undefined &&
395-
field.schemaType.name === "std::str" &&
396-
typeof value === "string" &&
397-
value.length === 100 &&
398-
!state.fullyFetchedData.has(cellId) ? (
399-
<FetchingDataPlaceholder state={state} data={data} field={field} />
394+
return !edits.activePropertyEdit.loaded ? (
395+
<div className={styles.fetchingDataPlaceholder}>loading...</div>
400396
) : (
401397
<DataEditor state={edits.activePropertyEdit} />
402398
);
@@ -532,14 +528,15 @@ const GridCell = observer(function GridCell({
532528
[styles.hasEdits]:
533529
!isDeletedRow && rowData && (!!cellEditState || !!linkEditState),
534530
[styles.hasErrors]:
535-
(cellEditState && !cellEditState.value.valid) ||
536-
(insertedRow && _value && !_value.valid) ||
537-
(!rowData &&
538-
isEditable &&
539-
field.required &&
540-
!field.hasDefault &&
541-
value === null &&
542-
!linkEditState),
531+
isEditable &&
532+
((cellEditState && !cellEditState.value.valid) ||
533+
(insertedRow && _value && !_value.valid) ||
534+
(!rowData &&
535+
isEditable &&
536+
field.required &&
537+
!field.hasDefault &&
538+
value === null &&
539+
!linkEditState)),
543540
})}
544541
onClick={() => {
545542
if (field.type === ObjectFieldType.link && content !== null) {
@@ -555,11 +552,8 @@ const GridCell = observer(function GridCell({
555552
onDoubleClick={() => {
556553
if (isEditable) {
557554
if (field.type === ObjectFieldType.property) {
558-
edits.startEditingCell(
559-
data.id,
560-
data.__tname__,
561-
field,
562-
state.fullyFetchedData.get(cellId) ?? value
555+
edits.startEditingCell(data.id, data.__tname__, field, () =>
556+
state.fetchFullCellData(data.id, value, field)
563557
);
564558
} else {
565559
state.openNestedView(
@@ -579,22 +573,6 @@ const GridCell = observer(function GridCell({
579573
);
580574
});
581575

582-
function FetchingDataPlaceholder({
583-
state,
584-
data,
585-
field,
586-
}: {
587-
state: DataInspectorState;
588-
data: any;
589-
field: ObjectField;
590-
}) {
591-
useEffect(() => {
592-
state.fetchFullCellData(data.id, field);
593-
}, []);
594-
595-
return <div className={styles.fetchingDataPlaceholder}>loading...</div>;
596-
}
597-
598576
const FieldHeaders = observer(function FieldHeaders() {
599577
const {state} = useDataInspectorState();
600578
const isMobile = useIsMobile();

shared/studio/tabs/dataview/state/edits.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class DataEditingManager extends Model({}) {
106106
objectId: string | number,
107107
objectTypeName: string,
108108
field: ObjectPropertyField,
109-
value: any
109+
valueGetter: () => any
110110
) {
111111
const cellId = `${objectId}__${field.name}`;
112112

@@ -117,7 +117,7 @@ export class DataEditingManager extends Model({}) {
117117
field.schemaType as PrimitiveType,
118118
field.required,
119119
field.multi,
120-
editValue?.value ?? value,
120+
editValue ? editValue.value : valueGetter(),
121121
editValue != null && !editValue.valid,
122122
(discard) => {
123123
if (!discard && state.isEdited) {

shared/studio/tabs/dataview/state/index.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -788,16 +788,44 @@ export class DataInspector extends Model({
788788
@observable.shallow
789789
fullyFetchedData = new Map<string, any>();
790790

791-
async fetchFullCellData(dataId: string, field: ObjectField) {
791+
fetchFullCellData(
792+
dataId: string | number,
793+
value: any,
794+
field: ObjectPropertyField
795+
) {
796+
if (typeof dataId !== "string") {
797+
return value;
798+
}
799+
800+
const cellId = `${dataId}__${field.name}`;
801+
802+
if (this.fullyFetchedData.has(cellId)) {
803+
return this.fullyFetchedData.get(cellId);
804+
}
805+
806+
const isTruncated =
807+
field.schemaType.name === "std::str" &&
808+
(field.multi
809+
? Array.isArray(value) &&
810+
typeof value[0] === "string" &&
811+
value.some((val) => val.length === 100)
812+
: typeof value === "string" && value.length === 100);
813+
814+
if (!isTruncated) {
815+
return value;
816+
}
817+
792818
const query = `select (select ${
793819
field.escapedSubtypeName ?? this._getObjectTypeQuery
794820
} filter .id = <uuid>$id).${field.escapedName}`;
795-
const conn = connCtx.get(this)!;
796821

797-
const val = (await conn.query(query, {id: dataId})).result![0];
798-
799-
runInAction(() => {
800-
this.fullyFetchedData.set(`${dataId}__${field.name}`, val);
822+
const conn = connCtx.get(this)!;
823+
return conn.query(query, {id: dataId}).then(({result}) => {
824+
const val = field.multi ? result! : result![0];
825+
runInAction(() => {
826+
this.fullyFetchedData.set(cellId, val);
827+
});
828+
return val;
801829
});
802830
}
803831

0 commit comments

Comments
 (0)