From a6d17ef79fb94334735998d3d11f7ea068dea93a Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Apr 2020 03:15:25 -0400 Subject: cleaned up some more of the pivot view event handling api --- .../views/collections/CollectionTimeView.tsx | 23 ++++++++++------------ src/client/views/collections/CollectionView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 7 +++++-- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 1760e2419..e05223ca0 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -1,6 +1,6 @@ import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../../new_fields/Doc"; +import { Doc, Opt, DocCastAsync } from "../../../new_fields/Doc"; import { List } from "../../../new_fields/List"; import { ObjectField } from "../../../new_fields/ObjectField"; import { RichTextField } from "../../../new_fields/RichTextField"; @@ -26,18 +26,15 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { _changing = false; @observable _layoutEngine = "pivot"; @observable _collapsed: boolean = false; - componentWillUnmount() { - this.props.Document.onChildClick = undefined; - } + @observable _childClickedScript: Opt; + @observable _viewDefDivClick: Opt; async componentDidMount() { - const childText = "const alias = getAlias(this); switchView(alias, thisContainer.childDetailView); alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; - this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "string", thisContainer: Doc.name, shiftKey: "boolean" }); - this.props.Document._fitToBox = true; - if (!this.props.Document.onViewDefClick) { - this.props.Document.onViewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" }); - } - this.props.Document.childDetailView = Cast(this.props.Document.childDetailView, Doc, null) ||// bcz: needs to be here to make sure the childDetailView layout template has been loaded when the first item is clicked; - DocumentView.findTemplate("detailView", StrCast(this.props.Document.type), ""); + const detailView = (await DocCastAsync(this.props.Document.childDetailView)) || DocumentView.findTemplate("detailView", StrCast(this.props.Document.type), ""); + const childText = "const alias = getAlias(this); switchView(alias, detailView); alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; + runInAction(() => { + this._childClickedScript = ScriptField.MakeScript(childText, { this: Doc.name, shiftKey: "boolean" }, { detailView: detailView! }); + this._viewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" }); + }); } layoutEngine = () => this._layoutEngine; @@ -88,7 +85,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { @computed get contents() { return
- +
; } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 0a3577bc7..19e235ff2 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -278,7 +278,7 @@ export class CollectionView extends Touchable { onMovePrevRequest={action(() => this._curLightboxImg = (this._curLightboxImg + images.length - 1) % images.length)} onMoveNextRequest={action(() => this._curLightboxImg = (this._curLightboxImg + 1) % images.length)} />); } - get _facetWidth() { return NumCast(this.props.Document._facetWidth) } + get _facetWidth() { return NumCast(this.props.Document._facetWidth); } set _facetWidth(value) { this.props.Document._facetWidth = value; } bodyPanelWidth = () => this.props.PanelWidth() - this.facetWidth(); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d98fe190c..f19181a20 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -44,6 +44,7 @@ import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { CollectionViewType } from "../CollectionView"; +import { Script } from "vm"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -69,6 +70,8 @@ type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof documentSchem const PanZoomDocument = makeInterface(panZoomSchema, documentSchema, positionSchema, pageSchema); export type collectionFreeformViewProps = { forceScaling?: boolean; // whether to force scaling of content (needed by ImageBox) + childClickScript?: ScriptField; + viewDefDivClick?: ScriptField; }; @observer @@ -847,7 +850,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u } @computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; } - @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } + @computed get onChildClickHandler() { return this.props.childClickScript || ScriptCast(this.Document.onChildClick); } backgroundHalo = () => BoolCast(this.Document.useClusters); getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { @@ -906,7 +909,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u } onViewDefDivClick = (e: React.MouseEvent, payload: any) => { - (this.props.Document.onViewDefDivClick as ScriptField)?.script.run({ this: this.props.Document, payload }); + (this.props.viewDefDivClick || ScriptCast(this.props.Document.onViewDefDivClick))?.script.run({ this: this.props.Document, payload }); e.stopPropagation(); } private viewDefToJSX(viewDef: ViewDefBounds): Opt { -- cgit v1.2.3-70-g09d2 From a3e2d21f848bae54b0de8d3a81a996f2f551c84f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Apr 2020 11:50:36 -0400 Subject: fixed onCheckedClick to use scriptingBox --- src/client/documents/Documents.ts | 2 ++ .../views/collections/CollectionTreeView.tsx | 27 +++++++++++----------- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/ScriptingBox.tsx | 4 ++-- .../authentication/models/current_user_utils.ts | 6 +++-- 5 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 129ab0403..608bd28ae 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -116,6 +116,8 @@ export interface DocumentOptions { boxShadow?: string; dontRegisterChildren?: boolean; "onClick-rawScript"?: string; // onClick script in raw text form + "onCheckedClick-rawScript"?: string; // onChecked script in raw text form + "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views schemaColumns?: List; dockingConfig?: string; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 9ec8c4c5b..d2c8cc3ad 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -19,7 +19,7 @@ import { makeTemplate } from '../../util/DropConverter'; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; -import { undoBatch } from '../../util/UndoManager'; +import { undoBatch, UndoManager } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from "../EditableView"; @@ -397,11 +397,13 @@ class TreeView extends React.Component { } } + get onCheckedClick() { return this.props.onCheckedClick || ScriptCast(this.props.document.onCheckedClick); } + @action bulletClick = (e: React.MouseEvent) => { - if (this.props.onCheckedClick && this.props.document.type !== DocumentType.COL) { + if (this.onCheckedClick && this.props.document.type !== DocumentType.COL) { // this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check"; - ScriptCast(this.props.onCheckedClick).script.run({ + this.onCheckedClick.script.run({ this: this.props.document.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.props.document, heading: this.props.containingCollection.title, checked: this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check", @@ -415,7 +417,7 @@ class TreeView extends React.Component { @computed get renderBullet() { - const checked = this.props.document.type === DocumentType.COL ? undefined : this.props.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined; + const checked = this.props.document.type === DocumentType.COL ? undefined : this.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined; return
{}
; @@ -764,8 +766,7 @@ export class CollectionTreeView extends CollectionSubView(Document, undefined as 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, - "onCheckedClick", obj.x, obj.y, { heading: "boolean", checked: "boolean", treeViewContainer: Doc.name }) + description: "Edit onChecked Script", event: () => UndoManager.RunInBatch(() => DocumentView.makeCustomViewClicked(this.props.Document, undefined, "onCheckedClick"), "edit onCheckedClick"), icon: "edit" }); !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); } @@ -818,7 +819,7 @@ export class CollectionTreeView extends CollectionSubView(Document, undefined as TreeView.GetChildElements(childDocs, this.props.Document, this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.props.Document.treeViewHideHeaderFields), - BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, this.props.onCheckedClick || ScriptCast(this.props.Document.onCheckedClick), + BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, this.props.onCheckedClick, this.props.onChildClick || ScriptCast(this.props.Document.onChildClick), this.props.ignoreFields) } @@ -839,12 +840,12 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, dataDoc: Doc, dataKey nonNumbers++; } }); - const facetValueDocSet = (nonNumbers / facetValues.length > .1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2))).map(facetValue => - { const doc = new Doc(); - doc.title = facetValue.toString(); - doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)",{},{ layoutDoc, facetHeader, facetValue }); - return doc; - }); + const facetValueDocSet = (nonNumbers / facetValues.length > .1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2))).map(facetValue => { + const doc = new Doc(); + doc.title = facetValue.toString(); + doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); + return doc; + }); return new List(facetValueDocSet); }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index cb7811fbb..54e4d549e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -746,7 +746,7 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: this.toggleFollowInPlace, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); - onClicks.push({ description: "Edit onClick Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", obj.x, obj.y) }); + onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocumentView.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index a257898ab..c607d6614 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -28,8 +28,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent { target && docCast(this.source).then((source) => { target.proto.data = new List([source || this]); } ); } )", { target: Doc.name }), { title: "On Child Clicked (open in target)", _width: 300, _height: 200 }); - const onClick = Docs.Create.ScriptingDocument(ScriptField.MakeScript("console.log('click')"), { title: "onClick", isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200 }, "onClick"); + const onClick = Docs.Create.ScriptingDocument(undefined, { title: "onClick", "onClick-rawScript": "console.log('click')", isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200 }, "onClick"); + const onCheckedClick = Docs.Create.ScriptingDocument(undefined, + { title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)", "onCheckedClick-params": new List(["heading", "checked", "containingTreeView"]), isTemplateDoc: true, isTemplateForField: "onCheckedClick", _width: 300, _height: 200 }, "onCheckedClick"); doc.childClickFuncs = Docs.Create.TreeDocument([openInTarget], { title: "on Child Click function templates" }); - doc.clickFuncs = Docs.Create.TreeDocument([onClick], { title: "onClick funcs" }); + doc.clickFuncs = Docs.Create.TreeDocument([onClick, onCheckedClick], { title: "onClick funcs" }); } static updateUserDocument(doc: Doc) { -- cgit v1.2.3-70-g09d2 From 86885c0e97322ae99f331e594a5c67cf04cb4ec2 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Apr 2020 12:33:21 -0400 Subject: extended getLocation to work with the map itself in addition to makers so that document titles can be used to indicate locations. --- src/client/views/collections/CollectionMapView.tsx | 35 +++++++++++----------- 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index 4fbccac33..583594057 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -1,18 +1,17 @@ import { GoogleApiWrapper, Map as GeoMap, MapProps, Marker } from "google-maps-react"; +import { computed, Lambda, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, Opt, DocListCast, FieldResult } from "../../../new_fields/Doc"; +import { Doc, DocListCast, FieldResult, Opt } from "../../../new_fields/Doc"; import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from "../../../new_fields/FieldSymbols"; import { makeInterface } from "../../../new_fields/Schema"; import { Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types"; +import { DocumentManager } from "../../util/DocumentManager"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; import "./CollectionMapView.scss"; import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); -import { DocumentManager } from "../../util/DocumentManager"; -import { UndoManager, undoBatch } from "../../util/UndoManager"; -import { IReactionDisposer, reaction, computed, runInAction, Lambda } from "mobx"; import requestPromise = require("request-promise"); -import { emptyFunction } from "../../../Utils"; type MapSchema = makeInterface<[typeof documentSchema]>; const MapSchema = makeInterface(documentSchema); @@ -58,15 +57,15 @@ class CollectionMapView extends CollectionSubView & const lat: Opt = Cast(doc[fieldKey + "-lat"], "number", null) || (Cast(doc[fieldKey + "-lat"], "string", null) && Number(Cast(doc[fieldKey + "-lat"], "string", null))) || undefined; const lng: Opt = Cast(doc[fieldKey + "-lng"], "number", null) || (Cast(doc[fieldKey + "-lng"], "string", null) && Number(Cast(doc[fieldKey + "-lng"], "string", null))) || undefined; const zoom: Opt = Cast(doc[fieldKey + "-zoom"], "number", null) || (Cast(doc[fieldKey + "-zoom"], "string", null) && Number(Cast(doc[fieldKey + "-zoom"], "string", null))) || undefined; - const address: Opt = Cast(doc[fieldKey + "-address"], "string", null); + const address: Opt = Cast(doc[fieldKey + "-address"], "string", (lat === undefined || lng === undefined ? Cast(doc.title, "string", null) : null)); if (lat !== undefined && lng !== undefined) { return ({ lat, lng, zoom }); } else if (address) { const id = doc[Id]; if (!this._initialLookupPending.get(id)) { - this._initialLookupPending.set(id, true); + this._initialLookupPending.set(id, true); `` setTimeout(() => { - this.respondToAddressChange(address, doc).then(() => this._initialLookupPending.delete(id)); + this.respondToAddressChange(address, fieldKey, doc).then(() => this._initialLookupPending.delete(id)); }); } return defaultLocation; @@ -119,7 +118,7 @@ class CollectionMapView extends CollectionSubView & />; } - private respondToAddressChange = async (newAddress: string, doc: Doc) => { + private respondToAddressChange = async (newAddress: string, fieldKey: string, doc: Doc) => { const response = await query(newAddress); if (!response || response.status === "ZERO_RESULTS") { return false; @@ -127,28 +126,28 @@ class CollectionMapView extends CollectionSubView & const { geometry, formatted_address } = response.results[0]; const { lat, lng } = geometry.location; runInAction(() => { - if (doc["mapLocation-lat"] !== lat || doc["mapLocation-lng"] !== lng) { + if (doc[fieldKey + "-lat"] !== lat || doc[fieldKey + "-lng"] !== lng) { this._cancelLocReq.set(doc[Id], true); - Doc.SetInPlace(doc, "mapLocation-lat", lat, true); - Doc.SetInPlace(doc, "mapLocation-lng", lng, true); + Doc.SetInPlace(doc, fieldKey + "-lat", lat, true); + Doc.SetInPlace(doc, fieldKey + "-lng", lng, true); } if (formatted_address !== newAddress) { this._cancelAddrReq.set(doc[Id], true); - Doc.SetInPlace(doc, "mapLocation-address", formatted_address, true); + Doc.SetInPlace(doc, fieldKey + "-address", formatted_address, true); } }); return true; } - private respondToLocationChange = async (newLat: FieldResult, newLng: FieldResult, doc: Doc) => { + private respondToLocationChange = async (newLat: FieldResult, newLng: FieldResult, fieldKey: string, doc: Doc) => { const response = await query({ lat: NumCast(newLat), lng: NumCast(newLng) }); if (!response || response.status === "ZERO_RESULTS") { return false; } const { formatted_address } = response.results[0]; - if (formatted_address !== doc["mapLocation-address"]) { + if (formatted_address !== doc[fieldKey + "-address"]) { this._cancelAddrReq.set(doc[Id], true); - Doc.SetInPlace(doc, "mapLocation-address", formatted_address, true); + Doc.SetInPlace(doc, fieldKey + "-address", formatted_address, true); } return true; } @@ -167,7 +166,7 @@ class CollectionMapView extends CollectionSubView & if (this._cancelLocReq.get(id)) { this._cancelLocReq.set(id, false); } else if (lat !== undefined && lng !== undefined) { - this.respondToLocationChange(lat, lng, layout).then(success => { + this.respondToLocationChange(lat, lng, "mapLocation", layout).then(success => { if (!success) { this._cancelLocReq.set(id, true); runInAction(() => { @@ -185,7 +184,7 @@ class CollectionMapView extends CollectionSubView & if (this._cancelAddrReq.get(id)) { this._cancelAddrReq.set(id, false); } else if (newValue?.length) { - this.respondToAddressChange(newValue, layout).then(success => { + this.respondToAddressChange(newValue, "mapLocation", layout).then(success => { if (!success) { this._cancelAddrReq.set(id, true); layout["mapLocation-address"] = oldValue; -- cgit v1.2.3-70-g09d2