aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts17
-rw-r--r--src/client/util/Scripting.ts8
-rw-r--r--src/client/util/type_decls.d3
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx5
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx42
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx39
-rw-r--r--src/client/views/nodes/DocumentView.tsx7
-rw-r--r--src/client/views/nodes/FieldView.tsx18
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx2
9 files changed, 117 insertions, 24 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 96a7332aa..a2444db06 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,6 +1,6 @@
import { AudioField } from "../../fields/AudioField";
import { Document } from "../../fields/Document";
-import { Field } from "../../fields/Field";
+import { Field, FieldWaiting } from "../../fields/Field";
import { HtmlField } from "../../fields/HtmlField";
import { ImageField } from "../../fields/ImageField";
import { InkField, StrokeData } from "../../fields/InkField";
@@ -23,6 +23,7 @@ import { PDFBox } from "../views/nodes/PDFBox";
import { VideoBox } from "../views/nodes/VideoBox";
import { WebBox } from "../views/nodes/WebBox";
import { HistogramBox } from "../views/nodes/HistogramBox";
+import { FieldView } from "../views/nodes/FieldView";
export interface DocumentOptions {
x?: number;
@@ -112,7 +113,7 @@ export namespace Documents {
function GetImagePrototype(): Document {
if (!imageProto) {
imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
+ { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString());
}
return imageProto;
@@ -155,7 +156,7 @@ export namespace Documents {
function GetVideoPrototype(): Document {
if (!videoProto) {
videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
+ { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
videoProto.SetNumber(KeyStore.CurPage, 0);
videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
}
@@ -218,6 +219,14 @@ export namespace Documents {
return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options)
}
+ export function CaptionDocument(doc: Document) {
+ const captionDoc = doc.CreateAlias();
+ captionDoc.SetText(KeyStore.OverlayLayout, FixedCaption());
+ captionDoc.SetNumber(KeyStore.Width, doc.GetNumber(KeyStore.Width, 0));
+ captionDoc.SetNumber(KeyStore.Height, doc.GetNumber(KeyStore.Height, 0));
+ return captionDoc;
+ }
+
// example of custom display string for an image that shows a caption.
function EmbeddedCaption() {
return `<div style="height:100%">
@@ -228,7 +237,7 @@ export namespace Documents {
+ FormattedTextBox.LayoutString("CaptionKey") +
`</div>
</div>` };
- function FixedCaption(fieldName: string = "Caption") {
+ export function FixedCaption(fieldName: string = "Caption") {
return `<div style="position:absolute; height:30px; bottom:0; width:100%">
<div style="position:absolute; width:100%; height:100%; text-align:center;bottom:0;">`
+ FormattedTextBox.LayoutString(fieldName + "Key") +
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 4cf98472f..4e97b9401 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -15,6 +15,8 @@ import { ListField } from "../../fields/ListField";
// @ts-ignore
import * as typescriptlib from '!!raw-loader!./type_decls.d'
+import { Documents } from "../documents/Documents";
+import { Key } from "../../fields/Key";
export interface ExecutableScript {
@@ -28,9 +30,9 @@ function Compile(script: string | undefined, diagnostics: Opt<any[]>, scope: { [
let func: () => Opt<Field>;
if (compiled && script) {
- let fieldTypes = [Document, NumberField, TextField, ImageField, RichTextField, ListField];
- let paramNames = ["KeyStore", ...fieldTypes.map(fn => fn.name)];
- let params: any[] = [KeyStore, ...fieldTypes]
+ let fieldTypes = [Document, NumberField, TextField, ImageField, RichTextField, ListField, Key];
+ let paramNames = ["KeyStore", "Documents", ...fieldTypes.map(fn => fn.name)];
+ let params: any[] = [KeyStore, Documents, ...fieldTypes]
for (let prop in scope) {
if (prop === "this") {
continue;
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index dcf79285d..4f69053b1 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -174,6 +174,7 @@ declare class ListField<T> extends BasicField<T[]>{
Copy(): Field;
}
declare class Key extends Field {
+ constructor(name:string);
Name: string;
TrySetValue(value: any): boolean;
GetValue(): any;
@@ -220,3 +221,5 @@ declare const KeyStore: {
// @ts-ignore
declare const console: any;
+
+declare const Documents: any;
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index da9f7b392..8f7b4cfe7 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -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);
}
}
@@ -259,6 +263,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 8e0a38f05..7dd364449 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
@@ -104,11 +105,11 @@ export class CollectionSchemaView extends CollectionViewBase {
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}
+ height={56}
GetValue={() => {
let field = props.doc.Get(props.fieldKey);
if (field && field instanceof Field) {
@@ -249,23 +250,48 @@ 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;
+ }
+
@observable _optionsActivated: number = 0;
@action
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}
@@ -275,7 +301,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>
@@ -297,6 +325,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/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index f33007196..7d903899d 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -17,6 +17,7 @@ import { NumberField } from "../../../fields/NumberField";
import { DocumentManager } from "../../util/DocumentManager";
import request = require("request");
import { ServerUtils } from "../../../server/ServerUtil";
+import { Server } from "../../Server";
export interface CollectionViewProps {
fieldKey: Key;
@@ -59,17 +60,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);
+ }
+ }))
})
-
-
}
}
@@ -111,6 +115,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, };
}
@@ -130,7 +149,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/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index cfe67c8fe..55aa1ccab 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);
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} />)
}