aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/Message.ts13
-rw-r--r--src/server/ServerUtil.ts64
-rw-r--r--src/server/authentication/controllers/WorkspacesMenu.css3
-rw-r--r--src/server/authentication/controllers/WorkspacesMenu.tsx89
-rw-r--r--src/server/authentication/models/current_user_utils.ts37
-rw-r--r--src/server/database.ts35
-rw-r--r--src/server/index.ts31
7 files changed, 86 insertions, 186 deletions
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 854ae0168..e9a8b0f0c 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -24,6 +24,14 @@ export interface Transferable {
readonly data?: any;
}
+export interface Reference {
+ readonly id: string;
+}
+
+export interface Diff extends Reference {
+ readonly diff: any;
+}
+
export namespace MessageStore {
export const Foo = new Message<string>("Foo");
export const Bar = new Message<string>("Bar");
@@ -32,4 +40,9 @@ export namespace MessageStore {
export const GetFields = new Message<string[]>("Get Fields"); // send string[] of 'id' get Transferable[] back
export const GetDocument = new Message<string>("Get Document");
export const DeleteAll = new Message<any>("Delete All");
+
+ export const GetRefField = new Message<string>("Get Ref Field");
+ export const GetRefFields = new Message<string[]>("Get Ref Fields");
+ export const UpdateField = new Message<Diff>("Update Ref Field");
+ export const CreateField = new Message<Reference>("Create Ref Field");
}
diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts
deleted file mode 100644
index eb5749dff..000000000
--- a/src/server/ServerUtil.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { HistogramField } from "../client/northstar/dash-fields/HistogramField";
-import { AudioField } from "../fields/AudioField";
-import { BooleanField } from "../fields/BooleanField";
-import { HtmlField } from "../fields/HtmlField";
-import { InkField } from "../fields/InkField";
-import { PDFField } from "../fields/PDFField";
-import { ScriptField } from "../fields/ScriptField";
-import { TupleField } from "../fields/TupleField";
-import { VideoField } from "../fields/VideoField";
-import { WebField } from "../fields/WebField";
-import { Utils } from "../Utils";
-import { Document } from "./../fields/Document";
-import { Field } from "./../fields/Field";
-import { ImageField } from "./../fields/ImageField";
-import { Key } from "./../fields/Key";
-import { ListField } from "./../fields/ListField";
-import { NumberField } from "./../fields/NumberField";
-import { RichTextField } from "./../fields/RichTextField";
-import { TextField } from "./../fields/TextField";
-import { Transferable, Types } from "./Message";
-import { TemplateField } from "../fields/TemplateField";
-import { IconField } from "../fields/IconFIeld";
-
-export class ServerUtils {
- public static prepend(extension: string): string {
- return window.location.origin + extension;
- }
-
- public static FromJson(json: Transferable): Field {
-
- if (!(json.data !== undefined && json.id && json.type !== undefined)) {
- console.log(
- "how did you manage to get an object that doesn't have a data or an id?"
- );
- return new TextField("Something to fill the space", Utils.GenerateGuid());
- }
-
- switch (json.type) {
- case Types.Boolean: return new BooleanField(json.data, json.id, false);
- case Types.Number: return new NumberField(json.data, json.id, false);
- case Types.Text: return new TextField(json.data, json.id, false);
- case Types.Icon: return new IconField(json.data, json.id, false);
- case Types.Html: return new HtmlField(json.data, json.id, false);
- case Types.Web: return new WebField(new URL(json.data), json.id, false);
- case Types.RichText: return new RichTextField(json.data, json.id, false);
- case Types.Key: return new Key(json.data, json.id, false);
- case Types.Image: return new ImageField(new URL(json.data), json.id, false);
- case Types.HistogramOp: return HistogramField.FromJson(json.id, json.data);
- case Types.PDF: return new PDFField(new URL(json.data), json.id, false);
- case Types.List: return ListField.FromJson(json.id, json.data);
- case Types.Script: return ScriptField.FromJson(json.id, json.data);
- case Types.Audio: return new AudioField(new URL(json.data), json.id, false);
- case Types.Video: return new VideoField(new URL(json.data), json.id, false);
- case Types.Tuple: return new TupleField(json.data, json.id, false);
- case Types.Ink: return InkField.FromJson(json.id, json.data);
- case Types.Templates: return TemplateField.FromJson(json.id, json.data);
- case Types.Document: return Document.FromJson(json.data, json.id, false);
- default:
- throw Error(
- "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"
- );
- }
- }
-}
diff --git a/src/server/authentication/controllers/WorkspacesMenu.css b/src/server/authentication/controllers/WorkspacesMenu.css
deleted file mode 100644
index b89039965..000000000
--- a/src/server/authentication/controllers/WorkspacesMenu.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.ids:hover {
- color: darkblue;
-} \ No newline at end of file
diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx
deleted file mode 100644
index b08c1aebe..000000000
--- a/src/server/authentication/controllers/WorkspacesMenu.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import * as React from 'react';
-import { observable, action, configure, reaction, computed, ObservableMap, runInAction } from 'mobx';
-import { observer } from "mobx-react";
-import './WorkspacesMenu.css';
-import { Document } from '../../../fields/Document';
-import { EditableView } from '../../../client/views/EditableView';
-import { KeyStore } from '../../../fields/KeyStore';
-
-export interface WorkspaceMenuProps {
- active: Document | undefined;
- open: (workspace: Document) => void;
- new: () => void;
- allWorkspaces: Document[];
- isShown: () => boolean;
- toggle: () => void;
-}
-
-@observer
-export class WorkspacesMenu extends React.Component<WorkspaceMenuProps> {
- constructor(props: WorkspaceMenuProps) {
- super(props);
- this.addNewWorkspace = this.addNewWorkspace.bind(this);
- }
-
- @action
- addNewWorkspace() {
- this.props.new();
- this.props.toggle();
- }
-
- render() {
- return (
- <div
- style={{
- width: "auto",
- maxHeight: '200px',
- overflow: 'scroll',
- borderRadius: 5,
- position: "absolute",
- top: 78,
- left: this.props.isShown() ? 11 : -500,
- background: "white",
- border: "black solid 2px",
- transition: "all 1s ease",
- zIndex: 15,
- padding: 10,
- paddingRight: 12,
- }}>
- <img
- src="https://bit.ly/2IBBkxk"
- style={{
- width: 20,
- height: 20,
- marginTop: 3,
- marginLeft: 3,
- marginBottom: 3,
- cursor: "grab"
- }}
- onClick={this.addNewWorkspace}
- />
- {this.props.allWorkspaces.map((s, i) =>
- <div
- key={s.Id}
- onContextMenu={(e) => {
- e.preventDefault();
- this.props.open(s);
- }}
- style={{
- marginTop: 10,
- color: s === this.props.active ? "red" : "black"
- }}
- >
- <span>{i + 1} - </span>
- <EditableView
- display={"inline"}
- GetValue={() => s.Title}
- SetValue={(title: string): boolean => {
- s.SetText(KeyStore.Title, title);
- return true;
- }}
- contents={s.Title}
- height={20}
- />
- </div>
- )}
- </div>
- );
- }
-} \ No newline at end of file
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 5d4479c88..5f45d7bcc 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -1,19 +1,20 @@
import { computed, observable, action, runInAction } from "mobx";
import * as rp from 'request-promise';
-import { Documents } from "../../../client/documents/Documents";
+import { Docs } from "../../../client/documents/Documents";
import { Attribute, AttributeGroup, Catalog, Schema } from "../../../client/northstar/model/idea/idea";
import { ArrayUtil } from "../../../client/northstar/utils/ArrayUtil";
-import { Server } from "../../../client/Server";
-import { Document } from "../../../fields/Document";
-import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
import { RouteStore } from "../../RouteStore";
-import { ServerUtils } from "../../ServerUtil";
+import { DocServer } from "../../../client/DocServer";
+import { Doc } from "../../../new_fields/Doc";
+import { List } from "../../../new_fields/List";
+import { CollectionViewType } from "../../../client/views/collections/CollectionBaseView";
+import { CollectionTreeView } from "../../../client/views/collections/CollectionTreeView";
+import { CollectionView } from "../../../client/views/collections/CollectionView";
export class CurrentUserUtils {
private static curr_email: string;
private static curr_id: string;
- @observable private static user_document: Document;
+ @observable private static user_document: Doc;
//TODO tfs: these should be temporary...
private static mainDocId: string | undefined;
@@ -23,15 +24,21 @@ export class CurrentUserUtils {
public static get MainDocId() { return this.mainDocId; }
public static set MainDocId(id: string | undefined) { this.mainDocId = id; }
- private static createUserDocument(id: string): Document {
- let doc = new Document(id);
- doc.Set(KeyStore.Workspaces, new ListField<Document>());
- doc.Set(KeyStore.OptionalRightCollection, Documents.SchemaDocument([], { title: "Pending documents" }));
+ private static createUserDocument(id: string): Doc {
+ let doc = new Doc(id, true);
+ doc.viewType = CollectionViewType.Tree;
+ doc.layout = CollectionView.LayoutString();
+ doc.title = this.email;
+ doc.data = new List<Doc>();
+ doc.excludeFromLibrary = true;
+ doc.optionalRightCollection = Docs.SchemaDocument([], { title: "Pending documents" });
+ // doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` });
+ // (doc.library as Doc).excludeFromLibrary = true;
return doc;
}
public static loadCurrentUser(): Promise<any> {
- let userPromise = rp.get(ServerUtils.prepend(RouteStore.getCurrUser)).then(response => {
+ let userPromise = rp.get(DocServer.prepend(RouteStore.getCurrUser)).then(response => {
if (response) {
let obj = JSON.parse(response);
CurrentUserUtils.curr_id = obj.id as string;
@@ -40,10 +47,10 @@ export class CurrentUserUtils {
throw new Error("There should be a user! Why does Dash think there isn't one?");
}
});
- let userDocPromise = rp.get(ServerUtils.prepend(RouteStore.getUserDocumentId)).then(id => {
+ let userDocPromise = rp.get(DocServer.prepend(RouteStore.getUserDocumentId)).then(id => {
if (id) {
- return Server.GetField(id).then(field =>
- runInAction(() => this.user_document = field instanceof Document ? field : this.createUserDocument(id)));
+ return DocServer.GetRefField(id).then(field =>
+ runInAction(() => this.user_document = field instanceof Doc ? field : this.createUserDocument(id)));
} else {
throw new Error("There should be a user id! Why does Dash think there isn't one?");
}
diff --git a/src/server/database.ts b/src/server/database.ts
index 5457e4dd5..37cfcf3a3 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -13,14 +13,14 @@ export class Database {
this.MongoClient.connect(this.url, (err, client) => this.db = client.db());
}
- public update(id: string, value: any, callback: () => void) {
+ public update(id: string, value: any, callback: () => void, upsert = true, collectionName = Database.DocumentsCollection) {
if (this.db) {
- let collection = this.db.collection('documents');
+ let collection = this.db.collection(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
const run = (): Promise<void> => {
return new Promise<void>(resolve => {
- collection.updateOne({ _id: id }, { $set: value }, { upsert: true }
+ collection.updateOne({ _id: id }, value, { upsert }
, (err, res) => {
if (err) {
console.log(err.message);
@@ -51,24 +51,37 @@ export class Database {
this.db && this.db.collection(collectionName).deleteMany({}, res));
}
- public insert(kvpairs: any, collectionName = Database.DocumentsCollection) {
- this.db && this.db.collection(collectionName).insertOne(kvpairs, (err, res) =>
- err // && console.log(err)
- );
+ public insert(value: any, collectionName = Database.DocumentsCollection) {
+ if ("id" in value) {
+ value._id = value.id;
+ delete value.id;
+ }
+ this.db && this.db.collection(collectionName).insertOne(value);
}
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) {
- 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) {
- 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 70a7d266c..6801b3132 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -16,13 +16,12 @@ import { Socket } from 'socket.io';
import * as webpack from 'webpack';
import * as wdm from 'webpack-dev-middleware';
import * as whm from 'webpack-hot-middleware';
-import { Field, FieldId } from '../fields/Field';
import { Utils } from '../Utils';
import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/controllers/user_controller';
import { DashUserModel } from './authentication/models/user_model';
import { Client } from './Client';
import { Database } from './database';
-import { MessageStore, Transferable } from "./Message";
+import { MessageStore, Transferable, Diff } from "./Message";
import { RouteStore } from './RouteStore';
const app = express();
const config = require('../../webpack.config');
@@ -232,14 +231,21 @@ server.on("connection", function (socket: Socket) {
Utils.AddServerHandlerCallback(socket, MessageStore.GetField, getField);
Utils.AddServerHandlerCallback(socket, MessageStore.GetFields, getFields);
Utils.AddServerHandler(socket, MessageStore.DeleteAll, deleteFields);
+
+ Utils.AddServerHandler(socket, MessageStore.CreateField, CreateField);
+ Utils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff));
+ 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');
}
@@ -262,5 +268,22 @@ function setField(socket: Socket, newValue: Transferable) {
socket.broadcast.emit(MessageStore.SetField.Message, newValue));
}
+function GetRefField([id, callback]: [string, (result?: Transferable) => void]) {
+ Database.Instance.getDocument(id, callback, "newDocuments");
+}
+
+function GetRefFields([ids, callback]: [string[], (result?: Transferable[]) => void]) {
+ Database.Instance.getDocuments(ids, callback, "newDocuments");
+}
+
+function UpdateField(socket: Socket, diff: Diff) {
+ Database.Instance.update(diff.id, diff.diff,
+ () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false, "newDocuments");
+}
+
+function CreateField(newValue: any) {
+ Database.Instance.insert(newValue, "newDocuments");
+}
+
server.listen(serverPort);
console.log(`listening on port ${serverPort}`); \ No newline at end of file