From e678ac7f21e0c44eaa8ad88577093cdb313e21bb Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Fri, 19 Apr 2019 23:13:17 -0400
Subject: Deleted more old fields and split new stuff into multiple files
---
src/new_fields/util.ts | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 src/new_fields/util.ts
(limited to 'src/new_fields/util.ts')
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
new file mode 100644
index 000000000..0f08ecf03
--- /dev/null
+++ b/src/new_fields/util.ts
@@ -0,0 +1,73 @@
+import { UndoManager } from "../client/util/UndoManager";
+import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
+import { SerializationHelper } from "../client/util/SerializationHelper";
+import { ProxyField } from "./Proxy";
+
+export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+ if (SerializationHelper.IsSerializing()) {
+ target[prop] = value;
+ return true;
+ }
+ if (typeof prop === "symbol") {
+ target[prop] = value;
+ return true;
+ }
+ const curValue = target.__fields[prop];
+ if (curValue === value || (curValue instanceof ProxyField && value instanceof RefField && curValue.fieldId === value[Id])) {
+ // TODO This kind of checks correctly in the case that curValue is a ProxyField and value is a RefField, but technically
+ // curValue should get filled in with value if it isn't already filled in, in case we fetched the referenced field some other way
+ return true;
+ }
+ if (value instanceof RefField) {
+ value = new ProxyField(value);
+ }
+ if (value instanceof ObjectField) {
+ if (value[Parent] && value[Parent] !== target) {
+ throw new Error("Can't put the same object in multiple documents at the same time");
+ }
+ value[Parent] = target;
+ value[OnUpdate] = (diff?: any) => {
+ if (!diff) diff = SerializationHelper.Serialize(value);
+ target[Update]({ [prop]: diff });
+ };
+ }
+ if (curValue instanceof ObjectField) {
+ delete curValue[Parent];
+ delete curValue[OnUpdate];
+ }
+ target.__fields[prop] = value;
+ target[Update]({ ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) });
+ UndoManager.AddEvent({
+ redo: () => receiver[prop] = value,
+ undo: () => receiver[prop] = curValue
+ });
+ return true;
+}
+
+export function getter(target: any, prop: string | symbol | number, receiver: any): any {
+ if (typeof prop === "symbol") {
+ return target.__fields[prop] || target[prop];
+ }
+ if (SerializationHelper.IsSerializing()) {
+ return target[prop];
+ }
+ return getField(target, prop, receiver);
+}
+
+export function getField(target: any, prop: string | number, ignoreProto: boolean = false, callback?: (field: Field | undefined) => void): any {
+ const field = target.__fields[prop];
+ if (field instanceof ProxyField) {
+ return field.value(callback);
+ }
+ if (field === undefined && !ignoreProto) {
+ const proto = getField(target, "prototype", true);
+ if (proto instanceof Doc) {
+ let field = proto[prop];
+ callback && callback(field === null ? undefined : field);
+ return field;
+ }
+ }
+ callback && callback(field);
+ return field;
+
+}
--
cgit v1.2.3-70-g09d2
From 8ddec1c70c01b3d7d919908299e1168b75698dc7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sat, 20 Apr 2019 19:06:28 -0400
Subject: More refactoring
---
.../views/collections/CollectionDockingView.tsx | 65 +++++++++++-----------
src/new_fields/Doc.ts | 13 +++--
src/new_fields/List.ts | 2 +-
src/new_fields/Proxy.ts | 20 +++----
src/new_fields/Types.ts | 2 -
src/new_fields/URLField.ts | 12 ++--
src/new_fields/util.ts | 4 +-
7 files changed, 59 insertions(+), 59 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e4c647635..b6c87231f 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -4,11 +4,8 @@ import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import { action, observable, reaction, trace } from "mobx";
import { observer } from "mobx-react";
import * as ReactDOM from 'react-dom';
-import { Document } from "../../../fields/Document";
-import { KeyStore } from "../../../fields/KeyStore";
import Measure from "react-measure";
-import { FieldId, Opt, Field, FieldWaiting } from "../../../fields/Field";
-import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne } from "../../../Utils";
+import { Utils, returnTrue, emptyFunction, returnOne } from "../../../Utils";
import { Server } from "../../Server";
import { undoBatch } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
@@ -17,20 +14,22 @@ import React = require("react");
import { SubCollectionViewProps } from "./CollectionSubView";
import { ServerUtils } from "../../../server/ServerUtil";
import { DragManager, DragLinksAsDocuments } from "../../util/DragManager";
-import { TextField } from "../../../fields/TextField";
-import { ListField } from "../../../fields/ListField";
-import { Transform } from '../../util/Transform'
+import { Transform } from '../../util/Transform';
+import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc";
+import { Cast, FieldValue } from "../../../new_fields/Types";
+import { List } from "../../../new_fields/List";
+import { DocServer } from "../../DocServer";
@observer
export class CollectionDockingView extends React.Component {
public static Instance: CollectionDockingView;
- public static makeDocumentConfig(document: Document) {
+ public static makeDocumentConfig(document: Doc) {
return {
type: 'react-component',
component: 'DocumentFrameRenderer',
- title: document.Title,
+ title: document.title,
props: {
- documentId: document.Id,
+ documentId: document[Id],
//collectionDockingView: CollectionDockingView.Instance
}
};
@@ -48,14 +47,14 @@ export class CollectionDockingView extends React.Component
this.AddRightSplit(dragDoc, true).contentItems[0].tab._dragListener.
onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }));
}
@action
- public OpenFullScreen(document: Document) {
+ public OpenFullScreen(document: Doc) {
let newItemStackConfig = {
type: 'stack',
content: [CollectionDockingView.makeDocumentConfig(document)]
@@ -83,7 +82,7 @@ export class CollectionDockingView extends React.Component void = () => {
if (this._containerRef.current) {
reaction(
- () => this.props.Document.GetText(KeyStore.Data, ""),
+ () => Cast(this.props.Document.data, "string", ""),
() => {
if (!this._goldenLayout || this._ignoreStateChange !== JSON.stringify(this._goldenLayout.toConfig())) {
setTimeout(() => this.setupGoldenLayout(), 1);
@@ -203,7 +202,7 @@ export class CollectionDockingView extends React.Component) =>
- (sourceDoc instanceof Document) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
+ (sourceDoc instanceof Doc) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
} else
if ((className === "lm_title" || className === "lm_tab lm_active") && !e.shiftKey) {
e.stopPropagation();
@@ -213,11 +212,11 @@ export class CollectionDockingView extends React.Component) => {
- if (f instanceof Document) {
+ if (f instanceof Doc) {
DragManager.StartDocumentDrag([tab], new DragManager.DocumentDragData([f]), x, y,
{
handlers: {
- dragComplete: action(emptyFunction),
+ dragComplete: emptyFunction,
},
hideSource: false
});
@@ -235,7 +234,7 @@ export class CollectionDockingView extends React.Component {
var json = JSON.stringify(this._goldenLayout.toConfig());
- this.props.Document.SetText(KeyStore.Data, json);
+ this.props.Document.data = json;
}
itemDropped = () => {
@@ -264,10 +263,9 @@ export class CollectionDockingView extends React.Component${count}`);
tab.element.append(counter);
counter.DashDocId = tab.contentItem.config.props.documentId;
- tab.reactionDisposer = reaction(() => [f.GetT(KeyStore.LinkedFromDocs, ListField), f.GetT(KeyStore.LinkedToDocs, ListField)],
- (lists) => {
- let count = (lists.length > 0 && lists[0] && lists[0]!.Data ? lists[0]!.Data.length : 0) +
- (lists.length > 1 && lists[1] && lists[1]!.Data ? lists[1]!.Data.length : 0);
+ tab.reactionDisposer = reaction((): [List | null | undefined, List | null | undefined] => [Cast(f.linkedFromDocs, List), Cast(f.linkedToDocs, List)],
+ ([linkedFrom, linkedTo]) => {
+ let count = (linkedFrom ? linkedFrom.length : 0) + (linkedTo ? linkedTo.length : 0);
counter.innerHTML = count;
});
}));
@@ -319,19 +317,22 @@ export class DockedFrameRenderer extends React.Component {
_mainCont = React.createRef();
@observable private _panelWidth = 0;
@observable private _panelHeight = 0;
- @observable private _document: Opt;
+ @observable private _document: Opt;
constructor(props: any) {
super(props);
- Server.GetField(this.props.documentId, action((f: Opt) => this._document = f as Document));
+ DocServer.GetRefField(this.props.documentId).then(action((f: Opt) => this._document = f as Doc));
}
- nativeWidth = () => this._document!.GetNumber(KeyStore.NativeWidth, this._panelWidth);
- nativeHeight = () => this._document!.GetNumber(KeyStore.NativeHeight, this._panelHeight);
+ nativeWidth = () => Cast(this._document!.nativeWidth, "number", this._panelWidth);
+ nativeHeight = () => Cast(this._document!.nativeHeight, "number", this._panelHeight);
contentScaling = () => {
- let wscale = this._panelWidth / (this.nativeWidth() ? this.nativeWidth() : this._panelWidth);
- if (wscale * this.nativeHeight() > this._panelHeight)
- return this._panelHeight / (this.nativeHeight() ? this.nativeHeight() : this._panelHeight);
+ const nativeH = this.nativeHeight();
+ const nativeW = this.nativeWidth();
+ let wscale = this._panelWidth / nativeW;
+ if (wscale * nativeH > this._panelHeight) {
+ return this._panelHeight / nativeH;
+ }
return wscale;
}
@@ -349,7 +350,7 @@ export class DockedFrameRenderer extends React.Component {
return (
- {
selectOnLoad={false}
parentActive={returnTrue}
whenActiveChanged={emptyFunction}
- focus={emptyDocFunction}
+ focus={emptyFunction}
ContainingCollectionView={undefined} />
);
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index e0eb44ee9..8cbd8cf38 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -6,14 +6,15 @@ import { DocServer } from "../client/DocServer";
import { setter, getter, getField } from "./util";
import { Cast, FieldCtor } from "./Types";
+export type FieldId = string;
export const HandleUpdate = Symbol("HandleUpdate");
export const Id = Symbol("Id");
export abstract class RefField {
@serializable(alias("id", primitive()))
- private __id: string;
- readonly [Id]: string;
+ private __id: FieldId;
+ readonly [Id]: FieldId;
- constructor(id?: string) {
+ constructor(id?: FieldId) {
this.__id = id || Utils.GenerateGuid();
this[Id] = this.__id;
}
@@ -39,7 +40,7 @@ export const Self = Symbol("Self");
@Deserializable("doc").withFields(["id"])
export class Doc extends RefField {
- constructor(id?: string, forceSave?: boolean) {
+ constructor(id?: FieldId, forceSave?: boolean) {
super(id);
const doc = new Proxy(this, {
set: setter,
@@ -53,7 +54,7 @@ export class Doc extends RefField {
return doc;
}
- [key: string]: Field | null | undefined;
+ [key: string]: Field | FieldWaiting | undefined;
@serializable(alias("fields", map(autoObject())))
@observable
@@ -72,7 +73,6 @@ export namespace Doc {
return new Promise(res => getField(self, key, ignoreProto, res));
}
export function GetTAsync(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): Promise {
- const self = doc[Self];
return new Promise(async res => {
const field = await GetAsync(doc, key, ignoreProto);
return Cast(field, ctor);
@@ -90,6 +90,7 @@ export namespace Doc {
return undefined;
}
const delegate = new Doc();
+ //TODO Does this need to be doc[Self]?
delegate.prototype = doc;
return delegate;
}
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index a1a623f83..58b252f7b 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -9,7 +9,7 @@ class ListImpl extends ObjectField {
constructor() {
super();
const list = new Proxy(this, {
- set: function (a, b, c, d) { return setter(a, b, c, d); },
+ set: setter,
get: getter,
deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 3b4b2e452..6a78388c1 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -1,7 +1,8 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { RefField, Id, ObjectField } from "./Doc";
+import { RefField, Id, ObjectField, FieldWaiting } from "./Doc";
import { primitive, serializable } from "serializr";
-import { observable } from "mobx";
+import { observable, action } from "mobx";
+import { DocServer } from "../client/DocServer";
@Deserializable("proxy")
export class ProxyField extends ObjectField {
@@ -32,7 +33,7 @@ export class ProxyField extends ObjectField {
private failed = false;
private promise?: Promise;
- value(callback?: ((field: T | undefined) => void)): T | undefined | null {
+ value(callback?: ((field: T | undefined) => void)): T | undefined | FieldWaiting {
if (this.cache) {
callback && callback(this.cache);
return this.cache;
@@ -41,13 +42,12 @@ export class ProxyField extends ObjectField {
return undefined;
}
if (!this.promise) {
- // this.promise = Server.GetField(this.fieldId).then(action((field: any) => {
- // this.promise = undefined;
- // this.cache = field;
- // if (field === undefined) this.failed = true;
- // return field;
- // }));
- this.promise = new Promise(r => r());
+ this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => {
+ this.promise = undefined;
+ this.cache = field;
+ if (field === undefined) this.failed = true;
+ return field;
+ }));
}
callback && this.promise.then(callback);
return null;
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 6ffb3e02f..0fbd8984c 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -50,8 +50,6 @@ export function Cast>(field: Field | null | undefined
} else if (field instanceof (ctor as any)) {
return field as ToType;
}
- } else {
- return defaultVal;
}
return defaultVal;
}
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index d27a2b692..e456a7d16 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -1,16 +1,16 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable } from "serializr";
+import { serializable, custom } from "serializr";
import { ObjectField } from "./Doc";
function url() {
- return {
- serializer: function (value: URL) {
+ return custom(
+ function (value: URL) {
return value.href;
},
- deserializer: function (jsonValue: string, done: (err: any, val: any) => void) {
- done(undefined, new URL(jsonValue));
+ function (jsonValue: string) {
+ return new URL(jsonValue);
}
- };
+ );
}
@Deserializable("url")
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 0f08ecf03..3806044bd 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -22,6 +22,7 @@ export function setter(target: any, prop: string | symbol | number, value: any,
value = new ProxyField(value);
}
if (value instanceof ObjectField) {
+ //TODO Instead of target, maybe use target[Self]
if (value[Parent] && value[Parent] !== target) {
throw new Error("Can't put the same object in multiple documents at the same time");
}
@@ -51,7 +52,7 @@ export function getter(target: any, prop: string | symbol | number, receiver: an
if (SerializationHelper.IsSerializing()) {
return target[prop];
}
- return getField(target, prop, receiver);
+ return getField(target, prop);
}
export function getField(target: any, prop: string | number, ignoreProto: boolean = false, callback?: (field: Field | undefined) => void): any {
@@ -69,5 +70,4 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
}
callback && callback(field);
return field;
-
}
--
cgit v1.2.3-70-g09d2
From 5ffb2f404a6a3da851c0fe7318b73f5c7723c3d7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Tue, 23 Apr 2019 01:05:12 -0400
Subject: Did most of Documents and some other stuff
---
src/Utils.ts | 19 +-
src/client/documents/Documents.ts | 202 +++++++++------------
src/client/northstar/dash-fields/HistogramField.ts | 2 +-
.../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +-
src/client/views/nodes/DocumentContentsView.tsx | 2 +-
src/new_fields/Doc.ts | 31 +++-
src/new_fields/List.ts | 2 +-
src/new_fields/Types.ts | 2 +-
src/new_fields/util.ts | 12 +-
9 files changed, 139 insertions(+), 135 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/Utils.ts b/src/Utils.ts
index 066d653f5..59ff45dc9 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -86,13 +86,20 @@ export class Utils {
}
}
-export function OmitKeys(obj: any, keys: any, addKeyFunc?: (dup: any) => void) {
+export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void): { omit: any, extract: any } {
+ const omit: any = { ...obj };
+ const extract: any = {};
+ keys.forEach(key => {
+ extract[key] = omit[key];
+ delete omit[key];
+ });
+ addKeyFunc && addKeyFunc(omit);
+ return { omit, extract };
+}
+
+export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
var dup: any = {};
- for (var key in obj) {
- if (keys.indexOf(key) === -1) {
- dup[key] = obj[key];
- }
- }
+ keys.forEach(key => dup[key] = obj[key]);
addKeyFunc && addKeyFunc(dup);
return dup;
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b0bb74d89..a145a76c9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,20 +1,6 @@
-import { AudioField } from "../../fields/AudioField";
-import { Document } from "../../fields/Document";
-import { Field, Opt } from "../../fields/Field";
-import { HtmlField } from "../../fields/HtmlField";
-import { ImageField } from "../../fields/ImageField";
-import { InkField, StrokeData } from "../../fields/InkField";
-import { Key } from "../../fields/Key";
-import { KeyStore } from "../../fields/KeyStore";
-import { ListField } from "../../fields/ListField";
-import { PDFField } from "../../fields/PDFField";
-import { TextField } from "../../fields/TextField";
-import { VideoField } from "../../fields/VideoField";
-import { WebField } from "../../fields/WebField";
import { HistogramField } from "../northstar/dash-fields/HistogramField";
import { HistogramBox } from "../northstar/dash-nodes/HistogramBox";
import { HistogramOperation } from "../northstar/operations/HistogramOperation";
-import { Server } from "../Server";
import { CollectionPDFView } from "../views/collections/CollectionPDFView";
import { CollectionVideoView } from "../views/collections/CollectionVideoView";
import { CollectionView } from "../views/collections/CollectionView";
@@ -34,39 +20,47 @@ import { AttributeTransformationModel } from "../northstar/core/attribute/Attrib
import { AggregateFunction } from "../northstar/model/idea/idea";
import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss";
import { IconBox } from "../views/nodes/IconBox";
-import { IconField } from "../../fields/IconFIeld";
+import { Field, Doc, Opt } from "../../new_fields/Doc";
+import { OmitKeys } from "../../Utils";
+import { ImageField, VideoField, AudioField, PdfField, WebField } from "../../new_fields/URLField";
+import { HtmlField } from "../../new_fields/HtmlField";
+import { List } from "../../new_fields/List";
+import { Cast } from "../../new_fields/Types";
export interface DocumentOptions {
x?: number;
y?: number;
- ink?: Map;
+ // ink?: Map;
width?: number;
height?: number;
nativeWidth?: number;
nativeHeight?: number;
title?: string;
- panx?: number;
- pany?: number;
+ panX?: number;
+ panY?: number;
page?: number;
scale?: number;
layout?: string;
- layoutKeys?: Key[];
viewType?: number;
backgroundColor?: string;
copyDraggedItems?: boolean;
+ backgroundLayout?: string;
+ curPage?: number;
+ // [key: string]: Opt;
}
+const delegateKeys = ["x", "y", "width", "height", "panX", "panY"];
-export namespace Documents {
- let textProto: Document;
- let histoProto: Document;
- let imageProto: Document;
- let webProto: Document;
- let collProto: Document;
- let kvpProto: Document;
- let videoProto: Document;
- let audioProto: Document;
- let pdfProto: Document;
- let iconProto: Document;
+export namespace Docs {
+ let textProto: Doc;
+ let histoProto: Doc;
+ let imageProto: Doc;
+ let webProto: Doc;
+ let collProto: Doc;
+ let kvpProto: Doc;
+ let videoProto: Doc;
+ let audioProto: Doc;
+ let pdfProto: Doc;
+ let iconProto: Doc;
const textProtoId = "textProto";
const histoProtoId = "histoProto";
const pdfProtoId = "pdfProto";
@@ -92,110 +86,80 @@ export namespace Documents {
iconProto = fields[iconProtoId] as Document || CreateIconPrototype();
});
}
- function assignOptions(doc: Document, options: DocumentOptions): Document {
- if (options.nativeWidth !== undefined) { doc.SetNumber(KeyStore.NativeWidth, options.nativeWidth); }
- if (options.nativeHeight !== undefined) { doc.SetNumber(KeyStore.NativeHeight, options.nativeHeight); }
- if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); }
- if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
- if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
- if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
- if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
- if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
- if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
- if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
- if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
- if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
- if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); }
- return doc;
- }
- function assignToDelegate(doc: Document, options: DocumentOptions): Document {
- if (options.x !== undefined) { doc.SetNumber(KeyStore.X, options.x); }
- if (options.y !== undefined) { doc.SetNumber(KeyStore.Y, options.y); }
- if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
- if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
- if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); }
- if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); }
- return doc;
+ function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Doc {
+ return Doc.assign(new Doc(protoId, true), { ...options, title: title, layout: layout });
}
-
- function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document {
- return assignOptions(new Document(protoId), { ...options, title: title, layout: layout });
+ function SetInstanceOptions(doc: Doc, options: DocumentOptions, value: U) {
+ const deleg = Doc.MakeDelegate(doc);
+ deleg.data = value;
+ return Doc.assign(deleg, options);
}
- function SetInstanceOptions(doc: Document, options: DocumentOptions, value: [T, { new(): U }] | Document, id?: string) {
- var deleg = doc.MakeDelegate(id);
- if (value instanceof Document) {
- deleg.Set(KeyStore.Data, value);
- }
- else {
- deleg.SetData(KeyStore.Data, value[0], value[1]);
- }
- return assignOptions(deleg, options);
+ function SetDelegateOptions(doc: Doc, options: DocumentOptions) {
+ const deleg = Doc.MakeDelegate(doc);
+ return Doc.assign(deleg, options);
}
- function CreateImagePrototype(): Document {
+ function CreateImagePrototype(): Doc {
let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString());
- imageProto.SetNumber(KeyStore.CurPage, 0);
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0 });
return imageProto;
}
- function CreateHistogramPrototype(): Document {
+ function CreateHistogramPrototype(): Doc {
let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString());
+ { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString() });
return histoProto;
}
- function CreateIconPrototype(): Document {
+ function CreateIconPrototype(): Doc {
let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(),
- { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE) });
return iconProto;
}
- function CreateTextPrototype(): Document {
+ function CreateTextPrototype(): Doc {
let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return textProto;
}
- function CreatePdfPrototype(): Document {
+ function CreatePdfPrototype(): Doc {
let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
- pdfProto.SetNumber(KeyStore.CurPage, 1);
- pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString());
+ { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 });
return pdfProto;
}
- function CreateWebPrototype(): Document {
+ function CreateWebPrototype(): Doc {
let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 300 });
return webProto;
}
- function CreateCollectionPrototype(): Document {
+ function CreateCollectionPrototype(): Doc {
let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
- { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
+ { panX: 0, panY: 0, scale: 1, width: 500, height: 500 });
return collProto;
}
- function CreateKVPPrototype(): Document {
+ function CreateKVPPrototype(): Doc {
let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return kvpProto;
}
- function CreateVideoPrototype(): Document {
+ function CreateVideoPrototype(): Doc {
let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- videoProto.SetNumber(KeyStore.CurPage, 0);
- videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0 });
return videoProto;
}
- function CreateAudioPrototype(): Document {
+ function CreateAudioPrototype(): Doc {
let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return audioProto;
}
+ function CreateInstance(proto: Doc, data: Field, options: DocumentOptions) {
+ const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys);
+ return SetDelegateOptions(SetInstanceOptions(proto, protoProps, data), delegateProps);
+ }
export function ImageDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(imageProto, options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
+ return CreateInstance(imageProto, new ImageField(new URL(url)), options);
// let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
// [new URL(url), ImageField]);
// doc.SetText(KeyStore.Caption, "my caption...");
@@ -204,23 +168,23 @@ export namespace Documents {
// return doc;
}
export function VideoDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(videoProto, options, [new URL(url), VideoField]), options);
+ return CreateInstance(videoProto, new VideoField(new URL(url)), options);
}
export function AudioDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(audioProto, options, [new URL(url), AudioField]), options);
+ return CreateInstance(audioProto, new AudioField(new URL(url)), options);
}
- export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}, id?: string, delegId?: string) {
- return assignToDelegate(SetInstanceOptions(histoProto, options, [histoOp, HistogramField], id).MakeDelegate(delegId), options);
+ export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}) {
+ return CreateInstance(histoProto, new HistogramField(histoOp), options);
}
export function TextDocument(options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(textProto, options, ["", TextField]).MakeDelegate(), options);
+ return CreateInstance(textProto, "", options);
}
export function IconDocument(icon: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(iconProto, { width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data], layout: IconBox.LayoutString(), ...options }, [icon, IconField]), options);
+ return CreateInstance(iconProto, new IconField(icon), options);
}
export function PdfDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(pdfProto, options, [new URL(url), PDFField]).MakeDelegate(), options);
+ return CreateInstance(pdfProto, new PdfField(new URL(url)), options);
}
export async function DBDocument(url: string, options: DocumentOptions = {}) {
let schemaName = options.title ? options.title : "-no schema-";
@@ -248,35 +212,35 @@ export namespace Documents {
return Documents.TreeDocument([], { width: 50, height: 100, title: schemaName });
}
export function WebDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(webProto, options, [new URL(url), WebField]).MakeDelegate(), options);
+ return CreateInstance(webProto, new WebField(new URL(url)), options);
}
export function HtmlDocument(html: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(webProto, options, [html, HtmlField]).MakeDelegate(), options);
+ return CreateInstance(webProto, new HtmlField(html), options);
}
- export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) {
- return assignToDelegate(SetInstanceOptions(kvpProto, options, document, id), options);
+ export function KVPDocument(document: Doc, options: DocumentOptions = {}) {
+ return CreateInstance(kvpProto, document, options);
}
- export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string, makePrototype: boolean = true) {
+ export function FreeformDocument(documents: Array, options: DocumentOptions, makePrototype: boolean = true) {
if (!makePrototype) {
- return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id);
+ return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, new List(documents));
}
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options);
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Freeform });
}
- export function SchemaDocument(documents: Array, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options);
+ export function SchemaDocument(documents: Array, options: DocumentOptions) {
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Schema });
}
- export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options);
+ export function TreeDocument(documents: Array, options: DocumentOptions) {
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Tree });
}
- export function DockDocument(config: string, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options);
+ export function DockDocument(config: string, options: DocumentOptions) {
+ return CreateInstance(collProto, config, { ...options, viewType: CollectionViewType.Docking });
}
- export function CaptionDocument(doc: Document) {
- const captionDoc = doc.CreateAlias();
- captionDoc.SetText(KeyStore.OverlayLayout, FixedCaption());
- captionDoc.SetNumber(KeyStore.Width, doc.GetNumber(KeyStore.Width, 0));
- captionDoc.SetNumber(KeyStore.Height, doc.GetNumber(KeyStore.Height, 0));
+ export function CaptionDocument(doc: Doc) {
+ const captionDoc = Doc.MakeAlias(doc);
+ captionDoc.overlayLayout = FixedCaption();
+ captionDoc.width = Cast(doc.width, "number", 0);
+ captionDoc.height = Cast(doc.height, "number", 0);
return captionDoc;
}
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index c699691a4..932166b21 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -15,7 +15,7 @@ export class HistogramField extends BasicField {
}
toString(): string {
- return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']));
+ return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit);
}
Copy(): Field {
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c6eea5623..7b7b7e65e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -71,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponentError loading layout data
"); }
CreateBindings(): JsxBindings {
- let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) };
+ let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit };
return bindings;
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5ae095e68..987cb2cc4 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -4,7 +4,7 @@ import { autoObject, SerializationHelper, Deserializable } from "../client/util/
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
import { setter, getter, getField } from "./util";
-import { Cast, ToConstructor } from "./Types";
+import { Cast, ToConstructor, PromiseValue } from "./Types";
export type FieldId = string;
export const HandleUpdate = Symbol("HandleUpdate");
@@ -54,7 +54,8 @@ export class Doc extends RefField {
return doc;
}
- [key: string]: Field | FieldWaiting | undefined;
+ proto: FieldResult;
+ [key: string]: FieldResult;
@serializable(alias("fields", map(autoObject())))
@observable
@@ -92,6 +93,32 @@ export namespace Doc {
proto[key] = value;
}
}
+ export function assign(doc: Doc, fields: Partial>>) {
+ for (const key in fields) {
+ if (fields.hasOwnProperty(key)) {
+ const value = fields[key];
+ if (value !== undefined) {
+ doc[key] = value;
+ }
+ }
+ }
+ return doc;
+ }
+
+ export function MakeAlias(doc: Doc) {
+ const alias = new Doc;
+
+ PromiseValue(Cast(doc.proto, Doc)).then(proto => {
+ if (proto) {
+ alias.proto = proto;
+ }
+ });
+
+ return alias;
+ }
+
+ export function MakeDelegate(doc: Doc): Doc;
+ export function MakeDelegate(doc: Opt): Opt;
export function MakeDelegate(doc: Opt): Opt {
if (!doc) {
return undefined;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index f3ec9e2c5..f01ac210a 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -33,4 +33,4 @@ class ListImpl extends ObjectField {
private [Self] = this;
}
export type List = ListImpl & T[];
-export const List: { new (): List } = ListImpl as any;
\ No newline at end of file
+export const List: { new (fields?: T[]): List } = ListImpl as any;
\ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 246b0624e..55083765a 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -68,7 +68,7 @@ export function FieldValue(field: Opt | Promise>, def
}
export interface PromiseLike {
- then(callback: (field: Opt | PromiseLike) => void): void;
+ then(callback: (field: Opt) => void): void;
}
export function PromiseValue(field: FieldResult): PromiseLike> {
return field instanceof Promise ? field : { then(cb: ((field: Opt) => void)) { return cb(field); } };
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 3806044bd..2d9721b2e 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -2,6 +2,7 @@ import { UndoManager } from "../client/util/UndoManager";
import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField } from "./Proxy";
+import { FieldValue } from "./Types";
export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
@@ -61,11 +62,16 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
return field.value(callback);
}
if (field === undefined && !ignoreProto) {
- const proto = getField(target, "prototype", true);
+ const proto = getField(target, "proto", true);
if (proto instanceof Doc) {
let field = proto[prop];
- callback && callback(field === null ? undefined : field);
- return field;
+ if (field instanceof Promise) {
+ callback && field.then(callback);
+ return undefined;
+ } else {
+ callback && callback(field);
+ return field;
+ }
}
}
callback && callback(field);
--
cgit v1.2.3-70-g09d2
From d4a77dd055685dd81a762ef40e0c3b7606586e9c Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sat, 27 Apr 2019 21:40:17 -0400
Subject: Split more files up
---
src/client/DocServer.ts | 3 +-
src/client/northstar/dash-fields/HistogramField.ts | 2 +-
src/client/northstar/dash-nodes/HistogramBox.tsx | 3 +-
src/client/util/Scripting.ts | 1 +
src/client/views/Main.tsx | 3 +-
.../views/collections/CollectionBaseView.tsx | 3 +-
.../views/collections/CollectionDockingView.tsx | 3 +-
.../views/collections/CollectionSchemaView.tsx | 3 +-
src/client/views/collections/CollectionSubView.tsx | 3 +-
.../views/collections/CollectionTreeView.tsx | 3 +-
.../CollectionFreeFormLinksView.tsx | 3 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 3 +-
src/client/views/nodes/DocumentView.tsx | 3 +-
src/client/views/nodes/FieldView.tsx | 1 +
src/client/views/nodes/LinkMenu.tsx | 3 +-
src/new_fields/Doc.ts | 37 +++-------------------
src/new_fields/HtmlField.ts | 2 +-
src/new_fields/IconField.ts | 2 +-
src/new_fields/InkField.ts | 2 +-
src/new_fields/List.ts | 3 +-
src/new_fields/ObjectField.ts | 17 ++++++++++
src/new_fields/Proxy.ts | 4 ++-
src/new_fields/RefField.ts | 18 +++++++++++
src/new_fields/RichTextField.ts | 2 +-
src/new_fields/Schema.ts | 8 ++---
src/new_fields/Types.ts | 2 +-
src/new_fields/URLField.ts | 2 +-
src/new_fields/util.ts | 4 ++-
.../authentication/controllers/WorkspacesMenu.tsx | 3 +-
src/server/database.ts | 2 ++
30 files changed, 88 insertions(+), 60 deletions(-)
create mode 100644 src/new_fields/ObjectField.ts
create mode 100644 src/new_fields/RefField.ts
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 3f17baec6..c7cbfce37 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,8 +1,9 @@
import * as OpenSocket from 'socket.io-client';
import { MessageStore, Types, Message } from "./../server/Message";
-import { Opt, FieldWaiting, RefField, HandleUpdate } from '../new_fields/Doc';
+import { Opt, FieldWaiting } from '../new_fields/Doc';
import { Utils } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
+import { RefField, HandleUpdate } from '../new_fields/RefField';
export namespace DocServer {
const _cache: { [id: string]: RefField | Promise> } = {};
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index 118f4cf7f..730289536 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -3,7 +3,7 @@ import { custom, serializable } from "serializr";
import { ColumnAttributeModel } from "../../../client/northstar/core/attribute/AttributeModel";
import { AttributeTransformationModel } from "../../../client/northstar/core/attribute/AttributeTransformationModel";
import { HistogramOperation } from "../../../client/northstar/operations/HistogramOperation";
-import { ObjectField } from "../../../new_fields/Doc";
+import { ObjectField } from "../../../new_fields/ObjectField";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { OmitKeys } from "../../../Utils";
import { Deserializable } from "../../util/SerializationHelper";
diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx
index 4a65b14cf..a9c68ccba 100644
--- a/src/client/northstar/dash-nodes/HistogramBox.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBox.tsx
@@ -20,7 +20,8 @@ import { HistogramLabelPrimitives } from "./HistogramLabelPrimitives";
import { StyleConstants } from "../utils/StyleContants";
import { NumCast, Cast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
-import { Doc, Id } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/RefField";
@observer
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index dbec82340..e45f61c11 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -11,6 +11,7 @@ import { Docs } from "../documents/Documents";
import { Doc, Field } from '../../new_fields/Doc';
import { ImageField, PdfField, VideoField, AudioField } from '../../new_fields/URLField';
import { List } from '../../new_fields/List';
+import { RichTextField } from '../../new_fields/RichTextField';
export interface ScriptSucccess {
success: true;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 1e3d4e259..4a68d1c68 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -33,10 +33,11 @@ import { MainOverlayTextBox } from './MainOverlayTextBox';
import { DocumentView } from './nodes/DocumentView';
import { PreviewCursor } from './PreviewCursor';
import { SelectionManager } from '../util/SelectionManager';
-import { FieldResult, Field, Doc, Id, Opt } from '../../new_fields/Doc';
+import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc';
import { Cast, FieldValue, StrCast } from '../../new_fields/Types';
import { DocServer } from '../DocServer';
import { listSpec } from '../../new_fields/Schema';
+import { Id } from '../../new_fields/RefField';
@observer
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 4807dc40a..b2fba1415 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -4,9 +4,10 @@ import * as React from 'react';
import { ContextMenu } from '../ContextMenu';
import { FieldViewProps } from '../nodes/FieldView';
import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Types';
-import { Doc, FieldResult, Opt, Id } from '../../../new_fields/Doc';
+import { Doc, FieldResult, Opt } from '../../../new_fields/Doc';
import { listSpec } from '../../../new_fields/Schema';
import { List } from '../../../new_fields/List';
+import { Id } from '../../../new_fields/RefField';
export enum CollectionViewType {
Invalid,
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 2ff409b9b..1574562c6 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -13,11 +13,12 @@ import React = require("react");
import { SubCollectionViewProps } from "./CollectionSubView";
import { DragManager, DragLinksAsDocuments } from "../../util/DragManager";
import { Transform } from '../../util/Transform';
-import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc";
+import { Doc, Opt, Field } from "../../../new_fields/Doc";
import { Cast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
import { listSpec } from "../../../new_fields/Schema";
+import { Id, FieldId } from "../../../new_fields/RefField";
@observer
export class CollectionDockingView extends React.Component {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 874170f3d..58d20819b 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -19,10 +19,11 @@ import { DocumentView } from "../nodes/DocumentView";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { Opt, Field, Doc, Id } from "../../../new_fields/Doc";
+import { Opt, Field, Doc } from "../../../new_fields/Doc";
import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
import { List } from "../../../new_fields/List";
+import { Id } from "../../../new_fields/RefField";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 558a8728f..4d090b680 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -10,12 +10,13 @@ import * as rp from 'request-promise';
import { CollectionView } from "./CollectionView";
import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
-import { Doc, ObjectField, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
import { listSpec } from "../../../new_fields/Schema";
import { Cast, PromiseValue } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
+import { ObjectField } from "../../../new_fields/ObjectField";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c9d8d83c8..7ec9a8549 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -10,7 +10,8 @@ import "./CollectionTreeView.scss";
import React = require("react");
import { Document, listSpec } from '../../../new_fields/Schema';
import { Cast, StrCast, BoolCast } from '../../../new_fields/Types';
-import { Doc, Id } from '../../../new_fields/Doc';
+import { Doc } from '../../../new_fields/Doc';
+import { Id } from '../../../new_fields/RefField';
export interface TreeViewProps {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index ce9995630..f693d55e8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -7,10 +7,11 @@ import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormLinksView.scss";
import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView";
import React = require("react");
-import { Doc, Id } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../new_fields/Doc";
import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
import { listSpec } from "../../../../new_fields/Schema";
import { List } from "../../../../new_fields/List";
+import { Id } from "../../../../new_fields/RefField";
@observer
export class CollectionFreeFormLinksView extends React.Component {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 047fbad18..18107e98a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -19,10 +19,11 @@ import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema";
-import { Doc, Id } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../new_fields/Doc";
import { FieldValue, Cast, NumCast } from "../../../../new_fields/Types";
import { pageSchema } from "../../nodes/ImageBox";
import { List } from "../../../../new_fields/List";
+import { Id } from "../../../../new_fields/RefField";
export const panZoomSchema = createSchema({
panX: "number",
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index aabc1633e..c304b6a35 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -15,7 +15,7 @@ import { ContextMenu } from "../ContextMenu";
import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
import React = require("react");
-import { Field, Opt, Doc, Id } from "../../../new_fields/Doc";
+import { Opt, Doc } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
import { FieldValue, Cast, PromiseValue } from "../../../new_fields/Types";
@@ -24,6 +24,7 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView";
import { DocServer } from "../../DocServer";
+import { Id } from "../../../new_fields/RefField";
const linkSchema = createSchema({
title: "string",
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c00c47fc4..dc36c5914 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -16,6 +16,7 @@ import { Opt, Doc, FieldResult } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField";
import { IconField } from "../../../new_fields/IconField";
+import { RichTextField } from "../../../new_fields/RichTextField";
//
diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx
index 3ecc8555d..e21adebbc 100644
--- a/src/client/views/nodes/LinkMenu.tsx
+++ b/src/client/views/nodes/LinkMenu.tsx
@@ -5,9 +5,10 @@ import { LinkBox } from "./LinkBox";
import { LinkEditor } from "./LinkEditor";
import './LinkMenu.scss';
import React = require("react");
-import { Doc, Id } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
import { Cast, FieldValue } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
+import { Id } from "../../../new_fields/RefField";
interface Props {
docView: DocumentView;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index fb7b6e360..4ef2a465f 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -8,38 +8,8 @@ import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
import { List } from "./List";
-
-export type FieldId = string;
-export const HandleUpdate = Symbol("HandleUpdate");
-export const Id = Symbol("Id");
-export abstract class RefField {
- @serializable(alias("id", primitive()))
- private __id: FieldId;
- readonly [Id]: FieldId;
-
- constructor(id?: FieldId) {
- this.__id = id || Utils.GenerateGuid();
- this[Id] = this.__id;
- }
-
- protected [HandleUpdate]?(diff: any): void;
-}
-
-export const Update = Symbol("Update");
-export const OnUpdate = Symbol("OnUpdate");
-export const Parent = Symbol("Parent");
-export class ObjectField {
- protected [OnUpdate]?: (diff?: any) => void;
- private [Parent]?: Doc;
- readonly [Id] = "";
-}
-
-export namespace ObjectField {
- export function MakeCopy(field: ObjectField) {
- //TODO Types
- return field;
- }
-}
+import { ObjectField } from "./ObjectField";
+import { RefField, FieldId, Id } from "./RefField";
export function IsField(field: any): field is Field {
return (typeof field === "string")
@@ -53,6 +23,7 @@ export type Opt = T | undefined;
export type FieldWaiting = T extends undefined ? never : Promise;
export type FieldResult = Opt | FieldWaiting>;
+export const Update = Symbol("Update");
export const Self = Symbol("Self");
@Deserializable("doc").withFields(["id"])
@@ -161,7 +132,7 @@ export namespace Doc {
copy[key] = field;
}
}
- })
+ });
return copy;
}
diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts
index 76fdb1f62..808a3499b 100644
--- a/src/new_fields/HtmlField.ts
+++ b/src/new_fields/HtmlField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
@Deserializable("html")
export class HtmlField extends ObjectField {
diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts
index 32f3aa4d5..46f111f8e 100644
--- a/src/new_fields/IconField.ts
+++ b/src/new_fields/IconField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
@Deserializable("icon")
export class IconField extends ObjectField {
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
index 49e6bf61e..42223c494 100644
--- a/src/new_fields/InkField.ts
+++ b/src/new_fields/InkField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
export enum InkTool {
None,
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index f01ac210a..428f661c9 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,8 +1,9 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Field, ObjectField, Update, OnUpdate, Self } from "./Doc";
+import { Field, Update, Self } from "./Doc";
import { setter, getter } from "./util";
import { serializable, alias, list } from "serializr";
import { observable } from "mobx";
+import { ObjectField, OnUpdate } from "./ObjectField";
@Deserializable("list")
class ListImpl extends ObjectField {
diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts
new file mode 100644
index 000000000..9cac2c528
--- /dev/null
+++ b/src/new_fields/ObjectField.ts
@@ -0,0 +1,17 @@
+import { Doc } from "./Doc";
+
+export const OnUpdate = Symbol("OnUpdate");
+export const Parent = Symbol("Parent");
+const Id = Symbol("Object Id");
+export class ObjectField {
+ protected [OnUpdate]?: (diff?: any) => void;
+ private [Parent]?: Doc;
+ readonly [Id] = "";
+}
+
+export namespace ObjectField {
+ export function MakeCopy(field: ObjectField) {
+ //TODO Types
+ return field;
+ }
+}
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 2aa78731e..56e41cc0f 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -1,8 +1,10 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { RefField, Id, ObjectField, FieldWaiting } from "./Doc";
+import { FieldWaiting } from "./Doc";
import { primitive, serializable } from "serializr";
import { observable, action } from "mobx";
import { DocServer } from "../client/DocServer";
+import { RefField, Id } from "./RefField";
+import { ObjectField } from "./ObjectField";
@Deserializable("proxy")
export class ProxyField extends ObjectField {
diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts
new file mode 100644
index 000000000..202c65f21
--- /dev/null
+++ b/src/new_fields/RefField.ts
@@ -0,0 +1,18 @@
+import { serializable, primitive, alias } from "serializr";
+import { Utils } from "../Utils";
+
+export type FieldId = string;
+export const HandleUpdate = Symbol("HandleUpdate");
+export const Id = Symbol("Id");
+export abstract class RefField {
+ @serializable(alias("id", primitive()))
+ private __id: FieldId;
+ readonly [Id]: FieldId;
+
+ constructor(id?: FieldId) {
+ this.__id = id || Utils.GenerateGuid();
+ this[Id] = this.__id;
+ }
+
+ protected [HandleUpdate]?(diff: any): void;
+}
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
index 156e4efd9..0fa3cf73c 100644
--- a/src/new_fields/RichTextField.ts
+++ b/src/new_fields/RichTextField.ts
@@ -1,4 +1,4 @@
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
import { serializable } from "serializr";
export class RichTextField extends ObjectField {
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index 5081521c7..7444878fe 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -21,15 +21,15 @@ export function makeInterface(...schemas: T): (doc?: Doc)
}
}
const proto = new Proxy({}, {
- get(target: any, prop) {
- const field = target.doc[prop];
+ get(target: any, prop, receiver) {
+ const field = receiver.doc[prop];
if (prop in schema) {
return Cast(field, (schema as any)[prop]);
}
return field;
},
- set(target: any, prop, value) {
- target.doc[prop] = value;
+ set(target: any, prop, value, receiver) {
+ receiver.doc[prop] = value;
return true;
}
});
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 7fa18673f..3f8eabd45 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -1,4 +1,4 @@
-import { Field, Opt, FieldWaiting, FieldResult, RefField } from "./Doc";
+import { Field, Opt, FieldResult } from "./Doc";
import { List } from "./List";
export type ToType | ListSpec> =
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index 1da245e73..95c679df7 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
function url() {
return custom(
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 2d9721b2e..011e8c8d9 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -1,8 +1,10 @@
import { UndoManager } from "../client/util/UndoManager";
-import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
+import { Update, Doc, Field } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField } from "./Proxy";
import { FieldValue } from "./Types";
+import { RefField, Id } from "./RefField";
+import { ObjectField, Parent, OnUpdate } from "./ObjectField";
export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx
index 29327e5ad..91756315d 100644
--- a/src/server/authentication/controllers/WorkspacesMenu.tsx
+++ b/src/server/authentication/controllers/WorkspacesMenu.tsx
@@ -3,8 +3,9 @@ import { observable, action, configure, reaction, computed, ObservableMap, runIn
import { observer } from "mobx-react";
import './WorkspacesMenu.css';
import { EditableView } from '../../../client/views/EditableView';
-import { Doc, Id } from '../../../new_fields/Doc';
+import { Doc } from '../../../new_fields/Doc';
import { StrCast } from '../../../new_fields/Types';
+import { Id } from '../../../new_fields/RefField';
export interface WorkspaceMenuProps {
active: Doc | undefined;
diff --git a/src/server/database.ts b/src/server/database.ts
index a61b4d823..6b3b6797f 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -60,11 +60,13 @@ export class Database {
}
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) {
+ console.log("getDocument");
this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) =>
fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined));
}
public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) {
+ console.log("getDocuments");
this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => {
if (err) {
console.log(err.message);
--
cgit v1.2.3-70-g09d2
From 506af03831bf3cc002f93ad8708eafb909c0a194 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sat, 27 Apr 2019 22:27:26 -0400
Subject: Various fixes
---
src/client/DocServer.ts | 24 ++++++++++++++++++----
src/client/documents/Documents.ts | 2 +-
src/client/northstar/dash-nodes/HistogramBox.tsx | 2 +-
src/client/views/collections/CollectionPDFView.tsx | 2 +-
src/client/views/collections/CollectionSubView.tsx | 1 +
.../views/collections/CollectionVideoView.tsx | 2 +-
src/client/views/collections/CollectionView.tsx | 2 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 2 +-
src/client/views/nodes/FieldView.tsx | 4 ++--
src/client/views/nodes/FormattedTextBox.tsx | 2 +-
src/client/views/nodes/KeyValueBox.tsx | 2 +-
src/new_fields/util.ts | 5 +++--
src/server/database.ts | 21 +++++++++++++------
src/server/index.ts | 10 +++++----
14 files changed, 55 insertions(+), 26 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index c7cbfce37..07997f072 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -55,12 +55,28 @@ export namespace DocServer {
map[id] = cached;
}
}
- const prom = Utils.EmitCallback(_socket, MessageStore.GetFields, requestedIds);
- requestedIds.map((id, index) => _cache[id] = prom.then((fields: RefField[]) => fields[index]));
+ const prom = Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds).then(fields => {
+ for (const key in fields) {
+ const field = fields[key];
+ if (field) {
+ fields[key] = SerializationHelper.Deserialize(field);
+ }
+ }
+ return fields;
+ });
+ requestedIds.forEach((id, index) => _cache[id] = prom.then((fields: RefField[]) => fields[index]));
const fields = await prom;
- requestedIds.map((id, index) => map[id] = fields[index]);
+ requestedIds.forEach((id, index) => {
+ const field = fields[index];
+ if (field) {
+ _cache[id] = field;
+ } else {
+ delete _cache[id];
+ }
+ map[id] = field;
+ });
const otherFields = await Promise.all(promises);
- waitingIds.map((id, index) => map[id] = otherFields[index]);
+ waitingIds.forEach((id, index) => map[id] = otherFields[index]);
return map;
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c30fb21d5..2a9687bda 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -138,7 +138,7 @@ export namespace Docs {
return webProto;
}
function CreateCollectionPrototype(): Doc {
- let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
+ let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("data"),
{ panX: 0, panY: 0, scale: 1, width: 500, height: 500 });
return collProto;
}
diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx
index a9c68ccba..19d108676 100644
--- a/src/client/northstar/dash-nodes/HistogramBox.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBox.tsx
@@ -26,7 +26,7 @@ import { Id } from "../../../new_fields/RefField";
@observer
export class HistogramBox extends React.Component {
- public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(HistogramBox, fieldStr); }
+ public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(HistogramBox, fieldStr); }
private _dropXRef = React.createRef();
private _dropYRef = React.createRef();
private _dropXDisposer?: DragManager.DragDropDisposer;
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index e73b7b4a6..99438b4e8 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -13,7 +13,7 @@ import { NumCast } from "../../../new_fields/Types";
@observer
export class CollectionPDFView extends React.Component {
- public static LayoutString(fieldKey: string = "DataKey") {
+ public static LayoutString(fieldKey: string = "data") {
return FieldView.LayoutString(CollectionPDFView, fieldKey);
}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 4d090b680..2c2d74302 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -53,6 +53,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) {
@action
protected async setCursorPosition(position: [number, number]) {
+ return;
let ind;
let doc = this.props.Document;
let id = CurrentUserUtils.id;
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index d314e3fc0..d45be228a 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -18,7 +18,7 @@ export class CollectionVideoView extends React.Component {
@observable _currentTimecode: number = 0;
@observable _isPlaying: boolean = false;
- public static LayoutString(fieldKey: string = "DataKey") {
+ public static LayoutString(fieldKey: string = "data") {
return FieldView.LayoutString(CollectionVideoView, fieldKey);
}
private get uIButtons() {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index e7bf1e121..b72065bca 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -13,7 +13,7 @@ import { trace } from 'mobx';
@observer
export class CollectionView extends React.Component {
- public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(CollectionView, fieldStr); }
+ public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(CollectionView, fieldStr); }
private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
let props = { ...this.props, ...renderProps };
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 18107e98a..dfacca204 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -314,7 +314,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
{this.childViews}
-
+ {/* */}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index dc36c5914..df76f7cea 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -45,8 +45,8 @@ export interface FieldViewProps {
@observer
export class FieldView extends React.Component {
- public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") {
- return `<${fieldType.name} {...props} fieldKey={${fieldStr}} />`;
+ public static LayoutString(fieldType: { name: string }, fieldStr: string = "data") {
+ return `<${fieldType.name} {...props} fieldKey={"${fieldStr}"} />`;
}
@computed
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 7a85c9dd3..96512718f 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -55,7 +55,7 @@ const RichTextDocument = makeInterface(richTextSchema);
@observer
export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTextBoxOverlay), RichTextDocument>(RichTextDocument) {
- public static LayoutString(fieldStr: string = "DataKey") {
+ public static LayoutString(fieldStr: string = "data") {
return FieldView.LayoutString(FormattedTextBox, fieldStr);
}
private _ref: React.RefObject;
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index ae39ebe2d..876a3c173 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -14,7 +14,7 @@ import { Doc, IsField } from "../../../new_fields/Doc";
export class KeyValueBox extends React.Component {
private _mainCont = React.createRef();
- public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(KeyValueBox, fieldStr); }
+ public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(KeyValueBox, fieldStr); }
@observable private _keyInput: string = "";
@observable private _valueInput: string = "";
@computed get splitPercentage() { return NumCast(this.props.Document.schemaSplitPercentage, 50); }
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 011e8c8d9..b2299f34a 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -5,8 +5,9 @@ import { ProxyField } from "./Proxy";
import { FieldValue } from "./Types";
import { RefField, Id } from "./RefField";
import { ObjectField, Parent, OnUpdate } from "./ObjectField";
+import { action } from "mobx";
-export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+export const setter = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
target[prop] = value;
return true;
@@ -46,7 +47,7 @@ export function setter(target: any, prop: string | symbol | number, value: any,
undo: () => receiver[prop] = curValue
});
return true;
-}
+});
export function getter(target: any, prop: string | symbol | number, receiver: any): any {
if (typeof prop === "symbol") {
diff --git a/src/server/database.ts b/src/server/database.ts
index 6b3b6797f..4775c0eeb 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -60,19 +60,28 @@ export class Database {
}
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) {
- console.log("getDocument");
- this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) =>
- fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined));
+ this.db && this.db.collection(collectionName).findOne({ _id: id }, (err, result) => {
+ if (result) {
+ result.id = result._id;
+ delete result._id;
+ fn(result);
+ } else {
+ fn(undefined);
+ }
+ });
}
public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) {
- console.log("getDocuments");
- this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => {
+ this.db && this.db.collection(collectionName).find({ _id: { "$in": ids } }).toArray((err, docs) => {
if (err) {
console.log(err.message);
console.log(err.errmsg);
}
- fn(docs.map(doc => ({ id: doc._id, type: doc.type, data: doc.data })));
+ fn(docs.map(doc => {
+ doc.id = doc._id;
+ delete doc._id;
+ return doc;
+ }));
});
}
diff --git a/src/server/index.ts b/src/server/index.ts
index 10158eb96..6801b3132 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -234,16 +234,18 @@ server.on("connection", function (socket: Socket) {
Utils.AddServerHandler(socket, MessageStore.CreateField, CreateField);
Utils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff));
- Utils.AddServerHandler(socket, MessageStore.GetRefField, GetRefField);
- Utils.AddServerHandler(socket, MessageStore.GetRefFields, GetRefFields);
+ Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField);
+ Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields);
});
-function deleteFields() {
- return Database.Instance.deleteAll();
+async function deleteFields() {
+ await Database.Instance.deleteAll();
+ await Database.Instance.deleteAll('newDocuments');
}
async function deleteAll() {
await Database.Instance.deleteAll();
+ await Database.Instance.deleteAll('newDocuments');
await Database.Instance.deleteAll('sessions');
await Database.Instance.deleteAll('users');
}
--
cgit v1.2.3-70-g09d2
From 307564d9b02ed9d4de8ffa4229b0494bf8d671bd Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Mon, 29 Apr 2019 01:36:00 -0400
Subject: Fixes
---
src/client/util/SerializationHelper.ts | 5 +++++
src/new_fields/Doc.ts | 20 +++++++++++++++++---
src/new_fields/List.ts | 26 +++++++++++++++++++-------
src/new_fields/util.ts | 14 +++++++++-----
src/server/database.ts | 2 +-
5 files changed, 51 insertions(+), 16 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index ac70aba9d..1a8cc3a44 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -63,6 +63,11 @@ export function Deserializable(name: string): DeserializableOpts;
export function Deserializable(constructor: Function): void;
export function Deserializable(constructor: Function | string): DeserializableOpts | void {
function addToMap(name: string, ctor: Function) {
+ const schema = getDefaultModelSchema(ctor as any) as any;
+ if (schema.targetClass !== ctor) {
+ const newSchema = { ...schema, factory: () => new (ctor as any)() };
+ setDefaultModelSchema(ctor as any, newSchema);
+ }
if (!(name in serializationTypes)) {
serializationTypes[name] = ctor;
reverseMap[ctor.name] = name;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 4ef2a465f..d15b6309d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -3,12 +3,12 @@ import { serializable, primitive, map, alias, list } from "serializr";
import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper";
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
-import { setter, getter, getField } from "./util";
+import { setter, getter, getField, updateFunction } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
import { List } from "./List";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Parent, OnUpdate } from "./ObjectField";
import { RefField, FieldId, Id } from "./RefField";
export function IsField(field: any): field is Field {
@@ -47,9 +47,23 @@ export class Doc extends RefField {
[key: string]: FieldResult;
@serializable(alias("fields", map(autoObject())))
+ private get __fields() {
+ return this.___fields;
+ }
+
+ private set __fields(value) {
+ this.___fields = value;
+ for (const key in value) {
+ const field = value[key];
+ if (!(field instanceof ObjectField)) continue;
+ field[Parent] = this[Self];
+ field[OnUpdate] = updateFunction(this[Self], key, field);
+ }
+ }
+
@observable
//{ [key: string]: Field | FieldWaiting | undefined }
- private __fields: any = {};
+ private ___fields: any = {};
private [Update] = (diff: any) => {
DocServer.UpdateField(this[Id], diff);
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index ecde4edc7..e4a80f7a1 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,13 +2,13 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self } from "./Doc";
import { setter, getter } from "./util";
import { serializable, alias, list } from "serializr";
-import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda } from "mobx";
+import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
import { ObjectField, OnUpdate } from "./ObjectField";
const listHandlers: any = {
push(...items: any[]) {
- console.log("push");
- console.log(...items);
+ // console.log("push");
+ // console.log(...items);
return this[Self].__fields.push(...items);
},
pop(): any {
@@ -62,7 +62,7 @@ function listObserver(this: ListImpl, change: IArrayChange extends ObjectField {
constructor(fields: T[] = []) {
super();
- this.__fields = fields;
+ this.___fields = fields;
this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
const list = new Proxy(this, {
set: setter,
@@ -76,13 +76,25 @@ class ListImpl extends ObjectField {
[key: number]: T | null | undefined;
@serializable(alias("fields", list(autoObject())))
+ private get __fields() {
+ return this.___fields;
+ }
+
+ private set __fields(value) {
+ this.___fields = value;
+ this[ObserveDisposer]();
+ this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
+ }
+
+ // @serializable(alias("fields", list(autoObject())))
@observable
- private __fields: (T | null | undefined)[];
+ private ___fields: (T | null | undefined)[];
private [Update] = (diff: any) => {
- console.log(diff);
+ // console.log(diff);
const update = this[OnUpdate];
- update && update(diff);
+ // update && update(diff);
+ update && update();
}
private [ObserveDisposer]: Lambda;
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index b2299f34a..511820115 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -31,17 +31,14 @@ export const setter = action(function (target: any, prop: string | symbol | numb
throw new Error("Can't put the same object in multiple documents at the same time");
}
value[Parent] = target;
- value[OnUpdate] = (diff?: any) => {
- if (!diff) diff = SerializationHelper.Serialize(value);
- target[Update]({ [prop]: diff });
- };
+ value[OnUpdate] = updateFunction(target, prop, value);
}
if (curValue instanceof ObjectField) {
delete curValue[Parent];
delete curValue[OnUpdate];
}
target.__fields[prop] = value;
- target[Update]({ ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) });
+ target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
@@ -80,3 +77,10 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
callback && callback(field);
return field;
}
+
+export function updateFunction(target: any, prop: any, value: any) {
+ return (diff?: any) => {
+ if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ target[Update](diff);
+ };
+}
\ No newline at end of file
diff --git a/src/server/database.ts b/src/server/database.ts
index 4775c0eeb..37cfcf3a3 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -20,7 +20,7 @@ export class Database {
let newProm: Promise;
const run = (): Promise => {
return new Promise(resolve => {
- collection.updateOne({ _id: id }, { $set: value }, { upsert }
+ collection.updateOne({ _id: id }, value, { upsert }
, (err, res) => {
if (err) {
console.log(err.message);
--
cgit v1.2.3-70-g09d2
From 877b104a61d2ab072e3b6a006168ec03e2c46365 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Tue, 30 Apr 2019 00:11:27 -0400
Subject: Mostly fixed lists
---
src/client/util/UndoManager.ts | 4 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 1 +
src/debug/Test.tsx | 8 +-
src/new_fields/Doc.ts | 10 +-
src/new_fields/List.ts | 192 +++++++++++++++++----
src/new_fields/util.ts | 8 +
6 files changed, 179 insertions(+), 44 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index f7c3e5a7b..0b5280c4a 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -141,10 +141,10 @@ export namespace UndoManager {
});
//TODO Make this return the return value
- export function RunInBatch(fn: () => void, batchName: string) {
+ export function RunInBatch(fn: () => T, batchName: string) {
let batch = StartBatch(batchName);
try {
- runInAction(fn);
+ return runInAction(fn);
} finally {
batch.end();
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dcded7648..d796bd8d5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -272,6 +272,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
get views() {
let curPage = FieldValue(this.Document.curPage, -1);
let docviews = (this.children || []).filter(doc => doc).reduce((prev, doc) => {
+ if (!FieldValue(doc)) return prev;
var page = Cast(doc.page, "number", -1);
if (page === curPage || page === -1) {
let minim = Cast(doc.isMinimized, "boolean");
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 7415d4b28..04ef00722 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -61,14 +61,12 @@ class Test extends React.Component {
assert(test2.testDoc === undefined);
test2.url = 35;
assert(test2.url === 35);
- const l = new List();
+ const l = new List();
//TODO push, and other array functions don't go through the proxy
- l.push(1);
+ l.push(doc2);
//TODO currently length, and any other string fields will get serialized
- l.length = 3;
- l[2] = 5;
+ doc.list = l;
console.log(l.slice());
- console.log(SerializationHelper.Serialize(l));
}
render() {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index d15b6309d..6ddb0df89 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -3,7 +3,7 @@ import { serializable, primitive, map, alias, list } from "serializr";
import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper";
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
-import { setter, getter, getField, updateFunction } from "./util";
+import { setter, getter, getField, updateFunction, deleteProperty } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
@@ -34,7 +34,7 @@ export class Doc extends RefField {
set: setter,
get: getter,
ownKeys: target => Object.keys(target.__fields),
- deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
+ deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
if (!id || forceSave) {
@@ -151,8 +151,8 @@ export namespace Doc {
}
export function MakeLink(source: Doc, target: Doc): Doc {
- let linkDoc = new Doc;
- UndoManager.RunInBatch(() => {
+ return UndoManager.RunInBatch(() => {
+ let linkDoc = new Doc;
linkDoc.title = "New Link";
linkDoc.linkDescription = "";
linkDoc.linkTags = "Default";
@@ -171,8 +171,8 @@ export namespace Doc {
source.linkedToDocs = linkedTo = new List();
}
linkedTo.push(linkDoc);
+ return linkDoc;
}, "make link");
- return linkDoc;
}
export function MakeDelegate(doc: Doc): Doc;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index e4a80f7a1..ec1bf44a9 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,21 +1,173 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self } from "./Doc";
-import { setter, getter } from "./util";
+import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
import { ObjectField, OnUpdate } from "./ObjectField";
+import { RefField } from "./RefField";
+import { ProxyField } from "./Proxy";
const listHandlers: any = {
- push(...items: any[]) {
- // console.log("push");
- // console.log(...items);
- return this[Self].__fields.push(...items);
+ /// Mutator methods
+ copyWithin() {
+ throw new Error("copyWithin not supported yet");
+ },
+ fill(value: any, start?: number, end?: number) {
+ if (value instanceof RefField) {
+ throw new Error("fill with RefFields not supported yet");
+ }
+ const res = this[Self].__fields.fill(value, start, end);
+ this[Update]();
+ return res;
},
pop(): any {
- return this[Self].__fields.pop();
+ const field = toRealField(this[Self].__fields.pop());
+ this[Update]();
+ return field;
+ },
+ push(...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.push(...items);
+ this[Update]();
+ return res;
+ },
+ reverse() {
+ const res = this[Self].__fields.reverse();
+ this[Update]();
+ return res;
+ },
+ shift() {
+ const res = toRealField(this[Self].__fields.shift());
+ this[Update]();
+ return res;
+ },
+ sort(cmpFunc: any) {
+ const res = this[Self].__fields.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
+ this[Update]();
+ return res;
+ },
+ splice(start: number, deleteCount: number, ...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.splice(start, deleteCount, ...items);
+ this[Update]();
+ return res.map(toRealField);
+ },
+ unshift(...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.unshift(...items);
+ this[Update]();
+ return res;
+
+ },
+ /// Accessor methods
+ concat(...items: any[]) {
+ return this[Self].__fields.map(toRealField).concat(...items);
+ },
+ includes(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).includes(valueToFind, fromIndex);
+ } else {
+ return fields.includes(valueToFind, fromIndex);
+ }
+ },
+ indexOf(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).indexOf(valueToFind, fromIndex);
+ } else {
+ return fields.indexOf(valueToFind, fromIndex);
+ }
+ },
+ join(separator: any) {
+ return this[Self].__fields.map(toRealField).join(separator);
+ },
+ lastIndexOf(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).lastIndexOf(valueToFind, fromIndex);
+ } else {
+ return fields.lastIndexOf(valueToFind, fromIndex);
+ }
+ },
+ slice(begin: number, end: number) {
+ return this[Self].__fields.slice(begin, end).map(toRealField);
+ },
+
+ /// Iteration methods
+ entries() {
+ return this[Self].__fields.map(toRealField).entries();
+ },
+ every(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).every(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ filter(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).filter(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ find(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).find(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ findIndex(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).findIndex(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ forEach(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).forEach(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ map(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).map(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ reduce(callback: any, initialValue: any) {
+ return this[Self].__fields.map(toRealField).reduce(callback, initialValue);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+ },
+ reduceRight(callback: any, initialValue: any) {
+ return this[Self].__fields.map(toRealField).reduceRight(callback, initialValue);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+ },
+ some(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).some(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ values() {
+ return this[Self].__fields.map(toRealField).values();
+ },
+ [Symbol.iterator]() {
+ return this[Self].__fields.map(toRealField).values();
}
};
+function toObjectField(field: Field) {
+ return field instanceof RefField ? new ProxyField(field) : field;
+}
+
+function toRealField(field: Field) {
+ return field instanceof ProxyField ? field.value() : field;
+}
+
function listGetter(target: any, prop: string | number | symbol, receiver: any): any {
if (listHandlers.hasOwnProperty(prop)) {
return listHandlers[prop];
@@ -38,36 +190,15 @@ interface ListIndexUpdate {
type ListUpdate = ListSpliceUpdate | ListIndexUpdate;
-const ObserveDisposer = Symbol("Observe Disposer");
-
-function listObserver(this: ListImpl, change: IArrayChange | IArraySplice) {
- if (change.type === "splice") {
- this[Update]({
- index: change.index,
- removedCount: change.removedCount,
- added: change.added,
- type: change.type
- });
- } else {
- //This should already be handled by the getter for the Proxy
- // this[Update]({
- // index: change.index,
- // newValue: change.newValue,
- // type: change.type
- // });
- }
-}
-
@Deserializable("list")
class ListImpl extends ObjectField {
constructor(fields: T[] = []) {
super();
this.___fields = fields;
- this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
const list = new Proxy(this, {
set: setter,
- get: getter,
- deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
+ get: listGetter,
+ deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
return list;
@@ -82,8 +213,6 @@ class ListImpl extends ObjectField {
private set __fields(value) {
this.___fields = value;
- this[ObserveDisposer]();
- this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
}
// @serializable(alias("fields", list(autoObject())))
@@ -97,7 +226,6 @@ class ListImpl extends ObjectField {
update && update();
}
- private [ObserveDisposer]: Lambda;
private [Self] = this;
}
export type List = ListImpl & T[];
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 511820115..128817ab8 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -78,6 +78,14 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
return field;
}
+export function deleteProperty(target: any, prop: string | number | symbol) {
+ if (typeof prop === "symbol") {
+ delete target[prop];
+ return true;
+ }
+ throw new Error("Currently properties can't be deleted from documents, assign to undefined instead");
+}
+
export function updateFunction(target: any, prop: any, value: any) {
return (diff?: any) => {
if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
--
cgit v1.2.3-70-g09d2
From ca4a0a6454e69f0eeabdfb6ec78f8ecd60e18b76 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Wed, 1 May 2019 02:03:40 -0400
Subject: Undo with lists is working better
---
src/client/views/DocumentDecorations.tsx | 8 ++++----
.../collectionFreeForm/CollectionFreeFormLinksView.tsx | 4 ++--
src/new_fields/Doc.ts | 9 ++++++---
src/new_fields/List.ts | 2 +-
src/new_fields/util.ts | 16 +++++++++++++---
5 files changed, 26 insertions(+), 13 deletions(-)
(limited to 'src/new_fields/util.ts')
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3ed8ba3b2..2a6d72dbc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -57,8 +57,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
reaction(() => SelectionManager.SelectedDocuments().slice(), (docs) => docs.length === 0 && (this._edtingTitle = false));
}
- @action titleChanged = (event: any) => { this._title = event.target.value; }
- @action titleBlur = () => { this._edtingTitle = false; }
+ @action titleChanged = (event: any) => { this._title = event.target.value; };
+ @action titleBlur = () => { this._edtingTitle = false; };
@action titleEntered = (e: any) => {
var key = e.keyCode || e.which;
// enter pressed
@@ -238,7 +238,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
iconDoc.y = NumCast(doc.y) - 24;
iconDoc.maximizedDoc = doc;
doc.minimizedDoc = iconDoc;
- console.log("Layout " + iconDoc.layout)
+ console.log("Layout " + iconDoc.layout);
docView.props.addDocument && docView.props.addDocument(iconDoc, false);
return iconDoc;
}
@@ -274,7 +274,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
minDocs.map(minDoc => {
minDoc.x = NumCast(minDocs[0].x);
minDoc.y = NumCast(minDocs[0].y);
- minDoc.linkTags = new List(minDocs.filter(d => d != minDoc));
+ minDoc.linkTags = new List(minDocs.filter(d => d !== minDoc));
if (this._iconifying && selectedDocs[0].props.removeDocument) {
selectedDocs[0].props.removeDocument(minDoc);
(minDoc.maximizedDoc as Doc).minimizedDoc = undefined;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 4a75fccff..b34e0856e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -60,11 +60,11 @@ export class CollectionFreeFormLinksView extends React.Component();
}
let srcBrushDocs = Cast(srcTarg.brushingDocs, listSpec(Doc));
if (srcBrushDocs === undefined) {
- srcTarg.brushingDocs = srcBrushDocs = new List();
+ srcTarg.brushingDocs = srcBrushDocs = new List();
}
brushAction(dstBrushDocs);
brushAction(srcBrushDocs);
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 113380ce8..b2979af11 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -25,6 +25,7 @@ export type FieldResult = Opt | FieldWaiting { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
+ this[SelfProxy] = doc;
if (!id || forceSave) {
DocServer.CreateField(SerializationHelper.Serialize(doc));
}
@@ -68,7 +70,7 @@ export class Doc extends RefField {
const field = value[key];
if (!(field instanceof ObjectField)) continue;
field[Parent] = this[Self];
- field[OnUpdate] = updateFunction(this[Self], key, field);
+ field[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
}
}
@@ -81,8 +83,9 @@ export class Doc extends RefField {
}
private [Self] = this;
- public [WidthSym] = () => { return NumCast(this.__fields.width); } // bcz: is this the right way to access width/height? it didn't work with : this.width
- public [HeightSym] = () => { return NumCast(this.__fields.height); }
+ private [SelfProxy]: any;
+ public [WidthSym] = () => NumCast(this.__fields.width); // bcz: is this the right way to access width/height? it didn't work with : this.width
+ public [HeightSym] = () => NumCast(this.__fields.height);
}
export namespace Doc {
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 5852e2c30..ff10a3f73 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -218,7 +218,7 @@ class ListImpl extends ObjectField {
}
[Copy]() {
- let copiedData = this.__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
+ let copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
let deepCopy = new ListImpl(copiedData as any);
return deepCopy;
}
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 128817ab8..bbd8157f6 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -31,7 +31,7 @@ export const setter = action(function (target: any, prop: string | symbol | numb
throw new Error("Can't put the same object in multiple documents at the same time");
}
value[Parent] = target;
- value[OnUpdate] = updateFunction(target, prop, value);
+ value[OnUpdate] = updateFunction(target, prop, value, receiver);
}
if (curValue instanceof ObjectField) {
delete curValue[Parent];
@@ -86,9 +86,19 @@ export function deleteProperty(target: any, prop: string | number | symbol) {
throw new Error("Currently properties can't be deleted from documents, assign to undefined instead");
}
-export function updateFunction(target: any, prop: any, value: any) {
+export function updateFunction(target: any, prop: any, value: any, receiver: any) {
+ let current = ObjectField.MakeCopy(value);
return (diff?: any) => {
- if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ if (true || !diff) {
+ diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ const oldValue = current;
+ const newValue = ObjectField.MakeCopy(value);
+ current = newValue;
+ UndoManager.AddEvent({
+ redo() { receiver[prop] = newValue; },
+ undo() { receiver[prop] = oldValue; }
+ });
+ }
target[Update](diff);
};
}
\ No newline at end of file
--
cgit v1.2.3-70-g09d2