aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deploy/assets/downarrow.pngbin0 -> 3363 bytes
-rw-r--r--src/client/util/DragManager.ts1
-rw-r--r--src/client/util/LinkManager.ts38
-rw-r--r--src/client/util/SearchUtil.ts33
-rw-r--r--src/client/util/TooltipTextMenu.scss2
-rw-r--r--src/client/util/TooltipTextMenu.tsx32
-rw-r--r--src/client/views/Main.scss18
-rw-r--r--src/client/views/MainView.tsx35
-rw-r--r--src/client/views/Templates.tsx3
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx4
-rw-r--r--src/client/views/collections/CollectionStackingView.scss14
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx64
-rw-r--r--src/client/views/collections/CollectionSubView.tsx1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx22
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx16
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx3
-rw-r--r--src/client/views/nodes/LinkEditor.tsx5
-rw-r--r--src/client/views/nodes/LinkMenuItem.tsx12
-rw-r--r--src/client/views/pdf/PDFMenu.tsx19
-rw-r--r--src/client/views/pdf/Page.tsx4
-rw-r--r--src/client/views/search/SearchItem.tsx18
-rw-r--r--src/new_fields/Doc.ts21
-rw-r--r--src/new_fields/Types.ts3
-rw-r--r--src/new_fields/util.ts2
-rw-r--r--src/server/GarbageColletor.ts51
-rw-r--r--src/server/authentication/models/current_user_utils.ts39
-rw-r--r--src/server/database.ts14
-rw-r--r--src/server/index.ts7
-rw-r--r--tance.jumpToDocument(linkedFwdDocs[altKey  1  0], ctrlKey, false, document = this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey  1  0], targetContext);792
32 files changed, 346 insertions, 935 deletions
diff --git a/deploy/assets/downarrow.png b/deploy/assets/downarrow.png
new file mode 100644
index 000000000..3c59ff5b1
--- /dev/null
+++ b/deploy/assets/downarrow.png
Binary files differ
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index f9492f452..6c2340d04 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -321,6 +321,7 @@ export namespace DragManager {
dragElement.style.top = "0";
dragElement.style.bottom = "";
dragElement.style.left = "0";
+ dragElement.style.transition = "none";
dragElement.style.color = "black";
dragElement.style.transformOrigin = "0 0";
dragElement.style.zIndex = globalCssVariables.contextMenuZindex;// "1000";
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index f2f3e51dd..944bc532f 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -68,8 +68,8 @@ export class LinkManager {
// finds all links that contain the given anchor
public getAllRelatedLinks(anchor: Doc): Doc[] {//List<Doc> {
let related = LinkManager.Instance.getAllLinks().filter(link => {
- let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc));
- let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, new Doc));
+ let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null));
+ let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null));
return protomatch1 || protomatch2;
});
return related;
@@ -100,9 +100,11 @@ export class LinkManager {
if (index > -1) groupTypes.splice(index, 1);
LinkManager.Instance.LinkManagerDoc.allGroupTypes = new List<string>(groupTypes);
LinkManager.Instance.LinkManagerDoc[groupType] = undefined;
- LinkManager.Instance.getAllLinks().forEach(linkDoc => {
- LinkManager.Instance.removeGroupFromAnchor(linkDoc, Cast(linkDoc.anchor1, Doc, new Doc), groupType);
- LinkManager.Instance.removeGroupFromAnchor(linkDoc, Cast(linkDoc.anchor2, Doc, new Doc), groupType);
+ LinkManager.Instance.getAllLinks().forEach(async linkDoc => {
+ const anchor1 = await Cast(linkDoc.anchor1, Doc);
+ const anchor2 = await Cast(linkDoc.anchor2, Doc);
+ anchor1 && LinkManager.Instance.removeGroupFromAnchor(linkDoc, anchor1, groupType);
+ anchor2 && LinkManager.Instance.removeGroupFromAnchor(linkDoc, anchor2, groupType);
});
}
return true;
@@ -122,8 +124,8 @@ export class LinkManager {
}
// gets the groups associates with an anchor in a link
- public getAnchorGroups(linkDoc: Doc, anchor: Doc): Array<Doc> {
- if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, new Doc))) {
+ public getAnchorGroups(linkDoc: Doc, anchor?: Doc): Array<Doc> {
+ if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) {
return DocListCast(linkDoc.anchor1Groups);
} else {
return DocListCast(linkDoc.anchor2Groups);
@@ -132,7 +134,7 @@ export class LinkManager {
// sets the groups of the given anchor in the given link
public setAnchorGroups(linkDoc: Doc, anchor: Doc, groups: Doc[]) {
- if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, new Doc))) {
+ if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) {
linkDoc.anchor1Groups = new List<Doc>(groups);
} else {
linkDoc.anchor2Groups = new List<Doc>(groups);
@@ -209,10 +211,10 @@ export class LinkManager {
let md: Doc[] = [];
let allLinks = LinkManager.Instance.getAllLinks();
allLinks.forEach(linkDoc => {
- let anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, new Doc));
- let anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, new Doc));
- anchor1Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) md.push(Cast(groupDoc.metadata, Doc, new Doc)); });
- anchor2Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) md.push(Cast(groupDoc.metadata, Doc, new Doc)); });
+ let anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, null));
+ let anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, null));
+ anchor1Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } });
+ anchor2Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } });
});
return md;
}
@@ -221,18 +223,20 @@ export class LinkManager {
public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean {
let allLinks = LinkManager.Instance.getAllLinks();
let index = allLinks.findIndex(linkDoc => {
- return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, new Doc), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, new Doc), anchor2)) ||
- (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, new Doc), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, new Doc), anchor1));
+ return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) ||
+ (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1));
});
return index !== -1;
}
// finds the opposite anchor of a given anchor in a link
+ //TODO This should probably return undefined if there isn't an opposite anchor
+ //TODO This should also await the return value of the anchor so we don't filter out promises
public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc {
- if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, new Doc))) {
- return Cast(linkDoc.anchor2, Doc, new Doc);
+ if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) {
+ return Cast(linkDoc.anchor2, Doc, null)!;
} else {
- return Cast(linkDoc.anchor1, Doc, new Doc);
+ return Cast(linkDoc.anchor1, Doc, null)!;
}
}
} \ No newline at end of file
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index ac2eb72e7..338628960 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -29,11 +29,16 @@ export namespace SearchUtil {
return { docs, numFound };
}
- export async function GetAliasesOfDocument(doc: Doc): Promise<Doc[]> {
- const proto = await Doc.GetT(doc, "proto", Doc, true);
- const protoId = (proto || doc)[Id];
- const result = await Search(`proto_i:"${protoId}"`, true);
- return result.docs;
+ export async function GetAliasesOfDocument(doc: Doc): Promise<Doc[]>;
+ export async function GetAliasesOfDocument(doc: Doc, returnDocs: false): Promise<string[]>;
+ export async function GetAliasesOfDocument(doc: Doc, returnDocs = true): Promise<Doc[] | string[]> {
+ const proto = Doc.GetProto(doc);
+ const protoId = proto[Id];
+ if (returnDocs) {
+ return (await Search(`proto_i:"${protoId}"`, returnDocs)).docs;
+ } else {
+ return (await Search(`proto_i:"${protoId}"`, returnDocs)).ids;
+ }
// return Search(`{!join from=id to=proto_i}id:${protoId}`, true);
}
@@ -41,4 +46,22 @@ export namespace SearchUtil {
const results = await Search(`proto_i:"${doc[Id]}"`, true);
return results.docs;
}
+
+ export async function GetContextsOfDocument(doc: Doc): Promise<{ contexts: Doc[], aliasContexts: Doc[] }> {
+ const docContexts = (await Search(`data_l:"${doc[Id]}"`, true)).docs;
+ const aliases = await GetAliasesOfDocument(doc, false);
+ const aliasContexts = (await Promise.all(aliases.map(doc => Search(`data_l:"${doc}"`, true))));
+ const contexts = { contexts: docContexts, aliasContexts: [] as Doc[] };
+ aliasContexts.forEach(result => contexts.aliasContexts.push(...result.docs));
+ return contexts;
+ }
+
+ export async function GetContextIdsOfDocument(doc: Doc): Promise<{ contexts: string[], aliasContexts: string[] }> {
+ const docContexts = (await Search(`data_l:"${doc[Id]}"`, false)).ids;
+ const aliases = await GetAliasesOfDocument(doc, false);
+ const aliasContexts = (await Promise.all(aliases.map(doc => Search(`data_l:"${doc}"`, false))));
+ const contexts = { contexts: docContexts, aliasContexts: [] as string[] };
+ aliasContexts.forEach(result => contexts.aliasContexts.push(...result.ids));
+ return contexts;
+ }
} \ No newline at end of file
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss
index b10573b3e..40ac3abb9 100644
--- a/src/client/util/TooltipTextMenu.scss
+++ b/src/client/util/TooltipTextMenu.scss
@@ -248,7 +248,7 @@
transform: translateY(-85px);
pointer-events: all;
height: 30px;
- width:500px;
+ width:550px;
.ProseMirror-example-setup-style hr {
padding: 2px 10px;
border: none;
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index e3e26d1f4..cb7ed976a 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -32,7 +32,6 @@ export class TooltipTextMenu {
private fontSizeToNum: Map<MarkType, number>;
private fontStylesToName: Map<MarkType, string>;
private listTypeToIcon: Map<NodeType, string>;
- private link: HTMLAnchorElement;
private linkEditor?: HTMLDivElement;
private linkText?: HTMLDivElement;
@@ -89,6 +88,7 @@ export class TooltipTextMenu {
});
});
+ this.updateLinkMenu();
//list of font styles
this.fontStylesToName = new Map();
@@ -121,11 +121,6 @@ export class TooltipTextMenu {
this.listTypeToIcon.set(schema.nodes.ordered_list, "1)");
this.listTypes = Array.from(this.listTypeToIcon.keys());
- this.link = document.createElement("a");
- this.link.target = "_blank";
- this.link.style.color = "white";
- //this.tooltip.appendChild(this.link);
-
this.tooltip.appendChild(this.createLink().render(this.view).dom);
this.tooltip.appendChild(this.createStar().render(this.view).dom);
@@ -191,6 +186,7 @@ export class TooltipTextMenu {
updateLinkMenu() {
if (!this.linkEditor || !this.linkText) {
this.linkEditor = document.createElement("div");
+ this.linkEditor.className = "ProseMirror-icon menuicon";
this.linkEditor.style.color = "black";
this.linkText = document.createElement("div");
this.linkText.style.cssFloat = "left";
@@ -231,8 +227,9 @@ export class TooltipTextMenu {
};
this.linkDrag = document.createElement("img");
this.linkDrag.src = "https://seogurusnyc.com/wp-content/uploads/2016/12/link-1.png";
- this.linkDrag.style.width = "20px";
- this.linkDrag.style.height = "20px";
+ this.linkDrag.style.width = "15px";
+ this.linkDrag.style.height = "15px";
+ this.linkDrag.title = "Drag to create link";
this.linkDrag.style.color = "black";
this.linkDrag.style.background = "black";
this.linkDrag.style.cssFloat = "left";
@@ -250,10 +247,10 @@ export class TooltipTextMenu {
hideSource: false
});
};
- // this.linkEditor.appendChild(this.linkDrag);
+ this.linkEditor.appendChild(this.linkDrag);
// this.linkEditor.appendChild(this.linkText);
// this.linkEditor.appendChild(linkBtn);
- //this.tooltip.appendChild(this.linkEditor);
+ this.tooltip.appendChild(this.linkEditor);
}
let node = this.view.state.selection.$from.nodeAfter;
@@ -444,16 +441,24 @@ export class TooltipTextMenu {
enable(state) { return !state.selection.empty; },
run: (state, dispatch, view) => {
// to remove link
+ let curLink = "";
if (this.markActive(state, markType)) {
- toggleMark(markType)(state, dispatch);
- return true;
+
+ let { from, $from, to, empty } = state.selection;
+ let node = state.doc.nodeAt(from);
+ node && node.marks.map(m => {
+ m.type === markType && (curLink = m.attrs.href);
+ })
+ //toggleMark(markType)(state, dispatch);
+ //return true;
}
// to create link
openPrompt({
title: "Create a link",
fields: {
href: new TextField({
- label: "Link target",
+ value: curLink,
+ label: "Link Target",
required: true
}),
title: new TextField({ label: "Title" })
@@ -603,7 +608,6 @@ export class TooltipTextMenu {
}
}
this.view.dispatch(this.view.state.tr.setStoredMarks(this._activeMarks));
- this.updateLinkMenu();
}
//finds all active marks on selection in given group
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index b85a8040a..f52e3b658 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -230,6 +230,8 @@ ul#add-options-list {
.mainView-libraryFlyout {
height: 100%;
position: absolute;
+ display: flex;
+ flex-direction:column;
}
.mainView-libraryHandle {
@@ -241,4 +243,20 @@ ul#add-options-list {
position: absolute;
z-index: 1;
background: gray;
+}
+
+.mainView-workspace {
+ height:200px;
+ position:relative;
+ display:flex;
+}
+.mainView-library {
+ height:75%;
+ position:relative;
+ display:flex;
+}
+.mainView-recentlyClosed {
+ height:25%;
+ position:relative;
+ display:flex;
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 61ccf4c1d..fe59f52c8 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,19 +1,19 @@
import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faArrowUp, faBell, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faArrowUp, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, configure, observable, runInAction } from 'mobx';
+import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx';
import { observer } from 'mobx-react';
import "normalize.css";
import * as React from 'react';
import { SketchPicker } from 'react-color';
import Measure from 'react-measure';
import * as request from 'request';
-import { Doc, DocListCast, Opt } from '../../new_fields/Doc';
+import { Doc, DocListCast, Opt, HeightSym } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { InkTool } from '../../new_fields/InkField';
import { List } from '../../new_fields/List';
import { listSpec } from '../../new_fields/Schema';
-import { Cast, FieldValue } from '../../new_fields/Types';
+import { Cast, FieldValue, NumCast } from '../../new_fields/Types';
import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
import { RouteStore } from '../../server/RouteStore';
import { emptyFunction, returnOne, returnTrue } from '../../Utils';
@@ -72,6 +72,22 @@ export class MainView extends React.Component {
window.removeEventListener("pointerup", this.pointerUp);
window.addEventListener("pointerup", this.pointerUp);
+
+ reaction(() => {
+ let workspaces = CurrentUserUtils.UserDocument.workspaces;
+ let recent = CurrentUserUtils.UserDocument.recentlyClosed;
+ if (!(recent instanceof Doc)) return 0;
+ if (!(workspaces instanceof Doc)) return 0;
+ let workspacesDoc = workspaces;
+ let recentDoc = recent;
+ let libraryHeight = this.getPHeight() - workspacesDoc[HeightSym]() - recentDoc[HeightSym]() - 20 + CurrentUserUtils.UserDocument[HeightSym]() * 0.00001;
+ return libraryHeight;
+ }, (libraryHeight: number) => {
+ if (libraryHeight && Math.abs(CurrentUserUtils.UserDocument[HeightSym]() - libraryHeight) > 5) {
+ CurrentUserUtils.UserDocument.height = libraryHeight;
+ }
+ (Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc) as Doc)!.allowClear = true;
+ }, { fireImmediately: true });
}
pointerDown = (e: PointerEvent) => this.isPointerDown = true;
@@ -163,7 +179,9 @@ export class MainView extends React.Component {
@action
createNewWorkspace = async (id?: string) => {
- const list = Cast(CurrentUserUtils.UserDocument.data, listSpec(Doc));
+ let workspaces = Cast(CurrentUserUtils.UserDocument.workspaces, Doc);
+ if (!(workspaces instanceof Doc)) return;
+ const list = Cast((CurrentUserUtils.UserDocument.workspaces as Doc).data, listSpec(Doc));
if (list) {
let freeformDoc = Docs.FreeformDocument([], { x: 0, y: 400, width: this.pwidth * .7, height: this.pheight, title: `WS collection ${list.length + 1}` });
var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
@@ -285,8 +303,11 @@ export class MainView extends React.Component {
};
@computed
get flyout() {
+ let sidebar = CurrentUserUtils.UserDocument.sidebar;
+ if (!(sidebar instanceof Doc)) return (null);
+ let sidebarDoc = sidebar;
return <DocumentView
- Document={CurrentUserUtils.UserDocument}
+ Document={sidebarDoc}
DataDoc={undefined}
addDocument={undefined}
addDocTab={this.addDocTabFunc}
@@ -304,7 +325,7 @@ export class MainView extends React.Component {
ContainingCollectionView={undefined}
zoomToScale={emptyFunction}
getScale={returnOne}>
- </DocumentView>;
+ </DocumentView>
}
@computed
get mainContent() {
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index 4843a70a6..236704fa2 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -69,8 +69,7 @@ export namespace Templates {
`< div >
<div style="height:100%; width:100%;position:absolute;">{layout}</div>
<div id="isExpander" style="height:15px; width:15px; margin-left:-16px; pointer-events:all; position:absolute; top: 0; background-color: rgba(0, 0, 0, .4); color: white;">
- <img id="isExpander" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAZlBMVEX///8AAABmZmb7+/tYWFhgYGBFRUVSUlL4+Pg/Pz9jY2N5eXmcnJyioqKBgYFzc3NtbW1LS0s3NzfW1taWlpaOjo6IiIgvLy9WVlampqZcXFw5OTlvb28mJiYxMTHe3t7l5eUjIyMY8kIZAAAD2UlEQVR4nO2d61biMBRGW1FBEVHxfp15/5ecOVa5lHxtArmck/Xtn1BotjtNoXQtm4YQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEFIrX6UHEA1gsmrneceRjHm7cj28attKFOf/TRyKIliH4vzbZE+xE2zbZYkxRWX5Y9JT/BW0X3G+NtlR3Ahar7jcMtlS3Ba0XXG+Y7JW3BW0XHHZM/lR7AvaVewL/ijuC1pV3Bf8VnQJ2lR0CYriq/Nxg4puwfa1aZ7dz9yUHnEgN26NZ3luWkPFd7fEtHsWVDwpO+YgTgYKCuYn6tAU7TBecaygcGpZEQie7m5luKJPQQFUvCwx5iAuvQoK4KShvSIoOHVtCz7dnOUecxBn7kG/urc2eCz6T9EOcxXDCgpAUetyAwoOCBqrGF5QMKR4mCA8L+pTBIJwkRl95eifJjPHTDYTFQ8vePyrs3BsBfXLzfFHkvKKMY4j1ctNnCmmuGKslfCQT0RZiPdFVmnFmOcy36sDWYn7DU9hxdifRkKuEGQh/pWW0K/QiUlxtUxVxTTXyhQtN6kuI6mpmO5qpxJFIBjl1yMVimmvV4PfrnIq3iYsKICTRj7F9L84gIq38fYwCCj4HnMfRY/FPL8ZFayYo6BQbLlJeZrYpVDFXAUFcMtKWkUgmOhmnwKKOQsK4NaxdIp5CwqZj8X8gv27jNecJ9nZuXtnie/SzjhRQcHkt6Fnq1imoAAUY1csVVDIUrFcQSGDIhC8jriLQZIrli0oXKdVLF1QSFqxfEEBVLyI8NYXCgoKySaqhinakajimxrBRBX1FBQSVNRyDP4SXVGbYHRFfYJN8xhTESwyj5HHHEjEihoLCqDiXfAb3aksKESqCAoqEIxUUW9BAS03E+93mOhcZDYcXVF3QeHBPcI3v4qo4EPiUQcBKr75vHaiv6AAKt6NV0SCqgoKqOKYovpFZgOo+DmsOHkyUlA4ZKKamaIdQPEJK5oqKKCKM7D9zFZBIayiuYICWm5cFWef7o3vs486CP8VdQIEVRcU7sFE7VecgSmqvKDgVxEJqi8ogIof2xVnH2YLCuMT1fAU7RirOPtrXHCsovmCwlDFCgoKWNH4IrMBTdQ/NUzRjiu3CeCq9HAPAVSspaDgX9FkQcG3ollB34qGBf0UTQv6KBoXHFc0LzimWIFg0ywGBBelBxcHXLGKggKqWElBwV2xIkF3xaoEXYqVCe4rVifYV3wpPZwULOouKLzUXVBY1F1QeKm7oLCoXVAqVi7YNM7/F0YIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCG+/ANh4i1CHdc63QAAAABJRU5ErkJggg=="
- width="15px" height="15px" />
+ <img id="isExpander" src="/assets/downarrow.png" width="15px" height="15px" />
</div>
</div > `
);
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 879898018..e4f9b5058 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -64,7 +64,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
active = (): boolean => {
var isSelected = this.props.isSelected();
- return isSelected || this._isChildActive || this.props.renderDepth === 0;
+ return isSelected || this._isChildActive || this.props.renderDepth === 0 || BoolCast(this.props.Document.excludeFromLibrary);
}
//TODO should this be observable?
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 19d07ecdc..d477f96f0 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -27,6 +27,7 @@ import { MainView } from '../MainView';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';
import { faFile } from '@fortawesome/free-solid-svg-icons';
+import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
library.add(faFile);
@observer
@@ -405,6 +406,9 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
if (doc instanceof Doc) {
let theDoc = doc;
CollectionDockingView.Instance._removedDocs.push(theDoc);
+ if (CurrentUserUtils.UserDocument.recentlyClosed instanceof Doc) {
+ Doc.AddDocToList(CurrentUserUtils.UserDocument.recentlyClosed, "data", doc, undefined, true, true);
+ }
SelectionManager.DeselectAll();
}
tab.contentItem.remove();
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 034a09eaa..bc733f152 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -16,7 +16,7 @@
align-items: center;
}
- .collectionStackingView-masonrySingle, .collectionStackingView-masonryGrid{
+ .collectionStackingView-masonrySingle, .collectionStackingView-masonryGrid {
width:100%;
height:100%;
position: absolute;
@@ -25,7 +25,17 @@
left: 0;
width: 100%;
position: absolute;
-
+ }
+ .collectionStackingView-masonrySingle {
+ width:100%;
+ height:100%;
+ position: absolute;
+ display:flex;
+ flex-direction: column;
+ top: 0;
+ left: 0;
+ width: 100%;
+ position: absolute;
}
.collectionStackingView-description {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 6b4eddec9..aea74321e 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, reaction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, untracked } from "mobx";
import { observer } from "mobx-react";
import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
@@ -10,7 +10,6 @@ import { ContextMenu } from "../ContextMenu";
import { CollectionSchemaPreview } from "./CollectionSchemaView";
import "./CollectionStackingView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { resolve } from "bluebird";
import { undoBatch } from "../../util/UndoManager";
import { DragManager } from "../../util/DragManager";
@@ -25,6 +24,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
@computed get columnWidth() { return this.singleColumn ? (this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin) : Math.min(this.props.PanelWidth() - 2 * this.xMargin, NumCast(this.props.Document.columnWidth, 250)); }
+ @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
singleColDocHeight(d: Doc) {
let nw = NumCast(d.nativeWidth);
@@ -35,14 +35,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
}
componentDidMount() {
this._heightDisposer = reaction(() => [this.yMargin, this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
- () => {
- if (this.singleColumn) {
- let children = this.childDocs.filter(d => !d.isMinimized);
- this.props.Document.height = children.reduce((height, d, i) =>
- height + this.singleColDocHeight(d) + (i === children.length - 1 ? this.yMargin : this.gridGap)
- , this.yMargin);
- }
- }, { fireImmediately: true });
+ () => this.singleColumn &&
+ (this.props.Document.height = this.filteredChildren.reduce((height, d, i) =>
+ height + this.singleColDocHeight(d) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap), this.yMargin))
+ , { fireImmediately: true });
}
componentWillUnmount() {
if (this._heightDisposer) this._heightDisposer();
@@ -50,14 +46,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@action
moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => {
- this.props.removeDocument(doc);
- addDocument(doc);
- return true;
+ return this.props.removeDocument(doc) && addDocument(doc);
}
- getDocTransform(doc: Doc, dref: HTMLDivElement) {
- let { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
+ getSingleDocTransform(doc: Doc, ind: number, width: number) {
+ let localY = this.filteredChildren.reduce((height, d, i) =>
+ height + (i < ind ? this.singleColDocHeight(d) + this.gridGap : 0), this.yMargin);
+ let translate = this.props.ScreenToLocalTransform().inverse().transformPoint((this.props.PanelWidth() - width) / 2, localY);
let outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
- let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+ let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translate[0], outerXf.translateY - translate[1]);
return this.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.columnWidth);
}
createRef = (ele: HTMLDivElement | null) => {
@@ -67,17 +63,15 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed
get singleColumnChildren() {
- let children = this.childDocs.filter(d => !d.isMinimized);
- return children.map((d, i) => {
+ return this.filteredChildren.map((d, i) => {
let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
- let dref = React.createRef<HTMLDivElement>();
- let dxf = () => this.getDocTransform(layoutDoc, dref.current!).scale(this.columnWidth / d[WidthSym]());
let width = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
let height = () => this.singleColDocHeight(layoutDoc);
+ let dxf = () => this.getSingleDocTransform(layoutDoc, i, width()).scale(this.columnWidth / d[WidthSym]());
+ let gap = i === 0 ? 0 : this.gridGap;
return <div className="collectionStackingView-columnDoc"
key={d[Id]}
- ref={dref}
- style={{ width: width(), height: height() }} >
+ style={{ width: width(), display: "inline-block", marginTop: gap, height: `${height() / (this.props.Document[HeightSym]() - 2 * this.yMargin) * 100}%` }} >
<CollectionSchemaPreview
Document={layoutDoc}
DataDocument={d !== this.props.DataDoc ? this.props.DataDoc : undefined}
@@ -98,11 +92,17 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
</div>;
});
}
+ getDocTransform(doc: Doc, dref: HTMLDivElement) {
+ let { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
+ let outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
+ let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+ return this.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.columnWidth);
+ }
docXfs: any[] = []
@computed
get children() {
this.docXfs.length = 0;
- return this.childDocs.filter(d => !d.isMinimized).map((d, i) => {
+ return this.filteredChildren.map((d, i) => {
let aspect = d.nativeHeight ? NumCast(d.nativeWidth) / NumCast(d.nativeHeight) : undefined;
let dref = React.createRef<HTMLDivElement>();
let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
@@ -187,14 +187,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
})
}
if (super.drop(e, de)) {
- if (targInd !== -1) {
- let newDoc = de.data.droppedDocuments[0];
- let docs = this.childDocList;
- if (docs) {
- let srcInd = docs.indexOf(newDoc);
- docs.splice(srcInd, 1);
- docs.splice(targInd > srcInd ? targInd - 1 : targInd, 0, newDoc);
- }
+ let newDoc = de.data.droppedDocuments[0];
+ let docs = this.childDocList;
+ if (docs) {
+ if (targInd === -1) targInd = docs.length;
+ else targInd = docs.indexOf(this.filteredChildren[targInd]);
+ let srcInd = docs.indexOf(newDoc);
+ docs.splice(srcInd, 1);
+ docs.splice(targInd > srcInd ? targInd - 1 : targInd, 0, newDoc);
}
}
return false;
@@ -223,7 +223,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
});
}
render() {
- let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.childDocs.filter(d => !d.isMinimized).length,
+ let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
let templatecols = "";
for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 79c23d71a..5287d3c13 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -102,6 +102,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
return added;
}
else if (de.data instanceof DragManager.AnnotationDragData) {
+ e.stopPropagation();
return this.props.addDocument(de.data.dropDocument);
}
return false;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 93a1ec1eb..d7725f444 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faAngleRight, faCamera, faExpand, faBell, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
+import { faAngleRight, faCamera, faExpand, faTrash, faBell, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, trace } from "mobx";
import { observer } from "mobx-react";
@@ -51,6 +51,7 @@ export interface TreeViewProps {
library.add(faTrashAlt);
library.add(faAngleRight);
library.add(faBell);
+library.add(faTrash);
library.add(faCamera);
library.add(faExpand);
library.add(faCaretDown);
@@ -471,9 +472,12 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
- if (!e.isPropagationStopped() && this.props.Document.excludeFromLibrary) { // excludeFromLibrary means this is the user document
+ if (!e.isPropagationStopped() && this.props.Document.workspaceLibrary) { // excludeFromLibrary means this is the user document
ContextMenu.Instance.addItem({ description: "Create Workspace", event: undoBatch(() => MainView.Instance.createNewWorkspace()) });
ContextMenu.Instance.addItem({ description: "Delete Workspace", event: undoBatch(() => this.remove(this.props.Document)) });
+ e.stopPropagation();
+ e.preventDefault();
+ ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
}
}
@@ -506,6 +510,17 @@ export class CollectionTreeView extends CollectionSubView(Document) {
</div>
</div >;
}
+ @computed get clearButton() {
+ return <div id="toolbar" key="toolbar">
+ <div >
+ <button className="toolbar-button round-button" title="Notifs"
+ onClick={undoBatch(action(() => Doc.GetProto(this.props.Document)[this.props.fieldKey] = undefined))}>
+ <FontAwesomeIcon icon={faTrash} size="sm" />
+ </button>
+ </div>
+ </div >;
+ }
+
render() {
let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
@@ -531,7 +546,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
TreeView.loadId = doc[Id];
Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true);
}} />
- {this.props.Document.excludeFromLibrary ? this.notifsButton : (null)}
+ {this.props.Document.workspaceLibrary ? this.notifsButton : (null)}
+ {this.props.Document.allowClear ? this.clearButton : (null)}
<ul className="no-indent" style={{ width: "max-content" }} >
{
TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4b7d462e5..7a22b7ec3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -249,16 +249,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
var scale = this.getLocalTransform().inverse().Scale;
const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight, Math.max(0, panY));
- // this.props.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
- // this.props.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
- this.props.Document.panX = panX;
+ this.props.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
+ this.props.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
+ // this.props.Document.panX = panX;
+ // this.props.Document.panY = panY;
if (this.props.Document.scrollY) {
this.props.Document.scrollY = panY;
- this.props.Document.panY = panY;
- }
- else {
-
- this.props.Document.panY = panY;
}
}
@@ -468,8 +464,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
description: "Add freeform arrangement",
event: () => {
let addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
- const docs = DocListCast(this.Document[this.props.fieldKey]);
- docs.map(d => d.transition = "transform 1s");
let overlayDisposer: () => void;
const script = this.Document[key];
let originalText: string | undefined = undefined;
@@ -484,6 +478,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
onError(script.errors.map(error => error.messageText).join("\n"));
return;
}
+ const docs = DocListCast(this.Document[this.props.fieldKey]);
+ docs.map(d => d.transition = "transform 1s");
this.Document[key] = new ScriptField(script);
overlayDisposer();
setTimeout(() => docs.map(d => d.transition = undefined), 1200);
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 0da4888a1..56a14e26e 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -24,6 +24,7 @@ import { Without, OmitKeys } from "../../../Utils";
import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { Doc } from "../../../new_fields/Doc";
+import { CollectionViewType } from "../collections/CollectionBaseView";
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
type BindingProps = Without<FieldViewProps, 'fieldKey'>;
@@ -82,7 +83,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
// by checking the layoutKey. This should probably be moved into
// a prop so that the overlay can explicitly turn off templates.
if ((this.props.layoutKey === "overlayLayout" && StrCast(this.props.Document.layout).indexOf("CollectionView") !== -1) ||
- (this.props.layoutKey === "layout" && StrCast(this.props.Document.layout).indexOf("CollectionView") === -1)) {
+ (this.props.layoutKey === "layout" && StrCast(this.props.Document.layout).indexOf("CollectionView") === -1) ||
+ (this.props.layoutKey === "layout" && NumCast(this.props.Document.viewType)) !== CollectionViewType.Freeform) {
this.templates.forEach(template => {
let self = this;
// this scales constants in the markup by the scaling applied to the document, but caps the constants to be smaller
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2610d0e6d..c75ff51e2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -375,7 +375,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
onPointerMove = (e: PointerEvent): void => {
if (!e.cancelBubble && this.active) {
- if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+ if (!this.props.Document.excludeFromLibrary && (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3)) {
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
if (!e.altKey && !this.topMost && e.buttons === 1 && !BoolCast(this.props.Document.lockedPosition)) {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 5da52f4c2..b9cecdd24 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -182,7 +182,8 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
return url.href;
}
let ext = path.extname(url.href);
- return url.href.replace(ext, this._curSuffix + ext);
+ const suffix = this.props.renderDepth <= 1 ? "_o" : this._curSuffix;
+ return url.href.replace(ext, suffix + ext);
}
@observable _smallRetryCount = 1;
diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx
index e6cc50620..a97ec8831 100644
--- a/src/client/views/nodes/LinkEditor.tsx
+++ b/src/client/views/nodes/LinkEditor.tsx
@@ -177,9 +177,10 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
LinkManager.Instance.deleteGroupType(groupType);
}
- copyGroup = (groupType: string): void => {
+ copyGroup = async (groupType: string): Promise<void> => {
let sourceGroupDoc = this.props.groupDoc;
- let sourceMdDoc = Cast(sourceGroupDoc.metadata, Doc, new Doc);
+ const sourceMdDoc = await Cast(sourceGroupDoc.metadata, Doc);
+ if (!sourceMdDoc) return;
let destDoc = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
// let destGroupList = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, destDoc);
diff --git a/src/client/views/nodes/LinkMenuItem.tsx b/src/client/views/nodes/LinkMenuItem.tsx
index 4dee6741f..9728671c0 100644
--- a/src/client/views/nodes/LinkMenuItem.tsx
+++ b/src/client/views/nodes/LinkMenuItem.tsx
@@ -56,11 +56,13 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
let mdRows: Array<JSX.Element> = [];
if (groupDoc) {
- let mdDoc = Cast(groupDoc.metadata, Doc, new Doc);
- let keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
- mdRows = keys.map(key => {
- return (<div key={key} className="link-metadata-row"><b>{key}</b>: {StrCast(mdDoc[key])}</div>);
- });
+ let mdDoc = Cast(groupDoc.metadata, Doc, null);
+ if (mdDoc) {
+ let keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
+ mdRows = keys.map(key => {
+ return (<div key={key} className="link-metadata-row"><b>{key}</b>: {StrCast(mdDoc[key])}</div>);
+ });
+ }
}
return (<div className="link-metadata">{mdRows}</div>);
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index f93b2e59f..d6970e7f4 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -3,11 +3,8 @@ import "./PDFMenu.scss";
import { observable, action, runInAction } from "mobx";
import { observer } from "mobx-react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { emptyFunction, returnZero, returnTrue, returnFalse } from "../../../Utils";
+import { emptyFunction, returnFalse } from "../../../Utils";
import { Doc } from "../../../new_fields/Doc";
-import { DragManager } from "../../util/DragManager";
-import { DocUtils } from "../../documents/Documents";
-import { PresentationView } from "../presentationview/PresentationView";
@observer
export default class PDFMenu extends React.Component {
@@ -20,7 +17,7 @@ export default class PDFMenu extends React.Component {
@observable private _transitionDelay: string = "";
- StartDrag: (e: PointerEvent) => void = emptyFunction;
+ StartDrag: (e: PointerEvent, ele: HTMLDivElement) => void = emptyFunction;
Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
Delete: () => void = emptyFunction;
Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
@@ -35,9 +32,10 @@ export default class PDFMenu extends React.Component {
private _offsetY: number = 0;
private _offsetX: number = 0;
- private _mainCont: React.RefObject<HTMLDivElement>;
+ private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+ private _commentCont: React.RefObject<HTMLDivElement> = React.createRef();
+ private _snippetButton: React.RefObject<HTMLButtonElement> = React.createRef();
private _dragging: boolean = false;
- private _snippetButton: React.RefObject<HTMLButtonElement>;
@observable private _keyValue: string = "";
@observable private _valueValue: string = "";
@observable private _added: boolean = false;
@@ -46,9 +44,6 @@ export default class PDFMenu extends React.Component {
super(props);
PDFMenu.Instance = this;
-
- this._mainCont = React.createRef();
- this._snippetButton = React.createRef();
}
pointerDown = (e: React.PointerEvent) => {
@@ -69,7 +64,7 @@ export default class PDFMenu extends React.Component {
return;
}
- this.StartDrag(e);
+ this.StartDrag(e, this._commentCont.current!);
this._dragging = true;
}
@@ -246,7 +241,7 @@ export default class PDFMenu extends React.Component {
style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
<FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
</button>,
- <button className="pdfMenu-button" title="Drag to Annotate" onPointerDown={this.pointerDown}><FontAwesomeIcon icon="comment-alt" size="lg" key="2" /></button>,
+ <button className="pdfMenu-button" title="Drag to Annotate" ref={this._commentCont} onPointerDown={this.pointerDown}><FontAwesomeIcon icon="comment-alt" size="lg" key="2" /></button>,
this.Status === "snippet" ? <button className="pdfMenu-button" title="Drag to Snippetize Selection" onPointerDown={this.snippetStart} ref={this._snippetButton}><FontAwesomeIcon icon="cut" size="lg" /></button> : undefined,
<button className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin} key="3"
style={this.Pinned ? { backgroundColor: "#121212" } : {}}>
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 92f5390ae..49eac71c4 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -152,7 +152,7 @@ export default class Page extends React.Component<IPageProps> {
* start a drag event and create or put the necessary info into the drag event.
*/
@action
- startDrag = (e: PointerEvent): void => {
+ startDrag = (e: PointerEvent, ele: HTMLDivElement): void => {
e.preventDefault();
e.stopPropagation();
let thisDoc = this.props.parent.Document;
@@ -163,7 +163,7 @@ export default class Page extends React.Component<IPageProps> {
// create dragData and star tdrag
let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDoc, targetDoc);
if (this._textLayer.current) {
- DragManager.StartAnnotationDrag([this._textLayer.current], dragData, e.pageX, e.pageY, {
+ DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
handlers: {
dragComplete: emptyFunction,
},
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 51f0ed607..804ffa7f5 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -187,10 +187,10 @@ export class SearchItem extends React.Component<SearchItemProps> {
if (this.props.doc.type === DocTypes.LINK) {
if (this.props.doc.anchor1 && this.props.doc.anchor2) {
- let doc1 = Cast(this.props.doc.anchor1, Doc, new Doc());
- let doc2 = Cast(this.props.doc.anchor2, Doc, new Doc());
- doc1.libraryBrush = true;
- doc2.libraryBrush = true;
+ let doc1 = Cast(this.props.doc.anchor1, Doc, null);
+ let doc2 = Cast(this.props.doc.anchor2, Doc, null);
+ doc1 && (doc1.libraryBrush = true);
+ doc2 && (doc2.libraryBrush = true);
}
} else {
let docViews: DocumentView[] = DocumentManager.Instance.getAllDocumentViews(this.props.doc);
@@ -204,10 +204,10 @@ export class SearchItem extends React.Component<SearchItemProps> {
if (this.props.doc.type === DocTypes.LINK) {
if (this.props.doc.anchor1 && this.props.doc.anchor2) {
- let doc1 = Cast(this.props.doc.anchor1, Doc, new Doc());
- let doc2 = Cast(this.props.doc.anchor2, Doc, new Doc());
- doc1.libraryBrush = false;
- doc2.libraryBrush = false;
+ let doc1 = Cast(this.props.doc.anchor1, Doc, null);
+ let doc2 = Cast(this.props.doc.anchor2, Doc, null);
+ doc1 && (doc1.libraryBrush = false);
+ doc2 && (doc2.libraryBrush = false);
}
} else {
let docViews: DocumentView[] = DocumentManager.Instance.getAllDocumentViews(this.props.doc);
@@ -241,7 +241,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
render() {
return (
<div className="search-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}>
- <div className="search-item" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} ref={this.collectionRef} id="result"
+ <div className="search-item" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} id="result"
onClick={this.onClick} onPointerDown={this.pointerDown} >
<div className="main-search-info">
<div title="Drag as document" onPointerDown={this.onPointerDown}> <FontAwesomeIcon icon="file" size="lg" /> </div>
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index c361e3032..aa13b1d7a 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -9,6 +9,7 @@ import { ObjectField } from "./ObjectField";
import { RefField, FieldId } from "./RefField";
import { ToScriptString, SelfProxy, Parent, OnUpdate, Self, HandleUpdate, Update, Id } from "./FieldSymbols";
import { scriptingGlobal } from "../client/util/Scripting";
+import { List } from "./List";
export namespace Field {
export function toScriptString(field: Field): string {
@@ -241,12 +242,24 @@ export namespace Doc {
return Array.from(results);
}
- export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean) {
+ export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean) {
+ if (target[key] === undefined) {
+ Doc.GetProto(target)[key] = new List<Doc>();
+ }
let list = Cast(target[key], listSpec(Doc));
if (list) {
- let ind = relativeTo ? list.indexOf(relativeTo) : -1;
- if (ind === -1) list.push(doc);
- else list.splice(before ? ind : ind + 1, 0, doc);
+ if (allowDuplicates !== true) {
+ let pind = list.reduce((l, d, i) => d instanceof Doc && Doc.AreProtosEqual(d, doc) ? i : l, -1);
+ if (pind !== -1) {
+ list.splice(pind, 1);
+ }
+ }
+ if (first) list.splice(0, 0, doc);
+ else {
+ let ind = relativeTo ? list.indexOf(relativeTo) : -1;
+ if (ind === -1) list.push(doc);
+ else list.splice(before ? ind : ind + 1, 0, doc);
+ }
}
return true;
}
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 8dd893aa4..39d384d64 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -45,9 +45,10 @@ export interface Interface {
[key: string]: InterfaceValue;
// [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
}
+export type WithoutRefField<T extends Field> = T extends RefField ? never : T;
export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
-export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T, defaultVal: WithoutList<ToType<T>> | null): WithoutList<ToType<T>>;
+export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
if (field instanceof Promise) {
return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal === null ? undefined : defaultVal;
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index abb777adf..b5e50d501 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -2,7 +2,6 @@ import { UndoManager } from "../client/util/UndoManager";
import { Doc, Field } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField } from "./Proxy";
-import { FieldValue } from "./Types";
import { RefField } from "./RefField";
import { ObjectField } from "./ObjectField";
import { action } from "mobx";
@@ -13,6 +12,7 @@ function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
}
const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+ //console.log("-set " + target[SelfProxy].title + "(" + target[SelfProxy][prop] + ")." + prop.toString() + " = " + value);
if (SerializationHelper.IsSerializing()) {
target[prop] = value;
return true;
diff --git a/src/server/GarbageColletor.ts b/src/server/GarbageColletor.ts
new file mode 100644
index 000000000..f26b0cec6
--- /dev/null
+++ b/src/server/GarbageColletor.ts
@@ -0,0 +1,51 @@
+import { Database } from './database';
+
+function addDoc(doc: any, ids: string[]) {
+ for (const key in doc) {
+ if (!doc.hasOwnProperty(key)) {
+ continue;
+ }
+ const field = doc[key];
+ if (!(field instanceof Object)) {
+ continue;
+ }
+ if (field.__type === "proxy") {
+ ids.push(field.fieldId);
+ } else if (field.__type === "list") {
+ addDoc(field.fields, ids);
+ }
+ }
+}
+
+async function GarbageCollect() {
+ // await new Promise(res => setTimeout(res, 3000));
+ const cursor = await Database.Instance.query({}, 'users');
+ const users = await cursor.toArray();
+ const ids: string[] = users.map(user => user.userDocumentId);
+ const visited = new Set<string>();
+
+ while (ids.length) {
+ const id = ids.pop()!;
+ if (visited.has(id)) continue;
+ const doc = await new Promise<{ [key: string]: any }>(res => Database.Instance.getDocument(id, res, "newDocuments"));
+ if (doc === undefined) {
+ console.log(`Couldn't find field with Id ${id}`);
+ continue;
+ }
+ visited.add(id);
+ addDoc(doc.fields, ids);
+ console.log(`To Go: ${ids.length}, visited: ${visited.size}`);
+ }
+
+ console.log(`Done: ${visited.size}`);
+
+ cursor.close();
+
+ const toDeleteCursor = await Database.Instance.query({ _id: { $nin: Array.from(visited) } });
+ const toDelete = (await toDeleteCursor.toArray()).map(doc => doc._id);
+ toDeleteCursor.close();
+ const result = await Database.Instance.delete({ _id: { $in: toDelete } }, "newDocuments");
+ console.log(`${result.deletedCount} documents deleted`);
+}
+
+GarbageCollect();
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 816c5f269..e328d6e5c 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -10,7 +10,7 @@ import { CollectionView } from "../../../client/views/collections/CollectionView
import { Doc } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
-import { Cast } from "../../../new_fields/Types";
+import { Cast, FieldValue } from "../../../new_fields/Types";
import { RouteStore } from "../../RouteStore";
export class CurrentUserUtils {
@@ -32,7 +32,11 @@ export class CurrentUserUtils {
doc.dropAction = "alias";
doc.layout = CollectionView.LayoutString();
doc.title = this.email;
+ this.updateUserDocument(doc);
doc.data = new List<Doc>();
+ doc.gridGap = 5;
+ doc.xMargin = 5;
+ doc.yMargin = 5;
doc.excludeFromLibrary = true;
doc.optionalRightCollection = Docs.StackingDocument([], { title: "New mobile uploads" });
// doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` });
@@ -40,6 +44,29 @@ export class CurrentUserUtils {
return doc;
}
+ static updateUserDocument(doc: Doc) {
+ if (doc.workspaces === undefined) {
+ const workspaces = Docs.TreeDocument([], { title: "Workspaces", height: 100 });
+ workspaces.excludeFromLibrary = true;
+ workspaces.workspaceLibrary = true;
+ doc.workspaces = workspaces;
+ }
+ if (doc.recentlyClosed === undefined) {
+ const recentlyClosed = Docs.TreeDocument([], { title: "Recently Closed", height: 75 });
+ recentlyClosed.excludeFromLibrary = true;
+ doc.recentlyClosed = recentlyClosed;
+ }
+ if (doc.sidebar === undefined) {
+ const sidebar = Docs.StackingDocument([doc.workspaces as Doc, doc, doc.recentlyClosed as Doc], { title: "Sidebar" });
+ sidebar.excludeFromLibrary = true;
+ sidebar.gridGap = 5;
+ sidebar.xMargin = 5;
+ sidebar.yMargin = 5;
+ doc.sidebar = sidebar;
+ }
+
+ }
+
public static async loadCurrentUser(): Promise<any> {
let userPromise = rp.get(DocServer.prepend(RouteStore.getCurrUser)).then(response => {
if (response) {
@@ -52,8 +79,14 @@ export class CurrentUserUtils {
});
let userDocPromise = await rp.get(DocServer.prepend(RouteStore.getUserDocumentId)).then(id => {
if (id) {
- return DocServer.GetRefField(id).then(field =>
- runInAction(() => this.user_document = field instanceof Doc ? field : this.createUserDocument(id)));
+ return DocServer.GetRefField(id).then(async field => {
+ if (field instanceof Doc) {
+ await this.updateUserDocument(field);
+ runInAction(() => this.user_document = field);
+ } else {
+ runInAction(() => this.user_document = 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 d240bd909..a17447629 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -41,11 +41,17 @@ export class Database {
}
}
- public delete(id: string, collectionName = Database.DocumentsCollection) {
+ public delete(query: any, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>;
+ public delete(id: string, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>;
+ public delete(id: any, collectionName = Database.DocumentsCollection) {
+ if (typeof id === "string") {
+ id = { _id: id };
+ }
if (this.db) {
- this.db.collection(collectionName).remove({ id: id });
+ const db = this.db;
+ return new Promise(res => db.collection(collectionName).deleteMany(id, (err, result) => res(result)));
} else {
- this.onConnect.push(() => this.delete(id, collectionName));
+ return new Promise(res => this.onConnect.push(() => res(this.delete(id, collectionName))));
}
}
@@ -125,7 +131,7 @@ export class Database {
return Promise.resolve<mongodb.Cursor>(this.db.collection(collectionName).find(query));
} else {
return new Promise<mongodb.Cursor>(res => {
- this.onConnect.push(() => res(this.query(query)));
+ this.onConnect.push(() => res(this.query(query, collectionName)));
});
}
}
diff --git a/src/server/index.ts b/src/server/index.ts
index a93940907..bf946fc9f 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -295,9 +295,10 @@ app.post(
const file = path.basename(files[name].path);
const ext = path.extname(file);
let resizers = [
- { resizer: sharp().resize(100, undefined, { withoutEnlargement: true }), suffix: "_s" },
- { resizer: sharp().resize(400, undefined, { withoutEnlargement: true }), suffix: "_m" },
- { resizer: sharp().resize(900, undefined, { withoutEnlargement: true }), suffix: "_l" },
+ { resizer: sharp().rotate(), suffix: "_o" },
+ { resizer: sharp().resize(100, undefined, { withoutEnlargement: true }).rotate(), suffix: "_s" },
+ { resizer: sharp().resize(400, undefined, { withoutEnlargement: true }).rotate(), suffix: "_m" },
+ { resizer: sharp().resize(900, undefined, { withoutEnlargement: true }).rotate(), suffix: "_l" },
];
let isImage = false;
if (pngTypes.includes(ext)) {
diff --git a/tance.jumpToDocument(linkedFwdDocs[altKey  1  0], ctrlKey, false, document = this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey  1  0], targetContext); b/tance.jumpToDocument(linkedFwdDocs[altKey  1  0], ctrlKey, false, document = this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey  1  0], targetContext);
deleted file mode 100644
index 0aa3ad47b..000000000
--- a/tance.jumpToDocument(linkedFwdDocs[altKey  1  0], ctrlKey, false, document = this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey  1  0], targetContext);
+++ /dev/null
@@ -1,792 +0,0 @@
-commit cc1f3b32d60786b56280a8b3c00059aa7823af89
-Merge: a81677c deb8576
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 26 14:54:46 2019 -0400
-
- merge
-
-commit a81677c7dffafa5134d4c5cbe893f7a886eaab63
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 26 14:48:16 2019 -0400
-
- can clear links on a doc
-
-commit 69e37491908b5c189b94f780994c1f142c69be2e
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 26 14:15:40 2019 -0400
-
- minor changes
-
-commit deb85766ac5648cc8e3ab4bf9d182ac5bbbbe144
-Merge: 219cabb 5e47775
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Wed Jun 26 12:51:18 2019 -0400
-
- Merge pull request #170 from browngraphicslab/presentation-selection-mohammad
-
- Presentation selection mohammad
-
-commit 5e477755b392128ab8b39c082f16dd67708be0d2
-Merge: 444f970 6d1f161
-Author: Sam Wilkins <samuel_wilkins@brown.edu>
-Date: Wed Jun 26 12:48:45 2019 -0400
-
- Merge branch 'presentation-selection-mohammad' of https://github.com/browngraphicslab/Dash-Web into presentation-selection-mohammad
-
-commit 444f970365a4280376e929e78c16090f6ae92739
-Merge: 64ffa0a 219cabb
-Author: Sam Wilkins <samuel_wilkins@brown.edu>
-Date: Wed Jun 26 12:48:40 2019 -0400
-
- merged with master
-
-commit 6d1f161de3c27ec07673b5e48a915961177b57b6
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Wed Jun 26 12:39:54 2019 -0400
-
- long line wrap
-
-commit f0632e4f6b608d05ef6d9f77d93da259c58c1e8d
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Wed Jun 26 12:33:16 2019 -0400
-
- long line wrap
-
-commit 0d5e2537520ca1e6a6b52f4d0f03aa2bcfc6c5c6
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Wed Jun 26 12:30:16 2019 -0400
-
- cleanup
-
-commit 8954bac59b50aa3618625379a17dbefe9aceca72
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Wed Jun 26 12:29:07 2019 -0400
-
- removed console.logs
-
-commit d0ff42632f8a155303e11945a1a974a15052f0db
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 26 11:40:36 2019 -0400
-
- link menu styling
-
-commit a3c4aa24a9e9074da8f2421954f610c8178e10b1
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 21:28:15 2019 -0400
-
- link metadata values appear on first load
-
-commit ca8a78de9957ad27d345ad51fdaee9dae3f096bd
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 20:44:34 2019 -0400
-
- can't link to containing collection
-
-commit 2d300b0cd3d02c900865c61eacd539efed5289e6
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 20:18:14 2019 -0400
-
- fixed link metadata rendering bug
-
-commit 2a698e88da5ef0a9fee1ff4ee69746f1242798c9
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 18:32:17 2019 -0400
-
- fixed render links in treeview
-
-commit 7abe170ce5bd0c415e23456eb2bed26e8fdee7aa
-Merge: 41cf1e8 219cabb
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 18:23:26 2019 -0400
-
- merge
-
-commit 41cf1e8536964764f18ab752140e484e36cbe464
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 25 17:09:36 2019 -0400
-
- links can save
-
-commit 64ffa0accfc872c81035079527952aabaf56c6f6
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Tue Jun 25 13:16:45 2019 -0400
-
- Small Css Fix On weight
-
-commit 219cabb3fe42ab199550efc3423b7aaed4e1ee93
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 22:45:19 2019 -0400
-
- Switched shift drag of tabs to normal drag and added drag target for document drag
-
-commit d475b19e9ba7bc8870ec7bc1e10b5cc88decea0b
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 15:56:42 2019 -0400
-
- fixed crash
-
-commit 522970375fe0227f9221a7e8be02875afd74ca63
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Mon Jun 24 14:01:29 2019 -0400
-
- link menu styling
-
-commit addf0e443f64951a437701f0d5a087c1d5968faf
-Merge: c9f77d5 d01039b
-Author: tschicke-brown <tyler_schicke@brown.edu>
-Date: Mon Jun 24 13:57:02 2019 -0400
-
- Merge pull request #167 from browngraphicslab/schema_fixes
-
- Schema and scripting fixes
-
-commit d01039b10f0ebd328224c0b1a190b0f884a7c727
-Merge: 6abf829 c9f77d5
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 13:56:30 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web into schema_fixes
-
-commit c9f77d5aab98e6e7865cdcad957d5c937631775d
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 13:41:39 2019 -0400
-
- Added ReadOnly mode for docs and changed computed values a bit
-
-commit e18662f2fa9e1d3dd1b0eb3b5531092258d05972
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Mon Jun 24 12:42:44 2019 -0400
-
- Refactoring
-
-commit 52051829373bc4acfe9d705b64c30e3fddebf439
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 10:49:05 2019 -0400
-
- Fixed image size stuff
-
-commit ac781d2fb714ca26fb364d00d5aeb7a20b008655
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 24 10:26:57 2019 -0400
-
- Changed how zooming works
-
-commit 6e5cd0e991e2e6d7ae8de1d73ff273ba0737355c
-Author: Tyler Schicke <tschicke@gmail.com>
-Date: Sun Jun 23 17:23:33 2019 -0400
-
- Fixed shift dragging with no open panes
-
-commit 32ef8d83d5829e2faadbebaf6f9b694df5d7ea02
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Fri Jun 21 17:41:20 2019 -0400
-
- link menu styling
-
-commit 7962aff8431b692af5229cd8e6c390bbe1110336
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Fri Jun 21 16:29:31 2019 -0400
-
- link menu styling
-
-commit a4b34adcb34184728be0b69b33a561f6d10f0a98
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Fri Jun 21 16:27:03 2019 -0400
-
- can drag just a group of links on a doc
-
-commit e1f5f341854944c533efdb7d36306edd1e1dc747
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Fri Jun 21 14:53:08 2019 -0400
-
- Some More documentation
-
-commit 542f25d4af36cf0948696d45afba2e9e19f5bc37
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Fri Jun 21 14:47:11 2019 -0400
-
- Redo Grouping Fixed
-
-commit 60f9122ea31d660d60d5429890c4eb0ef6d8613b
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Fri Jun 21 13:41:25 2019 -0400
-
- following link without viewdoc opens it to right
-
-commit d78c651322ad228152b862eaa378946fe65cc9f9
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Fri Jun 21 13:32:23 2019 -0400
-
- dragged links from menu are aliases
-
-commit 179afa6e80631fcb8899408c3961bf1757e5b19b
-Merge: ca5e29f a40e7bb
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Thu Jun 20 22:23:40 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit ca5e29fdc7c238274eaf90682a8fa2ddc90e4e17
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Thu Jun 20 22:22:57 2019 -0400
-
- fix to open on right, fix to image drag fro web, and layout fixes for stacking view multi-column
-
-commit a40e7bb5e9d1256002083d7e3f3c4db60cd8e9df
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Thu Jun 20 19:41:39 2019 -0400
-
- Fixed missed pointer up event
-
-commit f4b75a7c921181faeeee04fbd57cd24fbd57523e
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Thu Jun 20 19:16:42 2019 -0400
-
- Undo/Redo First Version
-
-commit b1a2871fcca57ce934b8613b315a08eede188669
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 19:03:16 2019 -0400
-
- link menu styling
-
-commit f2b54dc49205f8ea8944e26e43662a0c8dd08ed0
-Merge: 0cab79a 7d0f6c1
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 18:36:04 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit 0cab79a50719719e1dade40520a6967f7aa8f951
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 18:35:45 2019 -0400
-
- Added debug and release modes to server and client
-
-commit fbfe9faca199b6dedd6844f1fa20cc02060a3c5a
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 18:25:49 2019 -0400
-
- can see what docs are linked to in treeview:
-
-commit 7d0f6c18489f7155818611721985d9610b08d8e7
-Merge: d2dfc0f 46a2a9e
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Thu Jun 20 17:50:46 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 1f172642d12c4669960b8526324e4bd034994be4
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 17:44:24 2019 -0400
-
- Added arrange documents in grid command
-
-commit d2dfc0f9d35f0084a7c0dea73215f5d21055f2f3
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Thu Jun 20 17:17:14 2019 -0400
-
- pdf page sizes loading error
-
-commit e6ebed17e6ddb2ccee81d65fcb451a9b54302762
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 17:12:48 2019 -0400
-
- links can be made from freeform view to treeview
-
-commit 46a2a9e1f10b63feeb21a1e186daeaef2ccbcda4
-Merge: a39b285 a5dc0e0
-Author: bob <bcz@cs.brown.edu>
-Date: Thu Jun 20 17:11:29 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit a39b2854b848006c19460685d7bf4005a9f650ae
-Author: bob <bcz@cs.brown.edu>
-Date: Thu Jun 20 17:09:50 2019 -0400
-
- moved AddDocToList to Doc utils
-
-commit a5dc0e04add05f2f5bf1e17f1ac0a5e0aba1ea41
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 16:27:44 2019 -0400
-
- Added hidden flag to documents
-
-commit e88538bb8af2ba648da2326d0f6edd3e0186766e
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Thu Jun 20 15:45:07 2019 -0400
-
- Title changing to presentations added
-
-commit 9b3e80def0be6c09c31b5176817a54323d217d81
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 15:06:41 2019 -0400
-
- Handled more events in editable view
-
-commit 1f24c5010a1cf6365265ea1f02327bb81a98134a
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 14:54:55 2019 -0400
-
- Doc.GetProto change and swapped KVP syntax
-
-commit 4360287e6cafcb59af1ae62fc31ddc161bcf2e51
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 12:56:13 2019 -0400
-
- styling of link proxy
-
-commit 711abbeba69e4d9afc634b8edf019b12b6dff915
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Thu Jun 20 12:54:41 2019 -0400
-
- Documentation and reset Presentation at removal fixed
-
-commit a0246ef84396545f79fc4a8b21de1a56cbf06aca
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 11:34:28 2019 -0400
-
- merge
-
-commit 8dbfb3029a99eaf37a5234e9d9e33cc64f779b03
-Merge: af8e5cf e9d62f4
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 11:33:01 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit af8e5cf1bfbfa2d57b4fd89c72306a71d8cabe1d
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 11:32:54 2019 -0400
-
- Fixed context menu search
-
-commit cd2db5bf11fb89e3cd7016f7f798d65698c74c5e
-Merge: 73f0378 e9d62f4
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 11:31:15 2019 -0400
-
- merge
-
-commit 73f03785f938542a91b28b35043f2feda2bc1432
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Thu Jun 20 11:26:33 2019 -0400
-
- merge
-
-commit e9d62f4ca0dbeb57e46239047041a8a04da7b504
-Author: bob <bcz@cs.brown.edu>
-Date: Thu Jun 20 11:26:16 2019 -0400
-
- changed color picker. fixed delting selected docs. fixed scaling items in nested panels.
-
-commit a5478b2d4cc3b66c6b58471cbb05c623d0109724
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 10:04:51 2019 -0400
-
- "Fixed" search
-
-commit 01aee875e626c695fe208addaaa6f58aad387dd6
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Thu Jun 20 10:02:08 2019 -0400
-
- Mostly keep context menu on screen
-
-commit 38de022621175bda7410df4444fcd2bbee0919cb
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Wed Jun 19 23:43:47 2019 -0400
-
- slight tweaks.
-
-commit 9e55bfaad39aa47ab0594c6af7f1aa68e2a8db7a
-Merge: 118ecb1 827c589
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Wed Jun 19 22:40:57 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 118ecb14ce519bcbade12b3d52e11b22fcc371b3
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Wed Jun 19 22:40:54 2019 -0400
-
- cleaned up and enhanced tree view
-
-commit c5e401cb0a7fec2279ceecbc8d1429dcdd2f04b9
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 19 22:27:21 2019 -0400
-
- buttons on cut links functional except for when dragged from link menu
-
-commit 6fc6054dc7aea144fd967a8cb3fe7d8fe5ec6d6d
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Wed Jun 19 19:13:30 2019 -0400
-
- Width of the presentations fixed, removal of presentations option added, backUP group and normal groups updated when a doc is removed from presentation by removing it from both
-
-commit 827c58950b649629c84211d41fdd4d041287801e
-Merge: 05e50f2 96c26c5
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 18:49:50 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit 96c26c57527d443784bde9752551bfa10b3ce4d2
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Wed Jun 19 18:34:45 2019 -0400
-
- removed marquee summarizing icon
-
-commit 05e50f27a15e8a02ffb27606c51026d1b85bc677
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 17:36:52 2019 -0400
-
- Added basic keyboard controls to context menu
-
-commit fa37e023b88127cb8a6b393a848200361a396fb4
-Merge: 565b27c 5b2a498
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 16:21:09 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit 565b27cca8953a60067de367cae4c0a99beb3cab
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 16:21:03 2019 -0400
-
- started adding selection to context menu
-
-commit 5b2a498aca75bd53ffab61f998218bec546b8154
-Merge: 358437e 39e8a7a
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 16:17:21 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 358437eeafe42e029ffe27702bde15a3fad54a3b
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 16:17:18 2019 -0400
-
- working version of embedded tree view docs.
-
-commit 4c1383e47f2203a00bc7f3d73c209f3149d6a772
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Wed Jun 19 15:53:05 2019 -0400
-
- ...
-
-commit a288a2fd0a30a3a16dd01bc4e12dcf6bc117c766
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Wed Jun 19 15:25:24 2019 -0400
-
- Navigation and Zoom Option For Manual Selection Added and New Presentation TItle Naming Added
-
- Now, You can manually click on navigate or zoom and navigate to that document if current was their index. A way to manually disregard groups, and just navigate to that doc.
-
-commit 39e8a7a365442cdc11024c4de8019184fd0057ac
-Merge: 5b6f13d 9ab4739
-Author: Stanley Yip <33562077+yipstanley@users.noreply.github.com>
-Date: Wed Jun 19 15:05:38 2019 -0400
-
- Merge pull request #163 from browngraphicslab/pdf_fixes
-
- deleting annotations
-
-commit 5b6f13d64e9e38b94df0ae61ffedcb0b34290045
-Merge: 35e73f3 4ebbdd8
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 15:04:46 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit 35e73f369a2145d8a042e0011a43e71763d57998
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Wed Jun 19 15:02:48 2019 -0400
-
- added better search to context menu
-
-commit 9ab47393a2ce3d174ad3238422c2c310764be9af
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 14:40:28 2019 -0400
-
- interaction improvements with delete button
-
-commit b9849810231e540a5898a56012abd32c197b23b5
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 14:39:15 2019 -0400
-
- anna
-
-commit b960a876d6a31b3eaebb0ac6eca6f191a0d4c900
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 14:38:43 2019 -0400
-
- oop
-
-commit 46d57bc21cda4703855b85a4603bd471975d845b
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 14:25:47 2019 -0400
-
- deleting annotations
-
-commit f362dbfc237536c6c4a8c6d088c3dc818080f7c2
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Wed Jun 19 12:50:58 2019 -0400
-
- both tail ends of a cut link appear on hover/focus of an anchor
-
-commit fb62f3b2e39bbe2dd3da5eaffedbaa8e60f06dbb
-Author: Mohammad Amoush <mohammad_amoush@brown.edu>
-Date: Wed Jun 19 12:35:54 2019 -0400
-
- Grouping for different presentations fixed
-
-commit 4ebbdd803cdf83806902509dfa0432ce3a139403
-Merge: 0bb2052 c056ade
-Author: Stanley Yip <33562077+yipstanley@users.noreply.github.com>
-Date: Wed Jun 19 11:48:16 2019 -0400
-
- Merge pull request #162 from browngraphicslab/pdf_fixes
-
- Pdf fixes
-
-commit c056adeca11f35972b5f75c6b1cc31292d5765d4
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 11:47:20 2019 -0400
-
- push
-
-commit 37f327ab659e6fa1221f9f4ed7649402c5dedc00
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Wed Jun 19 11:24:32 2019 -0400
-
- aspect ratio, dragging, and full screen scrolling fixed
-
-commit 0bb20528c8167b3ba1c4c88d97586d50ae183b4c
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 10:37:36 2019 -0400
-
- added highlight for expanded tree view items
-
-commit f60398d5db9041e09c809c16a0b885936ac11a3d
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 10:21:37 2019 -0400
-
- fixed multi-column stacking
-
-commit 0674331f3611d297028526c888c718a75b012e0a
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 09:36:21 2019 -0400
-
- fixed resizing stacking views. changed defaults for new docs in treeView
-
-commit 1472d2b56aa64896f0a93f172322121d19cd1592
-Author: bob <bcz@cs.brown.edu>
-Date: Wed Jun 19 09:11:35 2019 -0400
-
- fixed lint errors.
-
-commit 8c94bb92b23dea138fa752929b6134e7214dfb60
-Merge: 3b880d7 13e301d
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 22:51:48 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 3b880d7b15b7107049ae27601b9f759b17f7fde9
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 22:51:46 2019 -0400
-
- added initial keyboard shortcuts for adding and moving docs in TreeView. fixed image drag bug.
-
-commit 13e301dea2f537b67b338cc6a98d3f3b5a8e1f36
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Tue Jun 18 20:58:32 2019 -0400
-
- Fixed linter errors
-
-commit 464fa03d6ebb2a7aaef1d7622afa3e1e7ee816a3
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Tue Jun 18 20:11:31 2019 -0400
-
- Context menu improvements and error fixes
-
-commit 4ffcff69a2fc767c6a03d46d7296b6a8c7ffd281
-Author: madelinegr <mgriswold99@gmail.com>
-Date: Tue Jun 18 19:13:45 2019 -0400
-
- Presentations Listed, Option to Change Added, and
-
-commit ca126adda9e4def83fb5c2e07e382917ca0b4ee0
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Tue Jun 18 17:24:59 2019 -0400
-
- Fixed docking view?
-
-commit b0ac30172019713e1c75083c1199485d902e0eed
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Tue Jun 18 16:37:28 2019 -0400
-
- Fixed zoomBasis stuff and added deletion handling for reponse from server
-
-commit 8e5afb5bbb47324a381b5184254e77eba7bd8536
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 18 16:30:24 2019 -0400
-
- can click on button link to node in different context than source
-
-commit 6fcd0d8d6fb1471b8af460f6d80bdf0d0e681566
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 18 15:17:27 2019 -0400
-
- added button to delete a link
-
-commit d91e7eec9a62363b383b929166cdf600b124334c
-Author: Fawn <fangrui_tong@brown.edu>
-Date: Tue Jun 18 15:09:21 2019 -0400
-
- links to nodes in different contexts render as a circle
-
-commit d3cad099d49690810166d0342f7c371bda0f007e
-Merge: 04668e2 b1af251
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 13:30:55 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 04668e21313f6e62e5ab35ac737fc54191769a5a
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 13:30:41 2019 -0400
-
- fixed cleanup of marquee keyhandler.
-
-commit b1af251b058743798aa3fa3895d22327c8560dfc
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Tue Jun 18 13:19:50 2019 -0400
-
- Added pointer down flag for tab focus
-
-commit 9544576ec0167d64f564ae4c87d392eba07ff467
-Author: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
-Date: Tue Jun 18 13:18:34 2019 -0400
-
- Added tab focusing on hover
-
-commit 2633f61d311528e62d50d4ff56f5884b3b51ac61
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 13:12:15 2019 -0400
-
- added undo/redo bindings for app.
-
-commit 3a25bad918c72f5d6de9a720de9e0d316c00f2fe
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 13:03:28 2019 -0400
-
- fixed issues with expanding text boxes that have a dynamic title
-
-commit f4fcf306e2579b7479610899a01c06fb157d47de
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 12:03:14 2019 -0400
-
- fixed goldenlayout nesting
-
-commit 4f0086f6ea948c1c5254db2acc93f6735987daa5
-Merge: 749eef1 d7ebe7b
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 11:31:49 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 749eef13af1338225b2bec4dbcd7a50a5650d285
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 11:31:46 2019 -0400
-
- fixed image drag drop when not selected.
-
-commit d7ebe7b7d19cf7dc797443aa485293670c3ee4e2
-Merge: 66d4cc9 08872de
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Tue Jun 18 11:08:44 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 66d4cc94bcc69f590d90dd35823f93b8e2fb90d8
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Tue Jun 18 10:52:10 2019 -0400
-
- selection fixes
-
-commit 08872def596af073c5f14336c8faf07f44561bbc
-Merge: 8d00265 c50ba1c
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 10:28:31 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit 8d0026573ad9a196f864490bcf07c78f54082bad
-Author: bob <bcz@cs.brown.edu>
-Date: Tue Jun 18 10:28:29 2019 -0400
-
- fixed selection within multicolumn stacking view. added drop of html image selections.
-
-commit c50ba1c4cc01d5cd085dee0dae6f633164efeb80
-Merge: cc032e2 64e6a94
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Tue Jun 18 10:10:58 2019 -0400
-
- Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-
-commit cc032e2f60015728f64f46ef009c9306e36746a0
-Author: yipstanley <stanley_yip@brown.edu>
-Date: Tue Jun 18 10:05:49 2019 -0400
-
- fixes
-
-commit 64e6a941639aab8d7109178aa151a50909547309
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 09:05:41 2019 -0400
-
- fixed index out of range
-
-commit 4b8324fcf44c5d3c3a4b3f6e98a4d1dfce84811b
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 08:53:01 2019 -0400
-
- removed trace
-
-commit a3b8a57027d7c45ea19d259e1ec18fa6a8648c24
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 08:49:02 2019 -0400
-
- looked like wrong code...
-
-commit 2f5c38c6a0a5220c2a31931c34d94e199854d703
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 08:36:37 2019 -0400
-
- more streamlining
-
-commit 62c781c0c79ac395c5e117d208a90485ff1ba599
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 02:19:07 2019 -0400
-
- faster loading of PDFs
-
-commit 4dc8c03562a0473becb895824740da487e16e771
-Author: Bob Zeleznik <zzzman@gmail.com>
-Date: Tue Jun 18 00:17:58 2019 -0400
-
- added dropping of Dash urls from gmail
-
-commit 9c7ff72a8ad249c05b672a46e3fbbb69ffca3a2a
-Merge: 8c64ffd 71b1cfb
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 17 23:04:22 2019 -0400
-
- Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
-
-commit 8c64ffd92e382050bc8727981cf9fb830e4f02a7
-Author: Tyler Schicke <tyler_schicke@brown.edu>
-Date: Mon Jun 17 23:04:07 2019 -0400
-
- Added share with user functionality