From 186cf33322b6c96386c6e9fdb823025d09c5caeb Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 21 Aug 2019 11:35:18 -0400 Subject: extended treeview functionality - better indenting, state management, drag dropping. --- src/client/views/EditableView.tsx | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'src/client/views/EditableView.tsx') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index c3612fee9..dd5395802 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -3,6 +3,7 @@ import { observer } from 'mobx-react'; import { observable, action, trace } from 'mobx'; import "./EditableView.scss"; import * as Autosuggest from 'react-autosuggest'; +import { undoBatch } from '../util/UndoManager'; export interface EditableProps { /** @@ -70,14 +71,12 @@ export class EditableView extends React.Component { onKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Tab") { e.stopPropagation(); + this.finalizeEdit(e.currentTarget.value, e.shiftKey); this.props.OnTab && this.props.OnTab(); } else if (e.key === "Enter") { e.stopPropagation(); if (!e.ctrlKey) { - if (this.props.SetValue(e.currentTarget.value, e.shiftKey)) { - this._editing = false; - this.props.isEditingCallback && this.props.isEditingCallback(false); - } + this.finalizeEdit(e.currentTarget.value, e.shiftKey); } else if (this.props.OnFillDown) { this.props.OnFillDown(e.currentTarget.value); this._editing = false; @@ -100,6 +99,14 @@ export class EditableView extends React.Component { e.stopPropagation(); } + @action + private finalizeEdit(value: string, shiftDown: boolean) { + if (this.props.SetValue(value, shiftDown)) { + this._editing = false; + this.props.isEditingCallback && this.props.isEditingCallback(false); + } + } + stopPropagation(e: React.SyntheticEvent) { e.stopPropagation(); } @@ -118,7 +125,7 @@ export class EditableView extends React.Component { className: "editableView-input", onKeyDown: this.onKeyDown, autoFocus: true, - onBlur: action(() => this._editing = false), + onBlur: e => this.finalizeEdit(e.currentTarget.value, false), onPointerDown: this.stopPropagation, onClick: this.stopPropagation, onPointerUp: this.stopPropagation, @@ -126,9 +133,14 @@ export class EditableView extends React.Component { onChange: this.props.autosuggestProps.onChange }} /> - : { this._editing = false; this.props.isEditingCallback && this.props.isEditingCallback(false); })} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} - style={{ display: this.props.display, fontSize: this.props.fontSize }} />; + : this.finalizeEdit(e.currentTarget.value, false)} + onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} + style={{ display: this.props.display, fontSize: this.props.fontSize }} + />; } else { if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue(); return ( -- cgit v1.2.3-70-g09d2 From f4df8cedd38dbf09e282315604ecaa6cde8185e5 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 11 Sep 2019 00:56:26 -0400 Subject: added start of parameterized button maker --- src/client/views/ContextMenuItem.tsx | 4 ++-- src/client/views/EditableView.tsx | 2 +- src/client/views/ScriptBox.tsx | 41 +++++++++++++++++++++++++++++++++ src/client/views/nodes/ButtonBox.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 1 + 5 files changed, 47 insertions(+), 5 deletions(-) (limited to 'src/client/views/EditableView.tsx') diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 0366a6a30..ac055be5b 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -10,7 +10,7 @@ library.add(faAngleRight); export interface OriginalMenuProps { description: string; - event: () => void; + event: (stuff?: any) => void; undoable?: boolean; icon: IconProp; //maybe should be optional (icon?) closeMenu?: () => void; @@ -44,7 +44,7 @@ export class ContextMenuItem extends React.Component { if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue(); return (
{this.props.contents}
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 7afba5e01..375a5cc93 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -10,6 +10,8 @@ import { emptyFunction } from "../../Utils"; import { ScriptCast } from "../../new_fields/Types"; import { CompileScript } from "../util/Scripting"; import { ScriptField } from "../../new_fields/ScriptField"; +import { DragManager } from "../util/DragManager"; +import { EditableView } from "./EditableView"; export interface ScriptBoxProps { onSave: (text: string, onError: (error: string) => void) => void; @@ -66,6 +68,45 @@ export class ScriptBox extends React.Component { ); } + //let l = docList(this.source.data).length; if (l) { let ind = this.target.index !== undefined ? (this.target.index+1) % l : 0; this.target.index = ind; this.target.proto = getProto(docList(this.source.data)[ind]);} + public static EditButtonScript(doc: Doc, fieldKey: string, content: any, clientX: number, clientY: number) { + let overlayDisposer: () => void = emptyFunction; + const script = ScriptCast(doc[fieldKey]); + let originalText = script && script.script.originalScript; + // tslint:disable-next-line: no-unnecessary-callback-wrapper + let scriptingBox = overlayDisposer()} onSave={(text, onError) => { + const script = CompileScript(text, { + params: { this: Doc.name }, + typecheck: false, + editable: true, + transformer: DocumentIconContainer.getTransformer() + }); + if (!script.compiled) { + onError(script.errors.map(error => error.messageText).join("\n")); + return; + } + + DragManager.StartButtonDrag([], text, "a script", + {}, this._params, (button: Doc) => { }, clientX, clientY); + + doc[fieldKey] = new ScriptField(script); + overlayDisposer(); + }} showDocumentIcons />; + let params = ""} + SetValue={(value: string) => (this._params = value.split(" ").filter(s => s !== " ")) ? true : true} + />; + let box =
+ {scriptingBox} + {params} +
+ overlayDisposer = OverlayView.Instance.addWindow(box, { x: 400, y: 200, width: 500, height: 400, title: `${doc.title || ""} OnClick` }); + } + static _params: string[] = []; public static EditClickScript(doc: Doc, fieldKey: string, prewrapper?: string, postwrapper?: string) { let overlayDisposer: () => void = emptyFunction; const script = ScriptCast(doc[fieldKey]); diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx index 54848344b..db4bb7972 100644 --- a/src/client/views/nodes/ButtonBox.tsx +++ b/src/client/views/nodes/ButtonBox.tsx @@ -44,8 +44,8 @@ export class ButtonBox extends DocComponent(Butt @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { - if (de.data instanceof DragManager.DocumentDragData) { - Doc.GetProto(this.dataDoc).source = new List(de.data.droppedDocuments); + if (de.data instanceof DragManager.DocumentDragData && e.target) { + Doc.GetProto(this.dataDoc)[(e.target as any).textContent] = new List(de.data.droppedDocuments); e.stopPropagation(); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 73426b3dc..84169cc93 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -601,6 +601,7 @@ export class DocumentView extends DocComponent(Docu let makes: ContextMenuProps[] = existingMake && "subitems" in existingMake ? existingMake.subitems : []; makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Into Background", event: this.makeBackground, icon: this.props.Document.lockedPosition ? "unlock" : "lock" }); makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Into Button", event: this.makeBtnClicked, icon: "concierge-bell" }); + makes.push({ description: "OnClick Button script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript(this.props.Document, "onClick", this._mainCont, obj.x, obj.y) }); makes.push({ description: "OnClick script", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick") }); makes.push({ description: "OnClick foreach doc", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick", "docList(this.collectionContext.data).map(d => {", "});\n") }); makes.push({ -- cgit v1.2.3-70-g09d2 From d7d73856ed405cef01b4cf727ca56f4d9a31e894 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 11 Sep 2019 15:45:37 -0400 Subject: cleaned up ScriptBox EditScript's restructured menus for dealing with onClicks... exposed more layout paramters for EditableViews. --- src/client/views/ContextMenuItem.tsx | 4 +- src/client/views/EditableView.tsx | 5 +- src/client/views/ScriptBox.tsx | 67 +++++++--------------- .../views/collections/CollectionSchemaCells.tsx | 3 +- .../views/collections/CollectionStackingView.tsx | 6 +- .../views/collections/CollectionTreeView.tsx | 5 +- src/client/views/nodes/ButtonBox.tsx | 19 +++++- src/client/views/nodes/DocumentView.tsx | 42 ++++++++------ src/client/views/nodes/KeyValuePair.tsx | 3 +- 9 files changed, 82 insertions(+), 72 deletions(-) (limited to 'src/client/views/EditableView.tsx') diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index ac055be5b..5f673b3f3 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -93,13 +93,13 @@ export class ContextMenuItem extends React.Component )} ; return ( -
+
{this.props.icon ? ( ) : null} -
+
{this.props.description}
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 1bdb26b3d..e9db4b048 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -28,7 +28,8 @@ export interface EditableProps { contents: any; fontStyle?: string; fontSize?: number; - height?: number; + height?: number | "auto"; + maxHeight?: number; display?: string; autosuggestProps?: { resetValue: () => void; @@ -145,7 +146,7 @@ export class EditableView extends React.Component { if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue(); return (
{this.props.contents}
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 1f3673390..8f08224c8 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -18,6 +18,7 @@ export interface ScriptBoxProps { onCancel?: () => void; initialText?: string; showDocumentIcons?: boolean; + setParams?: (p: string[]) => void; } @observer @@ -58,56 +59,30 @@ export class ScriptBox extends React.Component { onFocus = this.onFocus; onBlur = this.onBlur; } + let params = ""} + SetValue={(value: string) => this.props.setParams && this.props.setParams(value.split(" ").filter(s => s !== " ")) ? true : true} + />; return (
+
+ +
{params}
+
-
); } //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(doc: Doc, fieldKey: string, content: any, clientX: number, clientY: number) { - let overlayDisposer: () => void = emptyFunction; - const script = ScriptCast(doc[fieldKey]); - let originalText = script && script.script.originalScript; - // tslint:disable-next-line: no-unnecessary-callback-wrapper - let scriptingBox = overlayDisposer()} onSave={(text, onError) => { - const script = CompileScript(text, { - params: { this: Doc.name }, - typecheck: false, - editable: true, - transformer: DocumentIconContainer.getTransformer() - }); - if (!script.compiled) { - onError(script.errors.map(error => error.messageText).join("\n")); - return; - } - - DragManager.StartButtonDrag([], text, "a script", - {}, this._params, (button: Doc) => { }, clientX, clientY); - - doc[fieldKey] = new ScriptField(script); - overlayDisposer(); - }} showDocumentIcons />; - let params = ""} - SetValue={(value: string) => (this._params = value.split(" ").filter(s => s !== " ")) ? true : true} - />; - let box =
- {scriptingBox} - {params} -
- overlayDisposer = OverlayView.Instance.addWindow(box, { x: 400, y: 200, width: 500, height: 400, title: `${doc.title || ""} OnClick` }); - } - static _params: string[] = []; - public static EditClickScript(doc: Doc, fieldKey: string, prewrapper?: string, postwrapper?: string) { + public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, prewrapper?: string, postwrapper?: string) { let overlayDisposer: () => void = emptyFunction; const script = ScriptCast(doc[fieldKey]); let originalText: string | undefined = undefined; @@ -121,10 +96,9 @@ export class ScriptBox extends React.Component { } } // tslint:disable-next-line: no-unnecessary-callback-wrapper - let scriptingBox = overlayDisposer()} onSave={(text, onError) => { - if (prewrapper) { - text = prewrapper + text + (postwrapper ? postwrapper : ""); - } + let params: string[] = []; + let setParams = (p: string[]) => params.splice(0, params.length, ...p); + let scriptingBox = overlayDisposer()} onSave={(text, onError) => { const script = CompileScript(text, { params: { this: Doc.name }, typecheck: false, @@ -135,9 +109,12 @@ export class ScriptBox extends React.Component { onError(script.errors.map(error => error.messageText).join("\n")); return; } + + params.length && DragManager.StartButtonDrag([], text, "a script", {}, params, (button: Doc) => { }, clientX, clientY); + doc[fieldKey] = new ScriptField(script); overlayDisposer(); }} showDocumentIcons />; - overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, { x: 400, y: 200, width: 500, height: 400, title: `${doc.title || ""} OnClick` }); + overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, { x: 400, y: 200, width: 500, height: 400, title: title }); } } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 9c26a08f0..c59107b53 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -214,7 +214,8 @@ export class CollectionSchemaCell extends React.Component { isEditingCallback={this.isEditingCallback} display={"inline"} contents={contents} - height={Number(MAX_ROW_HEIGHT)} + height={"auto"} + maxHeight={Number(MAX_ROW_HEIGHT)} GetValue={() => { let field = props.Document[props.fieldKey]; if (Field.IsField(field)) { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 654ff2279..91e10b0ac 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -362,8 +362,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { subItems.push({ description: `${this.props.Document.fillColumn ? "Variable Size" : "Autosize"} Column`, event: () => this.props.Document.fillColumn = !this.props.Document.fillColumn, icon: "plus" }); 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" }); - subItems.push({ description: "Edit onChildClick script", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onChildClick") }); ContextMenu.Instance.addItem({ description: "Stacking Options ...", subitems: subItems, icon: "eye" }); + + let existingOnClick = ContextMenu.Instance.findByDescription("OnClick..."); + let 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 e31fa0b40..8539b3fcc 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -592,13 +592,14 @@ export class CollectionTreeView extends CollectionSubView(Document) {
(e.target as any).scrollHeight > (e.target as any).clientHeight && e.stopPropagation()} + onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> StrCast(this.resolvedDataDoc.title)} SetValue={undoBatch((value: string) => (Doc.GetProto(this.resolvedDataDoc).title = value) ? true : true)} OnFillDown={undoBatch((value: string) => { diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx index db4bb7972..68d3b8ae1 100644 --- a/src/client/views/nodes/ButtonBox.tsx +++ b/src/client/views/nodes/ButtonBox.tsx @@ -13,6 +13,8 @@ import { undoBatch } from '../../util/UndoManager'; import { DocComponent } from '../DocComponent'; import './ButtonBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; +import { ContextMenuProps } from '../ContextMenuItem'; +import { ContextMenu } from '../ContextMenu'; library.add(faEdit as any); @@ -41,11 +43,24 @@ export class ButtonBox extends DocComponent(Butt this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }); } } + + specificContextMenu = (e: React.MouseEvent): void => { + let funcs: ContextMenuProps[] = []; + funcs.push({ + description: "Clear Script Params", event: () => { + let params = Cast(this.props.Document.buttonParams, listSpec("string")); + params && params.map(p => this.props.Document[p] = undefined) + }, icon: "trash" + }); + + ContextMenu.Instance.addItem({ description: "OnClick...", subitems: funcs, icon: "asterisk" }); + } + @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { if (de.data instanceof DragManager.DocumentDragData && e.target) { - Doc.GetProto(this.dataDoc)[(e.target as any).textContent] = new List(de.data.droppedDocuments); + this.props.Document[(e.target as any).textContent] = new List(de.data.droppedDocuments); e.stopPropagation(); } } @@ -55,7 +70,7 @@ export class ButtonBox extends DocComponent(Butt 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 ( -
+
{(this.Document.text || this.Document.title)} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ca8fb573f..9c2cf5f01 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -446,10 +446,10 @@ export class DocumentView extends DocComponent(Docu @undoBatch makeCustomViewClicked = (): void => { - let options = { title: "data", width: NumCast(this.props.Document.width), height: NumCast(this.props.Document.height) }; + let options = { title: "data", width: NumCast(this.props.Document.width), height: NumCast(this.props.Document.height) + 25, x: -NumCast(this.props.Document.width) / 2, y: -NumCast(this.props.Document.height) / 2, }; let fieldTemplate = this.props.Document.type === DocumentType.TEXT ? Docs.Create.TextDocument(options) : Docs.Create.ImageDocument("http://www.cs.brown.edu", options); - let docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: StrCast(this.Document.title) + "layout", width: NumCast(this.props.Document.width) + 20, height: NumCast(this.props.Document.height) + 20 }); + let docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: StrCast(this.Document.title) + "layout", width: NumCast(this.props.Document.width) + 20, height: Math.max(100, NumCast(this.props.Document.height) + 45) }); let metaKey = "data"; let proto = Doc.GetProto(docTemplate); Doc.MakeTemplate(fieldTemplate, metaKey, proto, true); @@ -460,15 +460,21 @@ export class DocumentView extends DocComponent(Docu @undoBatch makeBtnClicked = (): void => { let doc = Doc.GetProto(this.props.Document); - doc.isButton = !BoolCast(doc.isButton); - if (doc.isButton) { - if (!doc.nativeWidth) { - doc.nativeWidth = this.props.Document[WidthSym](); - doc.nativeHeight = this.props.Document[HeightSym](); - } + if (doc.isButton || doc.onClick) { + doc.isButton = false; + doc.onClick = undefined; } else { - doc.nativeWidth = doc.nativeHeight = undefined; + doc.isButton = true; } + + // if (doc.isButton) { + // if (!doc.nativeWidth) { + // doc.nativeWidth = this.props.Document[WidthSym](); + // doc.nativeHeight = this.props.Document[HeightSym](); + // } + // } else { + // doc.nativeWidth = doc.nativeHeight = undefined; + // } } @undoBatch @@ -623,21 +629,25 @@ export class DocumentView extends DocComponent(Docu subitems.push({ description: "Open Right Alias", event: () => this.props.addDocTab && this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.dataDoc, "onRight"), icon: "caret-square-right" }); subitems.push({ description: "Open Fields", event: this.fieldsClicked, icon: "layer-group" }); cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" }); + let existingMake = ContextMenu.Instance.findByDescription("Make..."); let makes: ContextMenuProps[] = existingMake && "subitems" in existingMake ? existingMake.subitems : []; makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Into Background", event: this.makeBackground, icon: this.props.Document.lockedPosition ? "unlock" : "lock" }); - makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Into Button", event: this.makeBtnClicked, icon: "concierge-bell" }); - makes.push({ description: "Custom View", event: this.makeCustomViewClicked, icon: "concierge-bell" }); - makes.push({ description: "Custom Field", event: () => this.props.ContainingCollectionView && Doc.MakeTemplate(this.props.Document, StrCast(this.props.Document.title), this.props.ContainingCollectionView.props.Document, true), icon: "concierge-bell" }) - makes.push({ description: "OnClick Button script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript(this.props.Document, "onClick", this._mainCont, obj.x, obj.y) }); - makes.push({ description: "OnClick script", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick") }); - makes.push({ description: "OnClick foreach doc", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick", "docList(this.collectionContext.data).map(d => {", "});\n") }); + makes.push({ description: "Custom Document View", event: this.makeCustomViewClicked, icon: "concierge-bell" }); + makes.push({ description: "Metadata Field View", event: () => this.props.ContainingCollectionView && Doc.MakeTemplate(this.props.Document, StrCast(this.props.Document.title), this.props.ContainingCollectionView.props.Document, true), icon: "concierge-bell" }) makes.push({ description: "Into Portal", event: this.makeIntoPortal, icon: "window-restore" }); makes.push({ description: this.layoutDoc.ignoreClick ? "Selectable" : "Unselectable", event: () => this.layoutDoc.ignoreClick = !this.layoutDoc.ignoreClick, icon: this.layoutDoc.ignoreClick ? "unlock" : "lock" }); !existingMake && cm.addItem({ description: "Make...", subitems: makes, icon: "hand-point-right" }); + + let existingOnClick = ContextMenu.Instance.findByDescription("OnClick..."); + let onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; + onClicks.push({ description: this.props.Document.isButton || this.props.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.makeBtnClicked, 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 Foreach Doc Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("Foreach Collection Doc (d) => ", this.props.Document, "onClick", obj.x, obj.y, "docList(this.collectionContext.data).map(d => {", "});\n") }); + !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + let existing = ContextMenu.Instance.findByDescription("Layout..."); let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : []; - layoutItems.push({ description: `${this.layoutDoc.chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.layoutDoc.chromeStatus = (this.layoutDoc.chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); layoutItems.push({ description: `${this.layoutDoc.autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc.autoHeight = !this.layoutDoc.autoHeight, icon: "plus" }); layoutItems.push({ description: this.props.Document.ignoreAspect || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" }); diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 5afd4d834..a27dbd83d 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -112,7 +112,8 @@ export class KeyValuePair extends React.Component {
{ return Field.toKeyValueString(props.Document, props.fieldKey); }} -- cgit v1.2.3-70-g09d2