aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts30
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx71
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx11
-rw-r--r--src/client/views/nodes/ButtonBox.scss19
-rw-r--r--src/client/views/nodes/ButtonBox.tsx42
-rw-r--r--src/new_fields/Doc.ts14
6 files changed, 111 insertions, 76 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 24c093213..748fb9d13 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,27 @@ export namespace DragManager {
});
}
+ export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], 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)));
+ 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 +508,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/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 352bcd4a6..15bef39b3 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -286,20 +286,22 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
+
+ commands = [{
+ // 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)
+ },
+ {
+ 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
+ }];
@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.commands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
+ e.stopPropagation();
}
return true;
}
@@ -317,9 +319,7 @@ 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) => {
@@ -340,38 +340,19 @@ 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.commands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
}
autoSuggestDown = (e: React.PointerEvent) => {
e.stopPropagation();
}
+
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
- });
- e.preventDefault();
+ this.commands.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, e.clientX, e.clientY));
e.stopPropagation();
+ e.preventDefault();
}
render() {
@@ -419,7 +400,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 +423,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>
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/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/new_fields/Doc.ts b/src/new_fields/Doc.ts
index f6114d476..4833ad259 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -525,9 +525,18 @@ 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;
+ 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]();
@@ -541,8 +550,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) {
@@ -627,4 +634,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