diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c90599e0d..ada4828ee 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -10,6 +10,8 @@ - Added support for creating & generating `ObjectId` when creating objects. ([#1291](https://github.com/realm/realm-studio/pull/1291)) - Added support for editing existing `ObjectId` values. ([#1290](https://github.com/realm/realm-studio/pull/1290)) - Primary keys in Class/Schema creation now defaults to an `ObjectId` property named `_id`. +- Added support for creating `Decimal128` when creating objects. ([#1292](https://github.com/realm/realm-studio/pull/1292)) +- Added support for editing existing `Decimal128` values. ([#1292](https://github.com/realm/realm-studio/pull/1292)) ### Fixed diff --git a/src/ui/RealmBrowser/Content/CreateObjectDialog/CreateObjectDialog.scss b/src/ui/RealmBrowser/Content/CreateObjectDialog/CreateObjectDialog.scss index a5a090dd9..09a831065 100644 --- a/src/ui/RealmBrowser/Content/CreateObjectDialog/CreateObjectDialog.scss +++ b/src/ui/RealmBrowser/Content/CreateObjectDialog/CreateObjectDialog.scss @@ -66,6 +66,7 @@ } &__ObjectIdControl, + &__Decimal128Control, &__StringControl, &__DateControl, &__NummericControl { diff --git a/src/ui/RealmBrowser/Content/CreateObjectDialog/index.tsx b/src/ui/RealmBrowser/Content/CreateObjectDialog/index.tsx index 99b975304..01d9d04e3 100644 --- a/src/ui/RealmBrowser/Content/CreateObjectDialog/index.tsx +++ b/src/ui/RealmBrowser/Content/CreateObjectDialog/index.tsx @@ -18,7 +18,7 @@ import React from 'react'; import Realm from 'realm'; -import { ObjectId } from 'bson'; +import { ObjectId, Decimal128 } from 'bson'; import { v4 as uuid } from 'uuid'; import { CreateObjectHandler } from '..'; @@ -108,6 +108,8 @@ class CreateObjectDialogContainer extends React.PureComponent< property.type === 'double' ) { return 0; + } else if (property.type === 'decimal') { + return Decimal128.fromString('0'); } else if (property.type === 'string') { return ''; } else if (property.type === 'bool') { diff --git a/src/ui/RealmBrowser/Content/CreateObjectDialog/types/Decimal128Control.tsx b/src/ui/RealmBrowser/Content/CreateObjectDialog/types/Decimal128Control.tsx new file mode 100644 index 000000000..34878657b --- /dev/null +++ b/src/ui/RealmBrowser/Content/CreateObjectDialog/types/Decimal128Control.tsx @@ -0,0 +1,87 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2020 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +import React from 'react'; +import { Decimal128 } from 'bson'; +import { Button, Input, InputGroup, InputGroupAddon } from 'reactstrap'; + +import { IBaseControlProps } from './TypeControl'; +import { parseDecimal128 } from '../../../parsers'; + +interface IDecimal128ControlState { + internalValue: string | null; +} + +export class Decimal128Control extends React.PureComponent< + IBaseControlProps, + IDecimal128ControlState +> { + state: IDecimal128ControlState = { + internalValue: this.props.value?.toString() ?? null, + }; + + render() { + const { children, property, value } = this.props; + const { internalValue } = this.state; + + return ( + + + {internalValue && property.optional && ( + + + + )} + {children} + + ); + } + + private inputChangeEventHandler = (e: React.ChangeEvent) => + this.changeHandler(e.target.value); + + private handleClearValue = () => this.changeHandler(null); + + private changeHandler = (value: string | null) => { + const { property, onChange } = this.props; + + this.setState({ internalValue: value }); + + let parsedDecimal: Decimal128 | null = null; + + if (value) { + try { + parsedDecimal = parseDecimal128(value, property); + } catch (err) { + // tslint:disable-next-line:no-console + console.warn(err.message); + } + } + + onChange(parsedDecimal); + }; +} diff --git a/src/ui/RealmBrowser/Content/CreateObjectDialog/types/TypeControl.tsx b/src/ui/RealmBrowser/Content/CreateObjectDialog/types/TypeControl.tsx index ea13d9c65..440595372 100644 --- a/src/ui/RealmBrowser/Content/CreateObjectDialog/types/TypeControl.tsx +++ b/src/ui/RealmBrowser/Content/CreateObjectDialog/types/TypeControl.tsx @@ -24,13 +24,14 @@ import { IClassFocus } from '../../../focus'; import { BooleanControl } from './BooleanControl'; import { DataControl } from './DataControl'; import { DateControl } from './DateControl'; +import { Decimal128Control } from './Decimal128Control'; import { DefaultControl } from './DefaultControl'; import { ListControl } from './ListControl'; import { NummericControl } from './NummericControl'; import { ObjectControl } from './ObjectControl'; import { ObjectIdControl } from './ObjectIdControl'; import { StringControl } from './StringControl'; -import { ObjectId } from 'bson'; +import { ObjectId, Decimal128 } from 'bson'; export interface IBaseControlProps { children?: React.ReactNode; @@ -92,6 +93,15 @@ export const TypeControl = ({ onChange={onChange} /> ); + } else if (property.type === 'decimal') { + return ( + + ); } else if (property.type === 'date') { return ( { + if (value === '' && property.optional) { + return null; + } else { + try { + // Note: thousand separators are not supported by Decimal128, so we can help out the user by converting ',' to '.'. + return Decimal128.fromString(value.replace(',', '.')); + } catch (err) { + throw new Error(`"${value}" is not a proper ${property.type}`); + } + } +}; + export const parseNumber = ( value: string, property: Realm.ObjectSchemaProperty, @@ -104,12 +120,12 @@ export const parse = (value: string, property: Realm.ObjectSchemaProperty) => { return parseObjectId(value, property); case 'int': case 'float': - case 'double': { + case 'double': return parseNumber(value, property); - } - case 'bool': { + case 'decimal': + return parseDecimal128(value, property); + case 'bool': return parseBoolean(value, property); - } case 'date': return parseDate(value, property); case 'string': diff --git a/src/ui/RealmBrowser/primitives.ts b/src/ui/RealmBrowser/primitives.ts index ca039075f..5f27e3d24 100644 --- a/src/ui/RealmBrowser/primitives.ts +++ b/src/ui/RealmBrowser/primitives.ts @@ -17,10 +17,12 @@ //////////////////////////////////////////////////////////////////////////// export const TYPES: string[] = [ + 'object id', 'bool', 'int', 'float', 'double', + 'decimal', 'string', 'data', 'date',