aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/util/DragManager.ts4
-rw-r--r--src/client/util/DropConverter.ts2
-rw-r--r--src/client/views/DocComponent.tsx7
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx1
-rw-r--r--src/client/views/collections/CollectionSubView.tsx11
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx10
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx1
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx18
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx3
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx4
-rw-r--r--src/client/views/nodes/PresBox.tsx79
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx28
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx19
-rw-r--r--src/new_fields/Doc.ts28
-rw-r--r--src/new_fields/documentSchemas.ts2
-rw-r--r--src/server/authentication/models/current_user_utils.ts21
22 files changed, 155 insertions, 101 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 672f94f75..8ea8ded0f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -746,6 +746,10 @@ export namespace Docs {
};
return DockDocument(configs.map(c => c.doc), JSON.stringify(layoutConfig), options, id);
}
+
+ export function DelegateDocument(proto: Doc, options: DocumentOptions = {}) {
+ return InstanceFromProto(proto, undefined, options);
+ }
}
export namespace Get {
@@ -1052,4 +1056,5 @@ export namespace DocUtils {
}
Scripting.addGlobal("Docs", Docs);
+Scripting.addGlobal(function makeDelegate(proto: any) { const d = Docs.Create.DelegateDocument(proto, { title: "child of " + proto.title }); return d; });
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index c06ad3d60..041f2fc2c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -185,7 +185,8 @@ export namespace DragManager {
export function MakeDropTarget(
element: HTMLElement,
dropFunc: (e: Event, de: DropEvent) => void,
- doc?: Doc
+ doc?: Doc,
+ preDropFunc?: (e: Event, de: DropEvent) => void,
): DragDropDisposer {
if ("canDrop" in element.dataset) {
throw new Error(
@@ -199,6 +200,7 @@ export namespace DragManager {
if (de.complete.docDragData && doc?.targetDropAction) {
de.complete.docDragData.dropAction = StrCast(doc.targetDropAction) as dropActionType;
}
+ preDropFunc?.(e, de);
};
element.addEventListener("dashOnDrop", handler);
doc && element.addEventListener("dashPreDrop", preDropHandler);
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 60a6bbb3c..b1993d401 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -68,7 +68,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
});
dbox.dragFactory = layoutDoc;
dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined;
- dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
+ dbox.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory)');
} else if (doc.isButtonBar) {
dbox.ignoreClick = true;
}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index fd0d2bdbb..11866aebe 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,7 +1,7 @@
import { Doc, Opt, DataSym } from '../../new_fields/Doc';
import { Touchable } from './Touchable';
import { computed, action, observable } from 'mobx';
-import { Cast, BoolCast } from '../../new_fields/Types';
+import { Cast, BoolCast, ScriptCast } from '../../new_fields/Types';
import { listSpec } from '../../new_fields/Schema';
import { InkingControl } from './InkingControl';
import { InkTool } from '../../new_fields/InkField';
@@ -33,6 +33,7 @@ export function DocComponent<P extends DocComponentProps, T>(schemaCtor: (doc: D
interface ViewBoxBaseProps {
Document: Doc;
DataDoc?: Doc;
+ ContainingCollectionDoc: Opt<Doc>;
fieldKey: string;
isSelected: (outsideReaction?: boolean) => boolean;
renderDepth: number;
@@ -53,6 +54,8 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps, T>(schemaCtor:
// key where data is stored
@computed get fieldKey() { return this.props.fieldKey; }
+ lookupField = (field: string) => ScriptCast(this.layoutDoc.lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field, container: this.props.ContainingCollectionDoc }).result;
+
active = (outsideReaction?: boolean) => !this.props.Document.isBackground && (this.props.rootSelected(outsideReaction) || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0 || this.layoutDoc.forceActive);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
}
@@ -87,6 +90,8 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
// key where data is stored
@computed get fieldKey() { return this.props.fieldKey; }
+ lookupField = (field: string) => ScriptCast((this.layoutDoc as any).lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field }).result;
+
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
_annotationKey: string = "annotations";
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 769b323ae..a04136e51 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -69,7 +69,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
<FormattedTextBox key={index} {...this.props}
xMargin={NumCast(this.layoutDoc["_carousel-caption-xMargin"])}
yMargin={NumCast(this.layoutDoc["_carousel-caption-yMargin"])}
- Document={this.childLayoutPairs[index].layout} DataDoc={undefined} fieldKey={"caption"}></FormattedTextBox>
+ Document={this.childLayoutPairs[index].layout} DataDoc={undefined} fieldKey={"caption"} />
</div>
</>;
}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 0d859c3f1..822f44f5a 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -685,6 +685,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
if (curPres) {
const pinDoc = Doc.MakeAlias(doc);
pinDoc.presentationTargetDoc = doc;
+ pinDoc.presZoomButton = true;
Doc.AddDocToList(curPres, "data", pinDoc);
if (!DocumentManager.Instance.getDocumentView(curPres)) {
CollectionDockingView.AddRightSplit(curPres);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index eb70cec9d..1fd5c3f44 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -178,7 +178,6 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
LibraryPath={this.props.LibraryPath}
FreezeDimensions={this.props.freezeChildDimensions}
renderDepth={this.props.renderDepth + 1}
- RenderData={this.props.RenderData}
PanelWidth={width}
PanelHeight={height}
NativeHeight={returnZero}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index aaea13ded..af642bc52 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -67,7 +67,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
this.multiTouchDisposer?.();
if (ele) {
this._mainCont = ele;
- this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
+ this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this));
this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this));
this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this));
}
@@ -195,6 +195,15 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {
}
+ protected onInternalPreDrop(e: Event, de: DragManager.DropEvent) {
+ if (de.complete.docDragData) {
+ if (de.complete.docDragData.draggedDocuments.some(d => this.childDocs.includes(d))) {
+ de.complete.docDragData.dropAction = "move";
+ }
+ e.stopPropagation();
+ }
+ }
+
@undoBatch
@action
protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 835dfc637..6d6f8d316 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -742,7 +742,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
Doc.GetProto(img).doubleClickView = doubleClickView;
}
});
- Doc.GetProto(d).layout = ImageBox.LayoutString("hero");
+ Doc.GetProto(d).proto = heroView; // all devices "are" heroViews that share the same layout & defaults. Seems better than making them all be independent and copy a layout string // .layout = ImageBox.LayoutString("hero");
});
Document.childLayoutTemplate = heroView;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index d2afb4855..43da1c44f 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -74,6 +74,7 @@ export enum CollectionViewType {
export interface CollectionViewCustomProps {
filterAddDocument: (doc: Doc) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
childLayoutTemplate?: () => Opt<Doc>; // specify a layout Doc template to use for children of the collection
+ childLayoutString?: string; // specify a layout string to use for children of the collection
}
export interface CollectionRenderProps {
@@ -200,8 +201,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
// currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
const chrome = this.props.Document._chromeStatus === "disabled" || this.props.Document._chromeStatus === "replaced" || type === CollectionViewType.Docking ? (null) :
- <CollectionViewBaseChrome CollectionView={this} key="chrome" PanelWidth={this.bodyPanelWidth} type={type} collapse={this.collapse} />;
- return [chrome, this.SubViewHelper(type, renderProps)];
+ <CollectionViewBaseChrome key="chrome" CollectionView={this} PanelWidth={this.bodyPanelWidth} type={type} collapse={this.collapse} />;
+ return <>{chrome} {this.SubViewHelper(type, renderProps)}</>;
}
@@ -478,6 +479,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
</div>;
}
childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
+ childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString);
render() {
TraceMobx();
@@ -489,7 +491,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
whenActiveChanged: this.whenActiveChanged,
PanelWidth: this.bodyPanelWidth,
ChildLayoutTemplate: this.childLayoutTemplate,
- ChildLayoutString: StrCast(this.props.Document.childLayoutString),
+ ChildLayoutString: this.childLayoutString,
};
return (<div className={"collectionView"}
style={{
@@ -499,7 +501,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
}}
onContextMenu={this.onContextMenu}>
{this.showIsTagged()}
- <div style={{ width: `calc(100% - ${this.facetWidth()}px)` }}>
+ <div className="collectionView-facetCont" style={{ width: `calc(100% - ${this.facetWidth()}px)` }}>
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
</div>
{this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d =>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 707e103fb..411fbd9e2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -878,7 +878,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
onDoubleClick: this.onChildDoubleClickHandler,
ScreenToLocalTransform: childLayout.z ? this.getTransformOverlay : this.getTransform,
renderDepth: this.props.renderDepth + 1,
- RenderData: this.props.RenderData,
PanelWidth: childLayout[WidthSym],
PanelHeight: childLayout[HeightSym],
ContentScaling: returnOne,
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2894d9b65..cdbe506a5 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -14,13 +14,8 @@ import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, highlight?: boolean, z: number, transition?: string } | undefined;
sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined;
- x?: number;
- y?: number;
- z?: number;
zIndex?: number;
highlight?: boolean;
- width?: number;
- height?: number;
jitterRotation: number;
transition?: string;
fitToBox?: boolean;
@@ -38,13 +33,13 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
get displayName() { return "CollectionFreeFormDocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
- get X() { return this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
- get Y() { return this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
+ get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
+ get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); }
get Highlight() { return this.dataProvider?.highlight; }
- get width() { return this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
+ get width() { return this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
get height() {
- const hgt = this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.height : this.layoutDoc[HeightSym]();
+ const hgt = this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.height : this.layoutDoc[HeightSym]();
return (hgt === undefined && this.nativeWidth && this.nativeHeight) ? this.width * this.nativeHeight / this.nativeWidth : hgt;
}
@computed get freezeDimensions() { return this.props.FreezeDimensions; }
@@ -75,10 +70,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
contentScaling = () => this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1;
panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.());
panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
- getTransform = (): Transform => this.props.ScreenToLocalTransform()
- .translate(-this.X, -this.Y)
- .scale(1 / this.contentScaling())
-
+ getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling());
focusDoc = (doc: Doc) => this.props.focus(doc, false);
NativeWidth = () => this.nativeWidth;
NativeHeight = () => this.nativeHeight;
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 749fb98be..81667e549 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -77,11 +77,11 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
render() {
const style: { [key: string]: any } = {};
const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
+ const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
+ return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.props.RootDoc, this: this.props.Document }).result as string || "";
+ };
Object.keys(divKeys).map((prop: string) => {
const p = (this.props as any)[prop] as string;
- const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.props.RootDoc, this: this.props.Document }).result as string || "";
- };
style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
});
const Tag = this.props.htmltag as keyof JSX.IntrinsicElements;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7c7c03db2..7a16e8836 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -78,7 +78,6 @@ export interface DocumentViewProps {
setupDragLines?: () => void;
renderDepth: number;
ContentScaling: () => number;
- RenderData?: () => Doc;
PanelWidth: () => number;
PanelHeight: () => number;
pointerEvents?: boolean;
@@ -996,7 +995,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
LayoutTemplate={this.props.LayoutTemplate}
makeLink={this.makeLink}
rootSelected={this.rootSelected}
- RenderData={this.props.RenderData}
dontRegisterView={this.props.dontRegisterView}
fitToBox={this.props.fitToBox}
LibraryPath={this.props.LibraryPath}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 40d55ce38..016d2a1ae 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -50,12 +50,13 @@ export interface FieldViewProps {
setVideoBox?: (player: VideoBox) => void;
ContentScaling: () => number;
ChromeHeight?: () => number;
- RenderData?: () => Doc;
// properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
height?: number;
width?: number;
background?: string;
color?: string;
+ xMargin?: number;
+ yMargin?: number;
}
@observer
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index d43936949..39d7109b1 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -36,7 +36,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
@observable private _keyInput: string = "";
@observable private _valueInput: string = "";
@computed get splitPercentage() { return NumCast(this.props.Document.schemaSplitPercentage, 50); }
- get fieldDocToLayout() { return this.props.Document; }
+ get fieldDocToLayout() { return this.props.fieldKey ? Cast(this.props.Document[this.props.fieldKey], Doc, null) : this.props.Document; }
@action
onEnterKey = (e: React.KeyboardEvent): void => {
@@ -238,8 +238,8 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
const openItems: ContextMenuProps[] = open && "subitems" in open ? open.subitems : [];
openItems.push({
description: "Default Perspective", event: () => {
- this.props.addDocTab(this.fieldDocToLayout, "inTab");
this.props.addDocTab(this.props.Document, "close");
+ this.props.addDocTab(this.fieldDocToLayout, "onRight");
}, icon: "image"
});
!open && cm.addItem({ description: "Change Perspective...", subitems: openItems, icon: "external-link-alt" });
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 6e3420f22..343e74c87 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -17,6 +17,10 @@ import "./PresBox.scss";
import { ViewBoxBaseComponent } from "../DocComponent";
import { makeInterface } from "../../../new_fields/Schema";
import { List } from "../../../new_fields/List";
+import { Docs } from "../../documents/Documents";
+import { PrefetchProxy } from "../../../new_fields/Proxy";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { Scripting } from "../../util/Scripting";
type PresBoxSchema = makeInterface<[typeof documentSchema]>;
const PresBoxDocument = makeInterface(documentSchema);
@@ -26,7 +30,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
@observable _isChildActive = false;
@computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
- @computed get currentIndex() { return NumCast(this.rootDoc._itemIndex); }
+ @computed get currentIndex() { return NumCast(this.presElement?.currentIndex); }
+ @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
+ constructor(props: any) {
+ super(props);
+ if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
+ Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
+ title: "pres element template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data"
+ }));
+ // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
+ // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
+ // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
+ // stored on each pres element.
+ (this.presElement as Doc).lookupField = ScriptField.MakeScript(
+ `if (field === 'indexInPres') return docList(container[container.presentationFieldKey]).indexOf(data);` +
+ "if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 50 : 46;" +
+ "return undefined;", { field: "string", data: Doc.name, container: Doc.name });
+ }
+ this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
+ }
componentDidMount() {
this.rootDoc.presBox = this.rootDoc;
@@ -152,7 +174,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
if (docToJump === curDoc) {
//checking if curDoc has navigation open
- const target = await DocCastAsync(curDoc.presentationTargetDoc);
+ const target = (await DocCastAsync(curDoc.presentationTargetDoc)) || curDoc;
if (curDoc.presNavButton && target) {
DocumentManager.Instance.jumpToDocument(target, false, undefined, srcContext);
} else if (curDoc.presZoomButton && target) {
@@ -166,17 +188,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
}
-
//The function that is called when a document is clicked or reached through next or back.
//it'll also execute the necessary actions if presentation is playing.
public gotoDocument = (index: number, fromDoc: number) => {
this.updateCurrentPresentation();
Doc.UnBrushAllDocs();
if (index >= 0 && index < this.childDocs.length) {
- this.rootDoc._itemIndex = index;
+ this.presElement.currentIndex = index;
- if (!this.layoutDoc.presStatus) {
- this.layoutDoc.presStatus = true;
+ if (!this.presElement.presStatus) {
+ this.presElement.presStatus = true;
this.startPresentation(index);
}
@@ -189,10 +210,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
//The function that starts or resets presentaton functionally, depending on status flag.
startOrResetPres = () => {
this.updateCurrentPresentation();
- if (this.layoutDoc.presStatus) {
+ if (this.presElement.presStatus) {
this.resetPresentation();
} else {
- this.layoutDoc.presStatus = true;
+ this.presElement.presStatus = true;
this.startPresentation(0);
this.gotoDocument(0, this.currentIndex);
}
@@ -204,7 +225,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this.updateCurrentPresentation();
this.childDocs.forEach(doc => (doc.presentationTargetDoc as Doc).opacity = 1);
this.rootDoc._itemIndex = 0;
- this.layoutDoc.presStatus = false;
+ this.presElement.presStatus = false;
}
//The function that starts the presentation, also checking if actions should be applied
@@ -241,43 +262,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
});
- initializeViewAliases = (docList: Doc[], viewtype: CollectionViewType) => {
- const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 46;
- this.rootDoc.presCollapsedHeight = hgt;
- }
+ @undoBatch
+ viewChanged = action((e: React.ChangeEvent) => {
+ //@ts-ignore
+ const viewType = e.target.selectedOptions[0].value as CollectionViewType;
+ viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
+ this.updateMinimize(e, this.rootDoc._viewType = viewType);
+ });
+ whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
addDocumentFilter = (doc: Doc) => {
- doc.presentationTargetDoc = doc.aliasOf;
+ doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
+ !this.childDocs.includes(doc) && (doc.presZoomButton = true);
return true;
}
-
+ childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
-
selectElement = (doc: Doc) => this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.rootDoc._itemIndex));
-
getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
-
panelHeight = () => this.props.PanelHeight() - 20;
-
active = (outsideReaction?: boolean) => ((InkingControl.Instance.selectedTool === InkTool.None && !this.layoutDoc.isBackground) &&
(this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
- whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
-
- @undoBatch
- viewChanged = action((e: React.ChangeEvent) => {
- //@ts-ignore
- const viewType = e.target.selectedOptions[0].value as CollectionViewType;
- viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
- this.updateMinimize(e, this.rootDoc._viewType = viewType);
- });
-
- returnSelf = () => this.rootDoc;
- childLayoutTemplate = () => this.rootDoc._viewType === CollectionViewType.Stacking ? Cast(Doc.UserDoc()["template-presentation"], Doc, null) : undefined;
render() {
this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.map((child, i) => child));
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
- this.initializeViewAliases(this.childDocs, mode);
return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
<div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
<select className="presBox-viewPicker"
@@ -302,13 +311,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className="presBox-listCont" >
{mode !== CollectionViewType.Invalid ?
<CollectionView {...this.props}
+ ContainingCollectionDoc={this.props.Document}
PanelWidth={this.props.PanelWidth}
PanelHeight={this.panelHeight}
moveDocument={returnFalse}
childLayoutTemplate={this.childLayoutTemplate}
filterAddDocument={this.addDocumentFilter}
removeDocument={returnFalse}
- RenderData={this.returnSelf}
focus={this.selectElement}
ScreenToLocalTransform={this.getTransform} />
: (null)
@@ -316,4 +325,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
</div>;
}
-} \ No newline at end of file
+}
+Scripting.addGlobal(function lookupPresBoxField(presLayout: Doc, data: Doc, fieldKey: string) {
+});
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 3fb3f5644..30c4a45ac 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -58,14 +58,15 @@ import { FieldView, FieldViewProps } from "../FieldView";
import "./FormattedTextBox.scss";
import { FormattedTextBoxComment, formattedTextBoxCommentPlugin } from './FormattedTextBoxComment';
import React = require("react");
+import { ScriptField } from '../../../../new_fields/ScriptField';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
export interface FormattedTextBoxProps {
- hideOnLeave?: boolean;
- makeLink?: () => Opt<Doc>;
- xMargin?: number;
+ makeLink?: () => Opt<Doc>; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text
+ hideOnLeave?: boolean; // used by DocumentView for setting caption's hide on leave (bcz: would prefer to have caption-hideOnLeave field set or something similar)
+ xMargin?: number; // used to override document's settings for xMargin --- see CollectionCarouselView
yMargin?: number;
}
@@ -198,14 +199,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 1000)));
const curText = state.doc.textBetween(0, state.doc.content.size, " \n");
const curTemp = Cast(this.props.Document[this.props.fieldKey + "-textTemplate"], RichTextField);
- if (!this._applyingChange) {
+ const curProto = Cast(Cast(this.dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null);
+ const json = JSON.stringify(state.toJSON());
+ if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) {
this._applyingChange = true;
this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
- if (!curTemp || curText) { // if no template, or there's text, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
- this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()), curText);
+ if ((!curTemp && !curProto) || curText) { // if no template, or there's text, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
+ this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText);
this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
} else { // if we've deleted all the text in a note driven by a template, then restore the template data
- this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse(curTemp.Data)));
+ this.dataDoc[this.props.fieldKey] = undefined;
+ this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((curProto || curTemp).Data)));
this.dataDoc[this.props.fieldKey + "-noTemplate"] = undefined; // mark the data field as not being split from any template it might have
}
this._applyingChange = false;
@@ -1239,6 +1243,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
+ const style: { [key: string]: any } = {};
+ const divKeys = ["width", "height", "background"];
+ const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
+ return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.rootDoc, this: this.layoutDoc }).result as string || "";
+ };
+ divKeys.map((prop: string) => {
+ const p = (this.props as any)[prop] as string;
+ p && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
+ });
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground;
if (this.props.isSelected()) {
@@ -1257,6 +1270,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
pointerEvents: interactive ? "none" : undefined,
fontSize: Cast(this.layoutDoc._fontSize, "number", null),
fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"),
+ ...style
}}
onContextMenu={this.specificContextMenu}
onKeyDown={this.onKeyPress}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 1887c8d45..6d7602268 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -5,7 +5,7 @@ import { Doc, DataSym, DocListCast } from "../../../new_fields/Doc";
import { documentSchema } from '../../../new_fields/documentSchemas';
import { Id } from "../../../new_fields/FieldSymbols";
import { createSchema, makeInterface } from '../../../new_fields/Schema';
-import { Cast, NumCast } from "../../../new_fields/Types";
+import { Cast, NumCast, BoolCast, ScriptCast } from "../../../new_fields/Types";
import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero } from "../../../Utils";
import { Transform } from "../../util/Transform";
import { CollectionViewType } from '../collections/CollectionView';
@@ -38,11 +38,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
_heightDisposer: IReactionDisposer | undefined;
- @computed get indexInPres() { return DocListCast(this.presBoxDoc.presOrderedDocs).findIndex(d => d === this.rootDoc); }
- @computed get presBoxDoc() { return Cast(this.props.RenderData?.().presBox, Doc) as Doc; }
- @computed get targetDoc() { return this.rootDoc.presentationTargetDoc as Doc; }
- @computed get currentIndex() { return NumCast(this.presBoxDoc?._itemIndex); }
- @computed get collapsedHeight() { return NumCast(this.presBoxDoc?.presCollapsedHeight); }
+ // these fields are conditionally computed fields on the layout document that take this document as a parameter
+ @computed get indexInPres() { return Number(this.lookupField("indexInPres")); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
+ @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation elemnt template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
+ @computed get presStatus() { return BoolCast(this.layoutDoc.presStatus); }
+ @computed get currentIndex() { return NumCast(this.layoutDoc.currentIndex); }
+ @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
componentDidMount() {
this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
@@ -65,7 +66,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
this.targetDoc.opacity = 1;
}
} else {
- if (this.presBoxDoc.presStatus && this.indexInPres > this.currentIndex && this.targetDoc) {
+ if (this.presStatus && this.indexInPres > this.currentIndex && this.targetDoc) {
this.targetDoc.opacity = 0;
}
}
@@ -86,7 +87,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
}
} else {
if (this.rootDoc.presFadeButton) this.rootDoc.presFadeButton = false;
- if (this.presBoxDoc.presStatus && this.indexInPres < this.currentIndex && this.targetDoc) {
+ if (this.presStatus && this.indexInPres < this.currentIndex && this.targetDoc) {
this.targetDoc.opacity = 0;
}
}
@@ -107,7 +108,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
}
} else {
this.rootDoc.presHideAfterButton = false;
- if (this.presBoxDoc.presStatus && (this.indexInPres < this.currentIndex) && this.targetDoc) {
+ if (this.presStatus && (this.indexInPres < this.currentIndex) && this.targetDoc) {
this.targetDoc.opacity = 0.5;
}
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 9256f82c2..9efb14d03 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -292,6 +292,9 @@ export namespace Doc {
export function IsPrototype(doc: Doc) {
return GetT(doc, "isPrototype", "boolean", true);
}
+ export function IsBaseProto(doc: Doc) {
+ return GetT(doc, "baseProto", "boolean", true);
+ }
export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
const hasProto = doc.proto instanceof Doc;
const onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
@@ -581,30 +584,44 @@ export namespace Doc {
return copy;
}
- export function MakeClone(doc: Doc, cloneProto: boolean = true): Doc {
+ export function MakeClone(doc: Doc, cloneMap: Map<Doc, Doc> = new Map()): Doc {
+ if (Doc.IsBaseProto(doc)) return doc;
+ if (cloneMap.get(doc)) return cloneMap.get(doc)!;
const copy = new Doc(undefined, true);
+ cloneMap.set(doc, copy);
const exclude = Cast(doc.excludeFields, listSpec("string"), []);
Object.keys(doc).forEach(key => {
if (exclude.includes(key)) return;
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
const field = ProxyField.WithoutProxy(() => doc[key]);
- if (key === "proto" && cloneProto) {
+ if (key === "proto") {
if (doc[key] instanceof Doc) {
- copy[key] = Doc.MakeClone(doc[key]!, false);
+ copy[key] = Doc.MakeClone(doc[key]!, cloneMap);
}
} else {
if (field instanceof RefField) {
copy[key] = field;
} else if (cfield instanceof ComputedField) {
copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
+ if (field instanceof ObjectField) {
+ const list = Cast(doc[key], listSpec(Doc));
+ if (list !== undefined && !(list instanceof Promise)) {
+ copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.MakeClone(d as Doc, cloneMap)));
+ } else {
+ copy[key] = doc[key] instanceof Doc ?
+ key.includes("layout[") ?
+ undefined : Doc.MakeClone(doc[key] as Doc, cloneMap) : // reference documents except copy documents that are expanded teplate fields
+ ObjectField.MakeCopy(field);
+ }
+ }
} else if (field instanceof ObjectField) {
const list = Cast(doc[key], listSpec(Doc));
if (list !== undefined && !(list instanceof Promise)) {
- copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.MakeCopy(d as Doc, false)));
+ copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.MakeClone(d as Doc, cloneMap)));
} else {
copy[key] = doc[key] instanceof Doc ?
key.includes("layout[") ?
- Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields
+ undefined : Doc.MakeClone(doc[key] as Doc, cloneMap) : // reference documents except copy documents that are expanded teplate fields
ObjectField.MakeCopy(field);
}
} else if (field instanceof Promise) {
@@ -616,6 +633,7 @@ export namespace Doc {
});
Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true);
copy.cloneOf = doc;
+ cloneMap.set(doc, copy);
return copy;
}
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index e71fc27f3..e7d27d81e 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -78,7 +78,7 @@ export const documentSchema = createSchema({
// drag drop properties
dragFactory: Doc, // the document that serves as the "template" for the onDragStart script. ie, to drag out copies of the dragFactory document.
dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
- targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move")
+ targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move'
childDropAction: "string", // specify the override for what should happen when the child of a collection is dragged from it and dropped (can be "alias" or "copy")
removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped
});
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index b9de93559..b63a3dbbf 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -49,7 +49,7 @@ export class CurrentUserUtils {
);
queryTemplate.isTemplateDoc = makeTemplate(queryTemplate);
doc["template-button-query"] = CurrentUserUtils.ficon({
- onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
+ onDragStart: ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'),
dragFactory: new PrefetchProxy(queryTemplate) as any as Doc,
removeDropProperties: new List<string>(["dropAction"]), title: "query view", icon: "question-circle"
});
@@ -65,7 +65,7 @@ export class CurrentUserUtils {
);
slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
doc["template-button-slides"] = CurrentUserUtils.ficon({
- onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
+ onDragStart: ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'),
dragFactory: new PrefetchProxy(slideTemplate) as any as Doc,
removeDropProperties: new List<string>(["dropAction"]), title: "presentation slide", icon: "address-card"
});
@@ -73,11 +73,13 @@ export class CurrentUserUtils {
if (doc["template-button-description"] === undefined) {
const descriptionTemplate = Docs.Create.TextDocument(" ", { title: "header", _height: 100 }, "header"); // text needs to be a space to allow templateText to be created
- Doc.GetProto(descriptionTemplate).layout = "<div><FormattedTextBox {...props} background='orange' height='50px' fieldKey={'header'}/><FormattedTextBox {...props} height='calc(100% - 50px)' fieldKey={'text'}/></div>";
+ Doc.GetProto(descriptionTemplate).layout =
+ "<div><FormattedTextBox {...props} height='{this._headerHeight||75}px' background='{this._headerColor||`orange`}' fieldKey={'header'}/>" +
+ "<FormattedTextBox {...props} height='calc(100% - {this._headerHeight||75}px)' fieldKey={'text'}/></div>";
descriptionTemplate.isTemplateDoc = makeTemplate(descriptionTemplate, true, "descriptionView");
doc["template-button-description"] = CurrentUserUtils.ficon({
- onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
+ onDragStart: ScriptField.MakeFunction('makeDelegate(this.dragFactory)'),
dragFactory: new PrefetchProxy(descriptionTemplate) as any as Doc,
removeDropProperties: new List<string>(["dropAction"]), title: "description view", icon: "window-maximize"
});
@@ -127,7 +129,7 @@ export class CurrentUserUtils {
long.title = "Long Description";
doc["template-button-detail"] = CurrentUserUtils.ficon({
- onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'),
+ onDragStart: ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'),
dragFactory: new PrefetchProxy(detailView) as any as Doc,
removeDropProperties: new List<string>(["dropAction"]), title: "detail view", icon: "window-maximize"
});
@@ -136,7 +138,7 @@ export class CurrentUserUtils {
if (doc["template-buttons"] === undefined) {
doc["template-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument([doc["template-button-slides"] as Doc, doc["template-button-description"] as Doc,
doc["template-button-query"] as Doc, doc["template-button-detail"] as Doc], {
- title: "Compound Item Creators", _xMargin: 0, _showTitle: "title",
+ title: "Document Prototypes", _xMargin: 0, _showTitle: "title",
_autoHeight: true, _width: 500, columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled",
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
}));
@@ -257,7 +259,7 @@ export class CurrentUserUtils {
}[] {
if (doc.emptyPresentation === undefined) {
doc.emptyPresentation = Docs.Create.PresDocument(new List<Doc>(),
- { title: "Presentation", _viewType: CollectionViewType.Stacking, _LODdisable: true, _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" });
+ { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", _LODdisable: true, _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" });
}
if (doc.emptyCollection === undefined) {
doc.emptyCollection = Docs.Create.FreeformDocument([],
@@ -576,11 +578,6 @@ export class CurrentUserUtils {
// 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, _height: 46, isTemplateDoc: true, isTemplateForField: "data"
- }));
- }
if (doc.activePresentation === undefined) {
doc.activePresentation = Docs.Create.PresDocument(new List<Doc>(), {
title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias",