aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/EditableView.tsx11
-rw-r--r--src/client/views/Main.tsx170
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx7
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx82
-rw-r--r--src/client/views/collections/CollectionView.tsx5
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx41
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx7
-rw-r--r--src/client/views/nodes/DocumentView.tsx11
-rw-r--r--src/client/views/nodes/FieldView.tsx18
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/HistogramBox.tsx6
11 files changed, 226 insertions, 134 deletions
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 579d6e6ad..29bf6add7 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -16,6 +16,8 @@ export interface EditableProps {
* */
SetValue(value: string): boolean;
+ OnFillDown?(value: string): void;
+
/**
* The contents to render when not editing
*/
@@ -36,8 +38,13 @@ export class EditableView extends React.Component<EditableProps> {
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
- if (e.key == "Enter" && !e.ctrlKey) {
- if (this.props.SetValue(e.currentTarget.value)) {
+ if (e.key == "Enter") {
+ if (!e.ctrlKey) {
+ if (this.props.SetValue(e.currentTarget.value)) {
+ this.editing = false;
+ }
+ } else if (this.props.OnFillDown) {
+ this.props.OnFillDown(e.currentTarget.value);
this.editing = false;
}
} else if (e.key == "Escape") {
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 53a5aba6e..6534cb4f7 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -8,6 +8,7 @@ import "./Main.scss";
import { MessageStore } from '../../server/Message';
import { Utils } from '../../Utils';
import * as request from 'request'
+import * as rp from 'request-promise'
import { Documents } from '../documents/Documents';
import { Server } from '../Server';
import { setupDrag } from '../util/DragManager';
@@ -22,7 +23,7 @@ import "./Main.scss";
import { observer } from 'mobx-react';
import { InkingControl } from './InkingControl';
import { RouteStore } from '../../server/RouteStore';
-import { library } from '@fortawesome/fontawesome-svg-core';
+import { library, IconName } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFont } from '@fortawesome/free-solid-svg-icons';
import { faImage } from '@fortawesome/free-solid-svg-icons';
@@ -40,7 +41,7 @@ import Measure from 'react-measure';
import { DashUserModel } from '../../server/authentication/models/user_model';
import { ServerUtils } from '../../server/ServerUtil';
import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
-import { Field, Opt } from '../../fields/Field';
+import { Field, Opt, FieldWaiting } from '../../fields/Field';
import { ListField } from '../../fields/ListField';
import { Gateway, Settings } from '../northstar/manager/Gateway';
import { Catalog, Schema, Attribute, AttributeGroup } from '../northstar/model/idea/idea';
@@ -51,16 +52,26 @@ import '../northstar/utils/Extensions'
@observer
export class Main extends React.Component {
// dummy initializations keep the compiler happy
- @observable private mainContainer?: Document;
@observable private mainfreeform?: Document;
- @observable private userWorkspaces: Document[] = [];
@observable public pwidth: number = 0;
@observable public pheight: number = 0;
- @observable ActiveSchema: Schema | undefined;
private _northstarColumns: Document[] = [];
- public mainDocId: string | undefined;
- private currentUser?: DashUserModel;
+ @computed private get mainContainer(): Document | undefined {
+ let doc = this.userDocument.GetT(KeyStore.ActiveWorkspace, Document);
+ return doc == FieldWaiting ? undefined : doc;
+ }
+
+ private set mainContainer(doc: Document | undefined) {
+ if (doc) {
+ this.userDocument.Set(KeyStore.ActiveWorkspace, doc);
+ }
+ }
+
+ private get userDocument(): Document {
+ return CurrentUserUtils.UserDocument;
+ }
+
public static Instance: Main;
constructor(props: Readonly<{}>) {
@@ -70,9 +81,12 @@ export class Main extends React.Component {
configure({ enforceActions: "observed" });
if (window.location.pathname !== RouteStore.home) {
let pathname = window.location.pathname.split("/");
- this.mainDocId = pathname[pathname.length - 1];
+ if (pathname.length > 1 && pathname[pathname.length - 2] == 'doc') {
+ CurrentUserUtils.MainDocId = pathname[pathname.length - 1];
+ }
};
+ // this.initializeNorthstar();
let y = "";
y.ReplaceAll("a", "B");
@@ -92,7 +106,7 @@ export class Main extends React.Component {
library.add(faTree);
this.initEventListeners();
- Documents.initProtos(() => this.initAuthenticationRouters());
+ this.initAuthenticationRouters();
this.initializeNorthstar();
}
@@ -100,8 +114,8 @@ export class Main extends React.Component {
onHistory = () => {
if (window.location.pathname !== RouteStore.home) {
let pathname = window.location.pathname.split("/");
- this.mainDocId = pathname[pathname.length - 1];
- Server.GetField(this.mainDocId, action((field: Opt<Field>) => {
+ CurrentUserUtils.MainDocId = pathname[pathname.length - 1];
+ Server.GetField(CurrentUserUtils.MainDocId, action((field: Opt<Field>) => {
if (field instanceof Document) {
this.openWorkspace(field, true);
}
@@ -131,63 +145,50 @@ export class Main extends React.Component {
initAuthenticationRouters = () => {
// Load the user's active workspace, or create a new one if initial session after signup
- request.get(ServerUtils.prepend(RouteStore.getActiveWorkspace), (error, response, body) => {
- if (this.mainDocId || body) {
- Server.GetField(this.mainDocId || body, field => {
- if (field instanceof Document) {
- this.openWorkspace(field);
- this.populateWorkspaces();
- } else {
- this.createNewWorkspace(true, this.mainDocId);
- }
- });
- } else {
- this.createNewWorkspace(true, this.mainDocId);
- }
- });
- }
-
- @action
- createNewWorkspace = (init: boolean, id?: string): void => {
- let mainDoc = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: `Main Container ${this.userWorkspaces.length + 1}` }, id);
- let newId = mainDoc.Id;
- request.post(ServerUtils.prepend(RouteStore.addWorkspace), {
- body: { target: newId },
- json: true
- }, () => { if (init) this.populateWorkspaces(); });
-
- // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
- setTimeout(() => {
- let freeformDoc = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" });
- var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc)] }] };
- mainDoc.SetText(KeyStore.Data, JSON.stringify(dockingLayout));
- mainDoc.Set(KeyStore.ActiveFrame, freeformDoc);
- this.openWorkspace(mainDoc);
- let pendingDocument = Documents.SchemaDocument([], { title: "New Mobile Uploads" })
- mainDoc.Set(KeyStore.OptionalRightCollection, pendingDocument);
- }, 0);
- this.userWorkspaces.push(mainDoc);
+ if (!CurrentUserUtils.MainDocId) {
+ this.userDocument.GetTAsync(KeyStore.ActiveWorkspace, Document).then(doc => {
+ if (doc) {
+ this.openWorkspace(doc);
+ } else {
+ this.createNewWorkspace();
+ }
+ })
+ } else {
+ Server.GetField(CurrentUserUtils.MainDocId).then(field => {
+ if (field instanceof Document) {
+ this.openWorkspace(field)
+ } else {
+ this.createNewWorkspace(CurrentUserUtils.MainDocId);
+ }
+ })
+ }
}
@action
- populateWorkspaces = () => {
- // retrieve all workspace documents from the server
- request.get(ServerUtils.prepend(RouteStore.getAllWorkspaces), (error, res, body) => {
- let ids = JSON.parse(body) as string[];
- Server.GetFields(ids, action((fields: { [id: string]: Field }) => this.userWorkspaces = ids.map(id => fields[id] as Document)));
- });
+ createNewWorkspace = (id?: string): void => {
+ this.userDocument.GetTAsync<ListField<Document>>(KeyStore.Workspaces, ListField).then(action((list: Opt<ListField<Document>>) => {
+ if (list) {
+ let freeformDoc = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" });
+ var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc)] }] };
+ let mainDoc = Documents.DockDocument(JSON.stringify(dockingLayout), { title: `Main Container ${list.Data.length + 1}` }, id);
+ list.Data.push(mainDoc);
+ // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
+ setTimeout(() => {
+ mainDoc.Set(KeyStore.ActiveFrame, freeformDoc);
+ this.openWorkspace(mainDoc);
+ let pendingDocument = Documents.SchemaDocument([], { title: "New Mobile Uploads" })
+ mainDoc.Set(KeyStore.OptionalRightCollection, pendingDocument);
+ }, 0);
+ }
+ }));
}
@action
openWorkspace = (doc: Document, fromHistory = false): void => {
- request.post(ServerUtils.prepend(RouteStore.setActiveWorkspace), {
- body: { target: doc.Id },
- json: true
- });
this.mainContainer = doc;
fromHistory || window.history.pushState(null, doc.Title, "/doc/" + doc.Id);
this.mainContainer.GetTAsync(KeyStore.ActiveFrame, Document, field => this.mainfreeform = field);
- this.mainContainer.GetTAsync(KeyStore.OptionalRightCollection, Document, col => {
+ this.userDocument.GetTAsync(KeyStore.OptionalRightCollection, Document).then(col => {
// if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
setTimeout(() => {
if (col) {
@@ -201,10 +202,15 @@ export class Main extends React.Component {
});
}
+ @observable
+ workspacesShown: boolean = false;
+
+ areWorkspacesShown = () => {
+ return this.workspacesShown;
+ }
+ @action
toggleWorkspaces = () => {
- if (WorkspacesMenu.Instance) {
- WorkspacesMenu.Instance.toggle()
- }
+ this.workspacesShown = !this.workspacesShown;
}
screenToLocalTransform = () => Transform.Identity
@@ -247,7 +253,7 @@ export class Main extends React.Component {
let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
let addAudioNode = action(() => Documents.AudioDocument(audiourl, { width: 200, height: 200, title: "audio node" }))
- let btns = [
+ let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Document][] = [
[React.createRef<HTMLDivElement>(), "font", "Add Textbox", addTextNode],
[React.createRef<HTMLDivElement>(), "image", "Add Image", addImageNode],
[React.createRef<HTMLDivElement>(), "file-pdf", "Add PDF", addPDFNode],
@@ -268,9 +274,9 @@ export class Main extends React.Component {
<div id="add-options-content">
<ul id="add-options-list">
{btns.map(btn =>
- <li key={btn[1] as string} ><div ref={btn[0] as React.RefObject<HTMLDivElement>}>
- <button className="round-button add-button" title={btn[2] as string} onPointerDown={setupDrag(btn[0] as React.RefObject<HTMLDivElement>, btn[3] as any)} onClick={addClick(btn[3] as any)}>
- <FontAwesomeIcon icon={btn[1] as any} size="sm" />
+ <li key={btn[1]} ><div ref={btn[0]}>
+ <button className="round-button add-button" title={btn[2]} onPointerDown={setupDrag(btn[0], btn[3])} onClick={addClick(btn[3])}>
+ <FontAwesomeIcon icon={btn[1]} size="sm" />
</button>
</div></li>)}
</ul>
@@ -300,6 +306,12 @@ export class Main extends React.Component {
}
render() {
+ let workspaceMenu: any = null;
+ let workspaces = this.userDocument.GetT<ListField<Document>>(KeyStore.Workspaces, ListField);
+ if (workspaces && workspaces !== FieldWaiting) {
+ workspaceMenu = <WorkspacesMenu active={this.mainContainer} open={this.openWorkspace} new={this.createNewWorkspace} allWorkspaces={workspaces.Data}
+ isShown={this.areWorkspacesShown} toggle={this.toggleWorkspaces} />
+ }
return (
<div id="main-div">
<Measure onResize={(r: any) => runInAction(() => {
@@ -316,7 +328,7 @@ export class Main extends React.Component {
<ContextMenu />
{this.nodesMenu}
{this.miscButtons}
- <WorkspacesMenu active={this.mainContainer} open={this.openWorkspace} new={this.createNewWorkspace} allWorkspaces={this.userWorkspaces} />
+ {workspaceMenu}
<InkingControl />
</div>
);
@@ -326,8 +338,8 @@ export class Main extends React.Component {
@action SetNorthstarCatalog(ctlog: Catalog) {
if (ctlog && ctlog.schemas) {
- this.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(ctlog.schemas!, (s: Schema) => s.displayName === "mimic");
- this._northstarColumns = this.GetAllNorthstarColumnAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
+ CurrentUserUtils.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(ctlog.schemas!, (s: Schema) => s.displayName === "mimic");
+ this._northstarColumns = CurrentUserUtils.GetAllNorthstarColumnAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
}
}
async initializeNorthstar(): Promise<void> {
@@ -342,22 +354,10 @@ export class Main extends React.Component {
let cat = Gateway.Instance.ClearCatalog();
cat.then(async () => this.SetNorthstarCatalog(await Gateway.Instance.GetCatalog()));
}
- public GetAllNorthstarColumnAttributes() {
- if (!this.ActiveSchema || !this.ActiveSchema.rootAttributeGroup) {
- return [];
- }
- const recurs = (attrs: Attribute[], g: AttributeGroup) => {
- if (g.attributes) {
- attrs.push.apply(attrs, g.attributes);
- if (g.attributeGroups) {
- g.attributeGroups.forEach(ng => recurs(attrs, ng));
- }
- }
- };
- const allAttributes: Attribute[] = new Array<Attribute>();
- recurs(allAttributes, this.ActiveSchema.rootAttributeGroup);
- return allAttributes;
- }
}
-ReactDOM.render(<Main />, document.getElementById('root'));
+Documents.initProtos().then(() => {
+ return CurrentUserUtils.loadCurrentUser()
+}).then(() => {
+ ReactDOM.render(<Main />, document.getElementById('root'));
+});
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 8b9d178c9..53fe969fe 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -75,7 +75,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
@undoBatch
@action
- drop = (e: Event, de: DragManager.DropEvent): boolean => {
+ drop = (e: Event, de: DragManager.DropEvent) => {
if (super.drop(e, de)) {
if (de.data instanceof DragManager.DocumentDragData) {
let screenX = de.x - (de.data.xOffset as number || 0);
@@ -83,6 +83,10 @@ export class CollectionFreeFormView extends CollectionViewBase {
const [x, y] = this.getTransform().transformPoint(screenX, screenY);
de.data.droppedDocument.SetNumber(KeyStore.X, x);
de.data.droppedDocument.SetNumber(KeyStore.Y, y);
+ if (!de.data.droppedDocument.GetNumber(KeyStore.Width, 0)) {
+ de.data.droppedDocument.SetNumber(KeyStore.Width, 300);
+ de.data.droppedDocument.SetNumber(KeyStore.Height, 300);
+ }
this.bringToFront(de.data.droppedDocument);
}
return true;
@@ -262,6 +266,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
if (lvalue && lvalue != FieldWaiting) {
return lvalue.Data.map(doc => {
+ if (!doc) return null;
var page = doc.GetNumber(KeyStore.Page, 0);
return (page != curPage && page != 0) ? (null) :
(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} />);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 696527049..0ff6c3b40 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,6 +1,6 @@
import React = require("react")
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
+import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, trace, untracked } from "mobx";
import { observer } from "mobx-react";
@@ -8,7 +8,7 @@ import Measure from "react-measure";
import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
import "react-table/react-table.css";
import { Document } from "../../../fields/Document";
-import { Field, Opt } from "../../../fields/Field";
+import { Field, Opt, FieldWaiting } from "../../../fields/Field";
import { Key } from "../../../fields/Key";
import { KeyStore } from "../../../fields/KeyStore";
import { ListField } from "../../../fields/ListField";
@@ -24,6 +24,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
import { CollectionView, COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { CollectionViewBase } from "./CollectionViewBase";
+import { TextField } from "../../../fields/TextField";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -85,12 +86,31 @@ export class CollectionSchemaView extends CollectionViewBase {
)
let reference = React.createRef<HTMLDivElement>();
let onItemDown = setupDrag(reference, () => props.doc, (containingCollection: CollectionView) => this.props.removeDocument(props.doc));
+ let applyToDoc = (doc: Document, value: string) => {
+ let script = CompileScript(value, { this: doc }, true);
+ if (!script.compiled) {
+ return false;
+ }
+ let field = script();
+ if (field instanceof Field) {
+ doc.Set(props.fieldKey, field);
+ return true;
+ } else {
+ let dataField = ToField(field);
+ if (dataField) {
+ doc.Set(props.fieldKey, dataField);
+ return true;
+ }
+ }
+ return false;
+ }
return (
- <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
+ <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "56px" }} key={props.doc.Id} ref={reference}>
<EditableView
display={"inline"}
contents={contents}
- height={36} GetValue={() => {
+ height={56}
+ GetValue={() => {
let field = props.doc.Get(props.fieldKey);
if (field && field instanceof Field) {
return field.ToScriptString();
@@ -98,22 +118,14 @@ export class CollectionSchemaView extends CollectionViewBase {
return field || "";
}}
SetValue={(value: string) => {
- let script = CompileScript(value);
- if (!script.compiled) {
- return false;
- }
- let field = script();
- if (field instanceof Field) {
- props.doc.Set(props.fieldKey, field);
- return true;
- } else {
- let dataField = ToField(field);
- if (dataField) {
- props.doc.Set(props.fieldKey, dataField);
- return true;
+ return applyToDoc(props.doc, value);
+ }}
+ OnFillDown={(value: string) => {
+ this.props.Document.GetTAsync<ListField<Document>>(this.props.fieldKey, ListField).then((val) => {
+ if (val) {
+ val.Data.forEach(doc => applyToDoc(doc, value));
}
- }
- return false;
+ })
}}>
</EditableView>
</div>
@@ -238,6 +250,19 @@ export class CollectionSchemaView extends CollectionViewBase {
}
}
+ @action
+ addColumn = () => {
+ this.columns.push(new Key(this.newKeyName));
+ this.newKeyName = "";
+ }
+
+ @observable
+ newKeyName: string = "";
+
+ @action
+ newKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.newKeyName = e.currentTarget.value;
+ }
onWheel = (e: React.WheelEvent): void => {
if (this.props.active())
e.stopPropagation();
@@ -248,18 +273,29 @@ export class CollectionSchemaView extends CollectionViewBase {
OptionsMenuDown = (e: React.PointerEvent) => {
this._optionsActivated++;
}
+
+ @observable previewScript: string = "this";
+ @action
+ onPreviewScriptChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.previewScript = e.currentTarget.value;
+ }
+
render() {
library.add(faCog);
+ library.add(faPlus);
const columns = this.columns;
const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
//all the keys/columns that will be displayed in the schema
const allKeys = this.findAllDocumentKeys;
+ let doc: any = selected ? selected.Get(new Key(this.previewScript)) : undefined;
+
+ // let doc = CompileScript(this.previewScript, { this: selected }, true)();
let content = this._selectedIndex == -1 || !selected ? (null) : (
<Measure onResize={this.setScaling}>
{({ measureRef }) =>
<div className="collectionSchemaView-content" ref={measureRef}>
- <DocumentView Document={selected}
+ {doc instanceof Document ? <DocumentView Document={doc}
AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
isTopMost={false}
SelectOnLoad={false}
@@ -269,7 +305,9 @@ export class CollectionSchemaView extends CollectionViewBase {
PanelHeight={this.getPanelHeight}
ContainingCollectionView={this.props.CollectionView}
focus={this.focusDocument}
- />
+ /> : null}
+ <input value={this.previewScript} onChange={this.onPreviewScriptChange}
+ style={{ position: 'absolute', bottom: '0px' }} />
</div>
}
</Measure>
@@ -291,6 +329,8 @@ export class CollectionSchemaView extends CollectionViewBase {
return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
})}
</ul>
+ <input value={this.newKeyName} onChange={this.newKeyChange} />
+ <button onClick={this.addColumn}><FontAwesomeIcon style={{ color: "white" }} icon="plus" size="lg" /></button>
</div>
</div>
}>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index be757e22e..a740865ad 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -13,8 +13,7 @@ import { CollectionSchemaView } from "./CollectionSchemaView";
import { CollectionViewProps } from "./CollectionViewBase";
import { CollectionTreeView } from "./CollectionTreeView";
import { Field, FieldId, FieldWaiting } from "../../../fields/Field";
-import { Main } from "../Main";
-import { dropPoint } from "prosemirror-transform";
+import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
export enum CollectionViewType {
Invalid,
@@ -125,7 +124,7 @@ export class CollectionView extends React.Component<CollectionViewProps> {
}
specificContextMenu = (e: React.MouseEvent): void => {
- if (!e.isPropagationStopped() && this.props.Document.Id != Main.Instance.mainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
+ if (!e.isPropagationStopped() && this.props.Document.Id != CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) })
ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) })
ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) })
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 535a8a8d2..adaf810ea 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -14,10 +14,9 @@ import { RouteStore } from "../../../server/RouteStore";
import { TupleField } from "../../../fields/TupleField";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { NumberField } from "../../../fields/NumberField";
-import { DocumentManager } from "../../util/DocumentManager";
import request = require("request");
import { ServerUtils } from "../../../server/ServerUtil";
-import { addHiddenFinalProp } from "mobx/lib/internal";
+import { Server } from "../../Server";
export interface CollectionViewProps {
fieldKey: Key;
@@ -60,17 +59,20 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
let email = CurrentUserUtils.email;
if (id && email) {
let textInfo: [string, string] = [id, email];
- doc.GetOrCreateAsync<ListField<CursorEntry>>(KeyStore.Cursors, ListField, field => {
- let cursors = field.Data;
- if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.Data[0][0] === id)) > -1) {
- cursors[ind].Data[1] = position;
- } else {
- let entry = new TupleField<[string, string], [number, number]>([textInfo, position]);
- cursors.push(entry);
+ doc.GetTAsync(KeyStore.Prototype, Document).then(proto => {
+ if (!proto) {
+ return;
}
+ proto.GetOrCreateAsync<ListField<CursorEntry>>(KeyStore.Cursors, ListField, action((field: ListField<CursorEntry>) => {
+ let cursors = field.Data;
+ if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.Data[0][0] === id)) > -1) {
+ cursors[ind].Data[1] = position;
+ } else {
+ let entry = new TupleField<[string, string], [number, number]>([textInfo, position]);
+ cursors.push(entry);
+ }
+ }))
})
-
-
}
}
@@ -115,6 +117,21 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
ctor = Documents.PdfDocument;
}
if (type.indexOf("html") !== -1) {
+ if (path.includes('localhost')) {
+ let s = path.split('/');
+ let id = s[s.length - 1];
+ Server.GetField(id).then(field => {
+ if (field instanceof Document) {
+ let alias = field.CreateAlias();
+ alias.SetNumber(KeyStore.X, options.x || 0);
+ alias.SetNumber(KeyStore.Y, options.y || 0);
+ alias.SetNumber(KeyStore.Width, options.width || 300);
+ alias.SetNumber(KeyStore.Height, options.height || options.width || 300);
+ this.props.addDocument(alias, false);
+ }
+ })
+ return undefined;
+ }
ctor = Documents.WebDocument;
options = { height: options.width, ...options, };
}
@@ -134,7 +151,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
e.stopPropagation()
e.preventDefault()
- if (html && html.indexOf("<img") != 0) {
+ if (html && html.indexOf("<img") != 0 && !html.startsWith("<a")) {
console.log("not good");
let htmlDoc = Documents.HtmlDocument(html, { ...options, width: 300, height: 300 });
htmlDoc.SetText(KeyStore.DocumentText, text);
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 2f0459f88..12d14eb42 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -47,8 +47,13 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
}
render() {
+ let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField);
+ if (!lkeys || lkeys === FieldWaiting) {
+ return <p>Error loading layout keys</p>;
+ }
return <JsxParser
- components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }} bindings={this.CreateBindings()}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }}
+ bindings={this.CreateBindings()}
jsx={this.layout}
showWarnings={true}
onError={(test: any) => { console.log(test) }}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 383341e02..3873a6f89 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -18,6 +18,7 @@ import { ContextMenu } from "../ContextMenu";
import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
import React = require("react");
+import { ServerUtils } from "../../../server/ServerUtil";
export interface DocumentViewProps {
@@ -284,6 +285,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) })
ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) })
ContextMenu.Instance.addItem({
+ description: "Copy URL",
+ event: () => {
+ Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
+ }
+ });
+ ContextMenu.Instance.addItem({
description: "Copy ID",
event: () => {
Utils.CopyText(this.props.Document.Id);
@@ -314,10 +321,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
if (!this.props.Document) {
return (null);
}
- let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField);
- if (!lkeys || lkeys === FieldWaiting) {
- return <p>Error loading layout keys</p>;
- }
var scaling = this.props.ContentScaling();
var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f6343c631..4e83ec7b9 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -16,6 +16,9 @@ import { VideoBox } from "./VideoBox";
import { AudioBox } from "./AudioBox";
import { AudioField } from "../../../fields/AudioField";
import { ListField } from "../../../fields/ListField";
+import { DocumentContentsView } from "./DocumentContentsView";
+import { Transform } from "../../util/Transform";
+import { KeyStore } from "../../../fields/KeyStore";
//
@@ -65,7 +68,20 @@ export class FieldView extends React.Component<FieldViewProps> {
return <AudioBox {...this.props} />
}
else if (field instanceof Document) {
- return <div>{field.Title}</div>
+ return (<DocumentContentsView Document={field}
+ AddDocument={undefined}
+ RemoveDocument={undefined}
+ ScreenToLocalTransform={() => Transform.Identity}
+ ContentScaling={() => 1}
+ PanelWidth={() => 100}
+ PanelHeight={() => 100}
+ isTopMost={true}
+ SelectOnLoad={false}
+ focus={() => { }}
+ isSelected={() => false}
+ select={() => false}
+ layoutKey={KeyStore.Layout}
+ ContainingCollectionView={undefined} />)
}
else if (field instanceof ListField) {
return (<div>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index ba9bd9566..30fa1342e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -167,6 +167,8 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
onKeyPress={this.onKeyPress}
onPointerDown={this.onPointerDown}
onContextMenu={this.specificContextMenu}
+ // tfs: do we need this event handler
+ onKeyDown={this.onKeyPress}
onWheel={this.onPointerWheel}
ref={this._ref} />)
}
diff --git a/src/client/views/nodes/HistogramBox.tsx b/src/client/views/nodes/HistogramBox.tsx
index 980719a21..1508b201b 100644
--- a/src/client/views/nodes/HistogramBox.tsx
+++ b/src/client/views/nodes/HistogramBox.tsx
@@ -3,13 +3,12 @@ import { action, computed, observable, reaction } from "mobx";
import { observer } from "mobx-react";
import Measure from "react-measure";
import { Dictionary } from "typescript-collections";
+import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { Utils as DashUtils } from '../../../Utils';
import { ColumnAttributeModel } from "../../northstar/core/attribute/AttributeModel";
import { AttributeTransformationModel } from "../../northstar/core/attribute/AttributeTransformationModel";
import { FilterModel } from '../../northstar/core/filter/FilterModel';
-import { DateTimeVisualBinRange } from "../../northstar/model/binRanges/DateTimeVisualBinRange";
import { NominalVisualBinRange } from "../../northstar/model/binRanges/NominalVisualBinRange";
-import { QuantitativeVisualBinRange } from "../../northstar/model/binRanges/QuantitativeVisualBinRange";
import { ChartType, VisualBinRange } from '../../northstar/model/binRanges/VisualBinRange';
import { VisualBinRangeHelper } from "../../northstar/model/binRanges/VisualBinRangeHelper";
import { AggregateBinRange, AggregateFunction, Bin, Brush, DoubleValueAggregateResult, HistogramResult, MarginAggregateParameters, MarginAggregateResult } from "../../northstar/model/idea/idea";
@@ -20,7 +19,6 @@ import { LABColor } from '../../northstar/utils/LABcolor';
import { PIXIRectangle } from "../../northstar/utils/MathUtil";
import { SizeConverter } from "../../northstar/utils/SizeConverter";
import { StyleConstants } from "../../northstar/utils/StyleContants";
-import { Main } from "../Main";
import { FieldView, FieldViewProps } from './FieldView';
import "./HistogramBox.scss";
@@ -51,7 +49,7 @@ export class HistogramBox extends React.Component<FieldViewProps> {
componentDidMount() {
reaction(() => [this.props.doc.Title],
() => {
- Main.Instance.GetAllNorthstarColumnAttributes().map(a => {
+ CurrentUserUtils.GetAllNorthstarColumnAttributes().map(a => {
if (a.displayName == this.props.doc.Title) {
var atmod = new ColumnAttributeModel(a);
this._histoOp = new HistogramOperation(new AttributeTransformationModel(atmod, AggregateFunction.None),