diff options
author | monoguitari <113245090+monoguitari@users.noreply.github.com> | 2023-08-22 14:15:04 -0400 |
---|---|---|
committer | monoguitari <113245090+monoguitari@users.noreply.github.com> | 2023-08-22 14:15:04 -0400 |
commit | 9293fd8c4128b41b31f9b2214d6799fdff0f2aaa (patch) | |
tree | 45809c42545b10515f6f88065318b454549dacd1 /src/client/documents/Documents.ts | |
parent | 347e8e2bd32854b36828b7bcc645c9c361204251 (diff) | |
parent | 1c52bd054385d2584bbeae41eecdf9ba6999c25f (diff) |
Merge branch 'master' into advanced-trails
Diffstat (limited to 'src/client/documents/Documents.ts')
-rw-r--r-- | src/client/documents/Documents.ts | 313 |
1 files changed, 151 insertions, 162 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a91d5806c..e7d3e7efc 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,5 +1,5 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; -import { action, runInAction } from 'mobx'; +import { action, reaction, runInAction } from 'mobx'; import { basename } from 'path'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, Opt, updateCachedAcls } from '../../fields/Doc'; @@ -25,7 +25,7 @@ import { DirectoryImportBox } from '../util/Import & Export/DirectoryImportBox'; import { FollowLinkScript } from '../util/LinkFollower'; import { LinkManager } from '../util/LinkManager'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; -import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; +import { undoable, UndoManager } from '../util/UndoManager'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { DimUnit } from '../views/collections/collectionMulticolumn/CollectionMulticolumnView'; import { CollectionView } from '../views/collections/CollectionView'; @@ -34,7 +34,7 @@ import { ContextMenuProps } from '../views/ContextMenuItem'; import { DFLT_IMAGE_NATIVE_DIM } from '../views/global/globalCssVariables.scss'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke'; import { AudioBox } from '../views/nodes/AudioBox'; -import { FontIconBox } from '../views/nodes/button/FontIconBox'; +import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox'; import { ColorBox } from '../views/nodes/ColorBox'; import { ComparisonBox } from '../views/nodes/ComparisonBox'; import { DataVizBox } from '../views/nodes/DataVizBox/DataVizBox'; @@ -169,22 +169,25 @@ export class DocumentOptions { _nativeDimModifiable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers'); _nativeHeightUnfrozen?: BOOLt = new BoolInfo('native height can be changed independent of width by dragging decoration resizers'); - 'acl-Public'?: string; // public permissions - '_acl-Public'?: string; // public permissions + 'acl-Guest'?: STRt = new StrInfo("permissions granted to users logged in as 'guest' (either view, or private)"); // public permissions + '_acl-Guest'?: string; // public permissions type?: DTYPEt = new DTypeInfo('type of document', true); + type_collection?: COLLt = new CTypeInfo('how collection is rendered'); // sub type of a collection _type_collection?: COLLt = new CTypeInfo('how collection is rendered'); // sub type of a collection title?: STRt = new StrInfo('title of document'); caption?: RichTextField; author?: string; // STRt = new StrInfo('creator of document'); // bcz: don't change this. Otherwise, the userDoc's field Infos will have a FieldInfo assigned to its author field which will render it unreadable author_date?: DATEt = new DateInfo('date the document was created', true); annotationOn?: DOCt = new DocInfo('document annotated by this document'); + embedContainer?: DOCt = new DocInfo('document that displays (contains) this discument'); color?: STRt = new StrInfo('foreground color data doc'); hidden?: BOOLt = new BoolInfo('whether the document is not rendered by its collection'); backgroundColor?: STRt = new StrInfo('background color for data doc'); opacity?: NUMt = new NumInfo('document opacity'); viewTransitionTime?: NUMt = new NumInfo('transition duration for view parameters'); dontRegisterView?: BOOLt = new BoolInfo('are views of this document registered so that they can be found when following links, etc'); - dontUndo?: BOOLt = new BoolInfo('whether button clicks should be undoable (true for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)'); + _undoIgnoreFields?: List<string>; //'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)' + undoIgnoreFields?: List<string>; //'fields that should not be added to the undo stack (opacity for Undo/Redo/and sidebar) AND whether modifications to document are undoable (true for linearview menu buttons to prevent open/close from entering undo stack)' _headerHeight?: NUMt = new NumInfo('height of document header used for displaying title'); _headerFontSize?: NUMt = new NumInfo('font size of header of custom notes'); _headerPointerEvents?: PEVt = new PEInfo('types of events the header of a custom text document can consume'); @@ -286,12 +289,12 @@ export class DocumentOptions { _isTimelineLabel?: BOOLt = new BoolInfo('is document a timeline label'); _isLightbox?: BOOLt = new BoolInfo('whether a collection acts as a lightbox by opening lightbox links by hiding all other documents in collection besides link target'); - presPanX?: NUMt = new NumInfo('panX saved as a view spec'); - presPanY?: NUMt = new NumInfo('panY saved as a view spec'); - presViewScale?: NUMt = new NumInfo('viewScale saved as a view Spec'); - presTransition?: NUMt = new NumInfo('the time taken for the transition TO a document'); - presDuration?: NUMt = new NumInfo('the duration of the slide in presentation view'); - presZoomText?: BOOLt = new BoolInfo('whether text anchors should shown in a larger box when following links to make them stand out'); + config_panX?: NUMt = new NumInfo('panX saved as a view spec'); + config_panY?: NUMt = new NumInfo('panY saved as a view spec'); + config_viewScale?: NUMt = new NumInfo('viewScale saved as a view Spec'); + presentation_transition?: NUMt = new NumInfo('the time taken for the transition TO a document'); + presentation_duration?: NUMt = new NumInfo('the duration of the slide in presentation view'); + presentation_zoomText?: BOOLt = new BoolInfo('whether text anchors should shown in a larger box when following links to make them stand out'); data?: any; data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); @@ -302,7 +305,7 @@ export class DocumentOptions { noteType?: string; // freeform properties - _freeform_backgroundGrid?: boolean; + _freeform_backgroundGrid?: BOOLt = new BoolInfo('whether background grid is shown on freeform collections'); _freeform_scale?: NUMt = new NumInfo('how much a freeform view has been scaled (zoomed)'); _freeform_panX?: NUMt = new NumInfo('horizontal pan location of a freeform view'); _freeform_panY?: NUMt = new NumInfo('vertical pan location of a freeform view'); @@ -322,8 +325,9 @@ export class DocumentOptions { badgeValue?: ScriptField; //LINEAR VIEW - linearView_IsExpanded?: BOOLt = new BoolInfo('is linear view expanded'); + linearView_IsOpen?: BOOLt = new BoolInfo('is linear view open'); linearView_Expandable?: BOOLt = new BoolInfo('can linear view be expanded'); + linearView_Dropdown?: BOOLt = new BoolInfo('can linear view be opened as a dropdown'); linearView_SubMenu?: BOOLt = new BoolInfo('is doc a sub menu of more linear views'); flexGap?: NUMt = new NumInfo('Linear view flex gap'); flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse'; @@ -332,8 +336,8 @@ export class DocumentOptions { link_relationship?: string; // type of relatinoship a link represents link_displayLine?: BOOLt = new BoolInfo('whether a link line should be dipslayed between the two link anchors'); link_displayArrow?: BOOLt = new BoolInfo("whether to display link's directional arrowhead"); - link_anchor_1?: Doc; - link_anchor_2?: Doc; + link_anchor_1?: DOCt = new DocInfo('start anchor of a link'); + link_anchor_2?: DOCt = new DocInfo('end anchor of a link'); link_autoMoveAnchors?: BOOLt = new BoolInfo('whether link endpoint should move around the edges of a document to make shortest path to other link endpoint'); link_anchor_1_useSmallAnchor?: BOOLt = new BoolInfo('whether link_anchor_1 of a link should use a miniature anchor dot (as when the anchor is a text selection)'); link_anchor_2_useSmallAnchor?: BOOLt = new BoolInfo('whether link_anchor_1 of a link should use a miniature anchor dot (as when the anchor is a text selection)'); @@ -351,48 +355,50 @@ export class DocumentOptions { onDoubleClick?: ScriptField; onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked onChildDoubleClick?: ScriptField; // script given to children of a collection to execute when they are double clicked + onClickScriptDisable?: STRt = new StrInfo('"always" disable click script, "never" disable click script, or default'); defaultDoubleClick?: 'ignore' | 'default'; // ignore double clicks, or deafult (undefined) means open document full screen waitForDoubleClickToClick?: 'always' | 'never' | 'default'; // whether a click function wait for double click to expire. 'default' undefined = wait only if there's a click handler, "never" = never wait, "always" = alway wait onPointerDown?: ScriptField; onPointerUp?: ScriptField; - dragFactory_count?: NUMt = new NumInfo('number of items created from a drag button (used for setting title with incrementing index)', true); openFactoryLocation?: string; // an OpenWhere value to place the factory created document openFactoryAsDelegate?: BOOLt = new BoolInfo('create a delegate of the factory'); _forceActive?: BOOLt = new BoolInfo('flag to handle pointer events when not selected (or otherwise active)'); - enableDragWhenActive?: BOOLt = new BoolInfo('allow dragging even if document contentts are active (e.g., tree, groups)'); - _stayInCollection?: BOOLt = new BoolInfo('whether the document should remain in its collection when someone tries to drag and drop it elsewhere'); + _dragOnlyWithinContainer?: BOOLt = new BoolInfo('whether the document should remain in its collection when someone tries to drag and drop it elsewhere'); _raiseWhenDragged?: BOOLt = new BoolInfo('whether a document is brought to front when dragged.'); - allowOverlayDrop?: BOOLt = new BoolInfo('can documents be dropped onto this document without using dragging title bar or holding down embed key (ctrl)?', true); - childDropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto a child of a collection "); - targetDropAction?: DROPt = new DAInfo('what should happen to the source document when ??? '); + childDragAction?: DROPt = new DAInfo('what should happen to the child documents when they are dragged from the collection'); + dropConverter?: ScriptField; // script to run when documents are dropped on this Document. + dropAction?: DROPt = new DAInfo("what should happen to this document when it's dropped somewhere else"); _dropAction?: DROPt = new DAInfo("what should happen to this document when it's dropped somewhere else"); - _removeDropProperties?: List<string>; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document + _dropPropertiesToRemove?: List<string>; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document cloneFieldFilter?: List<string>; // fields not to copy when the document is clonedclipboard?: Doc; - dropConverter?: ScriptField; // script to run when documents are dropped on this Document. - dragFactory?: Doc; // document to create when dragging with a suitable onDragStart script - clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script + dragWhenActive?: BOOLt = new BoolInfo('should document drag when it is active - e.g., pileView, group'); + dragAction?: DROPt = new DAInfo('how to drag document when it is active (e.g., tree, groups)'); + dragFactory_count?: NUMt = new NumInfo('number of items created from a drag button (used for setting title with incrementing index)', true); + dragFactory?: DOCt = new DocInfo('document to create when dragging with a suitable onDragStart script'); + clickFactory?: DOCt = new DocInfo('document to create when clicking on a button with a suitable onClick script'); onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop target?: Doc; // available for use in scripts. used to provide a document parameter to the script (Note, this is a convenience entry since any field could be used for parameterizing a script) - treeViewHideTitle?: BOOLt = new BoolInfo('whether to hide the top document title of a tree view'); - treeViewHideUnrendered?: BOOLt = new BoolInfo("tells tree view not to display documents that have an 'layout_unrendered' tag unless they also have a treeViewFieldKey tag (presBox)"); - treeViewHideHeaderIfTemplate?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view only if a childLayoutTemplate is provided (presBox)'); - treeViewHideHeader?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view'); - treeViewHideHeaderFields?: BOOLt = new BoolInfo('whether to hide the drop down options for tree view items.'); - treeViewChildDoubleClick?: ScriptField; // - treeViewOpenIsTransient?: BOOLt = new BoolInfo("ignores the treeViewOpen Doc flag, allowing a treeViewItem's expand/collapse state to be independent of other views of the same document in the same or any other tree view"); - treeViewOpen?: BOOLt = new BoolInfo('whether this document is expanded in a tree view'); - treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view - treeViewExpandedViewLock?: BOOLt = new BoolInfo('whether the expanded view can be changed'); - treeViewChecked?: ScriptField; // script to call when a tree view checkbox is checked - treeViewTruncateTitleWidth?: NUMt = new NumInfo('maximum width of a treew view title before truncation'); - treeViewHasOverlay?: BOOLt = new BoolInfo('whether the treeview has an overlay for freeform annotations'); - treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy - treeViewFreezeChildren?: STRt = new StrInfo('set (add, remove, add|remove) to disable adding, removing or both from collection'); + treeView_HideTitle?: BOOLt = new BoolInfo('whether to hide the top document title of a tree view'); + treeView_HideUnrendered?: BOOLt = new BoolInfo("tells tree view not to display documents that have an 'layout_unrendered' tag unless they also have a treeView_FieldKey tag (presBox)"); + treeView_HideHeaderIfTemplate?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view only if a childLayoutTemplate is provided (presBox)'); + treeView_HideHeader?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view'); + treeView_HideHeaderFields?: BOOLt = new BoolInfo('whether to hide the drop down options for tree view items.'); + treeView_ChildDoubleClick?: ScriptField; // + treeView_OpenIsTransient?: BOOLt = new BoolInfo("ignores the treeView_Open Doc flag, allowing a treeView_Item's expand/collapse state to be independent of other views of the same document in the same or any other tree view"); + treeView_Open?: BOOLt = new BoolInfo('whether this document is expanded in a tree view'); + treeView_ExpandedView?: string; // which field/thing is displayed when this item is opened in tree view + treeView_ExpandedViewLock?: BOOLt = new BoolInfo('whether the expanded view can be changed'); + treeView_Checked?: ScriptField; // script to call when a tree view checkbox is checked + treeView_TruncateTitleWidth?: NUMt = new NumInfo('maximum width of a treew view title before truncation'); + treeView_HasOverlay?: BOOLt = new BoolInfo('whether the treeview has an overlay for freeform annotations'); + treeView_Type?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy + treeView_FreezeChildren?: STRt = new StrInfo('set (add, remove, add|remove) to disable adding, removing or both from collection'); sidebar_color?: string; // background color of text sidebar sidebar_collectionType?: string; // collection type of text sidebar + data_dashboards?: List<any>; // list of dashboards used in shareddocs; text?: string; textTransform?: string; letterSpacing?: string; @@ -404,6 +410,7 @@ export class DocumentOptions { clipboard?: Doc; hoverBackgroundColor?: string; // background color of a label when hovered + userBackgroundColor?: STRt = new StrInfo('background color associated with a Dash user (seen in header fields of shared documents)'); userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); } export namespace Docs { @@ -436,6 +443,7 @@ export namespace Docs { nativeHeightUnfrozen: true, layout_forceReflow: true, defaultDoubleClick: 'ignore', + systemIcon: 'BsFileEarmarkTextFill', }, }, ], @@ -457,21 +465,21 @@ export namespace Docs { DocumentType.IMG, { layout: { view: ImageBox, dataField: defaultDataKey }, - options: { freeform: '' }, + options: { freeform: '', systemIcon: 'BsFileEarmarkImageFill' }, }, ], [ DocumentType.WEB, { layout: { view: WebBox, dataField: defaultDataKey }, - options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always' }, + options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' }, }, ], [ DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1 }, + options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1, systemIcon: 'BsFillCollectionFill' }, }, ], [ @@ -485,35 +493,35 @@ export namespace Docs { DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { _layout_currentTimecode: 0 }, + options: { _layout_currentTimecode: 0, systemIcon: 'BsFileEarmarkPlayFill' }, }, ], [ DocumentType.AUDIO, { layout: { view: AudioBox, dataField: defaultDataKey }, - options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true }, + options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true, systemIcon: 'BsFillVolumeUpFill' }, }, ], [ DocumentType.REC, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { _height: 100, backgroundColor: 'pink' }, + options: { _height: 100, backgroundColor: 'pink', systemIcon: 'BsFillMicFill' }, }, ], [ DocumentType.PDF, { layout: { view: PDFBox, dataField: defaultDataKey }, - options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true }, + options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsFileEarmarkPdfFill' }, }, ], [ DocumentType.MAP, { layout: { view: MapBox, dataField: defaultDataKey }, - options: { _height: 600, _width: 800, nativeDimModifiable: true }, + options: { _height: 600, _width: 800, nativeDimModifiable: true, systemIcon: 'BsFillPinMapFill' }, }, ], [ @@ -536,31 +544,23 @@ export namespace Docs { link_description: '', layout_showCaption: 'link_description', backgroundColor: 'lightblue', // lightblue is default color for linking dot and link documents text comment area - _removeDropProperties: new List(['onClick']), + _dropPropertiesToRemove: new List(['onClick']), }, }, ], [ - DocumentType.LINKDB, - { - data: new List<Doc>(), - layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { childDropAction: 'embed', title: 'Global Link Database' }, - }, - ], - [ DocumentType.SCRIPTDB, { data: new List<Doc>(), layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { childDropAction: 'embed', title: 'Global Script Database' }, + options: { title: 'Global Script Database' }, }, ], [ DocumentType.SCRIPTING, { layout: { view: ScriptingBox, dataField: defaultDataKey }, - options: {}, + options: { systemIcon: 'BsFileEarmarkCodeFill' }, }, ], [ @@ -580,7 +580,7 @@ export namespace Docs { DocumentType.EQUATION, { layout: { view: EquationBox, dataField: 'text' }, - options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true }, + options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript }, ], [ @@ -615,14 +615,14 @@ export namespace Docs { DocumentType.FONTICON, { layout: { view: FontIconBox, dataField: 'icon' }, - options: { defaultDoubleClick: 'ignore', waitForDoubleClickToClick: 'never', enableDragWhenActive: true, layout_hideLinkButton: true, _width: 40, _height: 40 }, + options: { defaultDoubleClick: 'ignore', waitForDoubleClickToClick: 'never', layout_hideLinkButton: true, _width: 40, _height: 40 }, }, ], [ DocumentType.WEBCAM, { layout: { view: RecordingBox, dataField: defaultDataKey }, - options: {}, + options: { systemIcon: 'BsFillCameraVideoFill' }, }, ], [ @@ -636,7 +636,7 @@ export namespace Docs { DocumentType.CONFIG, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { layout_hideLinkButton: true, pointerEvents: 'none', layout_unrendered: true }, + options: { config: '', layout_hideLinkButton: true, layout_unrendered: true }, }, ], [ @@ -644,14 +644,14 @@ export namespace Docs { { // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method layout: { view: InkingStroke, dataField: 'stroke' }, - options: {}, + options: { systemIcon: 'BsFillPencilFill' }, }, ], [ DocumentType.SCREENSHOT, { layout: { view: ScreenshotBox, dataField: defaultDataKey }, - options: { nativeDimModifiable: true, nativeHeightUnfrozen: true }, + options: { nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsCameraFill' }, }, ], [ @@ -659,15 +659,14 @@ export namespace Docs { { data: '', layout: { view: ComparisonBox, dataField: defaultDataKey }, - options: { backgroundColor: 'gray', targetDropAction: 'embed' }, + options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', systemIcon: 'BsLayoutSplit' }, }, ], [ DocumentType.GROUPDB, { - data: new List<Doc>(), layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { childDropAction: 'embed', title: 'Global Group Database' }, + options: { title: 'Global Group Database' }, }, ], [ @@ -681,7 +680,7 @@ export namespace Docs { DocumentType.DATAVIZ, { layout: { view: DataVizBox, dataField: defaultDataKey }, - options: { _layout_fitWidth: true, nativeDimModifiable: true }, + options: { dataViz_title: '', _layout_fitWidth: true, nativeDimModifiable: true }, }, ], [ @@ -696,7 +695,22 @@ export namespace Docs { { data: '', layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 }, - options: { _height: 100, layout_forceReflow: true, nativeHeightUnfrozen: true, mass1: '', mass2: '', nativeDimModifiable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '' }, + options: { + _height: 100, + layout_forceReflow: true, + nativeHeightUnfrozen: true, + mass1: '', + mass2: '', + nativeDimModifiable: true, + position: '', + acceleration: '', + pendulum: '', + spring: '', + wedge: '', + simulation: '', + review: '', + systemIcon: 'BsShareFill', + }, }, ], ]); @@ -720,7 +734,7 @@ export namespace Docs { .filter(type => type !== DocumentType.NONE) .map(type => type + suffix); // fetch the actual prototype documents from the server - const actualProtos = Docs.newAccount ? {} : await DocServer.GetRefFields(prototypeIds); + const actualProtos = await DocServer.GetRefFields(prototypeIds); // update this object to include any default values: DocumentOptions for all prototypes prototypeIds.map(id => { const existing = actualProtos[id] as Doc; @@ -731,6 +745,10 @@ export namespace Docs { // an entry dedicated to the given DocumentType) target && PrototypeMap.set(type, target); }); + reaction( + () => (proto => StrCast(proto?.BROADCAST_MESSAGE))(DocServer.GetCachedRefField('rtfProto') as Doc), + msg => msg && alert(msg) + ); } /** @@ -745,13 +763,6 @@ export namespace Docs { } /** - * A collection of all links in the database. Ideally, this would be a search, but for now all links are cached here. - */ - export function MainLinkDocument() { - return Prototypes.get(DocumentType.LINKDB); - } - - /** * A collection of all scripts in the database */ export function MainScriptDocument() { @@ -798,6 +809,7 @@ export namespace Docs { x: 0, y: 0, _width: 300, + 'acl-Guest': SharingPermissions.View, ...(template.options || {}), layout: layout.view?.LayoutString(layout.dataField), data: template.data, @@ -834,20 +846,19 @@ export namespace Docs { * only when creating a DockDocument from the current user's already existing * main document. */ - function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDoc?: Doc) { + function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDoc?: Doc, noView?: boolean) { const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_'); // dataProps['acl-Override'] = SharingPermissions.Unset; - dataProps['acl-Public'] = options['acl-Public'] ? options['acl-Public'] : Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment; - + dataProps['acl-Guest'] = options['acl-Guest'] ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); dataProps.isSystem = viewProps.isSystem; dataProps.isDataDoc = true; dataProps.author = Doc.CurrentUserEmail; dataProps.author_date = new DateField(); if (fieldKey) { dataProps[`${fieldKey}_modificationDate`] = new DateField(); - dataProps[fieldKey] = data; + dataProps[fieldKey] = options.data ?? data; // so that the list of annotations is already initialised, prevents issues in addonly. // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do. @@ -862,30 +873,34 @@ export namespace Docs { dataDoc.proto = proto; } - const viewFirstProps: { [id: string]: any } = {}; - viewFirstProps['acl-Public'] = options['_acl-Public'] ? options['_acl-Public'] : Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment; - // viewFirstProps['acl-Override'] = SharingPermissions.Unset; - viewFirstProps.author = Doc.CurrentUserEmail; - let viewDoc: Doc; - // determines whether viewDoc should be created using placeholder Doc or default - if (placeholderDoc) { - placeholderDoc._height = options._height !== undefined ? Number(options._height) : undefined; - placeholderDoc._width = options._width !== undefined ? Number(options._width) : undefined; - viewDoc = Doc.assign(placeholderDoc, viewFirstProps, true, true); - } else { - viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true); - } - Doc.assign(viewDoc, viewProps, true, true); - if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as any)) { - DocUtils.MakeLinkToActiveAudio(() => viewDoc); - } + if (!noView) { + const viewFirstProps: { [id: string]: any } = { author: Doc.CurrentUserEmail }; + viewFirstProps['acl-Guest'] = options['_acl-Guest'] ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); + let viewDoc: Doc; + // determines whether viewDoc should be created using placeholder Doc or default + if (placeholderDoc) { + placeholderDoc._height = options._height !== undefined ? Number(options._height) : undefined; + placeholderDoc._width = options._width !== undefined ? Number(options._width) : undefined; + viewDoc = Doc.assign(placeholderDoc, viewFirstProps, true, true); + Array.from(Object.keys(placeholderDoc)) + .filter(key => key.startsWith('acl')) + .forEach(key => (dataDoc[key] = viewDoc[key] = placeholderDoc[key])); + } else { + viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true); + } + Doc.assign(viewDoc, viewProps, true, true); + if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as any)) { + DocUtils.MakeLinkToActiveAudio(() => viewDoc); + } + updateCachedAcls(dataDoc); + updateCachedAcls(viewDoc); - Doc.AddFileOrphan(dataDoc); + return viewDoc; + } updateCachedAcls(dataDoc); - updateCachedAcls(viewDoc); - return viewDoc; + return dataDoc; } export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) { @@ -1011,10 +1026,11 @@ export namespace Docs { I.rotation = 0; I.defaultDoubleClick = 'click'; I.author_date = new DateField(); - I['acl-Public'] = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment; + I['acl-Guest'] = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; //I['acl-Override'] = SharingPermissions.Unset; I[Initializing] = false; - return I; + + return InstanceFromProto(I, '', options); } export function PdfDocument(url: string, options: DocumentOptions = {}, overwriteDoc?: Doc) { @@ -1050,39 +1066,12 @@ export namespace Docs { export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) { const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _xPadding: 20, _yPadding: 20, ...options, _type_collection: CollectionViewType.Freeform }, id); - documents.forEach(d => (d.embedContainer = inst)); + documents.forEach(d => Doc.SetContainer(d, inst)); return inst; } - export function WebConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), undefined, options, id); - } - export function CollectionConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function PdfConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function TextConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function FunctionPlotConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function DataVizConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function LineChartConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function ComparisonConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function ImageConfigDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); - } - export function InkConfigDocument(options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id); + export function ConfigDocument(options: DocumentOptions, id?: string) { + return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id, '', undefined, undefined, true); } export function HTMLMarkerDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) { @@ -1096,7 +1085,7 @@ export namespace Docs { return InstanceFromProto( Prototypes.get(DocumentType.COL), new List(documents), - { enableDragWhenActive: true, _forceActive: true, _freeform_noZoom: true, _freeform_noAutoPan: true, ...options, _type_collection: CollectionViewType.Pile }, + { backgroundColor: 'transparent', dropAction: 'move', _forceActive: true, _freeform_noZoom: true, _freeform_noAutoPan: true, ...options, _type_collection: CollectionViewType.Pile }, id ); } @@ -1122,7 +1111,9 @@ export namespace Docs { } export function TreeDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _xMargin: 5, _yMargin: 5, ...options, _type_collection: CollectionViewType.Tree }, id, undefined, protoId); + const doc = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _xMargin: 5, _yMargin: 5, ...options, _type_collection: CollectionViewType.Tree }, id, undefined, protoId); + Doc.GetProto(doc).treeView = ''; /// not really needed, but makes keyvalue pane look better + return doc; } export function StackingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) { @@ -1155,8 +1146,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.LABEL), undefined, { ...(options || {}) }); } - export function EquationDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.EQUATION), undefined, { ...(options || {}) }, undefined, 'text'); + export function EquationDocument(text?: string, options?: DocumentOptions) { + return InstanceFromProto(Prototypes.get(DocumentType.EQUATION), text, { ...(options || {}) }, undefined, 'text'); } export function FunctionPlotDocument(documents: Array<Doc>, options?: DocumentOptions) { @@ -1174,20 +1165,19 @@ export namespace Docs { export function FontIconDocument(options?: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { ...(options || {}) }); } - export function FilterDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.FILTER), undefined, { ...(options || {}) }); - } export function PresElementBoxDocument() { return Prototypes.get(DocumentType.PRESELEMENT); } export function DataVizDocument(url: string, options?: DocumentOptions, overwriteDoc?: Doc) { - return InstanceFromProto(Prototypes.get(DocumentType.DATAVIZ), new CsvField(url), { title: 'Data Viz', ...options }, undefined, undefined, undefined, overwriteDoc); + return InstanceFromProto(Prototypes.get(DocumentType.DATAVIZ), new CsvField(url), { title: 'Data Viz', type: 'dataviz', ...options }, undefined, undefined, undefined, overwriteDoc); } export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { treeViewFreezeChildren: 'remove|add', ...options, _type_collection: CollectionViewType.Docking, dockingConfig: config }, id); + const ret = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { treeView_FreezeChildren: 'remove|add', ...options, type_collection: CollectionViewType.Docking, dockingConfig: config }, id); + documents.map(c => Doc.SetContainer(c, ret)); + return ret; } export function DirectoryImportDocument(options: DocumentOptions = {}) { @@ -1212,10 +1202,13 @@ export namespace Docs { const doc = DockDocument( configs.map(c => c.doc), JSON.stringify(layoutConfig), - options, + Doc.CurrentUserEmail === 'guest' ? options : { 'acl-Guest': SharingPermissions.View, ...options }, id ); - configs.map(c => (c.doc.embedContainer = doc)); + configs.map(c => { + Doc.SetContainer(c.doc, doc); + inheritParentAcls(doc, c.doc, false); + }); return doc; } @@ -1244,7 +1237,7 @@ export namespace DocUtils { const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields childFilters.forEach(filter => { - const fields = filter.split(':'); + const fields = filter.split(Doc.FilterSep); const key = fields[0]; const value = fields[1]; const modifiers = fields[2]; @@ -1262,7 +1255,7 @@ export namespace DocUtils { return false; } - for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== Utils.noDragsDocFilter.split(':')[0])) { + for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== Utils.noDragsDocFilter.split(Doc.FilterSep)[0])) { const facet = filterFacets[facetKey]; // facets that match some value in the field of the document (e.g. some text field) @@ -1306,7 +1299,7 @@ export namespace DocUtils { if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; } } - return (parentCollection?.currentFilter as Doc)?.childFilters_boolean === 'OR' ? false : true; + return parentCollection?.childFilters_boolean === 'OR' ? false : true; }) : childDocs; const rangeFilteredDocs = filteredDocs.filter(d => { @@ -1375,8 +1368,8 @@ export namespace DocUtils { source, target, { - 'acl-Public': SharingPermissions.Augment, - '_acl-Public': SharingPermissions.Augment, + 'acl-Guest': SharingPermissions.Augment, + '_acl-Guest': SharingPermissions.Augment, title: ComputedField.MakeFunction('generateLinkTitle(self)') as any, link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined, link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined, @@ -1550,7 +1543,7 @@ export namespace DocUtils { !simpleMenu && ContextMenu.Instance.addItem({ description: 'Quick Notes', - subitems: DocListCast((Doc.UserDoc()['template-notes'] as Doc).data).map((note, i) => ({ + subitems: DocListCast((Doc.UserDoc()['template_notes'] as Doc).data).map((note, i) => ({ description: ':' + StrCast(note.title), event: undoable((args: { x: number; y: number }) => { const textDoc = Docs.Create.TextDocument('', { @@ -1610,10 +1603,10 @@ export namespace DocUtils { } export function findTemplate(templateName: string, type: string, signature: string) { let docLayoutTemplate: Opt<Doc>; - const iconViews = DocListCast(Cast(Doc.UserDoc()['template-icons'], Doc, null)?.data); - const templBtns = DocListCast(Cast(Doc.UserDoc()['template-buttons'], Doc, null)?.data); - const noteTypes = DocListCast(Cast(Doc.UserDoc()['template-notes'], Doc, null)?.data); - const clickFuncs = DocListCast(Cast(Doc.UserDoc()['template-clickFuncs'], Doc, null)?.data); + const iconViews = DocListCast(Cast(Doc.UserDoc()['template_icons'], Doc, null)?.data); + const templBtns = DocListCast(Cast(Doc.UserDoc()['template_buttons'], Doc, null)?.data); + const noteTypes = DocListCast(Cast(Doc.UserDoc()['template_notes'], Doc, null)?.data); + const clickFuncs = DocListCast(Cast(Doc.UserDoc()['template_clickFuncs'], Doc, null)?.data); const allTemplates = iconViews .concat(templBtns) .concat(noteTypes) @@ -1695,11 +1688,10 @@ export namespace DocUtils { }); }); if (create) { - const newCollection = Docs.Create.PileDocument(docList, { title: 'pileup', x: (x || 0) - size, y: (y || 0) - size, _width: size * 2, _height: size * 2 }); + const newCollection = Docs.Create.PileDocument(docList, { title: 'pileup', x: (x || 0) - size, y: (y || 0) - size, _width: size * 2, _height: size * 2, dragWhenActive: true }); newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - size; newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - size; newCollection._width = newCollection._height = size * 2; - newCollection._jitterRotation = 10; return newCollection; } } @@ -1766,7 +1758,7 @@ export namespace DocUtils { return; } const full = { ...options, _width: 400, title: name }; - const pathname = Utils.prepend(result.accessPaths.agnostic.client); + const pathname = result.accessPaths.agnostic.client; const doc = await DocUtils.DocumentFromType(type, pathname, full, overwriteDoc); if (doc) { const proto = Doc.GetProto(doc); @@ -1891,14 +1883,11 @@ export namespace DocUtils { export function copyDragFactory(dragFactory: Doc) { if (!dragFactory) return undefined; const ndoc = dragFactory.isTemplateDoc ? Doc.ApplyTemplate(dragFactory) : Doc.MakeCopy(dragFactory, true); - ndoc && Doc.AddFileOrphan(Doc.GetProto(ndoc)); if (ndoc && dragFactory['dragFactory_count'] !== undefined) { dragFactory['dragFactory_count'] = NumCast(dragFactory['dragFactory_count']) + 1; Doc.SetInPlace(ndoc, 'title', ndoc.title + ' ' + NumCast(dragFactory['dragFactory_count']).toString(), true); } - if (ndoc && Doc.ActiveDashboard) inheritParentAcls(Doc.ActiveDashboard, ndoc); - return ndoc; } export function delegateDragFactory(dragFactory: Doc) { |