aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionCarouselView.scss1
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx18
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx3
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx10
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx3
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx5
-rw-r--r--src/client/views/collections/CollectionSubView.tsx114
-rw-r--r--src/client/views/collections/CollectionTimeView.scss7
-rw-r--r--src/client/views/collections/CollectionTreeView.scss9
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx77
-rw-r--r--src/client/views/collections/CollectionView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx14
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx21
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx3
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx1
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx1
16 files changed, 177 insertions, 118 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss
index ad369bbff..fd1296286 100644
--- a/src/client/views/collections/CollectionCarouselView.scss
+++ b/src/client/views/collections/CollectionCarouselView.scss
@@ -1,6 +1,7 @@
.collectionCarouselView-outer {
background: gray;
+ height : 100%;
.collectionCarouselView-caption {
margin-left: 10%;
margin-right: 10%;
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 00edf71dd..226a1c813 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -12,6 +12,8 @@ import { CollectionSubView } from './CollectionSubView';
import { faCaretLeft, faCaretRight } from '@fortawesome/free-solid-svg-icons';
import { Doc } from '../../../new_fields/Doc';
import { FormattedTextBox } from '../nodes/FormattedTextBox';
+import { ContextMenu } from '../ContextMenu';
+import { ObjectField } from '../../../new_fields/ObjectField';
type CarouselDocument = makeInterface<[typeof documentSchema,]>;
const CarouselDocument = makeInterface(documentSchema);
@@ -50,6 +52,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
<div>
<div className="collectionCarouselView-image">
<ContentFittingDocumentView {...this.props}
+ backgroundColor={this.props.backgroundColor}
Document={this.childLayoutPairs[index].layout}
DataDocument={this.childLayoutPairs[index].data}
PanelHeight={this.panelHeight}
@@ -70,8 +73,21 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
</div>
</>;
}
+
+
+ onContextMenu = (e: React.MouseEvent): void => {
+ // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
+ if (!e.isPropagationStopped()) {
+ ContextMenu.Instance.addItem({
+ description: "Make Hero Image", event: () => {
+ const index = NumCast(this.layoutDoc._itemIndex);
+ (this.dataDoc || Doc.GetProto(this.props.Document)).hero = ObjectField.MakeCopy(this.childLayoutPairs[index].layout.data as ObjectField);
+ }, icon: "plus"
+ });
+ }
+ }
render() {
- return <div className="collectionCarouselView-outer" ref={this.createDashEventsTarget}>
+ return <div className="collectionCarouselView-outer" ref={this.createDashEventsTarget} onContextMenu={this.onContextMenu}>
{this.content}
{this.buttons}
</div>;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index cb413b3e3..0b7dbea7c 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -599,6 +599,7 @@ interface DockedFrameProps {
dataDocumentId: FieldId;
glContainer: any;
libraryPath: (FieldId[]);
+ backgroundColor?: (doc:Doc) => string| undefined;
//collectionDockingView: CollectionDockingView
}
@observer
@@ -756,7 +757,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
parentActive={returnTrue}
whenActiveChanged={emptyFunction}
focus={emptyFunction}
- backgroundColor={returnEmptyString}
+ backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
addDocTab={this.addDocTab}
pinToPres={DockedFrameRenderer.PinDoc}
ContainingCollectionView={undefined}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 67062ae41..7eb316cf0 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -38,8 +38,8 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
componentDidMount() {
// is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported).
- this._widthDisposer = reaction(() => this.props.Document[HeightSym]() + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0),
- () => this.props.Document._width = 5 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10),
+ this._widthDisposer = reaction(() => this.props.Document[HeightSym]() + this.childDocs.length + (this.props.Document.linearViewIsExpanded ? 1 : 0),
+ () => this.props.Document._width = 5 + (this.props.Document.linearViewIsExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10),
{ fireImmediately: true }
);
@@ -84,8 +84,8 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
const guid = Utils.GenerateGuid();
return <div className="collectionLinearView-outer">
<div className="collectionLinearView" ref={this.createDashEventsTarget} >
- <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
- onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
+ <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle}
+ onChange={action((e: any) => this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} />
<label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
<div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document._width, 25) }}>
@@ -97,7 +97,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
return <div className={`collectionLinearView-docBtn` + (pair.layout.onClick || pair.layout.onDragStart ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
style={{
width: nested ? pair.layout[WidthSym]() : this.dimension() - deltaSize,
- height: nested && pair.layout.isExpanded ? pair.layout[HeightSym]() : this.dimension() - deltaSize,
+ height: nested && pair.layout.linearViewIsExpanded ? pair.layout[HeightSym]() : this.dimension() - deltaSize,
}} >
<DocumentView
Document={pair.layout}
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index caffa7eb1..a3b1b5ec0 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -37,7 +37,8 @@ export interface CellProps {
renderDepth: number;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
pinToPres: (document: Doc) => void;
- moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
+ moveDocument: (document: Doc, targetCollection: Doc | undefined,
+ addDocument: (document: Doc) => boolean) => boolean;
isFocused: boolean;
changeFocusedCellByIndex: (row: number, col: number) => void;
setIsEditing: (isEditing: boolean) => void;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index d21ae32bc..055035b3e 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -40,7 +40,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
@computed get filteredChildren() { return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.isMinimized).map(pair => pair.layout); }
@computed get xMargin() { return NumCast(this.props.Document._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
- @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document._yMargin, 0)); } // 2 * this.gridGap)); }
+ @computed get yMargin() { return Math.max(this.props.Document._showTitle && !this.props.Document._showTitleHover ? 30 : 0, NumCast(this.props.Document._yMargin, 0)); } // 2 * this.gridGap)); }
@computed get gridGap() { return NumCast(this.props.Document._gridGap, 10); }
@computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
@computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@@ -159,6 +159,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
return <ContentFittingDocumentView
Document={doc}
DataDocument={dataDoc}
+ backgroundColor={this.props.backgroundColor}
LayoutDoc={this.props.childLayoutTemplate}
LibraryPath={this.props.LibraryPath}
renderDepth={this.props.renderDepth + 1}
@@ -369,8 +370,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
if (!e.isPropagationStopped()) {
const subItems: ContextMenuProps[] = [];
subItems.push({ description: `${this.props.Document.fillColumn ? "Variable Size" : "Autosize"} Column`, event: () => this.props.Document.fillColumn = !this.props.Document.fillColumn, icon: "plus" });
- subItems.push({ description: `${this.props.Document.showTitles ? "Hide Titles" : "Show Titles"}`, event: () => this.props.Document.showTitles = !this.props.Document.showTitles ? "title" : "", icon: "plus" });
- subItems.push({ description: `${this.props.Document.showCaptions ? "Hide Captions" : "Show Captions"}`, event: () => this.props.Document.showCaptions = !this.props.Document.showCaptions ? "caption" : "", icon: "plus" });
ContextMenu.Instance.addItem({ description: "Stacking Options ...", subitems: subItems, icon: "eye" });
}
}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 32480ad4e..0963e1ea6 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -159,7 +159,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
const docDragData = de.complete.docDragData;
(this.props.Document.dropConverter instanceof ScriptField) &&
this.props.Document.dropConverter.script.run({ dragData: docDragData }); /// bcz: check this
- if (docDragData && !docDragData.applyAsTemplate) {
+ if (docDragData) {
if (de.altKey && docDragData.draggedDocuments.length) {
this.childDocs.map(doc => {
doc.layout_fromParent = docDragData.draggedDocuments[0];
@@ -253,7 +253,8 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
}
});
} else {
- const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300, documentText: text });
+ const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300 });
+ Doc.GetProto(htmlDoc)["data-text"] = text;
this.props.addDocument(htmlDoc);
}
return;
@@ -283,63 +284,74 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
const albumId = matches[3];
const mediaItems = await GooglePhotos.Query.AlbumSearch(albumId);
console.log(mediaItems);
+ return;
}
- const batch = UndoManager.StartBatch("collection view drop");
- const promises: Promise<void>[] = [];
- // tslint:disable-next-line:prefer-for-of
- for (let i = 0; i < e.dataTransfer.items.length; i++) {
- const item = e.dataTransfer.items[i];
- if (item.kind === "string" && item.type.indexOf("uri") !== -1) {
- let str: string;
- const prom = new Promise<string>(resolve => e.dataTransfer.items[i].getAsString(resolve))
- .then(action((s: string) => rp.head(Utils.CorsProxy(str = s))))
- .then(result => {
- const type = result["content-type"];
- if (type) {
- Docs.Get.DocumentFromType(type, str, options)
- .then(doc => doc && this.props.addDocument(doc));
- }
- });
- promises.push(prom);
- }
- const type = item.type;
- if (item.kind === "file") {
- const file = item.getAsFile();
- const formData = new FormData();
-
- if (!file || !file.type) {
- continue;
+ const { items } = e.dataTransfer;
+ const { length } = items;
+ if (length) {
+ const batch = UndoManager.StartBatch("collection view drop");
+ const promises: Promise<void>[] = [];
+ // tslint:disable-next-line:prefer-for-of
+ for (let i = 0; i < length; i++) {
+ const item = e.dataTransfer.items[i];
+ if (item.kind === "string" && item.type.indexOf("uri") !== -1) {
+ let str: string;
+ const prom = new Promise<string>(resolve => item.getAsString(resolve))
+ .then(action((s: string) => rp.head(Utils.CorsProxy(str = s))))
+ .then(result => {
+ const type = result["content-type"];
+ if (type) {
+ Docs.Get.DocumentFromType(type, str, options)
+ .then(doc => doc && this.props.addDocument(doc));
+ }
+ });
+ promises.push(prom);
}
+ const type = item.type;
+ if (item.kind === "file") {
+ const file = item.getAsFile();
+ const formData = new FormData();
+
+ if (!file || !file.type) {
+ continue;
+ }
- formData.append('file', file);
- const dropFileName = file ? file.name : "-empty-";
- promises.push(Networking.PostFormDataToServer("/uploadFormData", formData).then(results => {
- results.map(action((result: any) => {
- const { accessPaths, nativeWidth, nativeHeight, contentSize } = result;
- const full = { ...options, _width: 300, title: dropFileName };
- const pathname = Utils.prepend(accessPaths.agnostic.client);
- Docs.Get.DocumentFromType(type, pathname, full).then(doc => {
- if (doc) {
- const proto = Doc.GetProto(doc);
- proto.fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, "");
- nativeWidth && (proto["data-nativeWidth"] = nativeWidth);
- nativeHeight && (proto["data-nativeHeight"] = nativeHeight);
- contentSize && (proto.contentSize = contentSize);
- this.props?.addDocument(doc);
+ formData.append('file', file);
+ const dropFileName = file ? file.name : "-empty-";
+ promises.push(Networking.PostFormDataToServer("/uploadFormData", formData).then(results => {
+ results.map(action((result: any) => {
+ const { accessPaths, nativeWidth, nativeHeight, contentSize } = result;
+ if (Object.keys(accessPaths).length) {
+ const full = { ...options, _width: 300, title: dropFileName };
+ const pathname = Utils.prepend(accessPaths.agnostic.client);
+ Docs.Get.DocumentFromType(type, pathname, full).then(doc => {
+ if (doc) {
+ const proto = Doc.GetProto(doc);
+ proto.fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, "");
+ nativeWidth && (proto["data-nativeWidth"] = nativeWidth);
+ nativeHeight && (proto["data-nativeHeight"] = nativeHeight);
+ contentSize && (proto.contentSize = contentSize);
+ this.props?.addDocument(doc);
+ }
+ });
+ } else {
+ alert("Upload failed...");
}
- });
+ }));
}));
- }));
+ }
}
- }
- if (promises.length) {
- Promise.all(promises).finally(() => { completed && completed(); batch.end(); });
- } else {
- if (text && !text.includes("https://")) {
- this.props.addDocument(Docs.Create.TextDocument(text, { ...options, _width: 400, _height: 315 }));
+ if (promises.length) {
+ Promise.all(promises).finally(() => { completed && completed(); batch.end(); });
+ } else {
+ if (text && !text.includes("https://")) {
+ this.props.addDocument(Docs.Create.TextDocument(text, { ...options, _width: 400, _height: 315 }));
+ }
+ batch.end();
}
- batch.end();
+ } else {
+ alert("No uploadable content found.");
}
}
}
diff --git a/src/client/views/collections/CollectionTimeView.scss b/src/client/views/collections/CollectionTimeView.scss
index 2dffb3ea0..6ea5e6908 100644
--- a/src/client/views/collections/CollectionTimeView.scss
+++ b/src/client/views/collections/CollectionTimeView.scss
@@ -67,6 +67,7 @@
pointer-events: all;
padding: 5px;
border: 1px solid black;
+ display:none;
}
.collectionTimeView-treeView {
@@ -131,4 +132,10 @@
.collectionFreeform-customText {
text-align: center;
}
+}
+
+.collectionTimeView:hover, .collectionTimeView-pivot:hover {
+ .pivotKeyEntry {
+ display:unset;
+ }
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 2fa6813d7..6ebe81545 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -63,7 +63,9 @@
font-size: 8pt;
margin-left: 3px;
display: none;
- background: lightgray;
+}
+.collectionTreeView-keyHeader:hover {
+ background: #797777;
}
.collectionTreeView-subtitle {
@@ -84,9 +86,11 @@
.treeViewItem-openRight {
display: none;
height: 17px;
- background: gray;
width: 15px;
}
+.treeViewItem-openRight:hover {
+ background: #797777;
+}
.treeViewItem-border {
display: inherit;
@@ -101,7 +105,6 @@
.treeViewItem-openRight {
display: inline-block;
height: 17px;
- background: #a8a7a7;
width: 15px;
// display: inline;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index be2947dff..e2b3cc425 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -3,7 +3,7 @@ import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, runInAction, untracked } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from '../../../new_fields/Doc';
+import { Doc, DocListCast, Field, HeightSym, WidthSym, DataSym, Opt } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
@@ -56,12 +56,13 @@ export interface TreeViewProps {
indentDocument?: () => void;
outdentDocument?: () => void;
ScreenToLocalTransform: () => Transform;
+ backgroundColor?: (doc: Doc) => string | undefined;
outerXf: () => { translateX: number, translateY: number };
treeViewId: Doc;
parentKey: string;
active: (outsideReaction?: boolean) => boolean;
treeViewHideHeaderFields: () => boolean;
- preventTreeViewOpen: boolean;
+ treeViewPreventOpen: boolean;
renderedIds: string[];
onCheckedClick?: ScriptField;
}
@@ -84,11 +85,10 @@ library.add(faPlus, faMinus);
*
* special fields:
* treeViewOpen : flag denoting whether the documents sub-tree (contents) is visible or hidden
- * preventTreeViewOpen : ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document)
+ * treeViewPreventOpen : ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document)
* treeViewExpandedView : name of field whose contents are being displayed as the document's subtree
*/
class TreeView extends React.Component<TreeViewProps> {
- static loadId = "";
private _header?: React.RefObject<HTMLDivElement> = React.createRef();
private _treedropDisposer?: DragManager.DragDropDisposer;
private _dref = React.createRef<HTMLDivElement>();
@@ -97,8 +97,8 @@ class TreeView extends React.Component<TreeViewProps> {
get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); }
@observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
- set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = this._overrideTreeViewOpen = c; }
- @computed get treeViewOpen() { return (!this.props.preventTreeViewOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; }
+ set treeViewOpen(c: boolean) { if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = this._overrideTreeViewOpen = c; }
+ @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && BoolCast(this.props.document.treeViewOpen)) || this._overrideTreeViewOpen; }
@computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); }
@computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
@computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
@@ -171,7 +171,7 @@ class TreeView extends React.Component<TreeViewProps> {
editableView = (key: string, style?: string) => (<EditableView
oneLine={true}
display={"inline-block"}
- editing={this.dataDoc[Id] === TreeView.loadId}
+ editing={this.dataDoc[Id] === EditableView.loadId}
contents={StrCast(this.props.document[key])}
height={12}
fontStyle={style}
@@ -180,18 +180,17 @@ class TreeView extends React.Component<TreeViewProps> {
SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)}
OnFillDown={undoBatch((value: string) => {
Doc.SetInPlace(this.props.document, key, value, false);
- const layoutDoc = this.props.document.layout_custom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layout_custom)) : undefined;
- const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
- TreeView.loadId = doc[Id];
+ const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
+ EditableView.loadId = doc[Id];
return this.props.addDocument(doc);
})}
OnTab={undoBatch((shift?: boolean) => {
- TreeView.loadId = this.dataDoc[Id];
+ EditableView.loadId = this.dataDoc[Id];
shift ? this.props.outdentDocument?.() : this.props.indentDocument?.();
setTimeout(() => { // unsetting/setting brushing for this doc will recreate & refocus this editableView after all other treeview changes have been made to the Dom (which may remove focus from this document).
Doc.UnBrushDoc(this.props.document);
Doc.BrushDoc(this.props.document);
- TreeView.loadId = "";
+ EditableView.loadId = "";
}, 0);
})}
/>)
@@ -291,8 +290,8 @@ class TreeView extends React.Component<TreeViewProps> {
const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
- this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.preventTreeViewOpen,
+ this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
+ this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen,
[...this.props.renderedIds, doc[Id]], this.props.libraryPath, this.props.onCheckedClick);
} else {
contentElement = <EditableView
@@ -334,8 +333,8 @@ class TreeView extends React.Component<TreeViewProps> {
{!docs ? (null) :
TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document),
this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
- this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.preventTreeViewOpen,
+ this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform,
+ this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen,
[...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath, this.props.onCheckedClick)}
</ul >;
} else if (this.treeViewExpandedView === "fields") {
@@ -350,6 +349,7 @@ class TreeView extends React.Component<TreeViewProps> {
DataDocument={this.templateDataDoc}
LibraryPath={emptyPath}
renderDepth={this.props.renderDepth + 1}
+ backgroundColor={this.props.backgroundColor}
fitToBox={this.boundsOfCollectionDocument !== undefined}
PanelWidth={this.docWidth}
PanelHeight={this.docHeight}
@@ -386,7 +386,7 @@ class TreeView extends React.Component<TreeViewProps> {
@computed
get renderBullet() {
const checked = this.props.document.type === DocumentType.COL ? undefined : this.props.onCheckedClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined;
- return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "black"), opacity: 0.4 }}>
+ return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "inherit"), opacity: 0.4 }}>
{<FontAwesomeIcon icon={checked === "check" ? "check" : (checked === "x" ? "times" : checked === "unchecked" ? "square" : !this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down"))} />}
</div>;
}
@@ -417,7 +417,7 @@ class TreeView extends React.Component<TreeViewProps> {
return <>
<div className="docContainer" title="click to edit title" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
style={{
- color: this.props.document.isMinimized ? "red" : "black",
+ color: this.props.document.isMinimized ? "red" : "inherit",
background: Doc.IsHighlighted(this.props.document) ? "orange" : Doc.IsBrushed(this.props.document) ? "#06121212" : "0",
fontWeight: this.props.document.searchMatch ? "bold" : undefined,
outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
@@ -458,6 +458,7 @@ class TreeView extends React.Component<TreeViewProps> {
dropAction: dropActionType,
addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean,
pinToPres: (document: Doc) => void,
+ backgroundColor: undefined | ((document: Doc) => string | undefined),
screenToLocalXf: () => Transform,
outerXf: () => { translateX: number, translateY: number },
active: (outsideReaction?: boolean) => boolean,
@@ -465,7 +466,7 @@ class TreeView extends React.Component<TreeViewProps> {
ChromeHeight: undefined | (() => number),
renderDepth: number,
treeViewHideHeaderFields: () => boolean,
- preventTreeViewOpen: boolean,
+ treeViewPreventOpen: boolean,
renderedIds: string[],
libraryPath: Doc[] | undefined,
onCheckedClick: ScriptField | undefined
@@ -563,6 +564,7 @@ class TreeView extends React.Component<TreeViewProps> {
renderDepth={renderDepth}
deleteDoc={remove}
addDocument={addDocument}
+ backgroundColor={backgroundColor}
panelWidth={rowWidth}
panelHeight={rowHeight}
ChromeHeight={ChromeHeight}
@@ -575,7 +577,7 @@ class TreeView extends React.Component<TreeViewProps> {
parentKey={key}
active={active}
treeViewHideHeaderFields={treeViewHideHeaderFields}
- preventTreeViewOpen={preventTreeViewOpen}
+ treeViewPreventOpen={treeViewPreventOpen}
renderedIds={renderedIds} />;
});
}
@@ -602,13 +604,24 @@ export class CollectionTreeView extends CollectionSubView(Document) {
@action
remove = (document: Document): boolean => {
- const children = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
+ const children = Cast(this.props.Document[DataSym][this.props.fieldKey], listSpec(Doc), []);
if (children.indexOf(document) !== -1) {
children.splice(children.indexOf(document), 1);
return true;
}
return false;
}
+ @action
+ addDoc = (doc: Document, relativeTo: Opt<Doc>, before?: boolean): boolean => {
+ const doAddDoc = () =>
+ Doc.AddDocToList(this.props.Document[DataSym], this.props.fieldKey, doc, relativeTo, before, false, false, false);
+ if (this.props.Document.resolvedDataDoc instanceof Promise) {
+ this.props.Document.resolvedDataDoc.then(resolved => doAddDoc());
+ } else {
+ doAddDoc();
+ }
+ return true;
+ }
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
if (!e.isPropagationStopped() && this.props.Document === CurrentUserUtils.UserDocument.workspaces) {
@@ -624,7 +637,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
} else {
const layoutItems: ContextMenuProps[] = [];
- layoutItems.push({ description: (this.props.Document.preventTreeViewOpen ? "Persist" : "Abandon") + "Treeview State", event: () => this.props.Document.preventTreeViewOpen = !this.props.Document.preventTreeViewOpen, icon: "paint-brush" });
+ layoutItems.push({ description: (this.props.Document.treeViewPreventOpen ? "Persist" : "Abandon") + "Treeview State", event: () => this.props.Document.treeViewPreventOpen = !this.props.Document.treeViewPreventOpen, icon: "paint-brush" });
layoutItems.push({ description: (this.props.Document.treeViewHideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.props.Document.treeViewHideHeaderFields = !this.props.Document.treeViewHideHeaderFields, icon: "paint-brush" });
layoutItems.push({ description: (this.props.Document.treeViewHideTitle ? "Show" : "Hide") + " Title", event: () => this.props.Document.treeViewHideTitle = !this.props.Document.treeViewHideTitle, icon: "paint-brush" });
ContextMenu.Instance.addItem({ description: "Treeview Options ...", subitems: layoutItems, icon: "eye" });
@@ -656,8 +669,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
const heroView = ImageDocument(fallbackImg, { title: "heroView", isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
heroView.proto!.layout = ImageBox.LayoutString("hero");
- heroView.showTitle = "title";
- heroView.showTitleHover = "titlehover";
+ heroView._showTitle = "title";
+ heroView._showTitleHover = "titlehover";
Doc.AddDocToList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data",
Docs.Create.FontIconDocument({
@@ -701,17 +714,18 @@ export class CollectionTreeView extends CollectionSubView(Document) {
render() {
const dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
- const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
+ const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
const moveDoc = (d: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
return !this.childDocs ? (null) : (
<div className="collectionTreeView-dropTarget" id="body"
- style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document._yMargin, 20)}px` }}
+ style={{ background: this.props.backgroundColor?.(this.props.Document), paddingTop: `${NumCast(this.props.Document._yMargin, 20)}px` }}
onContextMenu={this.onContextMenu}
onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
{(this.props.Document.treeViewHideTitle ? (null) : <EditableView
contents={this.dataDoc.title}
+ editing={false}
display={"block"}
maxHeight={72}
height={"auto"}
@@ -719,18 +733,17 @@ export class CollectionTreeView extends CollectionSubView(Document) {
SetValue={undoBatch((value: string) => Doc.SetInPlace(this.dataDoc, "title", value, false) || true)}
OnFillDown={undoBatch((value: string) => {
Doc.SetInPlace(this.dataDoc, "title", value, false);
- const layoutDoc = this.props.Document.layout_custom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layout_custom)) : undefined;
- const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
- TreeView.loadId = doc[Id];
- Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
+ const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
+ EditableView.loadId = doc[Id];
+ this.addDoc(doc, this.childDocs.length ? this.childDocs[0] : undefined, true);
})} />)}
{this.props.Document.allowClear ? this.renderClearButton : (null)}
<ul className="no-indent" style={{ width: "max-content" }} >
{
TreeView.GetChildElements(this.childDocs, this.props.Document, this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
- moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
+ moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform,
this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => BoolCast(this.props.Document.treeViewHideHeaderFields),
- BoolCast(this.props.Document.preventTreeViewOpen), [], this.props.LibraryPath, ScriptCast(this.props.Document.onCheckedClick))
+ BoolCast(this.props.Document.treeViewPreventOpen), [], this.props.LibraryPath, ScriptCast(this.props.Document.onCheckedClick))
}
</ul>
</div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index de3e9737f..be971eda6 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -38,6 +38,7 @@ import { CollectionViewBaseChrome } from './CollectionViewChromes';
import { CollectionTimeView } from './CollectionTimeView';
import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView';
import { List } from '../../../new_fields/List';
+import { SubCollectionViewProps } from './CollectionSubView';
export const COLLECTION_BORDER_WIDTH = 2;
const path = require('path');
library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
@@ -133,7 +134,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
@action.bound
addDocument(doc: Doc): boolean {
- const targetDataDoc = this.props.Document.resolvedDataDoc && !this.props.Document.isTemplateForField ? this.props.Document : Doc.GetProto(this.props.Document[DataSym]);
+ const targetDataDoc = this.props.Document[DataSym];
targetDataDoc[this.props.fieldKey] = new List<Doc>([...DocListCast(targetDataDoc[this.props.fieldKey]), doc]); // DocAddToList may write to targetdataDoc's parent ... we don't want this. should really change GetProto to GetDataDoc and test for resolvedDataDoc there
// Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc);
targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
@@ -145,8 +146,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
removeDocument(doc: Doc): boolean {
const docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView);
docView && SelectionManager.DeselectDoc(docView);
- const targetDataDoc = this.props.Document.resolvedDataDoc ? this.props.Document : this.props.Document[DataSym];
- const value = Cast(targetDataDoc[this.props.fieldKey], listSpec(Doc), []);
+ const value = Cast(this.props.Document[DataSym][this.props.fieldKey], listSpec(Doc), []);
let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1);
index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1);
@@ -178,7 +178,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
}
private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
- const props = { ...this.props, ...renderProps, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" };
+ const props: SubCollectionViewProps = { ...this.props, ...renderProps, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" };
switch (type) {
case CollectionViewType.Schema: return (<CollectionSchemaView key="collview" {...props} />);
case CollectionViewType.Docking: return (<CollectionDockingView key="collview" {...props} />);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 050ca8347..d363770bf 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -44,7 +44,9 @@ export interface ViewDefResult {
}
function toLabel(target: FieldResult<Field>) {
if (typeof target === "number" || Number(target)) {
- return Number(target).toFixed(2).toString();
+ const truncated = Number(Number(target).toFixed(0));
+ const precise = Number(Number(target).toFixed(2));
+ return truncated === precise ? Number(target).toFixed(0) : Number(target).toFixed(2);
}
if (target instanceof ObjectField || target instanceof RefField) {
return target[ToString]();
@@ -287,7 +289,7 @@ export function computeTimelineLayout(
groupNames.push({ type: "text", text: Math.ceil(maxTime).toString(), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize, payload: undefined });
}
- const divider = { type: "div", color: "black", x: 0, y: 0, width: panelDim[0], height: 1, payload: undefined };
+ const divider = { type: "div", color: "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
return normalizeResults(panelDim, fontHeight, childPairs, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider], childDocs.filter(c => !filterDocs.includes(c)));
function layoutDocsAtTime(keyDocs: Doc[], key: number) {
@@ -303,7 +305,7 @@ export function computeTimelineLayout(
docMap.set(doc, {
type: "doc",
x: x, y: -Math.sqrt(stack) * pivotAxisWidth / 2 - pivotAxisWidth + (pivotAxisWidth - hgt) / 2,
- zIndex: (curTime === key ? 1000 : zind++), highlight: curTime === key, width: wid / (Math.max(stack, 1)), height: hgt, payload: undefined
+ zIndex: (curTime === key ? 1000 : zind++), highlight: curTime === key, width: wid / (Math.max(stack, 1)), height: hgt / (Math.max(stack, 1)), payload: undefined
});
stacking[stack] = x + pivotAxisWidth;
});
@@ -340,17 +342,17 @@ function normalizeResults(panelDim: number[], fontHeight: number, childPairs: {
extraDocs.map(ed => poolData.set(ed[Id], { x: 0, y: 0, zIndex: -99 }));
return {
- elements: viewDefsToJSX(extras.concat(groupNames.map(gname => ({
+ elements: viewDefsToJSX(extras.concat(groupNames).map(gname => ({
type: gname.type,
text: gname.text,
x: gname.x * scale,
y: gname.y * scale,
color: gname.color,
width: gname.width === undefined ? undefined : gname.width * scale,
- height: Math.max(fontHeight, (gname.height || 0) * scale),
+ height: gname.height === -1 ? 1 : Math.max(fontHeight, (gname.height || 0) * scale),
fontSize: gname.fontSize,
payload: gname.payload
- }))))
+ })))
};
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 07a5a2c7b..969d6b3c8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -4,13 +4,13 @@ import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrows
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocCastAsync } from "../../../../new_fields/Doc";
import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas";
import { Id } from "../../../../new_fields/FieldSymbols";
import { InkTool } from "../../../../new_fields/InkField";
import { createSchema, listSpec, makeInterface } from "../../../../new_fields/Schema";
import { ScriptField } from "../../../../new_fields/ScriptField";
-import { Cast, NumCast, ScriptCast, StrCast } from "../../../../new_fields/Types";
+import { Cast, NumCast, ScriptCast, BoolCast, StrCast } from "../../../../new_fields/Types";
import { TraceMobx } from "../../../../new_fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
@@ -206,6 +206,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
@undoBatch
+ @action
updateClusters(useClusters: boolean) {
this.props.Document.useClusters = useClusters;
this._clusterSets.length = 0;
@@ -243,7 +244,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
docs.map(doc => this._clusterSets[doc.cluster = NumCast(docFirst.cluster)].push(doc));
}
childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.cluster === i) && this.updateCluster(child));
- childLayouts.map(child => Doc.GetProto(child).clusterStr = child.cluster?.toString());
}
}
@@ -279,16 +279,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
getClusterColor = (doc: Doc) => {
- let clusterColor = "";
+ let clusterColor = this.props.backgroundColor?.(doc);
const cluster = NumCast(doc.cluster);
if (this.Document.useClusters) {
if (this._clusterSets.length <= cluster) {
setTimeout(() => this.updateCluster(doc), 0);
} else {
// choose a cluster color from a palette
- const colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"];
+ const colors = ["#da42429e", "#31ea318c", "rgba(197, 87, 20, 0.55)", "#4a7ae2c4", "rgba(216, 9, 255, 0.5)", "#ff7601", "#1dffff", "yellow", "rgba(27, 130, 49, 0.55)", "rgba(0, 0, 0, 0.268)"];
clusterColor = colors[cluster % colors.length];
- const set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor));
+ const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
// override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document
set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
@@ -697,7 +697,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
- setScaleToZoom = (doc: Doc, scale: number = 0.5) => {
+ setScaleToZoom = (doc: Doc, scale: number = 0.75) => {
this.Document.scale = scale * Math.min(this.props.PanelWidth() / NumCast(doc._width), this.props.PanelHeight() / NumCast(doc._height));
}
@@ -709,6 +709,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; }
@computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
+ backgroundHalo = () => BoolCast(this.Document.useClusters);
getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps {
return {
@@ -728,6 +729,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
ContainingCollectionDoc: this.props.Document,
focus: this.focusDocument,
backgroundColor: this.getClusterColor,
+ backgroundHalo: this.backgroundHalo,
parentActive: this.props.active,
bringToFront: this.bringToFront,
zoomToScale: this.zoomToScale,
@@ -867,6 +869,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
});
return rangeFilteredDocs;
}
+ childLayoutDocFunc = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null) as Doc;
get doLayoutComputation() {
const { newPool, computedElementData } = this.doInternalLayoutComputation;
runInAction(() =>
@@ -883,6 +886,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
computedElementData.elements.push({
ele: <CollectionFreeFormDocumentView key={pair.layout[Id]} {...this.getChildDocumentViewProps(pair.layout, pair.data)}
dataProvider={this.childDataProvider}
+ LayoutDoc={this.childLayoutDocFunc}
jitterRotation={NumCast(this.props.Document.jitterRotation)}
fitToBox={this.props.fitToBox || this.props.layoutEngine !== undefined} />,
bounds: this.childDataProvider(pair.layout)
@@ -1072,7 +1076,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
// this.Document.fitH = this.contentBounds && (this.contentBounds.b - this.contentBounds.y);
// if isAnnotationOverlay is set, then children will be stored in the extension document for the fieldKey.
// otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document
- // let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
return <div className={"collectionfreeformview-container"}
ref={this.createDashEventsTarget}
onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
@@ -1084,7 +1087,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
width: this.contentScaling ? `${100 / this.contentScaling}%` : "",
height: this.contentScaling ? `${100 / this.contentScaling}%` : this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
}}>
- {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
+ {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ?
this.placeholder : this.marqueeView}
<CollectionFreeFormOverlayView elements={this.elementFunc} />
</div>;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 4b0855635..85cda4ecb 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -308,8 +308,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
y: bounds.top,
_panX: 0,
_panY: 0,
- backgroundColor: this.props.isAnnotationOverlay ? "#00000015" : "white",
- defaultBackgroundColor: this.props.isAnnotationOverlay ? "#00000015" : "white",
+ backgroundColor: this.props.isAnnotationOverlay ? "#00000015" : undefined,
_width: bounds.width,
_height: bounds.height,
_LODdisable: true,
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 7d8de0db4..db5673573 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -207,6 +207,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
{...this.props}
Document={layout}
DataDocument={layout.resolvedDataDoc as Doc}
+ backgroundColor={this.props.backgroundColor}
CollectionDoc={this.props.Document}
PanelWidth={width}
PanelHeight={height}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index ec05443e5..630a178cf 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -208,6 +208,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
{...this.props}
Document={layout}
DataDocument={layout.resolvedDataDoc as Doc}
+ backgroundColor={this.props.backgroundColor}
CollectionDoc={this.props.Document}
PanelWidth={width}
PanelHeight={height}