diff --git a/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/FromApiUtils.java b/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/FromApiUtils.java index 4b5ba60a2..c1c8569ae 100644 --- a/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/FromApiUtils.java +++ b/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/FromApiUtils.java @@ -503,7 +503,12 @@ private static ValueDisplayField buildRelationshipField( public static Literal fromApiObject(ApiLiteral apiLiteral) { return switch (apiLiteral.getDataType()) { - case INT64 -> Literal.forInt64(apiLiteral.getValueUnion().getInt64Val()); + // JavaScript can't handle the full int64 range when parsing JSON, so parse them as strings. + case INT64 -> + Literal.forInt64( + apiLiteral.getValueUnion().getInt64Val() != null + ? Long.parseLong(apiLiteral.getValueUnion().getInt64Val()) + : null); case STRING -> Literal.forString(apiLiteral.getValueUnion().getStringVal()); case BOOLEAN -> Literal.forBoolean(apiLiteral.getValueUnion().isBoolVal()); case DATE -> Literal.forDate(apiLiteral.getValueUnion().getDateVal()); diff --git a/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/ToApiUtils.java b/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/ToApiUtils.java index 3f254f1c8..b2a20a4cb 100644 --- a/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/ToApiUtils.java +++ b/service/src/main/java/bio/terra/tanagra/app/controller/objmapping/ToApiUtils.java @@ -90,7 +90,10 @@ public static ApiLiteral toApiObject(Literal literal) { new ApiLiteral().dataType(ApiDataType.fromValue(literal.getDataType().name())); return switch (literal.getDataType()) { case INT64 -> - apiLiteral.valueUnion(new ApiLiteralValueUnion().int64Val(literal.getInt64Val())); + // JavaScript can't handle the full int64 range when parsing JSON, so send them as + // strings. + apiLiteral.valueUnion( + new ApiLiteralValueUnion().int64Val(literal.getInt64Val().toString())); case STRING -> apiLiteral.valueUnion(new ApiLiteralValueUnion().stringVal(literal.getStringVal())); case BOOLEAN -> diff --git a/service/src/main/resources/api/service_openapi.yaml b/service/src/main/resources/api/service_openapi.yaml index 0a791ecbc..909e9711f 100644 --- a/service/src/main/resources/api/service_openapi.yaml +++ b/service/src/main/resources/api/service_openapi.yaml @@ -1522,8 +1522,8 @@ components: boolVal: type: boolean int64Val: - type: integer - format: int64 + # Transfer int64s as strings to avoid overflowing JavaScript's number precision. + type: string stringVal: type: string dateVal: diff --git a/ui/codegen.sh b/ui/codegen.sh index 87c4bb256..f4b162c38 100755 --- a/ui/codegen.sh +++ b/ui/codegen.sh @@ -7,4 +7,4 @@ openapi-generator-cli generate -i ../service/src/main/resources/api/service_open # Generate plugin proto code. rm -rf src/proto mkdir src/proto -npx protoc --proto_path=../underlay/src/main/proto/ --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/proto/ --ts_proto_opt=esModuleInterop=true --ts_proto_opt=outputClientImpl=false ../underlay/src/main/proto/criteriaselector/dataschema/*.proto ../underlay/src/main/proto/criteriaselector/configschema/*.proto ../underlay/src/main/proto/viz/*.proto +npx protoc --proto_path=../underlay/src/main/proto/ --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/proto/ --ts_proto_opt=esModuleInterop=true --ts_proto_opt=outputClientImpl=false --ts_proto_opt=forceLong=bigint ../underlay/src/main/proto/criteriaselector/dataschema/*.proto ../underlay/src/main/proto/criteriaselector/configschema/*.proto ../underlay/src/main/proto/viz/*.proto diff --git a/ui/src/addByCode.tsx b/ui/src/addByCode.tsx index 1ba25c85c..54ff37858 100644 --- a/ui/src/addByCode.tsx +++ b/ui/src/addByCode.tsx @@ -204,7 +204,7 @@ export function AddByCode() { return undefined; } - const item = data[id]?.data as LookupEntryItem; + const item = data.get(id)?.data as LookupEntryItem; if (!item) { return undefined; } diff --git a/ui/src/addCohort.tsx b/ui/src/addCohort.tsx index d6350fea8..40dc87749 100644 --- a/ui/src/addCohort.tsx +++ b/ui/src/addCohort.tsx @@ -117,7 +117,7 @@ export function AddCohort() { return undefined; } - const cohortData = data[id].data as CohortData; + const cohortData = data.get(id)?.data as CohortData; if (!cohortData) { return undefined; } diff --git a/ui/src/addCriteria.tsx b/ui/src/addCriteria.tsx index a2fe0c468..0bb903992 100644 --- a/ui/src/addCriteria.tsx +++ b/ui/src/addCriteria.tsx @@ -21,7 +21,6 @@ import Loading from "components/loading"; import { Search } from "components/search"; import { TreeGrid, - TreeGridData, TreeGridId, TreeGridItem, TreeGridRowData, @@ -353,9 +352,9 @@ function AddCriteria(props: AddCriteriaProps) { const search = useCallback(async () => { const children: DataKey[] = []; - const data: TreeGridData = { - root: { data: {}, children }, - }; + const data = new Map([ + ["root", { data: {}, children }], + ]); if (query) { const res = await searchCriteria( @@ -377,13 +376,13 @@ function AddCriteria(props: AddCriteriaProps) { }, entry: entry, }; - data[key] = item; + data.set(key, item); }); } return data; }, [underlaySource, query, selectedOptions, optionsMap]); - const searchState = useSWRImmutable( + const searchState = useSWRImmutable>( { component: "AddCriteria", underlayName: underlay.name, @@ -523,7 +522,7 @@ function AddCriteria(props: AddCriteriaProps) { {!!query ? ( - {!searchState.data?.root?.children?.length ? ( + {!searchState.data?.get("root")?.children?.length ? (