From 0817d947b98b1b8e7f05df6b1d3db8eef4996ec9 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 6 Feb 2020 10:38:18 -0500 Subject: added synching of timelines with presentations --- src/new_fields/ScriptField.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index f8a8d1226..4c78ea3aa 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -114,8 +114,8 @@ export class ScriptField extends ObjectField { }); return compiled; } - public static MakeFunction(script: string, params: object = {}) { - const compiled = ScriptField.CompileScript(script, params, true); + public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) { + const compiled = ScriptField.CompileScript(script, params, true, capturedVariables); return compiled.compiled ? new ScriptField(compiled) : undefined; } -- cgit v1.2.3-70-g09d2 From c5c8c99151de576548dab215b82d44132b06f9a4 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 25 Feb 2020 12:45:33 -0500 Subject: added inheritable computations to template fields --- src/client/util/RichTextSchema.tsx | 27 ++++++++++++++++----------- src/new_fields/ScriptField.ts | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 626d9d75d..cc6b035d7 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -21,6 +21,7 @@ import { DocumentManager } from "./DocumentManager"; import ParagraphNodeSpec from "./ParagraphNodeSpec"; import { Transform } from "./Transform"; import React = require("react"); +import { CollectionSchemaBooleanCell } from "../views/collections/CollectionSchemaCells"; const blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]; @@ -869,6 +870,16 @@ export class DashFieldView { this._fieldWrapper.style.position = "relative"; this._fieldWrapper.style.display = "inline-block"; + const onchanged = (e: any) => { + this._reactionDisposer?.(); + let newText = this._fieldSpan.innerText.startsWith(":=") ? ":=-computed-" : this._fieldSpan.innerText; + this._options?.forEach(opt => StrCast(opt.title).startsWith(newText) && (newText = StrCast(opt.title))); + this._dashDoc![this._fieldKey] = newText; + if (newText.startsWith(":=") && this._dashDoc && e.data === null && !e.inputType.includes("delete")) { + Doc.Layout(tbox.props.Document)[this._fieldKey] = ComputedField.MakeFunction(this._fieldSpan.innerText.substring(2)); + } + } + this._fieldSpan = document.createElement("div"); this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; @@ -876,7 +887,7 @@ export class DashFieldView { this._fieldSpan.style.display = "inline-block"; this._fieldSpan.style.minWidth = "50px"; this._fieldSpan.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; - this._fieldSpan.addEventListener("input", this.onchanged); + this._fieldSpan.addEventListener("input", onchanged); this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onkeyup = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onmousedown = function (e: any) { e.stopPropagation(); }; @@ -913,21 +924,15 @@ export class DashFieldView { setDashDoc(tbox.props.DataDoc || tbox.dataDoc); } this._reactionDisposer?.(); - this._reactionDisposer = reaction(() => this._dashDoc?.[node.attrs.fieldKey], fval => this._fieldSpan.innerHTML = Field.toString(fval as Field) || "(null)", { fireImmediately: true }); + this._reactionDisposer = reaction(() => { + const dashVal = this._dashDoc?.[node.attrs.fieldKey]; + return StrCast(dashVal).startsWith(":=") || !dashVal ? Doc.Layout(tbox.props.Document)[this._fieldKey] : dashVal; + }, fval => this._fieldSpan.innerHTML = Field.toString(fval as Field) || "(null)", { fireImmediately: true }); this._fieldWrapper.appendChild(this._labelSpan); this._fieldWrapper.appendChild(this._fieldSpan); (this as any).dom = this._fieldWrapper; } - onchanged = () => { - this._reactionDisposer?.(); - - let newText = this._fieldSpan.innerText; - this._options?.forEach(opt => StrCast(opt.title).startsWith(newText) && (newText = StrCast(opt.title))); - this._dashDoc![this._fieldKey] = newText; - this._reactionDisposer = reaction(() => this._dashDoc?.[this._fieldKey], fval => this._fieldSpan.innerHTML = Field.toString(fval as Field) || "(null)"); - - } destroy() { this._reactionDisposer?.(); } diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 4c78ea3aa..131e1f339 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -130,7 +130,7 @@ export class ScriptField extends ObjectField { export class ComputedField extends ScriptField { _lastComputedResult: any; //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc - value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, _last_: this._lastComputedResult }, console.log).result); + value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ source: doc.expandedTemplate || doc, this: doc, _last_: this._lastComputedResult }, console.log).result); public static MakeScript(script: string, params: object = {}) { const compiled = ScriptField.CompileScript(script, params, false); return compiled.compiled ? new ComputedField(compiled) : undefined; -- cgit v1.2.3-70-g09d2 From dfeaa7b032376bc4001fcfdc197016ff1f09ebdf Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 25 Feb 2020 13:37:00 -0500 Subject: added 'source' parameter for computedField functions -- its the source document as opposed to 'this' which is the layout template) --- src/new_fields/ScriptField.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 131e1f339..9288fea9e 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -106,7 +106,7 @@ export class ScriptField extends ObjectField { } public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) { const compiled = CompileScript(script, { - params: { this: Doc.name, _last_: "any", ...params }, + params: { this: Doc.name, source: Doc.name, _last_: "any", ...params }, typecheck: false, editable: true, addReturn: addReturn, -- cgit v1.2.3-70-g09d2 From 786572f3cd674459f55b7f66e8eb257026f373ef Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 23 Mar 2020 21:24:50 -0400 Subject: fixed RichTextMenu to not obscure selection. fixed templateMenu to display a TreeView document of options. fixed resize in docDecorations for dragging corners other than bottom-right. --- src/client/util/DropConverter.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 4 +- src/client/views/DocumentDecorations.scss | 3 + src/client/views/DocumentDecorations.tsx | 6 +- src/client/views/TemplateMenu.tsx | 94 ++++++++++++++++++---- .../views/collections/CollectionDockingView.tsx | 27 +++++-- .../views/collections/CollectionLinearView.tsx | 20 ++--- .../views/collections/CollectionTreeView.scss | 1 + .../views/collections/CollectionTreeView.tsx | 7 +- .../views/collections/ParentDocumentSelector.tsx | 22 ++--- .../collections/collectionFreeForm/MarqueeView.tsx | 12 ++- src/client/views/nodes/DocumentView.tsx | 15 ++-- src/client/views/nodes/FormattedTextBox.tsx | 25 ++++-- src/client/views/search/SearchItem.tsx | 2 +- src/new_fields/Doc.ts | 2 - src/new_fields/ScriptField.ts | 4 +- src/new_fields/util.ts | 1 - .../authentication/models/current_user_utils.ts | 16 +++- 18 files changed, 189 insertions(+), 74 deletions(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 861cde5de..a6a43d06a 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -49,7 +49,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { (layoutDoc.layout instanceof Doc) && !data.userDropAction; } layoutDoc.isTemplateDoc = true; - dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); + dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: StrCast(layoutDoc.title), icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); dbox.dragFactory = layoutDoc; dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined; dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 23875fa33..8a33232b4 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -108,7 +108,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | this._pullColorAnimating = false; }); - get view0() { return this.props.views && this.props.views.length ? this.props.views[0] : undefined; } + get view0() { return this.props.views?.[0]; } @action onLinkButtonMoved = (e: PointerEvent): void => { @@ -250,7 +250,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | @computed get contextButton() { - return !this.view0 ? (null) : v).map(v => v as DocumentView)} Document={this.view0.props.Document} addDocTab={(doc, where) => { + return !this.view0 ? (null) : { where === "onRight" ? CollectionDockingView.AddRightSplit(doc) : this.props.stack ? CollectionDockingView.Instance.AddTab(this.props.stack, doc) : this.view0?.props.addDocTab(doc, "onRight"); diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 8d6002f8f..353520026 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -80,6 +80,7 @@ $linkGap : 3px; #documentDecorations-topLeftResizer, #documentDecorations-bottomRightResizer { cursor: nwse-resize; + background: dimGray; } #documentDecorations-bottomRightResizer { @@ -89,6 +90,7 @@ $linkGap : 3px; #documentDecorations-topRightResizer, #documentDecorations-bottomLeftResizer { cursor: nesw-resize; + background: dimGray; } #documentDecorations-topResizer, @@ -158,6 +160,7 @@ $linkGap : 3px; padding-top: 5px; width: $MINIMIZED_ICON_SIZE; height: $MINIMIZED_ICON_SIZE; + max-height: 20px; } .documentDecorations-background { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index c4abc935f..ff72592d8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -266,7 +266,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dist = Math.sqrt((e.clientX - down[0]) * (e.clientX - down[0]) + (e.clientY - down[1]) * (e.clientY - down[1])); dist = dist < 3 ? 0 : dist; SelectionManager.SelectedDocuments().map(dv => dv.props.Document).map(doc => doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc)). - map(d => d.borderRounding = `${Math.max(0, dist)}px`); + map(d => d.borderRounding = `${Math.max(0, dist)}%`); return false; } @@ -330,6 +330,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const width = (layoutDoc._width || 0); const height = (layoutDoc._height || (nheight / nwidth * width)); const scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling(); + if (nwidth && nheight) { + if (Math.abs(dW) > Math.abs(dH)) dH = dW * nheight / nwidth; + else dW = dH * nwidth / nheight; + } const actualdW = Math.max(width + (dW * scale), 20); const actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 5029b4074..cf6ce2c6f 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,4 +1,4 @@ -import { action, observable, runInAction, ObservableSet } from "mobx"; +import { action, observable, runInAction, ObservableSet, trace, computed } from "mobx"; import { observer } from "mobx-react"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; @@ -7,8 +7,13 @@ import { DocumentView } from "./nodes/DocumentView"; import { Template } from "./Templates"; import React = require("react"); import { Doc, DocListCast } from "../../new_fields/Doc"; +import { Docs, } from "../documents/Documents"; import { StrCast, Cast } from "../../new_fields/Types"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { CollectionTreeView } from "./collections/CollectionTreeView"; +import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath } from "../../Utils"; +import { Transform } from "../util/Transform"; +import { ScriptField, ComputedField } from "../../new_fields/ScriptField"; +import { Scripting } from "../util/Scripting"; @observer class TemplateToggle extends React.Component<{ template: Template, checked: boolean, toggle: (event: React.ChangeEvent, template: Template) => void }> { @@ -50,7 +55,10 @@ export class TemplateMenu extends React.Component { @observable private _hidden: boolean = true; toggleLayout = (e: React.ChangeEvent, layout: string): void => { - this.props.docViews.map(dv => dv.switchViews(e.target.checked, layout));//.setCustomView(e.target.checked, layout)); + this.props.docViews.map(dv => dv.switchViews(e.target.checked, layout)); + } + toggleDefault = (e: React.ChangeEvent): void => { + this.props.docViews.map(dv => dv.switchViews(false, "layout")); } toggleFloat = (e: React.ChangeEvent): void => { @@ -94,27 +102,81 @@ export class TemplateMenu extends React.Component { Array.from(Object.keys(Doc.GetProto(this.props.docViews[0].props.Document))). filter(key => key.startsWith("layout_")). map(key => runInAction(() => this._addedKeys.add(key.replace("layout_", "")))); - DocListCast(Cast(CurrentUserUtils.UserDocument.expandingButtons, Doc, null)?.data)?.map(btnDoc => { - if (StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title)) { - runInAction(() => this._addedKeys.add(StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title))); - } - }); } + return100 = () => 100; + @computed get scriptField() { + return ScriptField.MakeScript("switchView(firstDoc, this)", { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name, firstDoc: Doc.name }, + { firstDoc: this.props.docViews[0].props.Document }); + } render() { - const layout = Doc.Layout(this.props.docViews[0].Document); + const firstDoc = this.props.docViews[0].props.Document; + const templateName = StrCast(firstDoc.layoutKey, "layout").replace("layout_", ""); + const noteTypesDoc = Cast(Doc.UserDoc().noteTypes, Doc, null); + const noteTypes = DocListCast(noteTypesDoc?.data); + const addedTypes = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data) + const layout = Doc.Layout(firstDoc); const templateMenu: Array = []; this.props.templates.forEach((checked, template) => templateMenu.push()); - templateMenu.push(); - templateMenu.push(); + templateMenu.push(); + templateMenu.push(); templateMenu.push(); - this._addedKeys && Array.from(this._addedKeys).map(layout => - templateMenu.push( this.toggleLayout(e, layout)} />) - ); + templateMenu.push(); + if (noteTypesDoc) { + addedTypes.concat(noteTypes).map(template => template.treeViewChecked = ComputedField.MakeFunction("templateIsUsed(this, firstDoc)", { firstDoc: "string" }, { firstDoc: StrCast(firstDoc.title) })); + this._addedKeys && Array.from(this._addedKeys).filter(key => !noteTypes.some(nt => nt.title === key)).forEach(template => templateMenu.push( + this.toggleLayout(e, template)} />)); + templateMenu.push( + false} + removeDocument={(doc: Doc) => false} + addDocument={(doc: Doc) => false} /> + ); + } return
    - {templateMenu} + {templateMenu}
; } -} \ No newline at end of file +} + +Scripting.addGlobal(function switchView(doc: Doc, template: Doc) { + if (template.dragFactory) { + template = Cast(template.dragFactory, Doc, null); + } + let templateTitle = StrCast(template?.title); + return templateTitle && DocumentView.makeCustomViewClicked(doc, undefined, Docs.Create.FreeformDocument, templateTitle, template) +}); + +Scripting.addGlobal(function templateIsUsed(templateDoc: Doc, firstDocTitlte: string) { + const firstDoc = SelectionManager.SelectedDocuments()[0].props.Document; + const template = StrCast(templateDoc.dragFactory ? Cast(templateDoc.dragFactory, Doc, null)?.title : templateDoc.title); + return StrCast(firstDoc.layoutKey) === "layout_" + template ? 'check' : 'unchecked'; + // return SelectionManager.SelectedDocuments().some(view => StrCast(view.props.Document.layoutKey) === "layout_" + template) ? 'check' : 'unchecked' +}) \ No newline at end of file diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 00e22d6fb..1fb78f625 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -2,7 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faFile } from '@fortawesome/free-solid-svg-icons'; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, computed, Lambda, observable, reaction, runInAction } from "mobx"; +import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; @@ -20,7 +20,7 @@ import { DocServer } from "../../DocServer"; import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; -import { DragManager } from "../../util/DragManager"; +import { DragManager, dropActionType } from "../../util/DragManager"; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; @@ -504,15 +504,25 @@ export class CollectionDockingView extends React.Component { + const onDown = (e: React.PointerEvent) => { + if (!(e.nativeEvent as any).defaultPrevented) { e.preventDefault(); e.stopPropagation(); const dragData = new DragManager.DocumentDragData([doc]); - dragData.dropAction = doc.dropAction === "alias" ? "alias" : doc.dropAction === "copy" ? "copy" : undefined; + dragData.dropAction = doc.dropAction as dropActionType; DragManager.StartDocumentDrag([gearSpan], dragData, e.clientX, e.clientY); - }}>, gearSpan); + } + } + let rendered = false; + tab.buttonDisposer = reaction(() => ((view: Opt) => view ? [view] : [])(DocumentManager.Instance.getDocumentView(doc)), + (views) => { + !rendered && ReactDOM.render( + + , + gearSpan); + rendered = true; + }); + tab.reactComponents = [gearSpan]; tab.element.append(gearSpan); tab.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => { @@ -526,7 +536,8 @@ export class CollectionDockingView extends React.Component this.isCurrent(pair.layout)).map((pair, ind) => { + this.childLayoutPairs.map((pair, ind) => { Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log); }); } @@ -48,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { (i) => runInAction(() => { this._selectedIndex = i; let selected: any = undefined; - this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map(async (pair, ind) => { + this.childLayoutPairs.map(async (pair, ind) => { const isSelected = this._selectedIndex === ind; if (isSelected) { selected = pair; @@ -71,8 +71,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { } } - public isCurrent(doc: Doc) { return (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } - dimension = () => NumCast(this.props.Document._height); // 2 * the padding getTransform = (ele: React.RefObject) => () => { if (!ele.current) return Transform.Identity(); @@ -87,17 +85,21 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> - + -
- {this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => { +
+ {this.childLayoutPairs.map((pair, ind) => { const nested = pair.layout._viewType === CollectionViewType.Linear; const dref = React.createRef(); const nativeWidth = NumCast(pair.layout._nativeWidth, this.dimension()); const deltaSize = nativeWidth * .15 / 2; - return
this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 43ba5c614..35e3a8958 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import './ParentDocumentSelector.scss'; import { Doc } from "../../../new_fields/Doc"; import { observer } from "mobx-react"; -import { observable, action, runInAction } from "mobx"; +import { observable, action, runInAction, trace, computed } from "mobx"; import { Id } from "../../../new_fields/FieldSymbols"; import { SearchUtil } from "../../util/SearchUtil"; import { CollectionDockingView } from "./CollectionDockingView"; @@ -14,6 +14,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCog, faChevronCircleUp } from "@fortawesome/free-solid-svg-icons"; import { library } from "@fortawesome/fontawesome-svg-core"; import { DocumentView } from "../nodes/DocumentView"; +import { SelectionManager } from "../../util/SelectionManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -22,7 +23,6 @@ library.add(faCog); type SelectorProps = { Document: Doc, - Views: DocumentView[], Stack?: any, addDocTab(doc: Doc, location: string): void }; @@ -93,7 +93,7 @@ export class ParentDocSelector extends React.Component { } @observer -export class DockingViewButtonSelector extends React.Component<{ Document: Doc, Stack: any }> { +export class DockingViewButtonSelector extends React.Component<{ views: DocumentView[], Stack: any }> { @observable hover = false; customStylesheet(styles: any) { @@ -106,15 +106,19 @@ export class DockingViewButtonSelector extends React.Component<{ Document: Doc, }; } - render() { - const view = DocumentManager.Instance.getDocumentView(this.props.Document); - const flyout = ( + @computed get flyout() { + trace(); + return (
- +
); - return !this.props.Stack && e.stopPropagation()} className="buttonSelector"> - + } + + render() { + trace(); + return { this.props.views[0].select(false); e.stopPropagation(); }} className="buttonSelector"> + ; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4bf3329eb..17bba9568 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -107,8 +107,14 @@ export class MarqueeView extends React.Component(Docu static makeCustomViewClicked = (doc: Doc, dataDoc: Opt, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, name: string = "custom", docLayoutTemplate?: Doc) => { const batch = UndoManager.StartBatch("CustomViewClicked"); const customName = "layout_" + name; - if (!StrCast(doc.title).endsWith(name)) doc.title = doc.title + "_" + name; if (doc[customName] === undefined) { const _width = NumCast(doc._width); const _height = NumCast(doc._height); @@ -634,13 +633,15 @@ export class DocumentView extends DocComponent(Docu // } else if (custom) { DocumentView.makeNativeViewClicked(this.props.Document); + const userDoc = Doc.UserDoc(); - const imgView = Cast(Doc.UserDoc().iconView, Doc, null); - const iconImgView = Cast(Doc.UserDoc().iconImageView, Doc, null); - const iconColView = Cast(Doc.UserDoc().iconColView, Doc, null); + const imgView = Cast(userDoc.iconView, Doc, null); + const iconImgView = Cast(userDoc.iconImageView, Doc, null); + const iconColView = Cast(userDoc.iconColView, Doc, null); const iconViews = [imgView, iconImgView, iconColView]; - const expandingButtons = DocListCast(Cast(Doc.UserDoc().expandingButtons, Doc, null)?.data); - const allTemplates = iconViews.concat(expandingButtons); + const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data); + const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data); + const allTemplates = iconViews.concat(templateButtons).concat(noteTypes); let foundLayout: Opt; allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { if (StrCast(tempDoc.title) === this.props.Document.type + "_" + layout) { @@ -1028,7 +1029,7 @@ export class DocumentView extends DocComponent(Docu
); const captionView = (!showCaption ? (null) :
- { this.ProseRef = ele; - this.dropDisposer && this.dropDisposer(); + this.dropDisposer?.(); ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this))); } @@ -386,9 +387,14 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document.proto as Doc), icon: "eye" }); + this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document), icon: "eye" }); funcs.push({ description: "Reset Default Layout", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); - !this.props.Document.expandedTemplate && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = true; Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); }, icon: "eye" }); + !this.props.Document.expandedTemplate && funcs.push({ + description: "Make Template", event: () => { + this.props.Document.isTemplateDoc = makeTemplate(this.props.Document, true); + Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); + }, icon: "eye" + }); funcs.push({ description: "Toggle Single Line", event: () => this.props.Document._singleLine = !this.props.Document._singleLine, icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Sidebar", event: () => this.props.Document._showSidebar = !this.props.Document._showSidebar, icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Audio", event: () => this.props.Document._showAudio = !this.props.Document._showAudio, icon: "expand-arrows-alt" }); @@ -901,6 +907,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) { e.stopPropagation(); } + this._downX = this._downY = Number.NaN; } @action @@ -914,12 +921,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & prosediv && (prosediv.keeplocation = undefined); const pos = this._editorView?.state.selection.$from.pos || 1; keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); + const coords = !Number.isNaN(this._downX) ? { left: this._downX, top: this._downY, bottom: this._downY, right: this._downX } : this._editorView?.coordsAtPos(pos); // jump rich text menu to this textbox - const { current } = this._ref; - if (current && this.props.Document._chromeStatus !== "disabled") { - const x = Math.min(Math.max(current.getBoundingClientRect().left, 0), window.innerWidth - RichTextMenu.Instance.width); - const y = this._ref.current!.getBoundingClientRect().top - RichTextMenu.Instance.height - 50; + const bounds = this._ref.current?.getBoundingClientRect(); + if (bounds && this.props.Document._chromeStatus !== "disabled") { + const x = Math.min(Math.max(bounds.left, 0), window.innerWidth - RichTextMenu.Instance.width); + let y = Math.min(Math.max(0, bounds.top - RichTextMenu.Instance.height - 50), window.innerHeight - RichTextMenu.Instance.height); + if (coords && coords.left > x && coords.left < x + RichTextMenu.Instance.width && coords.top > y && coords.top < y + RichTextMenu.Instance.height + 50) { + y = Math.min(bounds.bottom, window.innerHeight - RichTextMenu.Instance.height); + } RichTextMenu.Instance.jumpTo(x, y); } } diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 2cbb24da7..63cef5101 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -272,7 +272,7 @@ export class SearchItem extends React.Component { @computed get contextButton() { - return CollectionDockingView.AddRightSplit(doc)} />; + return CollectionDockingView.AddRightSplit(doc)} />; } render() { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 50adf0392..322b57272 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -795,8 +795,6 @@ export namespace Doc { const prevLayout = StrCast(doc.layoutKey).split("_")[1]; const deiconify = prevLayout === "icon" && StrCast(doc.deiconifyLayout) ? "layout_" + StrCast(doc.deiconifyLayout) : ""; prevLayout === "icon" && (doc.deiconifyLayout = undefined); - if (StrCast(doc.title).endsWith("_" + prevLayout) && deiconify) doc.title = StrCast(doc.title).replace("_" + prevLayout, deiconify); - else doc.title = undefined; doc.layoutKey = deiconify || "layout"; } export function setDocFilterRange(target: Doc, key: string, range?: number[]) { diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 9288fea9e..606f55b7c 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -119,8 +119,8 @@ export class ScriptField extends ObjectField { return compiled.compiled ? new ScriptField(compiled) : undefined; } - public static MakeScript(script: string, params: object = {}) { - const compiled = ScriptField.CompileScript(script, params, false); + public static MakeScript(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) { + const compiled = ScriptField.CompileScript(script, params, false, capturedVariables); return compiled.compiled ? new ScriptField(compiled) : undefined; } } diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index 6d7f6b56e..3ab1b299b 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -7,7 +7,6 @@ import { ObjectField } from "./ObjectField"; import { action, trace } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols"; import { DocServer } from "../client/DocServer"; -import { props } from "bluebird"; function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 31588bf82..9c39ce7de 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -53,7 +53,7 @@ export class CurrentUserUtils { ]; doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" }); Doc.addFieldEnumerations(Doc.GetProto(noteTemplates[4]), "taskStatus", taskStatusValues); - doc.noteTypes = new PrefetchProxy(Docs.Create.TreeDocument(noteTemplates.map(nt => makeTemplate(nt, true, StrCast(nt.style)) ? nt : nt), { title: "Note Types", _height: 75 })); + doc.noteTypes = new PrefetchProxy(Docs.Create.TreeDocument(noteTemplates.map(nt => makeTemplate(nt, true, StrCast(nt.style)) ? nt : nt), { title: "Note Layouts", _height: 75 })); } // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools @@ -292,12 +292,20 @@ export class CurrentUserUtils { { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: "alias", onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'), dragFactory: slideTemplate, removeDropProperties: new List(["dropAction"]), title: "presentation slide", icon: "sticky-note" }); doc.descriptionBtn = Docs.Create.FontIconDocument( { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: "alias", onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'), dragFactory: descriptionTemplate, removeDropProperties: new List(["dropAction"]), title: "description view", icon: "sticky-note" }); - doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc, doc.slidesBtn as Doc, doc.descriptionBtn as Doc, - ...DocListCast(Cast(doc.noteTypes, Doc, null))], { + doc.templateButtons = Docs.Create.LinearDocument([doc.slidesBtn as Doc, doc.descriptionBtn as Doc], { + title: "template buttons", _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", dontSelect: true, + backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, + dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }) + }); + doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc, doc.templateButtons as Doc], { title: "expanding buttons", _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", - backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, + backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, linearViewIsExpanded: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }) }); + doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([doc.noteTypes as Doc, doc.templateButtons as Doc], { + title: "template layouts", _xPadding: 0, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", + { dragData: DragManager.DocumentDragData.name }) + })); } // sets up the default set of documents to be shown in the Overlay layer -- cgit v1.2.3-70-g09d2 From 089011c748e67fcce407021c6c28dc5028303a45 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 29 Mar 2020 00:25:33 -0400 Subject: clean up of parameterized templates. added 'self' to scripts to reference the expandedTemplate --- src/client/util/RichTextSchema.tsx | 28 ++++++++-------------- src/client/util/Scripting.ts | 2 ++ .../views/collections/CollectionViewChromes.tsx | 1 + src/new_fields/Doc.ts | 23 +++++++++++------- src/new_fields/ScriptField.ts | 5 ++-- 5 files changed, 31 insertions(+), 28 deletions(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 69296d8bc..71d4530f2 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -906,15 +906,13 @@ export class DashFieldView { if (modText) { self._fieldSpan.innerHTML = self._dashDoc![self._fieldKey] = modText; Doc.addFieldEnumerations(self._textBoxDoc, self._fieldKey, []); - } else if (!self._fieldSpan.innerText.startsWith(":=") && !self._fieldSpan.innerText.startsWith("=:=")) { - self._dashDoc![self._fieldKey] = newText; - } - - // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key - if (self._fieldSpan.innerText.startsWith(":=") && self._dashDoc) { - self._dashDoc[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2)); - } else if (self._fieldSpan.innerText.startsWith("=:=") && self._dashDoc) { + } // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key + else if (self._fieldSpan.innerText.startsWith(":=")) { + self._dashDoc![self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2)); + } else if (self._fieldSpan.innerText.startsWith("=:=")) { Doc.Layout(tbox.props.Document)[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(3)); + } else { + self._dashDoc![self._fieldKey] = newText; } }); }; @@ -928,14 +926,9 @@ export class DashFieldView { this._fieldCheck.style.minWidth = "12px"; this._fieldCheck.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; this._fieldCheck.onchange = function (e: any) { - // look for a document whose id === the fieldKey being displayed. If there's a match, then that document - // holds the different enumerated values for the field in the titles of its collected documents. - // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down. - const checked = e.target.checked; - DocServer.GetRefField(self._fieldKey).then(options => self._dashDoc![self._fieldKey] = checked); + self._dashDoc![self._fieldKey] = e.target.checked; } - this._fieldSpan = document.createElement("div"); this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; @@ -950,12 +943,11 @@ export class DashFieldView { const setDashDoc = (doc: Doc) => { self._dashDoc = doc; - if (self._dashDoc && self._options?.length && !self._dashDoc[self._fieldKey]) { + if (self._options?.length && !self._dashDoc[self._fieldKey]) { self._dashDoc[self._fieldKey] = StrCast(self._options[0].title); } - const layout = tbox.props.Document; - // NOTE: if the field key starts with "@", then the actual field key is stored in the "@"fieldKey. Dereferencing these fields happens in ImageBox and RichTextSchema - self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(layout[StrCast(self._fieldKey).substring(1)]) : self._fieldKey; + // NOTE: if the field key starts with "@", then the actual field key is stored in the field 'fieldKey' (removing the @). + self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(tbox.props.Document[StrCast(self._fieldKey).substring(1)]) : self._fieldKey; this._labelSpan.innerHTML = `${self._fieldKey}: `; const fieldVal = Cast(this._dashDoc?.[self._fieldKey], "boolean", null); this._fieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none"; diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 0fa96963e..ce21b7fa7 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -215,6 +215,8 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult { const { requiredType = "", addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options; + if (options.params && !options.params.this) options.params.this = Doc.name; + if (options.params && !options.params.self) options.params.self = Doc.name; if (options.globals) { Scripting.setScriptingGlobals(options.globals); } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 9391b153e..aa6e07968 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -400,6 +400,7 @@ export class CollectionViewBaseChrome extends React.Component and then arguments would be passed in the layout key as: + // layout_mytemplate(somparam=somearg). + // then any references to @someparam would be rewritten as accesses to 'somearg' on the expandedTemplate + export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) { if (!WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc; const templateField = StrCast(templateLayoutDoc.isTemplateForField); // the field that the template renders @@ -475,9 +481,10 @@ export namespace Doc { // If it doesn't find the expanded layout, then it makes a delegate of the template layout and // saves it on the data doc indexed by the template layout's id. // - const params = templateParams?.match(/\(([a-zA-Z0-9_-]*)\)/)?.[1].replace("()", "") || ""; + const args = templateArgs?.match(/\(([a-zA-Z0-9_-]*)\)/)?.[1].replace("()", "") || ""; + const params = args.split("=").length > 1 ? args.split("=")[0] : "PARAMS"; const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc); - const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + params + "]"; + const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + args + "]"; let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey]; if (templateLayoutDoc.resolvedDataDoc instanceof Promise) { expandedTemplateLayout = undefined; @@ -487,10 +494,10 @@ export namespace Doc { setTimeout(action(() => { if (!targetDoc[expandedLayoutFieldKey]) { const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]"); - newLayoutDoc["params"] = params; + // the template's arguments are stored in params which is derefenced to find + // the actual field key where the parameterized template data is stored. + newLayoutDoc[params] = args; newLayoutDoc.expandedTemplate = targetDoc; - // the template's parameters are stored in params which are derefenced to find - // the actual field key where the template data is stored. Currently this is only used in RichTextSchema's docView targetDoc[expandedLayoutFieldKey] = newLayoutDoc; const dataDoc = Doc.GetProto(targetDoc); newLayoutDoc.resolvedDataDoc = dataDoc; @@ -512,7 +519,7 @@ export namespace Doc { } const existingResolvedDataDoc = childDoc[DataSym] !== Doc.GetProto(childDoc)[DataSym] && childDoc[DataSym]; const resolvedDataDoc = existingResolvedDataDoc || (Doc.AreProtosEqual(containerDataDoc, containerDoc) || !containerDataDoc || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField) ? undefined : containerDataDoc); - return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc["params"]) + ")"), data: resolvedDataDoc }; + return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc["PARAMS"]) + ")"), data: resolvedDataDoc }; } export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc { diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 606f55b7c..954c22a8d 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -7,6 +7,7 @@ import { Doc, Field } from "../new_fields/Doc"; import { Plugins } from "./util"; import { computedFn } from "mobx-utils"; import { ProxyField } from "./Proxy"; +import { Cast } from "./Types"; function optional(propSchema: PropSchema) { return custom(value => { @@ -106,7 +107,7 @@ export class ScriptField extends ObjectField { } public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) { const compiled = CompileScript(script, { - params: { this: Doc.name, source: Doc.name, _last_: "any", ...params }, + params: { this: Doc.name, self: Doc.name, _last_: "any", ...params }, typecheck: false, editable: true, addReturn: addReturn, @@ -130,7 +131,7 @@ export class ScriptField extends ObjectField { export class ComputedField extends ScriptField { _lastComputedResult: any; //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc - value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ source: doc.expandedTemplate || doc, this: doc, _last_: this._lastComputedResult }, console.log).result); + value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.expandedTemplate, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result); public static MakeScript(script: string, params: object = {}) { const compiled = ScriptField.CompileScript(script, params, false); return compiled.compiled ? new ComputedField(compiled) : undefined; -- cgit v1.2.3-70-g09d2 From 71b0e84cb852bc171a5df96b36cbb5f7bd1c150c Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 30 Mar 2020 14:19:03 -0400 Subject: changed expandedTemplate to rootDocument --- src/client/util/ProsemirrorExampleTransfer.ts | 6 +++--- src/client/util/RichTextSchema.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 4 ++-- src/client/views/presentationview/PresElementBox.tsx | 2 +- src/new_fields/Doc.ts | 18 +++++++++--------- src/new_fields/ScriptField.ts | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/new_fields/ScriptField.ts') diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 5cbf401d4..42247f177 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -151,14 +151,14 @@ export default function buildKeymap>(schema: S, props: any }); bind("Ctrl-Enter", (state: EditorState, dispatch: (tx: Transaction) => void) => { const layoutDoc = props.Document; - const originalDoc = layoutDoc.expandedTemplate || layoutDoc; + const originalDoc = layoutDoc.rootDocument || layoutDoc; if (originalDoc instanceof Doc) { const newDoc = Docs.Create.TextDocument("", { title: "", layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), x: NumCast(originalDoc.x), y: NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10, _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height) }); FormattedTextBox.SelectOnLoad = newDoc[Id]; - originalDoc instanceof Doc && props.addDocument(newDoc); + props.addDocument(newDoc); } }); @@ -169,7 +169,7 @@ export default function buildKeymap>(schema: S, props: any }; const addTextOnRight = (force: boolean) => { const layoutDoc = props.Document; - const originalDoc = layoutDoc.expandedTemplate || layoutDoc; + const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { const newDoc = Docs.Create.TextDocument("", { title: "", layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 1c637cfbe..b612c82ae 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -849,7 +849,7 @@ export class DashDocView { this._renderDisposer?.(); this._renderDisposer = reaction(() => { if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { - finalLayout.expandedTemplate = dashDoc.aliasOf; + finalLayout.rootDocument = dashDoc.aliasOf; } const layoutKey = StrCast(finalLayout.layoutKey); const finalKey = layoutKey && StrCast(finalLayout[layoutKey]).split("'")?.[1]; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 8b7136876..39621b75c 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -125,7 +125,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } const dfield = this.dataField; - const rawdocs = (dfield instanceof Doc) ? [dfield] : Cast(dfield, listSpec(Doc), this.props.Document.expandedTemplate && !this.props.annotationsKey ? [Cast(this.props.Document.expandedTemplate, Doc, null)] : []); + const rawdocs = (dfield instanceof Doc) ? [dfield] : Cast(dfield, listSpec(Doc), this.props.Document.rootDocument && !this.props.annotationsKey ? [Cast(this.props.Document.rootDocument, Doc, null)] : []); const docs = rawdocs.filter(d => !(d instanceof Promise)).map(d => d as Doc); const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField); const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 324417cf8..edb9fd930 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -306,7 +306,7 @@ export class CollectionView extends Touchable { } get childDocs() { const dfield = this.dataField; - const rawdocs = (dfield instanceof Doc) ? [dfield] : Cast(dfield, listSpec(Doc), Cast(this.props.Document.expandedTemplate, Doc, null) ? [Cast(this.props.Document.expandedTemplate, Doc, null)] : []); + const rawdocs = (dfield instanceof Doc) ? [dfield] : Cast(dfield, listSpec(Doc), Cast(this.props.Document.rootDocument, Doc, null) ? [Cast(this.props.Document.rootDocument, Doc, null)] : []); const docs = rawdocs.filter(d => !(d instanceof Promise)).map(d => d as Doc); const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField); return viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 63e3e0431..080c722b2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -291,7 +291,7 @@ export class DocumentView extends DocComponent(Docu SelectionManager.DeselectAll(); UndoManager.RunInBatch(() => this.onClickHandler!.script.run({ this: this.props.Document, - self: Cast(this.props.Document.expandedTemplate, Doc, null) || this.props.Document, + self: Cast(this.props.Document.rootDocument, Doc, null) || this.props.Document, containingCollection: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey }, console.log) && !this.props.Document.dontSelect && !this.props.Document.isButton && this.select(false), "on click"); } else if (this.Document.type === DocumentType.BUTTON) { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index f83beade3..bc43beab9 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -389,7 +389,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & const funcs: ContextMenuProps[] = []; this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document), icon: "eye" }); funcs.push({ description: "Reset Default Layout", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); - !this.props.Document.expandedTemplate && funcs.push({ + !this.props.Document.rootDocument && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = makeTemplate(this.props.Document, true); Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); @@ -822,7 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & } } - const selectOnLoad = (Cast(this.props.Document.expandedTemplate, Doc, null) || this.props.Document)[Id] === FormattedTextBox.SelectOnLoad; + const selectOnLoad = (Cast(this.props.Document.rootDocument, Doc, null) || this.props.Document)[Id] === FormattedTextBox.SelectOnLoad; if (selectOnLoad && !this.props.dontRegisterView) { FormattedTextBox.SelectOnLoad = ""; this.props.select(false); diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 9329a5aa1..758795ed5 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -50,7 +50,7 @@ export class PresElementBox extends DocExtendableComponent and then arguments would be passed in the layout key as: // layout_mytemplate(somparam=somearg). - // then any references to @someparam would be rewritten as accesses to 'somearg' on the expandedTemplate + // then any references to @someparam would be rewritten as accesses to 'somearg' on the rootDocument export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) { const args = templateArgs?.match(/\(([a-zA-Z0-9._\-]*)\)/)?.[1].replace("()", "") || StrCast(templateLayoutDoc.PARAMS); if (!args && !WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc; @@ -499,8 +499,8 @@ export namespace Doc { const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]"); // the template's arguments are stored in params which is derefenced to find // the actual field key where the parameterized template data is stored. - newLayoutDoc[params] = args !== "..." ? args : ""; // ... signifies the layout has sub template(s) -- so we have to expand the layout for them so that they can get the correct 'expandedTemplate' field, but we don't need to reassign their params. it would be better if the 'expandedTemplate' field could be passed dynamically to avoid have to create instances - newLayoutDoc.expandedTemplate = targetDoc; + newLayoutDoc[params] = args !== "..." ? args : ""; // ... signifies the layout has sub template(s) -- so we have to expand the layout for them so that they can get the correct 'rootDocument' field, but we don't need to reassign their params. it would be better if the 'rootDocument' field could be passed dynamically to avoid have to create instances + newLayoutDoc.rootDocument = targetDoc; targetDoc[expandedLayoutFieldKey] = newLayoutDoc; const dataDoc = Doc.GetProto(targetDoc); newLayoutDoc.resolvedDataDoc = dataDoc; @@ -511,7 +511,7 @@ export namespace Doc { }), 0); } } - return expandedTemplateLayout instanceof Doc ? expandedTemplateLayout : undefined; // layout is undefined if the expandedTemplate is pending. + return expandedTemplateLayout instanceof Doc ? expandedTemplateLayout : undefined; // layout is undefined if the expandedTemplateLayout is pending. } // if the childDoc is a template for a field, then this will return the expanded layout with its data doc. @@ -882,10 +882,10 @@ export namespace Doc { Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc); } const options = optionsCollection as Doc; - const targetDoc = doc && Doc.GetProto(Cast(doc.expandedTemplate, Doc, null) || doc); - targetDoc && (targetDoc.backgroundColor = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this)["${enumeratedFieldKey}"])?._backgroundColor || "white"`, undefined, { options })); - targetDoc && (targetDoc.color = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this)["${enumeratedFieldKey}"]).color || "black"`, undefined, { options })); - targetDoc && (targetDoc.borderRounding = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this)["${enumeratedFieldKey}"]).borderRounding`, undefined, { options })); + const targetDoc = doc && Doc.GetProto(Cast(doc.rootDocument, Doc, null) || doc); + targetDoc && (targetDoc.backgroundColor = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"])?._backgroundColor || "white"`, undefined, { options })); + targetDoc && (targetDoc.color = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"]).color || "black"`, undefined, { options })); + targetDoc && (targetDoc.borderRounding = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"]).borderRounding`, undefined, { options })); enumerations.map(enumeration => { const found = DocListCast(options.data).find(d => d.title === enumeration.title); if (found) { diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 954c22a8d..148886848 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -131,7 +131,7 @@ export class ScriptField extends ObjectField { export class ComputedField extends ScriptField { _lastComputedResult: any; //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc - value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.expandedTemplate, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result); + value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result); public static MakeScript(script: string, params: object = {}) { const compiled = ScriptField.CompileScript(script, params, false); return compiled.compiled ? new ComputedField(compiled) : undefined; -- cgit v1.2.3-70-g09d2