Skip to content

Commit

Permalink
Embedded Object support. (#1298)
Browse files Browse the repository at this point in the history
* POC JSON value in table view

* Ensure first selected schema is not system schema or embeded.

* Filtering out embedded object classes & disallowing creation in GUI.

* LeftSidebar sees embedded objects as SystemClass.

* Disable 'Update reference' in context menu when embedded object.

* Temporarily disable creation of embedded objects with custom message.

* isEmbeddedType continued

* Disable double click on objects cells contain embedded object

* Disable "Add existing ClassName" from context menu, in embedded objects list.

* Spelling

* PR suggestions (simplified const & check back in-line)
  • Loading branch information
steffenagger authored and Kræn Hansen committed Jun 4, 2020
1 parent b98247f commit 6033d2c
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ dist/
node_modules/
realm-object-server/
.idea

.vscode
.DS_Store
data/

Expand Down
2 changes: 2 additions & 0 deletions src/ui/RealmBrowser/Content/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { TopBar } from './TopBar';
interface IBaseContentProps {
contentRef: (element: HTMLElement | null) => void;
dataVersion?: number;
allowCreate: boolean;
editMode: EditMode;
error?: Error;
filteredSortedResults: Realm.Collection<any>;
Expand Down Expand Up @@ -146,6 +147,7 @@ export const Content = ({
query={query}
queryError={queryError}
readOnly={props.readOnly}
allowCreate={props.allowCreate}
/>

<div className="RealmBrowser__TableContainer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface IOpenCreateObjectDialogProps
getClassFocus: (className: string) => IClassFocus;
isOpen: true;
schema: Realm.ObjectSchema;
isEmbeddedType: (className: string) => boolean;
}

export type ICreateObjectDialogProps =
Expand Down Expand Up @@ -76,6 +77,7 @@ export const CreateObjectDialog = ({
}
propertyName={propertyName}
value={values[propertyName]}
isEmbeddedType={props.isEmbeddedType}
/>
))
: null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface IPropertyRowProps {
property: Realm.ObjectSchemaProperty;
propertyName: string;
value: any;
isEmbeddedType: (className: string) => boolean;
}

export const PropertyRow = ({
Expand All @@ -42,6 +43,7 @@ export const PropertyRow = ({
property,
propertyName,
value,
isEmbeddedType,
}: IPropertyRowProps) => (
<FormGroup className="CreateObjectDialog__PropertyRow">
<Label
Expand All @@ -61,6 +63,7 @@ export const PropertyRow = ({
onChange={onValueChange}
property={property}
value={value}
isEmbeddedType={isEmbeddedType}
/>
</FormGroup>
);
5 changes: 5 additions & 0 deletions src/ui/RealmBrowser/Content/CreateObjectDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ interface IOpenCreateObjectDialogContainerProps {
onCancel: () => void;
onCreate: CreateObjectHandler;
schema: Realm.ObjectSchema;
isEmbeddedType: (className: string) => boolean;
}

export interface ICreateObjectDialogContainerState {
Expand Down Expand Up @@ -161,6 +162,7 @@ class CreateObjectDialogContainer extends React.PureComponent<
onCreate: this.onCreate,
onValueChange: this.onValueChange,
values: this.state.values,
isEmbeddedType: this.isEmbeddedType,
};
if (this.props.isOpen) {
return {
Expand Down Expand Up @@ -196,6 +198,9 @@ class CreateObjectDialogContainer extends React.PureComponent<
}
};

protected isEmbeddedType = (className: string) =>
this.props.isOpen && this.props.isEmbeddedType(className);

protected onValueChange = (propertyName: string, value: any) => {
this.setState({
values: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ import Realm from 'realm';

export interface IDefaultControlProps {
property: Realm.ObjectSchemaProperty;
message?: string;
}

export const DefaultControl = ({ property }: IDefaultControlProps) => (
<Alert color="warning">Cannot select "{property.type}" yet</Alert>
export const DefaultControl = ({ property, message }: IDefaultControlProps) => (
<Alert color="warning">
{message ?? `Cannot select "${property.type}" yet`}
</Alert>
);
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ import { ITypeControlProps, TypeControl } from './TypeControl';
interface IItemProps
extends Pick<
ITypeControlProps,
'generateInitialValue' | 'getClassFocus' | 'onChange' | 'value' | 'property'
| 'generateInitialValue'
| 'getClassFocus'
| 'onChange'
| 'value'
| 'property'
| 'isEmbeddedType'
> {
onDelete: () => void;
}
Expand All @@ -40,6 +45,7 @@ const Item = ({
onChange,
onDelete,
value,
isEmbeddedType,
}: IItemProps) => (
<section className="CreateObjectDialog__ListControl__Item">
<TypeControl
Expand All @@ -48,6 +54,7 @@ const Item = ({
onChange={onChange}
property={property}
value={value}
isEmbeddedType={isEmbeddedType}
>
<InputGroupAddon addonType="append">
<Button onClick={onDelete} size="sm">
Expand All @@ -63,7 +70,11 @@ const Item = ({
interface IListProps
extends Pick<
ITypeControlProps,
'generateInitialValue' | 'getClassFocus' | 'onChange' | 'value'
| 'generateInitialValue'
| 'getClassFocus'
| 'onChange'
| 'value'
| 'isEmbeddedType'
> {
itemProperty: Realm.ObjectSchemaProperty;
}
Expand All @@ -74,6 +85,7 @@ const List = ({
itemProperty,
onChange,
value,
isEmbeddedType,
}: IListProps) => (
<section className="CreateObjectDialog__ListControl__Items">
{Array.isArray(value) ? (
Expand All @@ -94,6 +106,7 @@ const List = ({
}}
property={itemProperty}
value={value[index]}
isEmbeddedType={isEmbeddedType}
/>
))
) : (
Expand Down Expand Up @@ -129,6 +142,7 @@ export const ListControl = ({
onChange,
property,
value,
isEmbeddedType,
}: ITypeControlProps): React.ReactElement<ITypeControlProps> => {
if (!property.objectType) {
return <Alert color="danger">Expected an objectType</Alert>;
Expand All @@ -142,6 +156,7 @@ export const ListControl = ({
itemProperty={itemProperty}
onChange={onChange}
value={value}
isEmbeddedType={isEmbeddedType}
/>
<section className="CreateObjectDialog__ListControl__Buttons">
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ export interface IOpenSelectObjectDialog {
isOptional: boolean;
onCancel: () => void;
onSelect: (object: any) => void;
isEmbeddedType: (className: string) => boolean;
}

export type ISelectObjectDialog = IOpenSelectObjectDialog | { isOpen: false };

export interface IObjectControlContainerProps extends IBaseControlProps {
getClassFocus: (className: string) => IClassFocus;
isEmbeddedType: (className: string) => boolean;
}

export interface IObjectControlContainerState {
Expand Down Expand Up @@ -84,6 +86,7 @@ class ObjectControlContainer extends React.Component<
isOptional: this.props.property.optional || false,
onCancel: this.onCancelSelectObjectDialog,
onSelect: this.updateObjectReference,
isEmbeddedType: this.props.isEmbeddedType,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface IBaseControlProps<ValueType = any> {
export interface ITypeControlProps extends IBaseControlProps {
generateInitialValue: (property: Realm.ObjectSchemaProperty) => any;
getClassFocus: (className: string) => IClassFocus;
isEmbeddedType: (className: string) => boolean;
}

export const TypeControl = ({
Expand All @@ -52,6 +53,7 @@ export const TypeControl = ({
onChange,
property,
value,
isEmbeddedType,
}: ITypeControlProps) => {
if (property.type === 'object id') {
return (
Expand Down Expand Up @@ -121,13 +123,24 @@ export const TypeControl = ({
/>
);
} else if (property.type === 'object') {
// TODO: implement
if (isEmbeddedType(property.objectType!)) {
return (
<DefaultControl
property={property}
message="Creation of embedded objects is not yet supported"
/>
);
}

return (
<ObjectControl
children={children}
getClassFocus={getClassFocus}
onChange={onChange}
property={property}
value={value as object}
isEmbeddedType={isEmbeddedType}
/>
);
} else if (property.type === 'list') {
Expand All @@ -139,6 +152,7 @@ export const TypeControl = ({
onChange={onChange}
property={property}
value={value as any[]}
isEmbeddedType={isEmbeddedType}
/>
);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface IOpenSelectObjectDialogProps extends IBaseSelectObjectDialogProps {
collection: Realm.Collection<any>,
) => void;
multiple: boolean;
isEmbeddedType: (className: string) => boolean;
}

export type ISelectObjectDialogProps =
Expand All @@ -69,13 +70,15 @@ export const SelectObjectDialog = ({
{props.isOpen ? (
<Content
editMode={EditMode.Disabled}
allowCreate={false}
highlightMode={
props.multiple ? HighlightMode.Multiple : HighlightMode.Single
}
focus={props.focus}
onHighlightChange={props.onHighlightChange}
readOnly={true}
ref={props.contentRef}
isEmbeddedType={props.isEmbeddedType}
/>
) : null}
</ModalBody>
Expand Down
2 changes: 2 additions & 0 deletions src/ui/RealmBrowser/Content/SelectObjectDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface IOpenSelectObjectDialogContainerProps {
isOptional: boolean;
multiple: boolean;
onCancel: () => void;
isEmbeddedType: (className: string) => boolean;
}

export interface IOpenSelectSingleObjectDialogContainerProps
Expand Down Expand Up @@ -91,6 +92,7 @@ export class SelectObjectDialogContainer extends React.Component<
contentRef: this.contentRef,
selection: this.state.selection,
multiple: this.props.multiple,
isEmbeddedType: this.props.isEmbeddedType,
};
} else {
return {
Expand Down
4 changes: 3 additions & 1 deletion src/ui/RealmBrowser/Content/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface ITopBarProps {
query: string;
queryError: Error | undefined;
readOnly: boolean;
allowCreate: boolean;
}

export const TopBar = ({
Expand All @@ -42,6 +43,7 @@ export const TopBar = ({
query,
queryError,
readOnly,
allowCreate,
}: ITopBarProps) => {
const className = getClassName(focus);
return (
Expand All @@ -54,7 +56,7 @@ export const TopBar = ({
queryError={queryError}
placeholder="Enter a query to filter the list"
/>
{!readOnly ? (
{allowCreate && !readOnly ? (
<Button
size="sm"
color="secondary"
Expand Down
Loading

0 comments on commit 6033d2c

Please sign in to comment.