aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2020-01-13 13:29:18 -0500
committerbob <bcz@cs.brown.edu>2020-01-13 13:29:18 -0500
commit9955ff8c2de58cfe37e02d6a356b5a8a2930bb05 (patch)
tree1d68af678d13d9b06238d76bf51900f8ff93d149 /src
parent4f63baaada3dd0f62c0164c53fb6e23408e319e1 (diff)
fixed some scripting and added some functions for adding docFilters to collections
Diffstat (limited to 'src')
-rw-r--r--src/client/views/ScriptBox.tsx13
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx5
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx6
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx19
-rw-r--r--src/client/views/collections/CollectionView.tsx6
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx7
-rw-r--r--src/client/views/nodes/DocumentView.tsx8
-rw-r--r--src/new_fields/Doc.ts45
8 files changed, 72 insertions, 37 deletions
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index ded2329b4..d24256886 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -82,28 +82,19 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
);
}
//let l = docList(this.source[0].data).length; if (l) { let ind = this.target[0].index !== undefined ? (this.target[0].index+1) % l : 0; this.target[0].index = ind; this.target[0].proto = getProto(docList(this.source[0].data)[ind]);}
- public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, prewrapper?: string, postwrapper?: string) {
+ public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, contextParams?: { [name: string]: string }) {
let overlayDisposer: () => void = emptyFunction;
const script = ScriptCast(doc[fieldKey]);
let originalText: string | undefined = undefined;
if (script) {
originalText = script.script.originalScript;
- if (prewrapper && originalText.startsWith(prewrapper)) {
- originalText = originalText.substr(prewrapper.length);
- }
- if (postwrapper && originalText.endsWith(postwrapper)) {
- originalText = originalText.substr(0, originalText.length - postwrapper.length);
- }
}
// tslint:disable-next-line: no-unnecessary-callback-wrapper
const params: string[] = [];
const setParams = (p: string[]) => params.splice(0, params.length, ...p);
const scriptingBox = <ScriptBox initialText={originalText} setParams={setParams} onCancel={overlayDisposer} onSave={(text, onError) => {
- if (prewrapper) {
- text = prewrapper + text + (postwrapper ? postwrapper : "");
- }
const script = CompileScript(text, {
- params: { this: Doc.name },
+ params: { this: Doc.name, ...contextParams },
typecheck: false,
editable: true,
transformer: DocumentIconContainer.getTransformer()
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 0114342b9..a965b2e9b 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
import React = require("react");
-import { action, observable } from "mobx";
+import { action, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import "./CollectionSchemaView.scss";
import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes } from '@fortawesome/free-solid-svg-icons';
@@ -286,7 +286,6 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
}
@undoBatch
- @action
onKeyDown = (e: React.KeyboardEvent): void => {
if (e.key === "Enter") {
const keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
@@ -296,7 +295,7 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
this.onSelect(this._searchTerm);
} else {
- this._searchTerm = this._key;
+ runInAction(() => this._searchTerm = this._key);
}
}
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c1e36272c..03c757a51 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -22,7 +22,6 @@ import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewField
import { CollectionSubView } from "./CollectionSubView";
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
-import { ScriptBox } from "../ScriptBox";
import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
import { TraceMobx } from "../../../new_fields/util";
import { CollectionViewType } from "./CollectionView";
@@ -374,11 +373,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
subItems.push({ description: `${this.props.Document.showTitles ? "Hide Titles" : "Show Titles"}`, event: () => this.props.Document.showTitles = !this.props.Document.showTitles ? "title" : "", icon: "plus" });
subItems.push({ description: `${this.props.Document.showCaptions ? "Hide Captions" : "Show Captions"}`, event: () => this.props.Document.showCaptions = !this.props.Document.showCaptions ? "caption" : "", icon: "plus" });
ContextMenu.Instance.addItem({ description: "Stacking Options ...", subitems: subItems, icon: "eye" });
-
- const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
- const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
- onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
- !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
}
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 79fc477ab..286fdf2bc 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -28,6 +28,7 @@ import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
+import { ScriptBox } from '../ScriptBox';
export interface TreeViewProps {
@@ -366,8 +367,13 @@ class TreeView extends React.Component<TreeViewProps> {
@action
bulletClick = (e: React.MouseEvent) => {
- if (this.props.document.onClick) {
- ScriptCast(this.props.document.onClick).script.run({ this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document }, console.log);
+ if (this.props.containingCollection.onChildClick) {
+ this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check";
+ ScriptCast(this.props.containingCollection.onChildClick).script.run({
+ this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document,
+ heading: this.props.containingCollection.title,
+ checked: this.props.document.treeViewChecked === "check" ? false : this.props.document.treeViewChecked === "x" ? "x" : "none"
+ }, console.log);
} else {
this.treeViewOpen = !this.treeViewOpen;
}
@@ -376,8 +382,9 @@ class TreeView extends React.Component<TreeViewProps> {
@computed
get renderBullet() {
- return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
- {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
+ const checked = this.props.containingCollection.onChildClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined;
+ return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "black"), opacity: 0.4 }}>
+ {<FontAwesomeIcon icon={checked === "check" ? "check" : (checked === "x" ? "times" : checked === "unchecked" ? "square" : !this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down"))} />}
</div>;
}
/**
@@ -617,6 +624,10 @@ export class CollectionTreeView extends CollectionSubView(Document) {
layoutItems.push({ description: (this.props.Document.hideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.props.Document.hideHeaderFields = !this.props.Document.hideHeaderFields, icon: "paint-brush" });
ContextMenu.Instance.addItem({ description: "Treeview Options ...", subitems: layoutItems, icon: "eye" });
}
+ const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+ const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+ onClicks.push({ description: "Edit onChecked Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Checked Changed ...", this.props.Document, "onChildClick", obj.x, obj.y, { heading: "boolean", checked: "boolean" }) });
+ !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
}
outerXf = () => Utils.GetScreenTransform(this._mainEle!);
onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 88023783b..55f0de779 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -34,6 +34,7 @@ import { FieldViewProps, FieldView } from '../nodes/FieldView';
import { Touchable } from '../Touchable';
import { TraceMobx } from '../../../new_fields/util';
import { Utils } from '../../../Utils';
+import { ScriptBox } from '../ScriptBox';
const path = require('path');
library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
@@ -233,6 +234,11 @@ export class CollectionView extends Touchable<FieldViewProps> {
const moreItems = more && "subitems" in more ? more.subitems : [];
moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
!more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
+
+ const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+ const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+ onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
+ !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
}
}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 184504e5a..996c7671e 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -217,9 +217,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
`(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
"true";
- const docFilter = StrCast(this.props.CollectionView.props.Document.docFilter);
- const finalScript = docFilter && !fullScript.startsWith("(())") ? `${fullScript} ${docFilter ? "&&" : ""} (${docFilter})` :
- docFilter ? docFilter : fullScript;
+ const docFilter = Cast(this.props.CollectionView.props.Document.docFilter, listSpec("string"), []);
+ const docFilterText = Doc.MakeDocFilter(docFilter);
+ const finalScript = docFilterText && !fullScript.startsWith("(())") ? `${fullScript} ${docFilterText ? "&&" : ""} (${docFilterText})` :
+ docFilterText ? docFilterText : fullScript;
this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(finalScript, { doc: Doc.name });
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ba35366ff..e45c19533 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -196,7 +196,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY);
} else if (this.props.Document.isButton === "Selector") { // this should be moved to an OnClick script
FormattedTextBoxComment.Hide();
- this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0], this.props.Document)]));
+ this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)]));
} else if (this.Document.isButton) {
SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered.
this.buttonClick(e.altKey, e.ctrlKey);
@@ -815,10 +815,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
}}>
<EditableView ref={this._titleRef}
- contents={this.Document[showTitle]}
+ contents={(this.props.DataDoc || this.props.Document)[showTitle]}
display={"block"} height={72} fontSize={12}
- GetValue={() => StrCast(this.Document[showTitle])}
- SetValue={undoBatch((value: string) => (Doc.GetProto(this.Document)[showTitle] = value) ? true : true)}
+ GetValue={() => StrCast((this.props.DataDoc || this.props.Document)[showTitle])}
+ SetValue={undoBatch((value: string) => (Doc.GetProto(this.props.DataDoc || this.props.Document)[showTitle] = value) ? true : true)}
/>
</div>);
return <>
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 8117453e7..32ab36c0f 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -742,8 +742,19 @@ export namespace Doc {
source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory :
source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined;
}
-}
+ export function MakeDocFilter(docFilters: string[]) {
+ let docFilterText = "";
+ for (let i = 0; i < docFilters.length; i += 3) {
+ const key = docFilters[i];
+ const value = docFilters[i + 1];
+ const modifiers = docFilters[i + 2];
+ const scriptText = `${modifiers === "x" ? "!" : ""}matchFieldValue(doc, "${key}", "${value}")`;
+ docFilterText = docFilterText ? docFilterText + " && " + scriptText : scriptText;
+ };
+ return docFilterText ? "(" + docFilterText + ")" : "";
+ }
+}
Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
@@ -761,9 +772,31 @@ Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: bo
const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)));
return docs.length ? new List(docs) : prevValue;
});
-Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, type: string, contains: boolean = true) {
- const scriptText = `${contains ? "" : "!"}(((doc.${key} && (doc.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))) ||
- ((doc.data_ext && doc.data_ext.${key}) && (doc.data_ext.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))))`;
- container.docFilter = scriptText;
- container.viewSpecScript = ScriptField.MakeFunction(scriptText, { doc: Doc.name });
+Scripting.addGlobal(function matchFieldValue(doc: Doc, key: string, value: any) {
+ const fieldVal = doc[key] ? doc[key] : doc[key + "_ext"];
+ if (StrCast(fieldVal, null) !== undefined) return StrCast(fieldVal) === value;
+ if (NumCast(fieldVal, null) !== undefined) return NumCast(fieldVal) === value;
+ if (Cast(fieldVal, listSpec("string"), []).length) {
+ let vals = Cast(fieldVal, listSpec("string"), []);
+ return vals.some(v => v === value);
+ }
+ return false;
+});
+Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers: string) {
+ const docFilters = Cast(container.docFilter, listSpec("string"), []);
+ let found = false;
+ for (let i = 0; i < docFilters.length && !found; i += 3) {
+ if (docFilters[i] === key && docFilters[i + 1] === value) {
+ found = true;
+ docFilters.splice(i, 3);
+ }
+ }
+ if (!found || modifiers !== "none") {
+ docFilters.push(key);
+ docFilters.push(value);
+ docFilters.push(modifiers);
+ container.docFilter = new List<string>(docFilters);
+ }
+ const docFilterText = Doc.MakeDocFilter(docFilters);
+ container.viewSpecScript = docFilterText ? ScriptField.MakeFunction(docFilterText, { doc: Doc.name }) : undefined;
}); \ No newline at end of file