aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/CurrentUserUtils.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-06-20 05:31:25 -0400
committerbobzel <zzzman@gmail.com>2022-06-20 05:31:25 -0400
commitc0826fb904f5d2448635b5dae1fc4337fead939e (patch)
tree212d37de8064cb180856e7bd26173dd27ba859ba /src/client/util/CurrentUserUtils.ts
parent3351c0372a8372a3e91bbd814f827a8b984f8665 (diff)
lots of changes to try to cleanup CurrentUserUtils so changes can be made without rebuilding the DB.
Diffstat (limited to 'src/client/util/CurrentUserUtils.ts')
-rw-r--r--src/client/util/CurrentUserUtils.ts1216
1 files changed, 568 insertions, 648 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b4e18a8bb..afb1442bf 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,16 +1,17 @@
import { computed, observable, reaction } from "mobx";
import * as rp from 'request-promise';
-import { DataSym, Doc, DocListCast, DocListCastAsync } from "../../fields/Doc";
+import { DataSym, Doc, DocListCast, DocListCastAsync, StrListCast } from "../../fields/Doc";
import { Id } from "../../fields/FieldSymbols";
import { InkTool } from "../../fields/InkField";
import { List } from "../../fields/List";
import { PrefetchProxy } from "../../fields/Proxy";
import { RichTextField } from "../../fields/RichTextField";
+import { listSpec } from "../../fields/Schema";
import { ComputedField, ScriptField } from "../../fields/ScriptField";
-import { BoolCast, Cast, DateCast, DocCast, NumCast, PromiseValue, StrCast } from "../../fields/Types";
+import { BoolCast, Cast, DateCast, DocCast, FieldValue, NumCast, PromiseValue, ScriptCast, StrCast } from "../../fields/Types";
import { ImageField, nullAudio } from "../../fields/URLField";
import { SharingPermissions } from "../../fields/util";
-import { Utils } from "../../Utils";
+import { OmitKeys, Utils } from "../../Utils";
import { DocServer } from "../DocServer";
import { Docs, DocumentOptions, DocUtils } from "../documents/Documents";
import { DocumentType } from "../documents/DocumentTypes";
@@ -42,17 +43,17 @@ interface Button {
toolTip?: string;
icon?: string;
btnType?: ButtonType;
- click?: string;
numBtnType?: NumButtonType;
numBtnMin?: number;
numBtnMax?: number;
switchToggle?: boolean;
- script?: string;
width?: number;
- list?: string[];
+ btnList?: List<string>;
ignoreClick?: boolean;
buttonText?: string;
- hidden?: string;
+ scripts?: { script?: string; onClick?: string; }
+ funcs?: { [key:string]: string };
+ subMenu?: Button[];
}
export let resolvedPorts: { server: number, socket: number };
@@ -73,101 +74,134 @@ export class CurrentUserUtils {
@observable public static headerBarHeight: number = 0;
@observable public static searchPanelWidth: number = 0;
- // sets up the default User Templates - slideView, headerView
- static setupExperimentalTemplateButtons(doc: Doc) {
- if (doc["template-experimental-buttons"] === undefined) {
- const requiredTypeNameFields = [
- {
- type: "slide", icon: "address-card", template: Docs.Create.MultirowDocument(
- [
- Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
- Docs.Create.TextDocument("", { title: "text", _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) })
- ],
- { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
- )
- },
- {
- type: "mobile", icon: "mobile", template: this.mobileButton({ title: "NEW MOBILE BUTTON", onClick: undefined, },
- [this.createToolButton({ ignoreClick: true, icon: "mobile", backgroundColor: "transparent" }),
- this.mobileTextContainer({},
- [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])
- ]
- )
- },
- ];
- const requiredTypes = requiredTypeNameFields.map(({ type, icon, template }) => {
- if (doc[`template-button-${type}`] === undefined) {
- template.isTemplateDoc = makeTemplate(template);
- doc[`template-button-${type}`] = CurrentUserUtils.createToolButton({
- onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(template) as any as Doc,
- title: type,
- icon,
- });
+ static AssignScripts(doc:Doc, scripts?:{ [key: string]: string;}, functions?:{[key:string]: string}) {
+ scripts && Object.keys(scripts).map(key => {
+ if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && scripts[key]) {
+ doc[key] = ScriptField.MakeScript(scripts[key], { dragData: DragManager.DocumentDragData.name, value:"any", scriptContext: "any" }, {"_readOnly_": true});
+ }
+ });
+ functions && Object.keys(functions).map(key => {
+ const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+ if (ScriptCast(cfield)?.script.originalScript !== functions[key] && functions[key]) {
+ doc[key] = ComputedField.MakeFunction(functions[key], { dragData: DragManager.DocumentDragData.name }, {"_readOnly_": true});
+ }
+ });
+ return doc;
+ }
+ static AssignOpts(doc:Doc|undefined, reqdOpts:DocumentOptions, items?:Doc[]) {
+ if (doc) {
+ const compareValues = (val1:any, val2:any) => {
+ if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) {
+ return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v));
+ }
+ return val1 === val2;
+ }
+ Object.entries(reqdOpts).forEach(pair => {
+ const targetDoc = pair[0].startsWith("_") ? doc : Doc.GetProto(doc as Doc);
+ if (!Object.getOwnPropertyNames(targetDoc).includes(pair[0].replace(/^_/,"")) ||
+ !compareValues(pair[1], targetDoc[pair[0]])) {
+ targetDoc[pair[0]] = pair[1];
}
- return doc[`template-button-${type}`] as Doc;
});
-
- doc["template-experimental-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, {
- title: "Experimental Tools", _xMargin: 0, _showTitle: "title", _chromeHidden: true,
- hidden: ComputedField.MakeFunction("IsNoviceMode()") as any,
- _stayInCollection: true, _hideContextMenu: true, _forceActive: true,
- _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
- dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
- }));
+ items?.forEach(item => !DocListCast(doc.data).includes(item) && Doc.AddDocToList(Doc.GetProto(doc), "data", item));
}
- return doc["template-experimental-buttons"] as Doc;
+ return doc;
}
- // setup the different note type skins
- static setupNoteTemplates(doc: Doc) {
- if (doc["template-notes"] === undefined) {
- const requiredTypeNameFields = [
- { type: "Note", backgroundColor: "yellow", icon: "sticky-note" },
- { type: "Idea", backgroundColor: "pink", icon: "lightbulb" },
- { type: "Topic", backgroundColor: "lightblue", icon: "book-open" }];
- const requiredTypes = requiredTypeNameFields.map(({ type, backgroundColor, icon }) =>
- doc[`template-note-${type}`] as Doc ??
- (() => {
- const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor, system: true, icon });
- noteView.isTemplateDoc = makeTemplate(noteView, true, type);
- return doc[`template-note-${type}`] = new PrefetchProxy(noteView);
- })());
-
- doc["template-notes"] = new PrefetchProxy(Docs.Create.TreeDocument(requiredTypes, { title: "Note Layouts", _height: 75, system: true }));
- }
+ // initializes experimental advanced template views - slideView, headerView
+ static setupExperimentalTemplateButtons(doc: Doc, field="template-experimental-buttons") {
+ const tempDocs = DocCast(doc[field]);
+ const requiredTypeNameFields:{opts:DocumentOptions, template:() => Doc}[] = [
+ {
+ opts:{type: "slide", icon: "address-card"}, template: () => Docs.Create.MultirowDocument(
+ [
+ Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
+ Docs.Create.TextDocument("", { title: "text", _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) })
+ ],
+ { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
+ )
+ },
+ {
+ opts:{type: "mobile", icon: "mobile"}, template: () => this.mobileButton({ title: "NEW MOBILE BUTTON", onClick: undefined, },
+ [this.createToolButton({ ignoreClick: true, icon: "mobile", backgroundColor: "transparent" }),
+ this.mobileTextContainer({},
+ [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])
+ ]
+ )
+ },
+ ];
+ const requiredTypes = requiredTypeNameFields.map(({ opts, template }) => {
+ const docType = DocListCast(tempDocs?.data)?.find(doc => doc.title === opts.type);
+ const reqdOpts = {
+ dragFactory: template(),
+ title: opts.type,
+ icon: opts.icon
+ };
+ const reqdScripts = {onDragStart: 'copyDragFactory(this.dragFactory)'};
+ const makeTemp = (doc:Doc) => {
+ doc.isTemplateDoc = makeTemplate(doc);
+ return doc;
+ }
+ return this.AssignScripts(!docType ? makeTemp(CurrentUserUtils.createToolButton(reqdOpts)) : this.AssignOpts(docType, reqdOpts)!, reqdScripts)!;
+ });
+
+ const reqdOpts = {
+ title: "Experimental Tools", _xMargin: 0, _showTitle: "title", _chromeHidden: true,
+ _stayInCollection: true, _hideContextMenu: true, _forceActive: true, system: true,
+ _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
+ };
+ const reqdScripts = {dropConverter : "convertToButtons(dragData)"};
+ const reqdFuncs = {hidden: "IsNoviceMode()"}
+ return this.AssignScripts(!tempDocs ?
+ (doc[field] = Docs.Create.MasonryDocument(requiredTypes, reqdOpts)) :
+ this.AssignOpts(tempDocs, reqdOpts, requiredTypes)!,
+ reqdScripts, reqdFuncs);
+ }
+
+ /// Initializes templates that can be applied to notes
+ static setupNoteTemplates(doc: Doc, field="template-notes") {
+ const tempNotes = DocCast(doc[field]);
+ const reqdTempOpts:DocumentOptions[] = [
+ { noteType: "Note", backgroundColor: "yellow", icon: "sticky-note"},
+ { noteType: "Idea", backgroundColor: "pink", icon: "lightbulb" },
+ { noteType: "Topic", backgroundColor: "lightblue", icon: "book-open" }];
+ const reqdNoteList = reqdTempOpts.map(opts => {
+ const reqdOpts = {...opts, title: "text", system: true};
+ const noteType = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.noteType === opts.noteType): undefined;
+ const makeTemp = (doc:Doc, noteType?:string) => {
+ doc.isTemplateDoc = makeTemplate(doc, true, noteType??"Note");
+ return doc;
+ }
+ return this.AssignOpts(noteType, reqdOpts) ?? makeTemp(Docs.Create.TextDocument("",reqdOpts), opts.noteType);
+ });
- return doc["template-notes"] as Doc;
+ const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, system: true };
+ return this.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts));
}
- // creates Note templates, and initial "user" templates
+ /// Initializes collection of templates for notes and click functions
static setupDocTemplates(doc: Doc) {
- if (doc.templateDocs === undefined) {
- doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([
- CurrentUserUtils.setupNoteTemplates(doc),
- CurrentUserUtils.setupExperimentalTemplateButtons(doc),
- CurrentUserUtils.setupClickEditorTemplates(doc)
- ], {
- title: "template layouts", _xMargin: 0, system: true,
- dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name })
- }));
- }
+ const templates = [
+ CurrentUserUtils.setupNoteTemplates(doc),
+ CurrentUserUtils.setupClickEditorTemplates(doc)
+ ];
+ const reqdOpts = { title: "template layouts", _xMargin: 0, system: true, };
+ const reqdScripts = { dropConverter: "convertToButtons(dragData)" };
+ return this.AssignScripts(this.AssignOpts(DocCast(doc.templateDocs), reqdOpts, templates) ?? (doc.templateDocs = Docs.Create.TreeDocument(templates, reqdOpts)), reqdScripts);
}
// setup templates for different document types when they are iconified from Document Decorations
- static setupDefaultIconTemplates(doc: Doc) {
- const templateIconsDoc = Cast(doc["template-icons"], Doc, null);
+ static setupDefaultIconTemplates(doc: Doc, field="template-icons") {
+ const templateIconsDoc = DocCast(doc[field]);
const makeIconTemplate = (type: DocumentType | undefined, templateField: string, iconTemplate: () => Doc) => {
const iconFieldName = "icon" + (type ? "_" + type : "");
if (!templateIconsDoc?.[iconFieldName]) {
const template = MakeTemplate(iconTemplate(), true, iconFieldName, templateField);
if (templateIconsDoc) {
- templateIconsDoc[iconFieldName] = new PrefetchProxy(template);
- Doc.AddDocToList(templateIconsDoc, "data", template);
- } else {
- return template;
+ templateIconsDoc[iconFieldName] = template;
}
+ return template;
}
};
const deiconifyScript = () => ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" });
@@ -182,46 +216,57 @@ export class CurrentUserUtils {
const fontBox = () => Docs.Create.FontIconDocument({
_nativeHeight: 30, _nativeWidth: 30, _width: 30, _height: 30, system: true, onClick: deiconifyScript()
});
- if (!templateIconsDoc) {
- const newIconsList = [
- makeIconTemplate(undefined, "title", () => labelBox({ _backgroundColor: "dimgray" })),
- makeIconTemplate(DocumentType.AUDIO, "title", () => labelBox({ _backgroundColor: "lightgreen" })),
- makeIconTemplate(DocumentType.PDF, "title", () => labelBox({ _backgroundColor: "pink" })),
- makeIconTemplate(DocumentType.WEB, "title", () => labelBox({ _backgroundColor: "brown" })),
- makeIconTemplate(DocumentType.RTF, "text", () => labelBox({ _showTitle: "creationDate" })),
- makeIconTemplate(DocumentType.IMG, "data", () => imageBox("", { _height: undefined, })),
- makeIconTemplate(DocumentType.COL, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {})),
- makeIconTemplate(DocumentType.VID, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {})),
- makeIconTemplate(DocumentType.BUTTON, "data", fontBox),
- //nasty hack .. templates are looked up exclusively by type -- but we want a template for a document with a certain field (transcription) .. so this hack and the companion hack in createCustomView does this for now
- makeIconTemplate("transcription" as any, "transcription", () => labelBox({ _backgroundColor: "orange" })),
- // makeIconTemplate(DocumentType.PDF, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {}))
- ].filter(d => d).map(d => d!);
-
- doc["template-icons"] = Docs.Create.TreeDocument(newIconsList, { title: "icon templates", _height: 75, system: true });
- }
+ const iconTemplates = [
+ makeIconTemplate(undefined, "title", () => labelBox({ _backgroundColor: "dimgray" })),
+ makeIconTemplate(DocumentType.AUDIO, "title", () => labelBox({ _backgroundColor: "lightgreen" })),
+ makeIconTemplate(DocumentType.PDF, "title", () => labelBox({ _backgroundColor: "pink" })),
+ makeIconTemplate(DocumentType.WEB, "title", () => labelBox({ _backgroundColor: "brown" })),
+ makeIconTemplate(DocumentType.RTF, "text", () => labelBox({ _showTitle: "creationDate" })),
+ makeIconTemplate(DocumentType.IMG, "data", () => imageBox("", { _height: undefined, })),
+ makeIconTemplate(DocumentType.COL, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {})),
+ makeIconTemplate(DocumentType.VID, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {})),
+ makeIconTemplate(DocumentType.BUTTON, "data", fontBox),
+ //nasty hack .. templates are looked up exclusively by type -- but we want a template for a document with a certain field (transcription) .. so this hack and the companion hack in createCustomView does this for now
+ makeIconTemplate("transcription" as any, "transcription", () => labelBox({ _backgroundColor: "orange" })),
+ // makeIconTemplate(DocumentType.PDF, "icon", () => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", {}))
+ ].filter(d => d).map(d => d!);
+
+ const reqdOpts = { title: "icon templates", _height: 75, system: true };
+ this.AssignOpts(templateIconsDoc, reqdOpts, iconTemplates) ?? (doc[field] = Docs.Create.TreeDocument(iconTemplates, reqdOpts));
}
+ /// initalizes the set of default versions of most document types
static creatorBtnDescriptors(doc: Doc): {
- title: string, toolTip: string, icon: string, drag?: string, ignoreClick?: boolean,
- click?: string, backgroundColor?: string, dragFactory?: Doc, noviceMode?: boolean, clickFactory?: Doc
+ title: string, toolTip: string, icon: string, ignoreClick?: boolean, dragFactory?: Doc,
+ backgroundColor?: string, clickFactory?: Doc, scripts?: { onClick?: string, onDragStart?: string}, funcs?: {onDragStart?:string, hidden?: string},
}[] {
const standardOps = () => ({ _fitWidth: true, system: true, "dragFactory-count": 0, cloneFieldFilter: new List<string>(["system"]) });
- if (doc.emptyPresentation === undefined) {
- doc.emptyPresentation = Docs.Create.PresDocument({ ...standardOps(), title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" });
- }
- if (doc.emptyCollection === undefined) {
- doc.emptyCollection = Docs.Create.FreeformDocument([], { ...standardOps(), title: "freeform", _width: 150, _height: 100 });
- }
- if (doc.emptyPane === undefined) {
- doc.emptyPane = Docs.Create.FreeformDocument([], { ...standardOps(), title: "Untitled Tab", _backgroundGridShow: true, _width: 500, _height: 800 });
- }
- if (doc.emptySlide === undefined) {
- doc.emptySlide = Docs.Create.TreeDocument([], {
- ...standardOps(), title: ComputedField.MakeFunction('self.text?.Text') as any, _viewType: CollectionViewType.Tree, treeViewHasOverlay: true, _fontSize: "20px", _autoHeight: true, "dragFactory-count": undefined,
- allowOverlayDrop: true, treeViewType: TreeViewType.outline, _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, backgroundColor: "white"
- });
- }
+ const emptyThings:{key:string, // the field name where the empty thing will be stored
+ opts:DocumentOptions, // the document options that are required for the empty thing
+ funcs?:{[key:string]: any}, // computed fields that are rquired for the empth thing
+ creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist
+ }[] = [
+ {key: "emptyPresentation", creator: Docs.Create.PresDocument, opts: { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias" as any, _chromeHidden: true, boxShadow: "0 0" }},
+ {key: "emptyCollection", creator: (opts) => Docs.Create.FreeformDocument([], opts), opts: { title: "freeform", _width: 150, _height: 100 }},
+ {key: "emptyPane", creator: (opts) => Docs.Create.FreeformDocument([], opts), opts : { title: "Untitled Tab", _backgroundGridShow: true, _width: 500, _height: 800 }},
+ {key: "emptySlide", creator: (opts) => Docs.Create.TreeDocument([], opts), funcs: {title: 'self.text?.Text'}, opts: {
+ _viewType: CollectionViewType.Tree, treeViewHasOverlay: true, _fontSize: "20px", _autoHeight: true,
+ "dragFactory-count": undefined, allowOverlayDrop: true, treeViewType: TreeViewType.outline, _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, backgroundColor: "white"
+ }},
+ {key: "emptyComparison", creator: Docs.Create.ComparisonDocument, opts: { title: "Comparer", _width: 300, _height: 300 }},
+ {key: "emptyScript", creator: (opts) => Docs.Create.ScriptingDocument(undefined, opts), opts: { title: "script", _width: 200, _height: 250, }},
+ {key: "emptyScreenshot", creator: Docs.Create.ScreenshotDocument, opts: { title: "empty screenshot", _width: 400, _height: 200 }},
+ {key: "emptyWebCam", creator: (opts) => Docs.Create.WebCamDocument("", opts), opts: { _width: 400, _height: 200, title: "recording", recording:true, system: true, cloneFieldFilter: new List<string>(["system"]) }},
+ {key: "emptyAudio", creator: (opts) => Docs.Create.AudioDocument(nullAudio, opts), opts: { title: "audio recording", x: 200, y: 200, _width: 200, _height: 100, }},
+ {key: "emptyNote", creator: (opts) => Docs.Create.TextDocument("", opts), opts: { title: "text note", _width: 200, _autoHeight: true }},
+ {key: "emptyButton", creator: Docs.Create.ButtonDocument, opts: { title: "Button", _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, }},
+ {key: "emptyWebpage", creator: (opts) => Docs.Create.WebDocument("http://www.bing.com/", opts), opts: { title: "webpage", _nativeWidth: 850, _height: 512, _width: 400, useCors: true, }},
+ {key: "emptyMap", creator: (opts) => Docs.Create.MapDocument([], opts), opts: { title: "map", _showSidebar: true, _width: 800, _height: 600, }}
+ ];
+
+ emptyThings.forEach(thing =>
+ this.AssignScripts(this.AssignOpts(DocCast(doc[thing.key]), {...standardOps(), ...thing.opts}) ?? (doc[thing.key] = thing.creator({...standardOps(), ...thing.opts})), thing.funcs))
+
if (doc.emptyHeader === undefined) {
const json = {
doc: {
@@ -242,196 +287,124 @@ export class CurrentUserUtils {
selection: { type: "text", anchor: 1, head: 1 },
storedMarks: []
};
- const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), {
- ...standardOps(), title: "text", _height: 70,
- _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true,
- }, "header");
const headerBtnHgt = 10;
- headerTemplate[DataSym].layout =
+ const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), {
+ ...standardOps(), title: "text", _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true,
+ layout:
"<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>" +
` <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight||0}px)'/>` +
" <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize||9}px' height='{(this._headerHeight||0)}px' background='{this._headerColor || MySharedDocs().userColor||`lightGray`}' />" +
` <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' background='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(0,this._height-30),this._headerHeight===0?50:0)) + (this._autoHeightMargins=this._headerHeight ? this._headerHeight+${headerBtnHgt}:0)’} >Metadata</HTMLdiv>` +
- "</HTMLdiv>";
+ "</HTMLdiv>"
+ }, "header");
// "<div style={'height:100%'}>" +
// " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._headerPointerEvents||`none`}' fontSize='{this._headerFontSize}px' height='{this._headerHeight}px' background='{this._headerColor||this.target.mySharedDocs.userColor}' />" +
// " <FormattedTextBox {...props} fieldKey={'text'} position='absolute' top='{(this._headerHeight)*scale}px' height='calc({100/scale}% - {this._headerHeight}px)'/>" +
// "</div>";
- (headerTemplate.proto as Doc).isTemplateDoc = makeTemplate(headerTemplate.proto as Doc, true, "headerView");
+ Doc.GetProto(headerTemplate).isTemplateDoc = makeTemplate(Doc.GetProto(headerTemplate), true, "headerView");
doc.emptyHeader = headerTemplate;
}
- if (doc.emptyComparison === undefined) {
- doc.emptyComparison = Docs.Create.ComparisonDocument({ ...standardOps(), title: "Comparer", _width: 300, _height: 300 });
- }
- if (doc.emptyScript === undefined) {
- doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { ...standardOps(), title: "script", _width: 200, _height: 250, });
- }
- if (doc.emptyScreenshot === undefined) {
- doc.emptyScreenshot = Docs.Create.ScreenshotDocument({ ...standardOps(), title: "empty screenshot", _width: 400, _height: 200 });
- }
- if (doc.emptyWall === undefined) {
- doc.emptyWall = Docs.Create.WebCamDocument("", { _width: 400, _height: 200, title: "recording", system: true, cloneFieldFilter: new List<string>(["system"]) });
- (doc.emptyWall as Doc).recording = true;
- }
- if (doc.emptyAudio === undefined) {
- doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { ...standardOps(), title: "audio recording", x: 200, y: 200, _width: 200, _height: 100, });
- }
- if (doc.emptyNote === undefined) {
- doc.emptyNote = Docs.Create.TextDocument("", { ...standardOps(), title: "text note", _width: 200, _autoHeight: true });
- }
- if (doc.emptyButton === undefined) {
- doc.emptyButton = Docs.Create.ButtonDocument({ ...standardOps(), title: "Button", _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, });
- }
- if (doc.emptyWebpage === undefined) {
- doc.emptyWebpage = Docs.Create.WebDocument("http://www.bing.com/", { ...standardOps(), title: "webpage", _nativeWidth: 850, _height: 512, _width: 400, useCors: true, });
- }
- if (doc.emptyMap === undefined) {
- doc.emptyMap = Docs.Create.MapDocument([], { ...standardOps(), title: "map", _showSidebar: true, _width: 800, _height: 600, });
- }
- if (doc.activeMobileMenu === undefined) {
- this.setupActiveMobileMenu(doc);
- }
+
return [
- { toolTip: "Tap to create a note in a new pane, drag for a note", title: "Note", icon: "sticky-note", click: 'openOnRight(copyDragFactory(this.clickFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyNote as Doc, noviceMode: true, clickFactory: doc.emptyNote as Doc, },
- { toolTip: "Tap to create a collection in a new pane, drag for a collection", title: "Col", icon: "folder", click: 'openOnRight(copyDragFactory(this.clickFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyCollection as Doc, noviceMode: true, clickFactory: doc.emptyPane as Doc, },
- { toolTip: "Tap to create a webpage in a new pane, drag for a webpage", title: "Web", icon: "globe-asia", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWebpage as Doc, noviceMode: true },
- { toolTip: "Tap to create a progressive slide", title: "Slide", icon: "file", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySlide as Doc },
- { toolTip: "Tap to create a comparison box in a new pane, drag for a comparison box", title: "Compare", icon: "columns", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyComparison as Doc, noviceMode: true },
- { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc },
- { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc },
- { toolTip: "Tap to create an audio recorder in a overlay pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openInOverlay(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
- { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc },
- // { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true },
- { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc },
- { toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc },
- { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc },
- { toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' },
- { toolTip: "Tap to create a map in the new pane, drag for a map", title: "Map", icon: "map-marker-alt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyMap as Doc, noviceMode: true }
- ];
-
+ { toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.clickFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, clickFactory: doc.emptyPane as Doc, },
+ { toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create an audio recorder", title: "Audio", icon: "microphone", dragFactory: doc.emptyAudio as Doc, scripts: {onClick: 'openInOverlay(copyDragFactory(this.dragFactory))',onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create a map", title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create a custom note", title: "Custom", icon: "window-maximize", dragFactory: doc.emptyHeader as Doc, scripts: {onClick: 'openOnRight(delegateDragFactory(this.dragFactory))', onDragStart: '{ return delegateDragFactory(this.dragFactory);}'}, },
+ { toolTip: "Tap or drag to create a progressive slide",title: "Slide", icon: "file", dragFactory: doc.emptySlide as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, funcs: { hidden: 'IsNoviceMode()'} },
+ { toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreenshot as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, funcs: { hidden: 'IsNoviceMode()'} },
+ { toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, funcs: { hidden: 'IsNoviceMode()'}},
+ { toolTip: "Tap or drag to create a button", title: "Button", icon: "bolt", dragFactory: doc.emptyButton as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, funcs:{ hidden: 'IsNoviceMode()'} },
+ { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, funcs: { hidden: 'IsNoviceMode()'}},
+ { toolTip: "Tap or drag to create a mobile view", title: "Phone", icon: "mobile", dragFactory: doc.activeMobileMenu as Doc, scripts: {onClick: 'openOnRight(Doc.UserDoc().activeMobileMenu)', onDragStart: 'this.dragFactory'}, funcs: {hidden: 'IsNoviceMode()'} },
+ { toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", scripts: {onClick: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' } },
+ // { toolTip: "Tap or drag to create a presentation", title: "Trails", icon: "pres-trail", dragFactory: doc.emptyPresentation as Doc,scripts: {onClick: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', onDragStart: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`}, funcs: {hidden: 'IsNoviceMode()'} },
+ ];
}
- // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
- static setupCreatorButtons(doc: Doc) {
- let alreadyCreatedButtons: string[] = [];
- const dragCreatorSet = Cast(doc.myItemCreators, Doc, null);
- if (dragCreatorSet) {
- alreadyCreatedButtons = DocListCast(dragCreatorSet.data).map(d => StrCast(d.title));
- }
- const buttons = CurrentUserUtils.creatorBtnDescriptors(doc).filter(d => !alreadyCreatedButtons?.includes(d.title));
- const creatorBtns = buttons.map(({ title, toolTip, icon, ignoreClick, drag, click, backgroundColor, dragFactory, noviceMode, clickFactory }) => Docs.Create.FontIconDocument({
- _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35,
- icon,
- title,
- toolTip,
- btnType: ButtonType.ToolButton,
- ignoreClick,
- _dropAction: "alias",
- onDragStart: drag ? ScriptField.MakeFunction(drag) : undefined,
- onClick: click ? ScriptField.MakeScript(click) : undefined,
- backgroundColor: backgroundColor ? backgroundColor : Colors.DARK_GRAY,
- color: Colors.WHITE,
- _hideContextMenu: true,
- _removeDropProperties: new List<string>(["_stayInCollection"]),
- _stayInCollection: true,
- dragFactory,
- clickFactory,
- hidden: !noviceMode ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined,
- system: true,
- }));
+ /// Initalizes the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
+ static setupCreatorButtons(doc: Doc, dragCreatorDoc?:Doc):Doc {
+ const creatorBtns = CurrentUserUtils.creatorBtnDescriptors(doc).map((reqdOpts) => {
+ const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(doc => doc.title === reqdOpts.title): undefined;
+ const opts:DocumentOptions = {...OmitKeys(reqdOpts, ["backgroundColor"]).omit,
+ _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35, _hideContextMenu: true, _stayInCollection: true, _dropAction: "alias",
+ btnType: ButtonType.ToolButton, backgroundColor: reqdOpts.backgroundColor ?? Colors.DARK_GRAY, color: Colors.WHITE, system: true,
+ _removeDropProperties: new List<string>(["_stayInCollection"]),
+ };
+ return this.AssignScripts(this.AssignOpts(btn, opts) ?? Docs.Create.FontIconDocument(opts), reqdOpts.scripts, reqdOpts.funcs);
+ });
- if (dragCreatorSet === undefined) {
- doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, {
- title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true,
- _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true, _forceActive: true,
- dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
- }));
- } else {
- creatorBtns.forEach(nb => Doc.AddDocToList(doc.myItemCreators as Doc, "data", nb));
- }
- return doc.myItemCreators as Doc;
+ const reqdOpts = {
+ title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, system: true,
+ _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true, _forceActive: true,
+ };
+ const reqdScripts = { dropConverter: "convertToButtons(dragData)" };
+ return this.AssignScripts(this.AssignOpts(dragCreatorDoc, reqdOpts, creatorBtns) ?? Docs.Create.MasonryDocument(creatorBtns, reqdOpts), reqdScripts);
}
- static menuBtnDescriptions(doc: Doc) {
- const badgeValue = ScriptField.MakeFunction("((len) => len ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length)")
+ /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents
+ static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] {
+ const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())";
return [
- { title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
- { title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
- { title: "Files", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' },
- { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
- { title: "Imports", target: Cast(doc.myImportDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
- { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
- { title: "Shared with me", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', badgeValue},
- { title: "Trails", target: Cast(doc.myTrails, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
- { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
+ { title: "Dashboards", target: CurrentUserUtils.MyDashboards, icon: "desktop", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "Search", target: CurrentUserUtils.MySearcher, icon: "search", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "Files", target: CurrentUserUtils.MyFilesystem, icon: "folder-open", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "Tools", target: CurrentUserUtils.MyTools, icon: "wrench", scripts:{onClick: 'selectMainMenu(self)'}, funcs: {hidden: "IsNoviceMode()"} },
+ { title: "Imports", target: CurrentUserUtils.MyImports, icon: "upload", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "Recently Closed", target: CurrentUserUtils.MyRecentlyClosed, icon: "archive", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "Shared with me", target: CurrentUserUtils.MySharedDocs, icon: "users", scripts:{onClick: 'selectMainMenu(self)'}, funcs:{badgeValue:badgeValue}},
+ { title: "Trails", target: CurrentUserUtils.MyTrails, icon: "pres-trail", scripts:{onClick: 'selectMainMenu(self)'} },
+ { title: "User Doc", target: CurrentUserUtils.MyUserDocView, icon: "address-card",scripts:{onClick: 'selectMainMenu(self)'}, funcs: {hidden: "IsNoviceMode()"} },
];
}
- static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
- if (doc.menuStack === undefined) {
- await this.setupLinkDocs(doc, linkDatabaseId);
- await this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing
- const menuBtns = CurrentUserUtils.menuBtnDescriptions(doc).map(({ title, target, icon, click, badgeValue, hidden }) =>
- Docs.Create.FontIconDocument({
- icon,
- btnType: ButtonType.MenuButton,
- _stayInCollection: true,
- _hideContextMenu: true,
- _chromeHidden: true,
- system: true,
- dontUndo: true,
- title,
- target,
- dontRegisterView: true,
- hidden: hidden ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined,
- _dropAction: "alias",
- _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
- _width: 60,
- _height: 60,
- badgeValue,
- onClick: ScriptField.MakeScript(click, { scriptContext: "any" })
- })
- );
-
- doc.searchBtn = menuBtns.find(btn => btn.title === "Search");
-
- doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
- title: "menuItemPanel",
- childDropAction: "alias",
- _chromeHidden: true,
- backgroundColor: Colors.DARK_GRAY,
- boxShadow: "rgba(0,0,0,0)",
- dontRegisterView: true,
- dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
- ignoreClick: true,
- _gridGap: 0,
- _yMargin: 0,
- _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, system: true
- }));
- }
- return doc.menuStack as Doc;
+ /// setup the left sidebar container and panels that can be displayed within it
+ static setupLeftSidebarPanel(doc: Doc, field="myLeftSidebarPanel") {
+ this.AssignOpts(DocCast(doc[field]), {}) ?? (doc[field] = ((doc:Doc) => {doc.system = true; return doc;})(new Doc()));
+ CurrentUserUtils.setupSearcher(doc, "mySearcher");
+ CurrentUserUtils.setupToolsBtnPanel(doc, "myTools");
+ CurrentUserUtils.setupImportSidebar(doc, "myImports");
+ CurrentUserUtils.setupDashboards(doc, "myDashboards");
+ CurrentUserUtils.setupTrails(doc, "myTrails");
+ CurrentUserUtils.setupFilesystem(doc, "myFilesystem");
+ CurrentUserUtils.setupRecentlyClosedDocs(doc, "myRecentlyClosed");
+ CurrentUserUtils.setupUserDocView(doc, "myUserDocView");
}
+ /// Initializes the left sidebar menu buttons and the panels they open up
+ static setupLeftSidebarMenu(doc: Doc, field="myLeftSidebarMenu") {
+ this.setupLeftSidebarPanel(doc); // the tools/panels opened up by the menu buttons
+ const myLeftSidebarMenu = DocCast(doc[field]);
+ const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, scripts, funcs }) => {
+ const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined;
+ const reqdBtnOpts:DocumentOptions = {
+ title, icon, target, btnType: ButtonType.MenuButton, system: true, dontUndo: true, dontRegisterView: true,
+ _width: 60, _height: 60, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, _dropAction: "alias",
+ _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
+ };
+ return this.AssignScripts(this.AssignOpts(btnDoc, reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), scripts, funcs);
+ });
- // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
- static setupActiveMobileMenu(doc: Doc) {
- if (doc.activeMobileMenu === undefined) {
- doc.activeMobileMenu = this.setupMobileMenu();
- }
- return doc.activeMobileMenu as Doc;
+ const reqdStackOpts:DocumentOptions ={
+ title: "menuItemPanel", childDropAction: "alias", backgroundColor: Colors.DARK_GRAY, boxShadow: "rgba(0,0,0,0)", dontRegisterView: true, ignoreClick: true,
+ _chromeHidden: true, _gridGap: 0, _yMargin: 0, _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, system: true
+ };
+ const reqdScripts = { dropConverter: "convertToButtons(dragData)" }
+ return this.AssignScripts(this.AssignOpts(myLeftSidebarMenu, reqdStackOpts, menuBtns) ?? (doc[field] = Docs.Create.StackingDocument(menuBtns, reqdStackOpts)), reqdScripts);
}
- // Sets up mobileMenu stacking document
- static setupMobileMenu() {
- const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), {
- _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeHidden: true,
- }));
- return menu;
+ // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
+ static setupActiveMobileMenu(doc: Doc, field="activeMobileMenu") {
+ const reqdOpts = { _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeHidden: true,};
+ this.AssignOpts(DocCast(doc[field]), reqdOpts, this.setupMobileButtons()) ?? (doc[field] = Docs.Create.StackingDocument(this.setupMobileButtons(), reqdOpts));
}
- // SEts up mobile buttons for inside mobile menu
+ // Sets up mobile buttons for inside mobile menu
static setupMobileButtons(doc?: Doc, buttons?: string[]) {
+ return [];
const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [
{ title: "DASHBOARDS", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Dashboards from your mobile, and navigate through all of your documents. " },
{ title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." },
@@ -533,375 +506,329 @@ export class CurrentUserUtils {
});
}
- static setupLibrary(userDoc: Doc) {
- return CurrentUserUtils.setupDashboards(userDoc);
- }
-
- // setup the Creator button which will display the creator panel. This panel will include the drag creators and the color picker.
- // when clicked, this panel will be displayed in the target container (ie, sidebarContainer)
- static setupToolsBtnPanel(doc: Doc) {
- // setup a masonry view of all he creators
- const creatorBtns = CurrentUserUtils.setupCreatorButtons(doc);
- const templateBtns = CurrentUserUtils.setupExperimentalTemplateButtons(doc);
-
- doc.myCreators = doc.myCreators ?? new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], {
- title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0, _fitWidth: true,
- _width: 500, _height: 300, ignoreClick: true, _lockedPosition: true, system: true, _chromeHidden: true,
- }));
- if (!DocListCast(doc.myCreators).includes(creatorBtns) || !DocListCast(doc.myCreators).includes(templateBtns)) Doc.GetProto(doc.myCreators as Doc).data = new List<Doc>([creatorBtns, templateBtns]);
-
- doc.myColorPicker = doc.myColorPicker ?? new PrefetchProxy(Docs.Create.ColorDocument({
- title: "color picker", _width: 220, _dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, _forceActive: true, _removeDropProperties: new List<string>(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true
- }));
-
- doc.myTools = doc.myTools ?? new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc], {
- title: "My Tools", _showTitle: "title", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true,
- system: true, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, boxShadow: "0 0",
- })) as any as Doc;
- if (!DocListCast(doc.myTools).includes(doc.myCreators as Doc)) Doc.GetProto(doc.myTools as Doc).data = new List<Doc>([doc.myCreators as Doc]);
- }
-
- static async setupDashboards(doc: Doc) {
- // setup dashboards library item
- await doc.myDashboards;
- if (doc.myDashboards === undefined) {
- const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`);
- const newDashboardButton: Doc = Docs.Create.FontIconDocument({ onClick: newDashboard, _forceActive: true, toolTip: "Create new dashboard", _stayInCollection: true, _hideContextMenu: true, title: "new dashboard", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
- doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "My Dashboards", _showTitle: "title", _height: 400, childHideLinkButton: true, freezeChildren: "remove|add",
- treeViewHideTitle: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newDashboardButton,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: TreeViewType.fileSystem, isFolder: true, system: true,
- explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files."
- }));
- const toggleDarkTheme = ScriptField.MakeScript(`this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`);
- const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
- const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
- const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`);
- const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
- const developerFilter = ScriptField.MakeFunction('!IsNoviceMode()');
- // (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
- // (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
- // (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "user-friends", "times"]);
- (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleDarkTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
- (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
- (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "chalkboard", "tv", "camera", "users", "times"]);
- (doc.myDashboards as any as Doc).childContextMenuFilters = new List<ScriptField>([undefined as any, developerFilter, developerFilter, developerFilter, undefined as any, undefined as any]);
- }
- return doc.myDashboards as any as Doc;
+ /// Search option on the left side button panel
+ static setupSearcher(doc: Doc, field:string) {
+ const reqdOpts:DocumentOptions = {
+ dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Search Panel", system: true, childDropAction: "alias",
+ _lockedPosition: true, _viewType: CollectionViewType.Schema, _searchDoc: true,
+ };
+ this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.SearchDocument(reqdOpts));
}
- static setupPresentations(doc: Doc) {
- if (doc.myTrails === undefined) {
- const newTrail = ScriptField.MakeScript(`createNewPresentation()`);
- const newTrailButton: Doc = Docs.Create.FontIconDocument({ onClick: newTrail, _forceActive: true, toolTip: "Create new trail", _stayInCollection: true, _hideContextMenu: true, title: "New trail", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
- doc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "My Trails", _showTitle: "title", _height: 100,
- treeViewHideTitle: true, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newTrailButton,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
- explainer: "All of the trails that you have created will appear here."
- }));
- (doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newTrail!]);
- (doc.myTrails as any as Doc).contextMenuLabels = new List<string>(["Create New Trail"]);
- (doc.myTrails as any as Doc).childContextMenuIcons = new List<string>(["plus"]);
- }
- return doc.myTrails as any as Doc;
+ /// Initializes the panel of draggable tools that is opened from the left sidebar.
+ static setupToolsBtnPanel(doc: Doc, field:string) {
+ const myTools = DocCast(doc[field]);
+ const creatorBtns = CurrentUserUtils.setupCreatorButtons(doc, DocListCast(myTools?.data)?.length ? DocListCast(myTools.data)[0]:undefined);
+ //const templateBtns = CurrentUserUtils.setupExperimentalTemplateButtons(doc);
+ const reqdToolOps:DocumentOptions = {
+ title: "My Tools", system: true, ignoreClick: true, boxShadow: "0 0",
+ _showTitle: "title", _width: 500, _yMargin: 20, _lockedPosition: true, _forceActive: true, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true,
+ };
+ this.AssignOpts(myTools, reqdToolOps, [creatorBtns, /*templateBtns*/]) ?? (doc[field] = Docs.Create.StackingDocument([creatorBtns, /*templateBtns*/], reqdToolOps));
}
- static async setupFilesystem(doc: Doc) {
- await doc.myFilesystem;
- if (doc.myFilesystem === undefined) {
- doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
- // doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
- const newFolder = ScriptField.MakeFunction(`makeTopLevelFolder()`, { scriptContext: "any" })!;
- const newFolderButton: Doc = Docs.Create.FontIconDocument({
- onClick: newFolder, _forceActive: true, toolTip: "Create new folder",
- _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30,
- buttonText: "New folder", icon: "folder-plus", system: true
- });
- doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileOrphans as Doc], {
- title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
- treeViewHideTitle: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- isFolder: true, treeViewType: TreeViewType.fileSystem, childHideLinkButton: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
- explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
- }));
- (doc.myFilesystem as any as Doc).contextMenuScripts = new List<ScriptField>([newFolder]);
- (doc.myFilesystem as any as Doc).contextMenuLabels = new List<string>(["Create new folder"]);
- (doc.myFilesystem as any as Doc).childContextMenuIcons = new List<string>(["plus"]);
+ /// initializes the left sidebar dashboard pane
+ static setupDashboards(doc: Doc, field:string) {
+ var myDashboards = DocCast(doc[field]);
+
+ const newDashboard = `createNewDashboard(Doc.UserDoc())`;
+ const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true,
+ title: "new dashboard", btnType: ButtonType.ClickButton, toolTip: "Create new dashboard", buttonText: "New trail", icon: "plus", system: true };
+ const reqdBtnScript = {onClick: newDashboard,}
+ const newDashboardButton = this.AssignScripts(this.AssignOpts(DocCast(myDashboards?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
+
+ const reqdOpts:DocumentOptions = {
+ title: "My Dashboards", childHideLinkButton: true, freezeChildren: "remove|add", treeViewHideTitle: true, boxShadow: "0 0", childDontRegisterViews: true,
+ targetDropAction: "same", treeViewType: TreeViewType.fileSystem, isFolder: true, system: true, treeViewTruncateTitleWidth: 150, ignoreClick: true,
+ buttonMenu: true, buttonMenuDoc: newDashboardButton, childDropAction: "alias",
+ _showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true,
+ contextMenuLabels: new List<string>(["Create New Dashboard"]),
+ contextMenuIcons: new List<string>(["plus"]),
+ childContextMenuLabels: new List<string>(["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]),// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters
+ childContextMenuIcons: new List<string>(["chalkboard", "tv", "camera", "users", "times"]), // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters
+ explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files."
+ };
+ myDashboards = this.AssignOpts(myDashboards, reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([], reqdOpts));
+ const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`;
+ const contextMenuScripts = [newDashboard];
+ const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters
+ const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts
+ if (Cast(myDashboards.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) {
+ myDashboards.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
+ }
+ if (Cast(myDashboards.childContextMenuScripts, listSpec(ScriptField), null)?.length !== childContextMenuScripts.length) {
+ myDashboards.childContextMenuScripts = new List<ScriptField>(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
+ }
+ if (Cast(myDashboards.childContextMenuFilters, listSpec(ScriptField), null)?.length !== childContextMenuFilters.length) {
+ myDashboards.childContextMenuFilters = new List<ScriptField>(childContextMenuFilters.map(script => !script ? script: ScriptField.MakeFunction(script)!));
}
- return doc.myFilesystem as any as Doc;
}
- static setupRecentlyClosedDocs(doc: Doc) {
- if (doc.myRecentlyClosedDocs === undefined) {
- const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
- const clearDocsButton: Doc = Docs.Create.FontIconDocument({ onClick: clearAll, _forceActive: true, toolTip: "Empty recently closed", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "Empty", icon: "trash", system: true });
- doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "My Recently Closed", _showTitle: "title", buttonMenu: true, buttonMenuDoc: clearDocsButton, childHideLinkButton: true,
- treeViewHideTitle: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
- explainer: "Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list."
-
- }));
- (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
- (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Empty recently closed"]);
- (doc.myRecentlyClosedDocs as any as Doc).contextMenuIcons = new List<string>(["trash"]);
-
+ /// initializes the left sidebar Trails pane
+ static setupTrails(doc: Doc, field:string) {
+ var myTrails = DocCast(doc[field]);
+ const reqdBtnOpts:DocumentOptions = { _forceActive: true, _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true,
+ title: "New trail", toolTip: "Create new trail", btnType: ButtonType.ClickButton, buttonText: "New trail", icon: "plus", system: true };
+ const reqdBtnScript = {onClick: `createNewPresentation()`};
+ const newTrailButton = this.AssignScripts(this.AssignOpts(DocCast(myTrails?.buttonMenuDoc), reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript);
+
+ const reqdOpts:DocumentOptions = {
+ title: "My Trails", _showTitle: "title", _height: 100,
+ treeViewHideTitle: true, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
+ treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newTrailButton,
+ contextMenuIcons: new List<string>(["plus"]),
+ contextMenuLabels: new List<string>(["Create New Trail"]),
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
+ explainer: "All of the trails that you have created will appear here."
+ };
+ myTrails = this.AssignOpts(myTrails, reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([],reqdOpts ));
+ const contextMenuScripts = [reqdBtnScript.onClick];
+ if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) {
+ myTrails.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
}
}
- static setupFilterDocs(doc: Doc) {
- // setup Filter item
- if (doc.currentFilter === undefined) {
- doc.currentFilter = Docs.Create.FilterDocument({
- title: "Unnamed Filter", _height: 150,
- treeViewHideTitle: true, _xPadding: 5, _yPadding: 5, _gridGap: 5, _forceActive: true, childDropAction: "none",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true, _autoHeight: true, _fitWidth: true
- });
- const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
- (doc.currentFilter as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
- (doc.currentFilter as Doc).contextMenuLabels = new List<string>(["Clear All"]);
- (doc.currentFilter as Doc).filterBoolean = "AND";
+ /// initializes the left sidebar File system pane
+ static setupFilesystem(doc: Doc, field:string) {
+ var myFilesystem = DocCast(doc[field]);
+ const reqdOrphansOpts:DocumentOptions = { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true };
+ this.AssignOpts(DocCast(doc.myFileOrphans), reqdOrphansOpts) ?? (doc.myFileOrphans = Docs.Create.TreeDocument([], reqdOrphansOpts));
+
+ const newFolder = `makeTopLevelFolder()`;
+ const newFolderOpts: DocumentOptions = {
+ _forceActive: true, _stayInCollection: true, _hideContextMenu: true, _width: 30, _height: 30,
+ title: "New folder", btnType: ButtonType.ClickButton, toolTip: "Create new folder", buttonText: "New folder", icon: "folder-plus", system: true
+ };
+ const newFolderScript = { onClick: newFolder};
+ const newFolderButton = this.AssignScripts(this.AssignOpts(DocCast(myFilesystem?.buttonMenuDoc), newFolderOpts) ?? Docs.Create.FontIconDocument(newFolderOpts), newFolderScript);
+
+ const reqdOpts:DocumentOptions = { _showTitle: "title", _height: 100, _gridGap: 5, _forceActive: true, _lockedPosition: true,
+ title: "My Documents", buttonMenu: true, buttonMenuDoc: newFolderButton, treeViewHideTitle: true, targetDropAction: "proto", system: true,
+ isFolder: true, treeViewType: TreeViewType.fileSystem, childHideLinkButton: true, boxShadow: "0 0", childDontRegisterViews: true,
+ treeViewTruncateTitleWidth: 150, ignoreClick: true, childDropAction: "alias",
+ childContextMenuLabels: new List<string>(["Create new folder"]),
+ childContextMenuIcons: new List<string>(["plus"]),
+ explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
+ };
+ myFilesystem = this.AssignOpts(myFilesystem, reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([DocCast(doc.myFileOrphans)], reqdOpts));
+ const childContextMenuScripts = [newFolder];
+ if (Cast(myFilesystem.childContextMenuScripts, listSpec(ScriptField), null)?.length !== childContextMenuScripts.length) {
+ myFilesystem.childContextMenuScripts = new List<ScriptField>(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
}
}
- static setupUserDoc(doc: Doc) {
- if (doc.myUserDoc === undefined) {
- doc.treeViewOpen = true;
- doc.treeViewExpandedView = "fields";
- doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], {
- treeViewHideTitle: true, _gridGap: 5, _forceActive: true, title: "My UserDoc", _showTitle: "title",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
- })) as any as Doc;
+ /// initializes the panel displaying docs that have been recently closed
+ static setupRecentlyClosedDocs(doc: Doc, field:string) {
+ const reqdOpts:DocumentOptions = { _showTitle: "title", _lockedPosition: true, _gridGap: 5, _forceActive: true,
+ title: "My Recently Closed", buttonMenu: true, childHideLinkButton: true, treeViewHideTitle: true, childDropAction: "alias", system: true,
+ treeViewTruncateTitleWidth: 150, ignoreClick: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same",
+ contextMenuLabels: new List<string>(["Empty recently closed"]),
+ contextMenuIcons:new List<string>(["trash"]),
+ explainer: "Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list."
+ };
+ const recentlyClosed = this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([], reqdOpts));
+
+ const clearAll = (target:string) => `getProto(${target}).data = new List([])`;
+ const clearBtnsOpts:DocumentOptions = { _width: 30, _height: 30, _forceActive: true, _stayInCollection: true, _hideContextMenu: true,
+ title: "Empty", target: recentlyClosed, btnType: ButtonType.ClickButton, buttonText: "Empty", icon: "trash", system: true,
+ toolTip: "Empty recently closed",};
+ const clearBtnsScripts = {onClick: clearAll("self.target")}
+ const clearDocsButton = this.AssignScripts(
+ this.AssignOpts(DocCast(recentlyClosed?.clearDocsBtn), clearBtnsOpts) ?? (recentlyClosed.clearDocsBtn = Docs.Create.FontIconDocument(clearBtnsOpts)),
+ clearBtnsScripts);
+
+ if (recentlyClosed.buttonMenuDoc !== clearDocsButton) Doc.GetProto(recentlyClosed).buttonMenuDoc = clearDocsButton;
+
+ if (!Cast(recentlyClosed.contextMenuScripts, listSpec(ScriptField),null)?.find((script) => script.script.originalScript === clearAll("self"))) {
+ recentlyClosed.contextMenuScripts = new List<ScriptField>([ScriptField.MakeScript(clearAll("self"))!])
}
}
- static setupSidebarContainer(doc: Doc) {
- if (doc.sidebar === undefined) {
- const sidebarContainer = new Doc();
- sidebarContainer.system = true;
- doc.sidebar = new PrefetchProxy(sidebarContainer);
- }
- return doc.sidebar as Doc;
+ /// creates a new, empty filter doc
+ static createFilterDoc() {
+ const clearAll = `getProto(self).data = new List([])`;
+ const reqdOpts:DocumentOptions = {
+ _lockedPosition: true, _autoHeight: true, _fitWidth: true, _height: 150, _xPadding: 5, _yPadding: 5, _gridGap: 5, _forceActive: true,
+ title: "Unnamed Filter", filterBoolean: "AND", boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", ignoreClick: true, system: true,
+ childDropAction: "none", treeViewHideTitle: true, treeViewTruncateTitleWidth: 150,
+ childContextMenuLabels: new List<string>(["Clear All"]),
+ childContextMenuScripts: new List<ScriptField>([ScriptField.MakeFunction(clearAll)!]),
+ };
+ return Docs.Create.FilterDocument(reqdOpts);
}
- // setup the list of sidebar mode buttons which determine what is displayed in the sidebar
- static async setupSidebarButtons(doc: Doc) {
- CurrentUserUtils.setupSidebarContainer(doc);
- CurrentUserUtils.setupToolsBtnPanel(doc);
- CurrentUserUtils.setupImportSidebar(doc);
- CurrentUserUtils.setupDashboards(doc);
- CurrentUserUtils.setupPresentations(doc);
- CurrentUserUtils.setupFilesystem(doc);
- CurrentUserUtils.setupRecentlyClosedDocs(doc);
- CurrentUserUtils.setupUserDoc(doc);
+ /// initializes the left sidebar panel view of the UserDoc
+ static setupUserDocView(doc: Doc, field:string) {
+ const reqdOpts:DocumentOptions = {
+ _lockedPosition: true, _gridGap: 5, _forceActive: true, title: Doc.CurrentUserEmail +"-view",
+ boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", ignoreClick: true, system: true,
+ treeViewHideTitle: true, treeViewTruncateTitleWidth: 150
+ };
+ if (!doc[field]) this.AssignOpts(doc, {treeViewOpen: true, treeViewExpandedView: "fields" })
+ this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.TreeDocument([doc], reqdOpts));
}
- static linearButtonList = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, {
- ...opts, _gridGap: 0, _xMargin: 5, _yMargin: 5, boxShadow: "0 0", _forceActive: true,
+ static linearButtonList = (title: string, opts: DocumentOptions, docs: Doc[]) => Docs.Create.LinearDocument(docs, {
+ title, ...opts, _gridGap: 0, _xMargin: 5, _yMargin: 5, boxShadow: "0 0", _forceActive: true,
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
_lockedPosition: true, system: true, flexDirection: "row"
- })) as any as Doc
+ })
- static createToolButton = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
+ static createToolButton = (opts: DocumentOptions) => Docs.Create.FontIconDocument({
btnType: ButtonType.ToolButton, _forceActive: true, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["_dropAction", "_hideContextMenu", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true, ...opts,
- })) as any as Doc
-
- /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
- static setupDockedButtons(doc: Doc) {
- if (doc.dockedBtns === undefined) {
- const dockBtn = (opts: DocumentOptions) => CurrentUserUtils.createToolButton({ _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, ...opts });
- const btnDescs = [
- { title: "undo", opts: () => ({ icon: "undo-alt", onClick: ScriptField.MakeScript("undo()"), toolTip: "Click to undo" }) },
- { title: "redo", opts: () => ({ icon: "redo-alt", onClick: ScriptField.MakeScript("redo()"), toolTip: "Click to redo" }) }
- ];
- doc.dockedBtns = CurrentUserUtils.linearButtonList({
- title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true,
- childDontRegisterViews: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true
- }, btnDescs.map(desc => doc[`dockedBtn-${desc.title}`] as Doc ?? (doc[`dockedBtn-${desc.title}`] = dockBtn({ title: desc.title, ...desc.opts() }))));
+ })
+
+ /// initializes the required buttons in the expanding button menu at the bottom of the Dash window
+ static setupDockedButtons(doc: Doc, field="myDockedBtns") {
+ const dockedBtns = DocCast(doc[field]);
+ const dockBtn = (title:string, onClick: string, opts: DocumentOptions) => {
+ const btn = this.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === title), opts) ??
+ CurrentUserUtils.createToolButton({title, ...opts});
+ this.AssignScripts(btn, {onClick})
+ return btn;
}
+ const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet
+ { title: "undo", click: "undo()", opts: { icon: "undo-alt", toolTip: "Click to undo" }},
+ { title: "redo", click:"redo()", opts: { icon: "redo-alt", toolTip: "Click to redo" }}
+ ];
+ const btns = btnDescs.map(desc => dockBtn(desc.title, desc.click, {_width: 30, _height: 30, dontUndo: true, _stayInCollection: true, ...desc.opts}));
+ const dockBtnsReqdOpts = {
+ title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true,
+ childDontRegisterViews: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true
+ };
+ reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true });
+ reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
+ return this.AssignOpts(dockedBtns, dockBtnsReqdOpts, btns) ?? (doc[field] = CurrentUserUtils.linearButtonList("dockedBtns", dockBtnsReqdOpts, btns));
}
- static textTools(doc: Doc) {
- const tools: Button[] =
- [
- {
- title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true,
- list: ["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia",
- "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"],
- script: 'setFont(value, _readOnly_)'
- },
- { title: "Size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions, ignoreClick: true, script: 'setFontSize(value, _readOnly_)' },
- { title: "Color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, script: 'setFontColor(value, _readOnly_)' },
- { title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", click: 'toggleBold(_readOnly_)' },
- { title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", click: 'toggleItalic(_readOnly_)' },
- { title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", click: 'toggleUnderline(_readOnly_)' },
- { title: "Bullets", toolTip: "Bullet List", btnType: ButtonType.ToggleButton, icon: "list", click: 'setBulletList("bullet", _readOnly_)' },
- { title: "#", toolTip: "Number List", btnType: ButtonType.ToggleButton, icon: "list-ol", click: 'setBulletList("decimal", _readOnly_)' },
-
- // { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", click: 'toggleStrikethrough()'},
- // { title: "Superscript", tooltip: "Superscript", btnType: ButtonType.ToggleButton, icon: "superscript", click: 'toggleSuperscript()'},
- // { title: "Subscript", tooltip: "Subscript", btnType: ButtonType.ToggleButton, icon: "subscript", click: 'toggleSubscript()'},
- { title: "Left", toolTip: "Left align", btnType: ButtonType.ToggleButton, icon: "align-left", click: 'setAlignment("left", _readOnly_)' },
- { title: "Center", toolTip: "Center align", btnType: ButtonType.ToggleButton, icon: "align-center", click: 'setAlignment("center", _readOnly_)' },
- { title: "Right", toolTip: "Right align", btnType: ButtonType.ToggleButton, icon: "align-right", click: 'setAlignment("right", _readOnly_)' },
- { title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", click: 'toggleNoAutoLinkAnchor(_readOnly_)' },
- ];
- return tools;
+ static textTools():Button[] {
+ return [
+ {
+ title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true,
+ btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]),
+ scripts :{script : 'setFont(value, _readOnly_)'}
+ },
+ { title: "Size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions, ignoreClick: true, scripts: {script: '{ return setFontSize(value, _readOnly_);}'} },
+ { title: "Color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, scripts:{script: '{ return setFontColor(value, _readOnly_); }'}},
+ { title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", scripts: {onClick: '{ return toggleBold(_readOnly_); }'} },
+ { title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", scripts: {onClick: '{ return toggleItalic(_readOnly_);}'} },
+ { title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline",scripts: {onClick:'{ return toggleUnderline(_readOnly_);}'} },
+ { title: "Bullets", toolTip: "Bullet List", btnType: ButtonType.ToggleButton, icon: "list", scripts: {onClick: '{ return setBulletList("bullet", _readOnly_);}'} },
+ { title: "#", toolTip: "Number List", btnType: ButtonType.ToggleButton, icon: "list-ol", scripts: {onClick: '{ return setBulletList("decimal", _readOnly_);}'} },
+
+ // { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
+ // { title: "Superscript", tooltip: "Superscript", btnType: ButtonType.ToggleButton, icon: "superscript", scripts: {onClick:: 'toggleSuperscript()'}},
+ // { title: "Subscript", tooltip: "Subscript", btnType: ButtonType.ToggleButton, icon: "subscript", scripts: {onClick:: 'toggleSubscript()'}},
+ { title: "Left", toolTip: "Left align", btnType: ButtonType.ToggleButton, icon: "align-left", scripts: {onClick:'{ return setAlignment("left", _readOnly_);}' }},
+ { title: "Center", toolTip: "Center align", btnType: ButtonType.ToggleButton, icon: "align-center", scripts: {onClick:'{ return setAlignment("center", _readOnly_);}'} },
+ { title: "Right", toolTip: "Right align", btnType: ButtonType.ToggleButton, icon: "align-right", scripts: {onClick:'{ return setAlignment("right", _readOnly_);}'} },
+ { title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", scripts: {onClick:'{ return toggleNoAutoLinkAnchor(_readOnly_);}'}},
+ ];
}
- static inkTools(doc: Doc) {
- const tools: Button[] = [
- { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen-nib", click: 'setActiveInkTool("pen", _readOnly_)' },
- { title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("write", _readOnly_)' },
- { title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", click: 'setActiveInkTool("eraser", _readOnly_)' },
- // { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", click: 'setActiveInkTool("highlighter")' },
- { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", click: 'setActiveInkTool("circle", _readOnly_)' },
+ static inkTools():Button[] {
+ return [
+ { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen-nib", scripts:{onClick:'{ return setActiveInkTool("pen", _readOnly_);}' }},
+ { title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", scripts:{onClick:'{ return setActiveInkTool("write", _readOnly_);}'} },
+ { title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", scripts:{onClick:'{ return setActiveInkTool("eraser", _readOnly_);}' }},
+ // { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", scripts:{onClick: 'setActiveInkTool("highlighter")'} },
+ { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", scripts:{onClick:'{ return setActiveInkTool("circle", _readOnly_);}'} },
// { title: "Square", toolTip: "Square (Ctrl+Shift+S)", btnType: ButtonType.ToggleButton, icon: "square", click: 'setActiveInkTool("square")' },
- { title: "Line", toolTip: "Line (Ctrl+Shift+L)", btnType: ButtonType.ToggleButton, icon: "minus", click: 'setActiveInkTool("line", _readOnly_)' },
- { title: "Fill", toolTip: "Fill color", btnType: ButtonType.ColorButton, ignoreClick: true, icon: "fill-drip", script: "setFillColor(value, _readOnly_)" },
- { title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberButton, numBtnType: NumButtonType.Slider, numBtnMin: 1, ignoreClick: true, script: 'setStrokeWidth(value, _readOnly_)' },
- { title: "Color", toolTip: "Stroke color", btnType: ButtonType.ColorButton, icon: "pen", ignoreClick: true, script: 'setStrokeColor(value, _readOnly_)' },
+ { title: "Line", toolTip: "Line (Ctrl+Shift+L)", btnType: ButtonType.ToggleButton, icon: "minus", scripts:{onClick: '{ return setActiveInkTool("line", _readOnly_);}' }},
+ { title: "Fill", toolTip: "Fill color", btnType: ButtonType.ColorButton, ignoreClick: true, icon: "fill-drip", scripts: {script: "{ return setFillColor(value, _readOnly_);}"} },
+ { title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberButton, numBtnType: NumButtonType.Slider, numBtnMin: 1, ignoreClick: true, scripts: {script: '{ return setStrokeWidth(value, _readOnly_);}'} },
+ { title: "Color", toolTip: "Stroke color", btnType: ButtonType.ColorButton, icon: "pen", ignoreClick: true, scripts: {script: '{ return setStrokeColor(value, _readOnly_);}'} },
];
- return tools;
}
- static schemaTools(doc: Doc) {
- const tools: Button[] =
- [{ title: "Show preview", toolTip: "Show preview of selected document", btnType: ButtonType.ToggleButton, buttonText: "Show Preview", icon: "eye", click: 'toggleSchemaPreview(_readOnly_)', }];
- return tools;
+ static schemaTools():Button[] {
+ return [{ title: "Show preview", toolTip: "Show preview of selected document", btnType: ButtonType.ToggleButton, buttonText: "Show Preview", icon: "eye", scripts:{onClick:'toggleSchemaPreview(_readOnly_)'}, }];
}
- static webTools(doc: Doc) {
- const tools: Button[] =
- [
- { title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", click: 'webBack(_readOnly_)' },
- { title: "Forward", toolTip: "Go forward", btnType: ButtonType.ClickButton, icon: "arrow-right", click: 'webForward(_readOnly_)' },
- //{ title: "Reload", toolTip: "Reload webpage", btnType: ButtonType.ClickButton, icon: "redo-alt", click: 'webReload()' },
- { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, script: 'webSetURL(value, _readOnly_)' },
- ];
-
- return tools;
+ static webTools() {
+ return [
+ { title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", click: 'webBack(_readOnly_)' },
+ { title: "Forward", toolTip: "Go forward", btnType: ButtonType.ClickButton, icon: "arrow-right", click: 'webForward(_readOnly_)' },
+ //{ title: "Reload", toolTip: "Reload webpage", btnType: ButtonType.ClickButton, icon: "redo-alt", click: 'webReload()' },
+ { title: "URL", toolTip: "URL", width: 250, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, script: 'webSetURL(value, _readOnly_)' },
+ ];
}
- static contextMenuTools(doc: Doc) {
+ static contextMenuTools():Button[] {
return [
{
title: "Perspective", toolTip: "View", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true,
- list: [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree,
- CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn,
- CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel,
- CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
- CollectionViewType.Grid],
- script: 'setView(value, _readOnly_)',
+ btnList: new List<string>([CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree,
+ CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn,
+ CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel,
+ CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
+ CollectionViewType.Grid]),
+ scripts: {script: 'setView(value, _readOnly_)'},
}, // Always show
- { title: "Back", toolTip: "Prev Animation Frame", width: 20, btnType: ButtonType.ClickButton, click: 'prevKeyFrame(_readOnly_)', icon: "chevron-left", hidden: 'IsNoviceMode()' },
- { title: "Fwd", toolTip: "Next Animation Frame", width: 20, btnType: ButtonType.ClickButton, click: 'nextKeyFrame(_readOnly_)', icon: "chevron-right", hidden: 'IsNoviceMode()' },
- { title: "Fill", toolTip: "Background Fill Color", width: 20, btnType: ButtonType.ColorButton, ignoreClick: true, icon: "fill-drip", script: "setBackgroundColor(value, _readOnly_)", hidden: 'selectedDocumentType()' }, // Only when a document is selected
- { title: "Header", toolTip: "Header Color", btnType: ButtonType.ColorButton, ignoreClick: true, icon: "heading", script: "setHeaderColor(value, _readOnly_)", hidden: 'selectedDocumentType()', },
- { title: "Overlay", toolTip: "Overlay", btnType: ButtonType.ToggleButton, icon: "layer-group", click: 'toggleOverlay(_readOnly_)', hidden: 'selectedDocumentType(undefined, "freeform", true)' }, // Only when floating document is selected in freeform
+ { title: "Back", toolTip: "Prev Animation Frame", width: 20, btnType: ButtonType.ClickButton,icon: "chevron-left", scripts:{onClick: 'prevKeyFrame(_readOnly_)'}, funcs: {hidden: 'IsNoviceMode()'} },
+ { title: "Fwd", toolTip: "Next Animation Frame", width: 20, btnType: ButtonType.ClickButton, icon: "chevron-right", scripts:{onClick: 'nextKeyFrame(_readOnly_)'}, funcs: {hidden: 'IsNoviceMode()'}},
+ { title: "Fill", toolTip: "Background Fill Color", width: 20, btnType: ButtonType.ColorButton, ignoreClick: true, icon: "fill-drip", scripts: { script: "setBackgroundColor(value, _readOnly_)"}, funcs:{ hidden: 'selectedDocumentType()' }}, // Only when a document is selected
+ { title: "Header", toolTip: "Header Color", btnType: ButtonType.ColorButton, ignoreClick: true, icon: "heading", scripts: {script: "setHeaderColor(value, _readOnly_)"}, funcs : {hidden: 'selectedDocumentType()'} },
+ { title: "Overlay", toolTip: "Overlay", btnType: ButtonType.ToggleButton, icon: "layer-group", scripts: {onClick : 'toggleOverlay(_readOnly_)'}, funcs: {hidden: 'selectedDocumentType(undefined, "freeform", true)'} }, // Only when floating document is selected in freeform
// { title: "Alias", btnType: ButtonType.ClickButton, icon: "copy", hidden: 'selectedDocumentType()' }, // Only when a document is selected
- { title: "Text", type: "textTools", subMenu: CurrentUserUtils.textTools(doc), expanded: 'selectedDocumentType("rtf")' }, // Always available
- { title: "Ink", type: "inkTools", subMenu: CurrentUserUtils.inkTools(doc), expanded: 'selectedDocumentType("ink")' }, // Always available
- { title: "Web", type: "webTools", subMenu: CurrentUserUtils.webTools(doc), hidden: 'selectedDocumentType("web")' }, // Only when Web is selected
- { title: "Schema", type: "schemaTools", subMenu: CurrentUserUtils.schemaTools(doc), hidden: 'selectedDocumentType(undefined, "schema")' } // Only when Schema is selected
+ { title: "Text", icon: "text", subMenu: CurrentUserUtils.textTools(), funcs: { linearViewIsExpanded: `selectedDocumentType("${DocumentType.RTF}")`} }, // Always available
+ { title: "Ink", icon: "ink", subMenu: CurrentUserUtils.inkTools(), funcs: { linearViewIsExpanded: `selectedDocumentType("${DocumentType.INK}")`} }, // Always available
+ { title: "Web", icon: "web", subMenu: CurrentUserUtils.webTools(), funcs: { linearViewIsExpanded: `selectedDocumentType("${DocumentType.WEB}")`, hidden: `!selectedDocumentType("${DocumentType.WEB}")`} }, // Only when Web is selected
+ { title: "Schema", icon: "schema", subMenu: CurrentUserUtils.schemaTools(), funcs: { linearViewIsExpanded: `selectedDocumentType(undefined, "${CollectionViewType.Schema}")`, hidden: `!selectedDocumentType(undefined, "${CollectionViewType.Schema}")`} } // Only when Schema is selected
];
}
- // Sets up the default context menu buttons
- static setupContextMenuButtons(doc: Doc) {
- const btnFunc = (params: Button) => Docs.Create.FontIconDocument({
- title: params.title, icon: params.icon, toolTip: params.toolTip, color: Colors.WHITE, system: true, dontUndo: true, ignoreClick: params.ignoreClick,
+ /// initializes a context menu button for the top bar context menu
+ static setupContextMenuButton(params:Button, btnDoc?:Doc) {
+ const reqdOpts:DocumentOptions = {
+ title: params.title, btnType: params.btnType, icon: params.icon, toolTip: params.toolTip, ignoreClick: params.ignoreClick,
+ numBtnType: params.numBtnType, numBtnMin: params.numBtnMin, numBtnMax: params.numBtnMax,_nativeHeight: 30, btnList: params.btnList,
+ backgroundColor: params.scripts?.onClick ? undefined: "transparent", /// a bit hacky. if an onClick is specified, then we assume we assume a toggle use onClick to get the backgroundColor (see below). Otherwise, assume a transparent background
_nativeWidth: params.width ? params.width : 30,
- _nativeHeight: 30,
_width: params.width ? params.width : 30,
_height: 30,
- btnType: params.btnType,
- numBtnType: params.numBtnType, numBtnMin: params.numBtnMin, numBtnMax: params.numBtnMax,
- btnList: new List<string>(params.list),
+ color: Colors.WHITE, system: true, dontUndo: true,
_stayInCollection: true,
_hideContextMenu: true,
_lockedPosition: true,
_dropAction: "alias",
_removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
- script: params.script ? ScriptField.MakeScript(params.script, { value: "any" }) : undefined,
- backgroundColor: params.click ? ComputedField.MakeFunction(params.click) as any : "transparent",
- onClick: params.click ? ScriptField.MakeScript(params.click, { scriptContext: "any" }, { _readOnly_: false }) : undefined,
- hidden: params.hidden ? ComputedField.MakeFunction(params.hidden) as any : undefined,
- });
- if (doc.contextMenuBtns === undefined) {
- doc.contextMenuBtns = CurrentUserUtils.linearButtonList(
- { title: "menu buttons", flexGap: 0, childDontRegisterViews: true, linearViewIsExpanded: true, ignoreClick: true, linearViewExpandable: false, _height: 35 },
- CurrentUserUtils.contextMenuTools(doc).map(params =>
- !params.subMenu ?
- btnFunc(params) :
- CurrentUserUtils.linearButtonList({
- title: params.title,
- childDontRegisterViews: true,
- linearViewSubMenu: true, flexGap: 0, ignoreClick: true,
- linearViewExpandable: true, icon: params.title, _height: 30,
- linearViewIsExpanded: params.expanded ? !(ComputedField.MakeFunction(params.expanded) as any) : undefined,
- hidden: params.hidden ? ComputedField.MakeFunction(params.hidden) as any : undefined,
- }, params.subMenu.map(btnFunc))));
- } else {
- const menuBtnList = DocListCast((doc.contextMenuBtns as Doc).data);
- let prev = "";
- CurrentUserUtils.contextMenuTools(doc).forEach(params => {
- const menuBtnDoc = menuBtnList.find(doc => doc.title === params.title);
- if (!menuBtnDoc) {
- const newMenuBtnDoc = !params.subMenu ?
- btnFunc(params) :
- CurrentUserUtils.linearButtonList({
- title: params.title,
- childDontRegisterViews: true,
- linearViewSubMenu: true, flexGap: 0, ignoreClick: true,
- linearViewExpandable: true, icon: params.title, _height: 30,
- linearViewIsExpanded: params.expanded ? !(ComputedField.MakeFunction(params.expanded) as any) : undefined,
- hidden: params.hidden ? ComputedField.MakeFunction(params.hidden) as any : undefined,
- }, params.subMenu.map(btnFunc));
- const after = menuBtnList.find(doc => doc.title === prev);
- Doc.AddDocToList(doc.contextMenuBtns as Doc, "data", newMenuBtnDoc, after, false, !after);
- }
- const subMenuBtnList = menuBtnDoc?.data ? DocListCast(menuBtnDoc.data) : undefined;
- if (menuBtnDoc && subMenuBtnList && params.subMenu && DocListCast(doc.data).length !== subMenuBtnList.length) {
- let prevSub = "";
- params.subMenu.forEach(sub => {
- if (!subMenuBtnList.find(doc => doc.title === sub.title)) {
- const newSubMenuBtnDoc = btnFunc(sub);
- const after = subMenuBtnList.find(doc => doc.title === prevSub);
- Doc.AddDocToList(menuBtnDoc, "data", newSubMenuBtnDoc, after, false, !prevSub);
- }
- prevSub = params.title;
- });
- }
- prev = params.title;
- });
+ };
+ const reqdFuncs:{[key:string]:any} = {
+ ...params.funcs,
+ backgroundColor: params.scripts?.onClick /// a bit hacky. if onClick is set, then we assume it returns a color value when queried with '_readOnly_'. This will be true for toggle buttons, but not generally
}
+ return this.AssignScripts(this.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs);
}
- // sets up the default set of documents to be shown in the Overlay layer
- static setupOverlays(doc: Doc) {
- if (doc.myOverlayDocs === undefined) {
- doc.myOverlayDocs = new PrefetchProxy(Docs.Create.FreeformDocument([], { title: "overlay documents", backgroundColor: "#aca3a6", system: true }));
- }
+ /// Initializes all the default buttons for the top bar context menu
+ static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") {
+ const ctxtMenuBtnsDoc = DocCast(doc[field]);
+ const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => {
+ const menuBtnDoc = DocListCast(ctxtMenuBtnsDoc?.data).find(doc => doc.title === params.title);
+ if (!params.subMenu) {
+ return this.setupContextMenuButton(params, menuBtnDoc);
+ } else {
+ const reqdSubMenuOpts = { title: params.title, icon: params.icon, childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: true,
+ linearViewSubMenu: true, linearViewExpandable: true, };
+ const reqdSubMenuFuncs:{[key:string]:any} = { ...params.funcs};
+ return this.AssignScripts(this.AssignOpts(menuBtnDoc, reqdSubMenuOpts) ??
+ CurrentUserUtils.linearButtonList("submenu", reqdSubMenuOpts, params.subMenu.map(sub =>
+ this.setupContextMenuButton(sub, DocListCast(menuBtnDoc?.data).find(doc => doc.title === sub.title))
+ )), undefined, reqdSubMenuFuncs);
+ }
+ });
+ const reqdCtxtOpts = { title: "menu buttons", flexGap: 0, childDontRegisterViews: true, linearViewIsExpanded: true, ignoreClick: true, linearViewExpandable: false, _height: 35 };
+ return this.AssignOpts(ctxtMenuBtnsDoc, reqdCtxtOpts) ?? (doc[field] = CurrentUserUtils.linearButtonList("contextMenuButtons", reqdCtxtOpts, ctxtMenuBtns));
}
- // the initial presentation Doc to use
- static setupDefaultPresentation(doc: Doc) {
- if (doc["template-presentation"] === undefined) {
- doc["template-presentation"] = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
- title: "pres element template", backgroundColor: "transparent", _xMargin: 5, _fitWidth: true, _height: 46, isTemplateDoc: true, isTemplateForField: "data", system: true
- }));
- }
+ /// collection of documents rendered in the overlay layer above all tabs and other UI
+ static setupOverlays(doc: Doc, field = "myOverlayDocs") {
+ const reqdOpts = { title: "overlay documents", backgroundColor: "#aca3a6", system: true };
+ return this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.FreeformDocument([], reqdOpts));
}
-
- // Sharing sidebar is where shared documents are contained
+
+ /// The database of all links on all documents
static async setupLinkDocs(doc: Doc, linkDatabaseId: string) {
if (doc.myLinkDatabase === undefined) {
let linkDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(linkDatabaseId);
@@ -915,6 +842,8 @@ export class CurrentUserUtils {
doc.myLinkDatabase = new PrefetchProxy(linkDocs);
}
}
+
+ /// Shared documents option on the left side button panel
// A user's sharing document is where all documents that are shared to that user are placed.
// When the user views one of these documents, it will be added to the sharing documents 'viewed' list field
// The sharing document also stores the user's color value which helps distinguish shared documents from personal documents
@@ -941,37 +870,26 @@ export class CurrentUserUtils {
};
const sharedDocs = Docs.newAccount ? undefined : DocCast(doc.mySharedDocs) ?? DocCast(await DocServer.GetRefField(sharingDocumentId + "outer"));
- if (!(sharedDocs instanceof Doc)) {
- doc.mySharedDocs = new PrefetchProxy(
- Docs.Create.TreeDocument([], {...sharedDocOpts, ...sharedRequiredDocOpts}, sharingDocumentId + "outer", sharingDocumentId));
- } else {
- Object.entries(sharedRequiredDocOpts).forEach(pair => {
- const targetDoc = pair[0].startsWith("_") ? sharedDocs as Doc : Doc.GetProto(sharedDocs as Doc);
- targetDoc[pair[0]] = pair[1];
- });
- }
+ return this.AssignOpts(DocCast(sharedDocs), sharedRequiredDocOpts) ??
+ (doc.mySharedDocs = Docs.Create.TreeDocument([], {...sharedDocOpts, ...sharedRequiredDocOpts}, sharingDocumentId + "outer", sharingDocumentId));
}
- // Import sidebar is where shared documents are contained
- static setupImportSidebar(doc: Doc) {
- if (doc.myImportDocs === undefined) {
- const newImportButton: Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Import from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Import", btnType: ButtonType.ClickButton, buttonText: "Import", icon: "upload", system: true });
- doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
- title: "My Imports", _forceActive: true, buttonMenu: true, buttonMenuDoc: newImportButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
- childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
- dontRegisterView: true, explainer: "This is where documents that are Imported into Dash will go."
- }));
- }
- }
-
- // Search sidebar is where searches within the document are performed
- static setupSearchSidebar(doc: Doc) {
- if (doc.mySearchPanel === undefined) {
- doc.mySearchPanel = new PrefetchProxy(Docs.Create.SearchDocument({
- dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, _searchDoc: true,
- childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "Search Panel", system: true
- })) as any as Doc;
- }
+ /// Import option on the left side button panel
+ static setupImportSidebar(doc: Doc, field:string) {
+ const reqdOpts:DocumentOptions = {
+ title: "My Imports", _forceActive: true, buttonMenu: true, ignoreClick: true, _showTitle: "title",
+ _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
+ childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
+ dontRegisterView: true, explainer: "This is where documents that are Imported into Dash will go."
+ };
+ const myImports = this.AssignOpts(DocCast(doc[field]), reqdOpts) ?? (doc[field] = Docs.Create.StackingDocument([], reqdOpts));
+
+ const reqdBtnOpts:DocumentOptions = { _forceActive: true, toolTip: "Import from computer",
+ _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Import", btnType: ButtonType.ClickButton,
+ buttonText: "Import", icon: "upload", system: true };
+ const reqdBtnScripts = { onClick: "importDocument()" };
+ const newImportBtn = this.AssignOpts(DocCast(myImports.buttonMenuDoc), reqdBtnOpts) ?? (myImports.buttonMenuDoc = Docs.Create.FontIconDocument(reqdBtnOpts));
+ this.AssignScripts(newImportBtn, reqdBtnScripts);
}
static setupClickEditorTemplates(doc: Doc) {
@@ -1033,8 +951,8 @@ export class CurrentUserUtils {
}, { fireImmediately: true });
// Document properties on load
doc.system = true;
- doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
doc.title = Doc.CurrentUserEmail;
+ doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
doc._raiseWhenDragged = true;
doc._showLabel = true;
doc._showMenuLabel = true;
@@ -1053,29 +971,22 @@ export class CurrentUserUtils {
doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, false);
doc.activeCollectionNestedBackground = Cast(doc.activeCollectionNestedBackground, "string", null);
doc.noviceMode = BoolCast(doc.noviceMode, true);
- doc.savedFilters = new List<Doc>();
+ !doc.savedFilters && (doc.savedFilters = new List<Doc>());
doc.filterDocCount = 0;
doc.freezeChildren = "remove|add";
doc.myPublishedDocs = doc.myPublishedDocs ?? new List<Doc>();
- doc.myHeaderBarDoc = doc.myHeaderBarDoc ?? Docs.Create.MulticolumnDocument([], { title: "header bar", system: true });
+ doc.myHeaderBar = doc.myHeaderBar?? Docs.Create.MulticolumnDocument([], { title: "header bar", system: true }); // drop down panel at top of dashboard for stashing documents
+ await this.setupLinkDocs(doc, linkDatabaseId);
+ await this.setupSharedDocs(doc, sharingDocumentId); // sets up the right sidebar collection for mobile upload documents and sharing
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
- this.setupImportSidebar(doc); // sets up the import sidebar
- this.setupSearchSidebar(doc); // sets up the search sidebar
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
- this.setupOverlays(doc); // documents in overlay layer
- this.setupContextMenuButtons(doc); // set up context menu buttons
+ this.setupOverlays(doc); // sets up the overlay panel where documents and other widgets can be added to float over the rest of the dashboard
+ this.setupContextMenuButtons(doc); // set up the row of buttons at the top of the dashboard that change depending on what is selected
this.setupDockedButtons(doc); // the bottom bar of font icons
- await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels
- await this.setupMenuPanel(doc, sharingDocumentId, linkDatabaseId);
+ this.setupLeftSidebarMenu(doc); // the left-side column of buttons that open their contents in a flyout panel on the left
if (!doc.globalScriptDatabase) doc.globalScriptDatabase = Docs.Prototypes.MainScriptDocument();
- setTimeout(() => this.setupDefaultPresentation(doc), 0); // presentation that's initially triggered
-
- // setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet
- doc["dockedBtn-undo"] && reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(doc["dockedBtn-undo"] as Doc).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
- doc["dockedBtn-redo"] && reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(doc["dockedBtn-redo"] as Doc).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true });
-
setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500);
doc.fieldInfos = await Docs.setupFieldInfos();
if (doc.activeDashboard instanceof Doc) {
@@ -1227,7 +1138,7 @@ export class CurrentUserUtils {
public static async snapshotDashboard(userDoc: Doc) {
const copy = await CollectionDockingView.Copy(CurrentUserUtils.ActiveDashboard);
- Doc.AddDocToList(Cast(userDoc.myDashboards, Doc, null), "data", copy);
+ Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", copy);
CurrentUserUtils.openDashboard(userDoc, copy);
}
@@ -1277,15 +1188,24 @@ export class CurrentUserUtils {
return tbox;
}
- public static get DockedBtns() { return Cast(Doc.UserDoc().dockedBtns, Doc, null); }
- public static get MySearchPanelDoc() { return Cast(Doc.UserDoc().mySearchPanelDoc, Doc, null); }
- public static get ActiveDashboard() { return Cast(Doc.UserDoc().activeDashboard, Doc, null); }
- public static get MyHeaderBarDoc() { return Cast(Doc.UserDoc().myHeaderBarDoc, Doc, null); }
- public static get ActivePresentation() { return Cast(Doc.UserDoc().activePresentation, Doc, null); }
- public static get MyRecentlyClosed() { return Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null); }
- public static get MyDashboards() { return Cast(Doc.UserDoc().myDashboards, Doc, null); }
- public static get EmptyPane() { return Cast(Doc.UserDoc().emptyPane, Doc, null); }
- public static get OverlayDocs() { return DocListCast((Doc.UserDoc().myOverlayDocs as Doc)?.data); }
+ public static get MyUserDocView() { return DocCast(Doc.UserDoc().myUserDocView); }
+ public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); }
+ public static get MySearcher() { return DocCast(Doc.UserDoc().mySearcher); }
+ public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); }
+ public static get MyHeaderBar() { return DocCast(Doc.UserDoc().myHeaderBar); }
+ public static get MyTools() { return DocCast(Doc.UserDoc().myTools); }
+ public static get MyDashboards() { return DocCast(Doc.UserDoc().myDashboards); }
+ public static get MyLeftSidebarMenu() { return DocCast(Doc.UserDoc().myLeftSidebarMenu); }
+ public static get MyLeftSidebarPanel() { return DocCast(Doc.UserDoc().myLeftSidebarPanel); }
+ public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); }
+ public static get MyTrails() { return DocCast(Doc.UserDoc().myTrails); }
+ public static get MyImports() { return DocCast(Doc.UserDoc().myImports); }
+ public static get MyContextMenuBtns() { return DocCast(Doc.UserDoc().myContextMenuBtns); }
+ public static get MyRecentlyClosed() { return DocCast(Doc.UserDoc().myRecentlyClosed); }
+ public static get MyOverlayDocs() { return DocListCast(DocCast(Doc.UserDoc().myOverlayDocs)?.data); }
+ public static get ActiveDashboard() { return DocCast(Doc.UserDoc().activeDashboard); }
+ public static get ActivePresentation() { return DocCast(Doc.UserDoc().activePresentation); }
+ public static get EmptyPane() { return DocCast(Doc.UserDoc().emptyPane); }
public static set SelectedTool(tool: InkTool) { Doc.UserDoc().activeInkTool = tool; }
@computed public static get SelectedTool(): InkTool { return StrCast(Doc.UserDoc().activeInkTool, InkTool.None) as InkTool; }
}
@@ -1298,7 +1218,7 @@ ScriptingGlobals.add(function openDragFactory(dragFactory: Doc) {
view && SelectionManager.SelectView(view, false);
}
});
-ScriptingGlobals.add(function MySharedDocs() { return Doc.SharingDoc(); }, "document containing all shared Docs");
+ScriptingGlobals.add(function MySharedDocs() { return CurrentUserUtils.MySharedDocs; }, "document containing all shared Docs");
ScriptingGlobals.add(function IsNoviceMode() { return Doc.UserDoc().noviceMode; }, "is Dash in novice mode");
ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering");
ScriptingGlobals.add(function snapshotDashboard() { CurrentUserUtils.snapshotDashboard(Doc.UserDoc()); }, "creates a snapshot copy of a dashboard");
@@ -1329,15 +1249,15 @@ ScriptingGlobals.add(function selectedDocumentType(docType?: DocumentType, colTy
const parentDoc: Doc = Cast(selected.context, Doc, null);
selected = parentDoc;
}
- if (selected && docType && selected.type === docType) return false;
- else if (selected && colType && selected.viewType === colType) return false;
- else if (selected && !colType && !docType) return false;
- else return true;
+ if (selected && docType && selected.type === docType) return true;
+ else if (selected && colType && selected.viewType === colType) return true;
+ else if (selected && !colType && !docType) return true;
+ else return false;
});
ScriptingGlobals.add(function makeTopLevelFolder() {
const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
TreeView._editTitleOnLoad = { id: folder[Id], parent: undefined };
- return Doc.AddDocToList(Doc.UserDoc().myFilesystem as Doc, "data", folder);
+ return Doc.AddDocToList(CurrentUserUtils.MyFilesystem, "data", folder);
});
ScriptingGlobals.add(function nextKeyFrame(readOnly: boolean) {
if (readOnly) return;