aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/DragManager.ts31
-rw-r--r--src/client/util/RichTextSchema.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts3
-rw-r--r--src/client/views/MetadataEntryMenu.scss6
-rw-r--r--src/client/views/MetadataEntryMenu.tsx45
-rw-r--r--src/client/views/PreviewCursor.tsx2
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx151
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx1
-rw-r--r--src/client/views/nodes/ButtonBox.scss19
-rw-r--r--src/client/views/nodes/ButtonBox.tsx42
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx5
-rw-r--r--src/client/views/nodes/WebBox.scss10
-rw-r--r--src/client/views/nodes/WebBox.tsx42
-rw-r--r--src/new_fields/Doc.ts17
15 files changed, 243 insertions, 144 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 24c093213..4c9c9c17c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,5 +1,5 @@
import { action, runInAction } from "mobx";
-import { Doc } from "../../new_fields/Doc";
+import { Doc, Field } from "../../new_fields/Doc";
import { Cast, StrCast } from "../../new_fields/Types";
import { URLField } from "../../new_fields/URLField";
import { emptyFunction } from "../../Utils";
@@ -9,6 +9,11 @@ import { DocumentManager } from "./DocumentManager";
import { LinkManager } from "./LinkManager";
import { SelectionManager } from "./SelectionManager";
import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
+import { Docs } from "../documents/Documents";
+import { CompileScript } from "./Scripting";
+import { ScriptField } from "../../new_fields/ScriptField";
+import { List } from "../../new_fields/List";
+import { PrefetchProxy } from "../../new_fields/Proxy";
export type dropActionType = "alias" | "copy" | undefined;
export function SetupDrag(
@@ -247,6 +252,28 @@ export namespace DragManager {
});
}
+ export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize?: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
+ let dragData = new DragManager.DocumentDragData([], [undefined]);
+ runInAction(() => StartDragFunctions.map(func => func()));
+ StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
+ (dropData: { [id: string]: any }) => {
+ let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+ let compiled = CompileScript(script, {
+ params: { doc: Doc.name },
+ typecheck: false,
+ editable: true
+ });
+ if (compiled.compiled) {
+ let scriptField = new ScriptField(compiled);
+ bd.onClick = scriptField;
+ }
+ params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+ initialize && initialize(bd);
+ bd.buttonParams = new List<string>(params);
+ dropData.droppedDocuments = [bd];
+ });
+ }
+
export function StartLinkedDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
dragData.moveDocument = moveLinkedDocument;
@@ -482,7 +509,7 @@ export namespace DragManager {
// if (parent && dragEle) parent.appendChild(dragEle);
});
if (target) {
- if (finishDrag) finishDrag(dragData);
+ finishDrag && finishDrag(dragData);
target.dispatchEvent(
new CustomEvent<DropEvent>("dashOnDrop", {
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 6d2abfaa2..9fdda4845 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -105,7 +105,6 @@ export const nodes: { [index: string]: NodeSpec } = {
// }
// }]
},
-
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
// `alt`, and `href` attributes. The latter two default to the empty
// string.
@@ -197,7 +196,6 @@ export const nodes: { [index: string]: NodeSpec } = {
...listItem,
content: 'paragraph block*'
},
-
};
const emDOM: DOMOutputSpecArray = ["em", 0];
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index fda3f55bb..d0464bd5f 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -181,9 +181,6 @@ export default class KeyManager {
break;
case "a":
case "v":
- stopPropagation = false;
- preventDefault = false;
- break;
case "x":
case "c":
stopPropagation = false;
diff --git a/src/client/views/MetadataEntryMenu.scss b/src/client/views/MetadataEntryMenu.scss
index e28c4d0e0..7da55fd1c 100644
--- a/src/client/views/MetadataEntryMenu.scss
+++ b/src/client/views/MetadataEntryMenu.scss
@@ -1,7 +1,11 @@
.metadataEntry-outerDiv {
display: flex;
+ width: 310px;
flex-direction: column;
- width: 300px;
+
+ input[type=checkbox] {
+ margin-left: 5px;
+ }
}
.metadataEntry-keys {
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index ec628c5a3..f1b101b8e 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -3,7 +3,7 @@ import "./MetadataEntryMenu.scss";
import { observer } from 'mobx-react';
import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx';
import { KeyValueBox } from './nodes/KeyValueBox';
-import { Doc, Field } from '../../new_fields/Doc';
+import { Doc, Field, DocListCast, DocListCastAsync } from '../../new_fields/Doc';
import * as Autosuggest from 'react-autosuggest';
import { undoBatch } from '../util/UndoManager';
import { emptyFunction } from '../../Utils';
@@ -19,6 +19,8 @@ export interface MetadataEntryProps {
export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
@observable private _currentKey: string = "";
@observable private _currentValue: string = "";
+ @observable private suggestions: string[] = [];
+ private _addChildren: boolean = false;
@observable _allSuggestions: string[] = [];
_suggestionDispser: IReactionDisposer | undefined;
private userModified = false;
@@ -84,16 +86,27 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
e.stopPropagation();
const script = KeyValueBox.CompileKVPScript(this._currentValue);
if (!script) return;
+
let doc = this.props.docs;
if (typeof doc === "function") {
doc = doc();
}
doc = await doc;
+
let success: boolean;
if (doc instanceof Doc) {
success = KeyValueBox.ApplyKVPScript(doc, this._currentKey, script);
} else {
- success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script));
+ let childSuccess = true;
+ if (this._addChildren) {
+ for (let document of doc) {
+ let collectionChildren = await DocListCastAsync(document.data);
+ if (collectionChildren) {
+ childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script));
+ }
+ }
+ }
+ success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess;
}
if (!success) {
if (this.props.onError) {
@@ -154,6 +167,33 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
this._suggestionDispser && this._suggestionDispser();
}
+ onClick = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._addChildren = !this._addChildren;
+ }
+
+ private get considerChildOptions() {
+ let docSource = this.props.docs;
+ if (typeof docSource === "function") {
+ docSource = docSource();
+ }
+ docSource = docSource as Doc[] | Doc;
+ if (docSource instanceof Doc) {
+ if (docSource.viewType === undefined) {
+ return (null);
+ }
+ } else if (Array.isArray(docSource)) {
+ if (!docSource.every(doc => doc.viewType !== undefined)) {
+ return null;
+ }
+ }
+ return (
+ <div style={{ display: "flex" }}>
+ Children:
+ <input type="checkbox" onChange={this.onClick} ></input>
+ </div>
+ );
+ }
+
render() {
return (
<div className="metadataEntry-outerDiv">
@@ -169,6 +209,7 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
ref={this.autosuggestRef} />
Value:
<input className="metadataEntry-input" value={this._currentValue} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} />
+ {this.considerChildOptions}
</div>
<div className="metadataEntry-keys" >
<ul>
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 9ec31d67d..1329dc02c 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -49,7 +49,7 @@ export class PreviewCursor extends React.Component<{}> {
}
// tests for URL and makes web document
- let re: any = /^https?:\/\/www\./g;
+ let re: any = /^https?:\/\//g;
if (re.test(e.clipboardData.getData("text/plain"))) {
const url = e.clipboardData.getData("text/plain");
PreviewCursor._addDocument(Docs.Create.WebDocument(url, {
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 333baf288..1156d8fa7 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -41,16 +41,31 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
//(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
+ private _buttonizableCommands = [{
+ // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting...
+ title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"],
+ immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d)))
+ },
+ {
+ title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"],
+ immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined
+ },
+ {
+ title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"],
+ immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1 },
+ initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; }
+ }];
+ private _picker: any;
+ private _commandRef = React.createRef<HTMLInputElement>();
+ private _autosuggestRef = React.createRef<Autosuggest>();
+ @observable private _currentKey: string = "";
@observable private _viewSpecsOpen: boolean = false;
@observable private _dateWithinValue: string = "";
@observable private _dateValue: Date | string = "";
@observable private _keyRestrictions: [JSX.Element, string][] = [];
@observable private suggestions: string[] = [];
- _commandRef = React.createRef<HTMLInputElement>();
@computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
- private _picker: any;
-
getFilters = (script: string) => {
let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
let arr: any[] = re.exec(script);
@@ -215,25 +230,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
subChrome = () => {
switch (this.props.type) {
- case CollectionViewType.Stacking: return (
- <CollectionStackingViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type} />);
- case CollectionViewType.Schema: return (
- <CollectionSchemaViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type}
- />);
- case CollectionViewType.Tree: return (
- <CollectionTreeViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type}
- />);
- default:
- return null;
+ case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ default: return null;
}
}
@@ -267,6 +267,17 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
})} />);
}
+ @action.bound
+ clearFilter = () => {
+ let compiled = CompileScript("return true", { params: { doc: Doc.name }, typecheck: false });
+ if (compiled.compiled) {
+ this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
+ }
+
+ this._keyRestrictions = [];
+ this.addKeyRestrictions([]);
+ }
+
private dropDisposer?: DragManager.DragDropDisposer;
protected createDropTarget = (ele: HTMLDivElement) => {
this.dropDisposer && this.dropDisposer();
@@ -278,32 +289,13 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
@undoBatch
@action
protected drop(e: Event, de: DragManager.DropEvent): boolean {
- if (de.data instanceof DragManager.DocumentDragData) {
- if (de.data.draggedDocuments.length) {
- if (this._currentKey === "Set Template") {
- this.props.CollectionView.props.Document.childLayout = de.data.draggedDocuments[0];
- }
- if (this._currentKey === "Set Content") {
- Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(de.data.draggedDocuments);
- }
- e.stopPropagation();
- return true;
- }
+ if (de.data instanceof DragManager.DocumentDragData && de.data.draggedDocuments.length) {
+ this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
+ e.stopPropagation();
}
return true;
}
- @action.bound
- clearFilter = () => {
- let compiled = CompileScript("return true", { params: { doc: Doc.name }, typecheck: false });
- if (compiled.compiled) {
- this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
- }
-
- this._keyRestrictions = [];
- this.addKeyRestrictions([]);
- }
-
datePickerRef = (node: HTMLInputElement) => {
if (node) {
try {
@@ -318,10 +310,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
- @observable private _currentKey: string = "";
- @observable _allCommands: string[] = ["Set Template", "Set Content"];
- private autosuggestRef = React.createRef<Autosuggest>();
-
renderSuggestion = (suggestion: string) => {
return <p>{suggestion}</p>;
}
@@ -340,38 +328,41 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
this.suggestions = [];
}
getKeySuggestions = async (value: string): Promise<string[]> => {
- return this._allCommands.filter(c => c.indexOf(value) !== -1);
+ return this._buttonizableCommands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
}
autoSuggestDown = (e: React.PointerEvent) => {
e.stopPropagation();
}
+
+ private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+ private _sensitivity: number = 16;
+
dragCommandDown = (e: React.PointerEvent) => {
- let de = new DragManager.DocumentDragData([this.props.CollectionView.props.Document], [undefined]);
- DragManager.StartDocumentDrag([this._commandRef.current!], de, e.clientX, e.clientY, {
- finishDrag: (dropData: { [id: string]: any }) => {
- let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: this._currentKey });
- let script = `getProto(target).data = copyField(this.source);`;
- let compiled = CompileScript(script, {
- params: { doc: Doc.name },
- capturedVariables: { target: this.props.CollectionView.props.Document },
- typecheck: false,
- editable: true
- });
- if (compiled.compiled) {
- let scriptField = new ScriptField(compiled);
- bd.onClick = scriptField;
- }
- dropData.droppedDocuments = [bd];
- },
- handlers: {
- dragComplete: action(() => {
- }),
- },
- hideSource: false
- });
+
+ this._startDragPosition = { x: e.clientX, y: e.clientY };
+ document.addEventListener("pointermove", this.dragPointerMove);
+ document.addEventListener("pointerup", this.dragPointerUp);
+ e.stopPropagation();
e.preventDefault();
+ }
+
+ dragPointerMove = (e: PointerEvent) => {
e.stopPropagation();
+ e.preventDefault();
+ let [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y];
+ if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
+ this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c =>
+ DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
+ { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY));
+ document.removeEventListener("pointermove", this.dragPointerMove);
+ document.removeEventListener("pointerup", this.dragPointerUp);
+ }
+ }
+ dragPointerUp = (e: PointerEvent) => {
+ document.removeEventListener("pointermove", this.dragPointerMove);
+ document.removeEventListener("pointerup", this.dragPointerUp);
+
}
render() {
@@ -419,7 +410,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
<div className="collectionViewBaseChrome-viewSpecsMenu-row">
<div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
CREATED WITHIN:
- </div>
+ </div>
<select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
style={{ textTransform: "uppercase", textAlign: "center" }}
value={this._dateWithinValue}
@@ -442,15 +433,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
placeholder="Value" />
</div>
<div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
- <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
- ADD KEY RESTRICTION
- </button>
- <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
- APPLY FILTER
- </button>
- <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.clearFilter}>
- CLEAR
- </button>
+ <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}> ADD KEY RESTRICTION </button>
+ <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}> APPLY FILTER </button>
+ <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.clearFilter}> CLEAR </button>
</div>
</div>
</div>
@@ -464,7 +449,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
renderSuggestion={this.renderSuggestion}
onSuggestionsFetchRequested={this.onSuggestionFetch}
onSuggestionsClearRequested={this.onSuggestionClear}
- ref={this.autosuggestRef} />
+ ref={this._autosuggestRef} />
</div>
</div>
</div>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 224e8047d..0a2dcbe3b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -187,8 +187,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
componentDidMount() {
this._childLayoutDisposer = reaction(() => [this.childDocs, Cast(this.props.Document.childLayout, Doc)],
- async (args) => args[1] instanceof Doc &&
- this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined)));
+ async (args) => {
+ this.childDocs.filter(doc => args[1] instanceof Doc || doc.layout instanceof Doc).map(async doc => {
+ if (!Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc)) {
+ Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined);
+ }
+ });
+ });
}
componentWillUnmount() {
this._childLayoutDisposer && this._childLayoutDisposer();
@@ -291,7 +296,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
if (super.drop(e, de)) {
if (de.data instanceof DragManager.DocumentDragData) {
if (de.data.droppedDocuments.length) {
- let z = NumCast(de.data.draggedDocuments[0].z);
+ let z = NumCast(de.data.droppedDocuments[0].z);
let x = (z ? xpo : xp) - de.data.xOffset;
let y = (z ? ypo : yp) - de.data.yOffset;
let dropX = NumCast(de.data.droppedDocuments[0].x);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index e70d526c5..27eafd769 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -203,7 +203,6 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
onClick = (e: React.MouseEvent): void => {
if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
- //this is probably the wrong transform
PreviewCursor.Show(e.clientX, e.clientY, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument);
// let the DocumentView stopPropagation of this event when it selects this document
} else { // why do we get a click event when the cursor have moved a big distance?
diff --git a/src/client/views/nodes/ButtonBox.scss b/src/client/views/nodes/ButtonBox.scss
index 5ed435505..75a790667 100644
--- a/src/client/views/nodes/ButtonBox.scss
+++ b/src/client/views/nodes/ButtonBox.scss
@@ -3,14 +3,29 @@
height: 100%;
pointer-events: all;
border-radius: inherit;
- display:table;
+ display:flex;
+ flex-direction: column;
}
.buttonBox-mainButton {
width: 100%;
height: 100%;
border-radius: inherit;
+ text-align: center;
+ display: table;
+}
+.buttonBox-mainButtonCenter {
+ height: 100%;
display:table-cell;
vertical-align: middle;
- text-align: center;
+}
+
+.buttonBox-params {
+ display:flex;
+ flex-direction: row;
+}
+
+.buttonBox-missingParam {
+ width:100%;
+ background: lightgray;
} \ No newline at end of file
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index ca5f0acc2..54848344b 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -1,25 +1,19 @@
-import * as React from 'react';
-import { FieldViewProps, FieldView } from './FieldView';
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { DocComponent } from '../DocComponent';
-import { ContextMenu } from '../ContextMenu';
import { library } from '@fortawesome/fontawesome-svg-core';
import { faEdit } from '@fortawesome/free-regular-svg-icons';
-import { emptyFunction } from '../../../Utils';
-import { ScriptBox } from '../ScriptBox';
-import { CompileScript } from '../../util/Scripting';
-import { OverlayView } from '../OverlayView';
-import { Doc } from '../../../new_fields/Doc';
-
-import './ButtonBox.scss';
+import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
-import { DocumentIconContainer } from './DocumentIcon';
-import { StrCast, BoolCast } from '../../../new_fields/Types';
+import * as React from 'react';
+import { Doc, DocListCastAsync } from '../../../new_fields/Doc';
+import { List } from '../../../new_fields/List';
+import { createSchema, makeInterface, listSpec } from '../../../new_fields/Schema';
+import { ScriptField } from '../../../new_fields/ScriptField';
+import { BoolCast, StrCast, Cast } from '../../../new_fields/Types';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
-import { action, computed } from 'mobx';
-import { List } from '../../../new_fields/List';
+import { DocComponent } from '../DocComponent';
+import './ButtonBox.scss';
+import { FieldView, FieldViewProps } from './FieldView';
+
library.add(faEdit as any);
@@ -52,12 +46,24 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.data instanceof DragManager.DocumentDragData) {
Doc.GetProto(this.dataDoc).source = new List<Doc>(de.data.droppedDocuments);
+ e.stopPropagation();
}
}
+ // (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")")
render() {
+ let params = Cast(this.props.Document.buttonParams, listSpec("string"));
+ let missingParams = params && params.filter(p => this.props.Document[p] === undefined);
+ params && params.map(async p => await DocListCastAsync(this.props.Document[p])); // bcz: really hacky form of prefetching ...
return (
<div className="buttonBox-outerDiv" ref={this.createDropTarget} >
- <div className="buttonBox-mainButton" style={{ background: StrCast(this.props.Document.backgroundColor), color: StrCast(this.props.Document.color, "black") }} >{this.Document.text || this.Document.title}</div>
+ <div className="buttonBox-mainButton" style={{ background: StrCast(this.props.Document.backgroundColor), color: StrCast(this.props.Document.color, "black") }} >
+ <div className="buttonBox-mainButtonCenter">
+ {(this.Document.text || this.Document.title)}
+ </div>
+ </div>
+ <div className="buttonBox-params" >
+ {!missingParams || !missingParams.length ? (null) : missingParams.map(m => <div key={m} className="buttonBox-missingParam">{m}</div>)}
+ </div>
</div>
);
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 467f10ab8..0e04bacf7 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -34,16 +34,12 @@ import "./FormattedTextBox.scss";
import React = require("react");
import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/GoogleApiClientUtils';
import { DocumentDecorations } from '../DocumentDecorations';
-import { MainOverlayTextBox } from '../MainOverlayTextBox';
import { DictationManager } from '../../util/DictationManager';
import { ReplaceStep } from 'prosemirror-transform';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
-// FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document
-//
-
export const Blank = `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`;
export interface FormattedTextBoxProps {
@@ -146,7 +142,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
paste = (e: ClipboardEvent) => {
- //this is throwing a ton of erros so i had to comment it out
if (e.clipboardData && this._editorView) {
// let pdfPasteText = `${Utils.GenerateDeterministicGuid("pdf paste")}`;
// for (let i = 0; i < e.clipboardData.items.length; i++) {
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 07774263c..43220df71 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -1,3 +1,5 @@
+@import "../globalCssVariables.scss";
+
.webBox-cont,
.webBox-cont-interactive {
padding: 0vw;
@@ -61,6 +63,14 @@
width: 40px;
transform-origin: top left;
}
+
+ .switchToText {
+ color: $main-accent;
+ }
+
+ .switchToText:hover {
+ color: $dark-color;
+ }
}
button:hover {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 1b54472e5..095b0094e 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,4 +1,5 @@
import { observer } from "mobx-react";
+import { FieldResult, Doc, Field } from "../../../new_fields/Doc";
import { HtmlField } from "../../../new_fields/HtmlField";
import { WebField } from "../../../new_fields/URLField";
import { DocumentDecorations } from "../DocumentDecorations";
@@ -13,17 +14,17 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faStickyNote } from '@fortawesome/free-solid-svg-icons';
import { observable, action, computed } from "mobx";
import { listSpec } from "../../../new_fields/Schema";
-import { Field, FieldResult } from "../../../new_fields/Doc";
import { RefField } from "../../../new_fields/RefField";
import { ObjectField } from "../../../new_fields/ObjectField";
import { updateSourceFile } from "typescript";
import { KeyValueBox } from "./KeyValueBox";
import { setReactionScheduler } from "mobx/lib/internal";
import { library } from "@fortawesome/fontawesome-svg-core";
+import { SelectionManager } from "../../util/SelectionManager";
import { Docs } from "../../documents/Documents";
-import { PreviewCursor } from "../PreviewCursor";
library.add(faStickyNote);
+library.add(faStickyNote)
@observer
export class WebBox extends React.Component<FieldViewProps> {
@@ -75,21 +76,27 @@ export class WebBox extends React.Component<FieldViewProps> {
}
}
- switchToText() {
- if (this.props.removeDocument) this.props.removeDocument(this.props.Document);
- // let newPoint = PreviewCursor._getTransform().transformPoint(PreviewCursor._clickPoint[0], PreviewCursor._clickPoint[1]);
+
+ switchToText = () => {
+ let url: string = "";
+ let field = Cast(this.props.Document[this.props.fieldKey], WebField);
+ if (field) url = field.url.href;
+
let newBox = Docs.Create.TextDocument({
- width: 200, height: 100,
- // x: newPoint[0],
- // y: newPoint[1],
x: NumCast(this.props.Document.x),
y: NumCast(this.props.Document.y),
- title: "-pasted text-"
+ title: url,
+ width: 200,
+ height: 70,
+ documentText: "@@@" + url
});
- newBox.proto!.autoHeight = true;
- PreviewCursor._addLiveTextDoc(newBox);
- return;
+ SelectionManager.SelectedDocuments().map(dv => {
+ dv.props.addDocument && dv.props.addDocument(newBox, false);
+ dv.props.removeDocument && dv.props.removeDocument(dv.props.Document);
+ });
+
+ Doc.BrushDoc(newBox);
}
urlEditor() {
@@ -117,14 +124,15 @@ export class WebBox extends React.Component<FieldViewProps> {
<div style={{
display: "flex",
flexDirection: "row",
-
+ justifyContent: "space-between",
+ minWidth: "100px",
}}>
<button className="submitUrl" onClick={this.submitURL}>
- SUBMIT URL
- </button>
- <button className="switchToText" onClick={this.switchToText} style={{ paddingLeft: 10 }} >
- <FontAwesomeIcon icon={faStickyNote} size={"2x"} />
+ SUBMIT
</button>
+ <div className="switchToText" title="Convert web to text doc" onClick={this.switchToText} style={{ display: "flex", alignItems: "center", justifyContent: "center" }} >
+ <FontAwesomeIcon icon={faStickyNote} size={"lg"} />
+ </div>
</div>
</div>
</div>
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 6b72bc58f..c57c4e659 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -525,13 +525,23 @@ export namespace Doc {
return otherdoc;
}
export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetData?: Doc) {
+ if (!templateDoc) {
+ target.layout = undefined;
+ target.nativeWidth = undefined;
+ target.nativeHeight = undefined;
+ target.onClick = undefined;
+ target.type = undefined;
+ return;
+ }
let temp = Doc.MakeDelegate(templateDoc);
target.nativeWidth = Doc.GetProto(target).nativeWidth = undefined;
target.nativeHeight = Doc.GetProto(target).nativeHeight = undefined;
+ !templateDoc.nativeWidth && (target.nativeWidth = 0);
+ !templateDoc.nativeHeight && (target.nativeHeight = 0);
target.width = templateDoc.width;
target.height = templateDoc.height;
target.onClick = templateDoc.onClick instanceof ObjectField && templateDoc.onClick[Copy]();
- Doc.GetProto(target).type = DocumentType.TEMPLATE;
+ target.type = DocumentType.TEMPLATE;
if (targetData && targetData.layout === target) {
targetData.layout = temp;
targetData.miniLayout = StrCast(templateDoc.miniLayout);
@@ -541,8 +551,6 @@ export namespace Doc {
target.miniLayout = StrCast(templateDoc.miniLayout);
target.detailedLayout = target.layout;
}
- !templateDoc.nativeWidth && (target.nativeWidth = 0);
- !templateDoc.nativeHeight && (target.nativeHeight = 0);
}
export function MakeTemplate(fieldTemplate: Doc, metaKey: string, templateDataDoc: Doc) {
@@ -670,4 +678,5 @@ export namespace Doc {
}
Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`; });
Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
-Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); }); \ No newline at end of file
+Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); });
+Scripting.addGlobal(function aliasDocs(field: any) { return new List<Doc>(field.map((d: any) => Doc.MakeAlias(d))); }); \ No newline at end of file