aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionPivotView.scss88
-rw-r--r--src/client/views/collections/CollectionPivotView.tsx174
-rw-r--r--src/client/views/collections/CollectionTimeView.scss9
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx38
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx7
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx34
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx77
-rw-r--r--src/client/views/presentationview/PresElementBox.scss2
9 files changed, 80 insertions, 351 deletions
diff --git a/src/client/views/collections/CollectionPivotView.scss b/src/client/views/collections/CollectionPivotView.scss
deleted file mode 100644
index 505091e98..000000000
--- a/src/client/views/collections/CollectionPivotView.scss
+++ /dev/null
@@ -1,88 +0,0 @@
-.collectionPivotView {
- display: flex;
- flex-direction: row;
- position: absolute;
- height: 100%;
- width: 100%;
-
- .collectionPivotView-flyout {
- width: 400px;
- height: 300px;
- display: inline-block;
-
- .collectionPivotView-flyout-item {
- background-color: lightgray;
- text-align: left;
- display: inline-block;
- position: relative;
- width: 100%;
- }
- }
-
- .pivotKeyEntry {
- position: absolute;
- top: 5px;
- right: 5px;
- z-index: 10;
- pointer-events: all;
- padding: 5px;
- border: 1px solid black;
- }
-
- .collectionPivotView-treeView {
- display: flex;
- flex-direction: column;
- width: 200px;
- height: 100%;
-
- .collectionPivotView-addfacet {
- display: inline-block;
- width: 200px;
- height: 30px;
- background: darkGray;
- text-align: center;
-
- .collectionPivotView-button {
- align-items: center;
- display: flex;
- width: 100%;
- height: 100%;
-
- .collectionPivotView-span {
- margin: auto;
- }
- }
-
- >div,
- >div>div {
- width: 100%;
- height: 100%;
- text-align: center;
- }
- }
-
- .collectionPivotView-tree {
- display: inline-block;
- width: 100%;
- height: calc(100% - 30px);
- }
- }
-
- .collectionPivotView-pivot {
- display: inline-block;
- width: calc(100% - 200px);
- height: 100%;
- }
-
- .collectionPivotView-dragger {
- background-color: lightgray;
- height: 40px;
- width: 20px;
- position: absolute;
- border-radius: 10px;
- top: 55%;
- border: 1px black solid;
- z-index: 2;
- left: -10px;
- }
-} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx
deleted file mode 100644
index 992018a3f..000000000
--- a/src/client/views/collections/CollectionPivotView.tsx
+++ /dev/null
@@ -1,174 +0,0 @@
-import { faEdit } from "@fortawesome/free-solid-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Set } from "typescript-collections";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
-import { Docs } from "../../documents/Documents";
-import { EditableView } from "../EditableView";
-import { anchorPoints, Flyout } from "../TemplateMenu";
-import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
-import "./CollectionPivotView.scss";
-import { CollectionSubView } from "./CollectionSubView";
-import { CollectionTreeView } from "./CollectionTreeView";
-import React = require("react");
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { RichTextField } from "../../../new_fields/RichTextField";
-
-@observer
-export class CollectionPivotView extends CollectionSubView(doc => doc) {
- componentDidMount() {
- this.props.Document._freeformLayoutEngine = "pivot";
- const childDetailed = this.props.Document.childDetailed; // bcz: needs to be here to make sure the childDetailed layout template has been loaded when the first item is clicked;
- if (!this.props.Document._facetCollection) {
- const facetCollection = Docs.Create.TreeDocument([], { title: "facetFilters", _yMargin: 0, treeViewHideTitle: true });
- facetCollection.target = this.props.Document;
- this.props.Document.excludeFields = new List<string>(["_facetCollection", "_docFilter"]);
-
- const scriptText = "setDocFilter(containingTreeView.target, heading, this.title, checked)";
- const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(containingCollection.childDetailed, alias, 'layout_detailed'); useRightSplit(alias); ";
- facetCollection.onCheckedClick = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "boolean", checked: "boolean", containingTreeView: Doc.name });
- this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "boolean", containingCollection: Doc.name });
- this.props.Document._facetCollection = facetCollection;
- this.props.Document._fitToBox = true;
- }
- }
- bodyPanelWidth = () => this.props.PanelWidth() - this._facetWidth;
- getTransform = () => this.props.ScreenToLocalTransform().translate(-this._facetWidth, 0);
-
- @computed get _allFacets() {
- const facets = new Set<string>();
- this.childDocs.forEach(child => Object.keys(Doc.GetProto(child)).forEach(key => facets.add(key)));
- return facets.toArray();
- }
-
- /**
- * Responds to clicking the check box in the flyout menu
- */
- facetClick = (facetHeader: string) => {
- const facetCollection = this.props.Document._facetCollection;
- if (facetCollection instanceof Doc) {
- const found = DocListCast(facetCollection.data).findIndex(doc => doc.title === facetHeader);
- if (found !== -1) {
- (facetCollection.data as List<Doc>).splice(found, 1);
- const docFilter = Cast(this.props.Document._docFilter, listSpec("string"));
- if (docFilter) {
- let index: number;
- while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
- docFilter.splice(index, 3);
- }
- }
- } else {
- const newFacet = Docs.Create.TreeDocument([], { title: facetHeader, treeViewOpen: true, isFacetFilter: true });
- const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.dataDoc };
- const params = { layoutDoc: Doc.name, dataDoc: Doc.name, };
- newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, params, capturedVariables);
- Doc.AddDocToList(facetCollection, "data", newFacet);
- }
- }
- }
- _canClick = false;
- _facetWidthOnDown = 0;
- @observable _facetWidth = 200;
- onPointerDown = (e: React.PointerEvent) => {
- this._canClick = true;
- this._facetWidthOnDown = e.screenX;
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- document.addEventListener("pointermove", this.onPointerMove);
- document.addEventListener("pointerup", this.onPointerUp);
- e.stopPropagation();
- e.preventDefault();
- }
-
-
- @action
- onPointerMove = (e: PointerEvent) => {
- this._facetWidth = Math.max(this.props.ScreenToLocalTransform().transformPoint(e.clientX, 0)[0], 0);
- Math.abs(e.movementX) > 6 && (this._canClick = false);
- }
- @action
- onPointerUp = (e: PointerEvent) => {
- if (Math.abs(e.screenX - this._facetWidthOnDown) < 6 && this._canClick) {
- this._facetWidth = this._facetWidth < 15 ? 200 : 0;
- }
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- }
-
- menuCallback = (x: number, y: number) => {
- ContextMenu.Instance.clearItems();
- const docItems: ContextMenuProps[] = [];
- const keySet: Set<string> = new Set();
-
- this.childLayoutPairs.map(pair =>
- Array.from(Object.keys(Doc.GetProto(pair.layout))).filter(fieldKey => pair.layout[fieldKey] instanceof RichTextField || typeof (pair.layout[fieldKey]) === "string").map(fieldKey =>
- keySet.add(fieldKey)));
- keySet.toArray().map(fieldKey =>
- docItems.push({ description: ":" + fieldKey, event: () => this.props.Document.pivotField = fieldKey, icon: "compress-arrows-alt" }));
- docItems.push({ description: ":(null)", event: () => this.props.Document.pivotField = undefined, icon: "compress-arrows-alt" })
- ContextMenu.Instance.addItem({ description: "Pivot Fields ...", subitems: docItems, icon: "eye" });
- const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(x, y);
- ContextMenu.Instance.displayMenu(x, y, ":");
- }
-
- @observable private collapsed: boolean = false;
- private toggleVisibility = action(() => this.collapsed = !this.collapsed);
-
- render() {
- const facetCollection = Cast(this.props.Document?._facetCollection, Doc, null);
- const flyout = (
- <div className="collectionPivotView-flyout" style={{ width: `${this._facetWidth}` }}>
- {this._allFacets.map(facet => <label className="collectionPivotView-flyout-item" key={`${facet}`} onClick={e => this.facetClick(facet)}>
- <input type="checkbox" onChange={e => { }} checked={DocListCast((this.props.Document._facetCollection as Doc)?.data).some(d => d.title === facet)} />
- <span className="checkmark" />
- {facet}
- </label>)}
- </div>
- );
- const newEditableViewProps = {
- GetValue: () => "",
- SetValue: (value: any) => {
- if (value?.length) {
- this.props.Document.pivotField = value;
- return true;
- }
- return false;
- },
- showMenuOnLoad: true,
- contents: ":" + StrCast(this.props.Document.pivotField),
- toggle: this.toggleVisibility,
- color: "#f1efeb" // this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
- };
- return !facetCollection ? (null) :
- <div className="collectionPivotView" style={{ height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
- <div className={"pivotKeyEntry"}>
- <EditableView {...newEditableViewProps} menuCallback={this.menuCallback} />
- </div>
- <div className="collectionPivotView-dragger" key="dragger" onPointerDown={this.onPointerDown} style={{ transform: `translate(${this._facetWidth}px, 0px)` }} >
- <span title="library View Dragger" style={{ width: "5px", position: "absolute", top: "0" }} />
- </div>
- <div className="collectionPivotView-treeView" style={{ width: `${this._facetWidth}px`, overflow: this._facetWidth < 15 ? "hidden" : undefined }}>
- <div className="collectionPivotView-addFacet" style={{ width: `${this._facetWidth}px` }} onPointerDown={e => e.stopPropagation()}>
- <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}>
- <div className="collectionPivotView-button">
- <span className="collectionPivotView-span">Facet Filters</span>
- <FontAwesomeIcon icon={faEdit} size={"lg"} />
- </div>
- </Flyout>
- </div>
- <div className="collectionPivotView-tree" key="tree">
- <CollectionTreeView {...this.props} Document={facetCollection} />
- </div>
- </div>
- <div className="collectionPivotView-pivot" key="pivot" style={{ width: this.bodyPanelWidth() }}>
- <CollectionFreeFormView {...this.props} ScreenToLocalTransform={this.getTransform} PanelWidth={this.bodyPanelWidth} />
- </div>
- </div>;
- }
-} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionTimeView.scss b/src/client/views/collections/CollectionTimeView.scss
index 805d06d3d..3aac2bc75 100644
--- a/src/client/views/collections/CollectionTimeView.scss
+++ b/src/client/views/collections/CollectionTimeView.scss
@@ -1,4 +1,4 @@
-.collectionTimeView {
+.collectionTimeView, .collectionTimeView-pivot {
display: flex;
flex-direction: row;
position: absolute;
@@ -93,7 +93,7 @@
}
}
- .collectionTimeView-pivot {
+ .collectionTimeView-innards {
display: inline-block;
width: calc(100% - 200px);
height: 100%;
@@ -110,4 +110,9 @@
z-index: 2;
left: -10px;
}
+}
+.collectionTimeView-pivot {
+ .collectionFreeform-customText {
+ text-align: center;
+ }
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index b4ab88f9a..253dfa890 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -107,8 +107,10 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
const keySet: Set<string> = new Set();
this.childLayoutPairs.map(pair =>
- Array.from(Object.keys(Doc.GetProto(pair.layout))).filter(fieldKey => pair.layout[fieldKey] instanceof RichTextField || typeof (pair.layout[fieldKey]) === "number" || typeof (pair.layout[fieldKey]) === "string").map(fieldKey =>
- keySet.add(fieldKey)));
+ Array.from(Object.keys(Doc.GetProto(pair.layout))).filter(fieldKey =>
+ pair.layout[fieldKey] instanceof RichTextField ||
+ typeof (pair.layout[fieldKey]) === "number" ||
+ typeof (pair.layout[fieldKey]) === "string").map(fieldKey => keySet.add(fieldKey)));
keySet.toArray().map(fieldKey =>
docItems.push({ description: ":" + fieldKey, event: () => this.props.Document.pivotField = fieldKey, icon: "compress-arrows-alt" }));
docItems.push({ description: ":(null)", event: () => this.props.Document.pivotField = undefined, icon: "compress-arrows-alt" })
@@ -189,11 +191,12 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
}
@computed get contents() {
- return <div className="collectionTimeView-pivot" key="pivot" style={{ width: this.bodyPanelWidth() }}>
+ return <div className="collectionTimeView-innards" key="timeline" style={{ width: this.bodyPanelWidth() }}>
<CollectionFreeFormView {...this.props} ScreenToLocalTransform={this.getTransform} PanelWidth={this.bodyPanelWidth} />
</div>;
}
+ _changing = false;
render() {
const facetCollection = Cast(this.props.Document?._facetCollection, Doc, null);
const flyout = (
@@ -219,8 +222,33 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
toggle: this.toggleVisibility,
color: "#f1efeb" // this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
};
+
+ let nonNumbers = 0;
+ this.childDocs.map(doc => {
+ const num = NumCast(doc[StrCast(this.props.Document.pivotField)], Number(StrCast(doc[StrCast(this.props.Document.pivotField)])));
+ if (Number.isNaN(num)) {
+ nonNumbers++;
+ }
+ });
+ const doTimeline = nonNumbers / this.childDocs.length < 0.1;
+ if (doTimeline !== (this.props.Document._freeformLayoutEngine === "timeline")) {
+ if (!this._changing) {
+ this._changing = true;
+ setTimeout(() => {
+ if (nonNumbers / this.childDocs.length > 0.1) {
+ this.childDocs.map(child => child.isMinimized = false);
+ this.props.Document._freeformLayoutEngine = "pivot";
+ } else {
+ this.props.Document._freeformLayoutEngine = "timeline";
+ }
+ this._changing = false;
+ }, 0);
+ }
+ return (null);
+ }
+
return !facetCollection ? (null) :
- <div className="collectionTimeView" style={{ height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
+ <div className={"collectionTimeView" + (doTimeline ? "" : "-pivot")} style={{ height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
<div className={"pivotKeyEntry"}>
<EditableView {...newEditableViewProps} menuCallback={this.menuCallback} />
</div>
@@ -243,7 +271,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
</div>
</div>
{this.contents}
- {!this.props.isSelected() ? (null) : <>
+ {!this.props.isSelected() || !doTimeline ? (null) : <>
<div className="collectionTimeView-thumb-min collectionTimeView-thumb" key="min" onPointerDown={this.onMinDown} />
<div className="collectionTimeView-thumb-max collectionTimeView-thumb" key="mid" onPointerDown={this.onMaxDown} />
<div className="collectionTimeView-thumb-mid collectionTimeView-thumb" key="max" onPointerDown={this.onMidDown} />
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 3cb24f079..631870866 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -659,7 +659,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
Document.childLayout = cardLayout;
Document.childDetailed = detailedLayout;
- Document._viewType = CollectionViewType.Pivot;
+ Document._viewType = CollectionViewType.Time;
Document.pivotField = "company";
}
});
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 5a7bdef61..d5d62159b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -29,7 +29,6 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV
import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionLinearView } from './CollectionLinearView';
import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
-import { CollectionPivotView } from './CollectionPivotView';
import { CollectionSchemaView } from "./CollectionSchemaView";
import { CollectionStackingView } from './CollectionStackingView';
import { CollectionStaffView } from './CollectionStaffView';
@@ -52,7 +51,6 @@ export enum CollectionViewType {
Masonry,
Multicolumn,
Multirow,
- Pivot,
Time,
Carousel,
Linear,
@@ -71,7 +69,6 @@ export namespace CollectionViewType {
["masonry", CollectionViewType.Masonry],
["multicolumn", CollectionViewType.Multicolumn],
["multirow", CollectionViewType.Multirow],
- ["pivot", CollectionViewType.Pivot],
["time", CollectionViewType.Time],
["carousel", CollectionViewType.Carousel],
["linear", CollectionViewType.Linear],
@@ -191,7 +188,6 @@ export class CollectionView extends Touchable<FieldViewProps> {
case CollectionViewType.Carousel: { return (<CollectionCarouselView key="collview" {...props} />); }
case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView key="collview" {...props} />); }
case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView key="collview" {...props} />); }
- case CollectionViewType.Pivot: { return (<CollectionPivotView key="collview" {...props} />); }
case CollectionViewType.Time: { return (<CollectionTimeView key="collview" {...props} />); }
case CollectionViewType.Freeform:
default: { this.props.Document._freeformLayoutEngine = undefined; return (<CollectionFreeFormView key="collview" {...props} />); }
@@ -234,8 +230,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
subItems.push({ description: "Multirow", event: () => this.props.Document._viewType = CollectionViewType.Multirow, icon: "columns" });
subItems.push({ description: "Masonry", event: () => this.props.Document._viewType = CollectionViewType.Masonry, icon: "columns" });
subItems.push({ description: "Carousel", event: () => this.props.Document._viewType = CollectionViewType.Carousel, icon: "columns" });
- subItems.push({ description: "Pivot", event: () => this.props.Document._viewType = CollectionViewType.Pivot, icon: "columns" });
- subItems.push({ description: "Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" });
+ subItems.push({ description: "Pivot/Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" });
switch (this.props.Document._viewType) {
case CollectionViewType.Freeform: {
subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index c5db6f10f..f00af52cf 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -70,7 +70,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
case CollectionViewType.Stacking: return this._stacking_commands;
case CollectionViewType.Masonry: return this._stacking_commands;
case CollectionViewType.Freeform: return this._freeform_commands;
- case CollectionViewType.Pivot: return this._freeform_commands;
case CollectionViewType.Time: return this._freeform_commands;
case CollectionViewType.Carousel: return this._freeform_commands;
}
@@ -271,32 +270,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
return this.props.CollectionView.props.Document;
}
- private get pivotKey() {
- return StrCast(this.document.pivotField);
- }
-
- private set pivotKey(value: string) {
- this.document.pivotField = value;
- }
-
- @observable private pivotKeyDisplay = this.pivotKey;
- getPivotInput = () => {
- if (StrCast(this.document._freeformLayoutEngine) !== "pivot") {
- return (null);
- }
- return (<input className="collectionViewBaseChrome-viewSpecsInput"
- placeholder="PIVOT ON..."
- value={this.pivotKeyDisplay}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => this.pivotKeyDisplay = e.currentTarget.value)}
- onKeyPress={action((e: React.KeyboardEvent<HTMLInputElement>) => {
- const value = e.currentTarget.value;
- if (e.which === 13) {
- this.pivotKey = value;
- this.pivotKeyDisplay = "";
- }
- })} />);
- }
-
@action.bound
clearFilter = () => {
this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction("true", { doc: Doc.name });
@@ -419,10 +392,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry</option>
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="7">MultiCol</option>
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="8">MultiRow</option>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="9">Pivot</option>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="10">Time</option>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="11">Carousel</option>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="12">Linear</option>
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="9">Pivo/Time</option>
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="10">Carousel</option>
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="11">Linear</option>
</select>
<div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: collapsed ? "none" : "grid" }}>
<div className="collectionViewBaseChrome-filterIcon" onPointerDown={this.openViewSpecs} >
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index d2a2b42a0..6f84346df 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -46,10 +46,14 @@ export function computePivotLayout(
poolData: ObservableMap<string, any>,
pivotDoc: Doc,
childDocs: Doc[],
- childPairs: { layout: Doc, data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: any) => ViewDefResult[]
+ childPairs: { layout: Doc, data?: Doc }[],
+ panelDim: number[],
+ viewDefsToJSX: (views: any) => ViewDefResult[]
) {
- const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 200);
+ const fieldKey = "data";
+ const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 1000);
const pivotColumnGroups = new Map<FieldResult<Field>, Doc[]>();
+ const fontSize = NumCast(pivotDoc[fieldKey + "-timelineFontSize"], panelDim[1] > 58 ? 20 : Math.max(7, panelDim[1] / 3));
const pivotFieldKey = toLabel(pivotDoc.pivotField);
for (const doc of childDocs) {
@@ -69,16 +73,20 @@ export function computePivotLayout(
const expander = 1.05;
const gap = .15;
let x = 0;
+ let max_text = 60;
pivotColumnGroups.forEach((val, key) => {
let y = 0;
let xCount = 0;
+ const text = toLabel(key);
+ max_text = Math.max(max_text, Math.min(500, text.length));
groupNames.push({
type: "text",
- text: toLabel(key),
+ text,
x,
y: pivotAxisWidth,
width: pivotAxisWidth * expander * numCols,
- fontSize: NumCast(pivotDoc.pivotFontSize, 20)
+ height: max_text,
+ fontSize
});
for (const doc of val) {
const layoutDoc = Doc.Layout(doc);
@@ -103,37 +111,7 @@ export function computePivotLayout(
x += pivotAxisWidth * (numCols * expander + gap);
});
- const grpEles = groupNames.map(gn => { return { x: gn.x, y: gn.y, width: gn.width, height: undefined } as PivotData; });
- const docEles = childPairs.map(pair =>
- docMap.get(pair.layout) || { x: NumCast(pair.layout.x), y: NumCast(pair.layout.y), width: NumCast(pair.layout._width), height: NumCast(pair.layout._height) } // new pos is computed pos, or pos written to the document's fields
- );
- const minLabelHeight = 56;
- const aggBounds = aggregateBounds(docEles.concat(grpEles), 0, 0);
- const wscale = panelDim[0] / (aggBounds.r - aggBounds.x);
- const scale = wscale * (aggBounds.b - aggBounds.y) > panelDim[1] - (2 * minLabelHeight) ? (panelDim[1] - (2 * minLabelHeight)) / (aggBounds.b - aggBounds.y) : wscale;
- const centerY = ((panelDim[1] - 2 * minLabelHeight) - (aggBounds.b - aggBounds.y) * scale) / 2;
- const centerX = (panelDim[0] - (aggBounds.r - aggBounds.x) * scale) / 2;
-
- childPairs.map(pair => {
- const fallbackPos = {
- x: NumCast(pair.layout.x),
- y: NumCast(pair.layout.y),
- z: NumCast(pair.layout.z),
- width: NumCast(pair.layout._width),
- height: NumCast(pair.layout._height)
- };
- const newPosRaw = docMap.get(pair.layout) || fallbackPos; // new pos is computed pos, or pos written to the document's fields
- const newPos = { x: newPosRaw.x * scale + centerX, y: (newPosRaw.y - aggBounds.y) * scale + centerY, z: newPosRaw.z, width: (newPosRaw.width || 0) * scale, height: newPosRaw.height! * scale };
- const lastPos = poolData.get(pair.layout[Id]); // last computed pos
- if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.width !== lastPos.width || newPos.height !== lastPos.height) {
- runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...newPos }));
- }
- });
- return {
- elements: viewDefsToJSX([{ type: "text", text: "", x: 0, y: -aggBounds.y * scale - minLabelHeight, width: panelDim[0], height: panelDim[1], fontSize: 1 }].concat(groupNames.map(gname => {
- return { type: gname.type, text: gname.text, x: gname.x * scale + centerX, y: (gname.y - aggBounds.y) * scale + centerY, width: (gname.width || 0) * scale, height: Math.max(minLabelHeight, centerY), fontSize: gname.fontSize };
- })))
- };
+ return normalizeResults(panelDim, max_text, childPairs, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
}
@@ -186,7 +164,7 @@ export function computeTimelineLayout(
groupNames.push({ type: "text", text: prevKey.toString(), x: x, y: 0, height: fontHeight, fontSize });
}
- const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, panelDim[1] / 2.5);
+ const pivotAxisWidth = NumCast(pivotDoc.pivotTimeWidth, panelDim[1] / 2.5);
let stacking: number[] = [];
sortedKeys.forEach(key => {
const keyDocs = pivotDateGroups.get(key)!;
@@ -212,12 +190,19 @@ export function computeTimelineLayout(
groupNames.push({ type: "text", text: Math.ceil(maxTime).toString(), x: Math.ceil(maxTime - minTime) * scaling, y: 0, height: fontHeight, fontSize });
}
- const grpEles = groupNames.map(gn => { return { x: gn.x, y: gn.y, height: gn.height } as PivotData; });
+ const divider = { type: "div", color: "black", x: 0, y: 0, width: panelDim[0], height: 1 } as any;
+ return normalizeResults(panelDim, fontHeight, childPairs, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider]);
+}
+
+function normalizeResults(panelDim: number[], fontHeight: number, childPairs: { data?: Doc, layout: Doc }[], docMap: any,
+ poolData: any, viewDefsToJSX: any, groupNames: PivotData[], minWidth: number, extras: any[]) {
+
+ const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, height: gn.height }) as PivotData);
const docEles = childPairs.filter(d => !d.layout.isMinimized).map(pair =>
docMap.get(pair.layout) || { x: NumCast(pair.layout.x), y: NumCast(pair.layout.y), width: pair.layout[WidthSym](), height: pair.layout[HeightSym]() } as PivotData // new pos is computed pos, or pos written to the document's fields
);
const aggBounds = aggregateBounds(docEles.concat(grpEles), 0, 0);
- aggBounds.r = Math.max((maxTime - minTime) * scaling, aggBounds.r - aggBounds.x);
+ aggBounds.r = Math.max(minWidth, aggBounds.r - aggBounds.x);
const wscale = panelDim[0] / (aggBounds.r - aggBounds.x);
let scale = wscale * (aggBounds.b - aggBounds.y) > panelDim[1] ? (panelDim[1]) / (aggBounds.b - aggBounds.y) : wscale;
if (Number.isNaN(scale)) scale = 1;
@@ -237,12 +222,18 @@ export function computeTimelineLayout(
runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...newPos }));
}
});
+
return {
- elements: viewDefsToJSX([
- { type: "div", color: "black", x: 0, y: 0, width: panelDim[0], height: 1 } as any
- ].concat(groupNames.map(gname => {
- return { type: gname.type, text: gname.text, x: gname.x * scale, y: gname.y * scale, width: gname.width === undefined ? gname.width : gname.width * scale, height: Math.max(fontHeight, gname.height! * scale), fontSize: gname.fontSize };
- })))
+ elements: viewDefsToJSX(extras.concat(groupNames.map(gname => ({
+ type: gname.type,
+ text: gname.text,
+ x: gname.x * scale,
+ y: gname.y * scale,
+ width: gname.width === undefined ? undefined : gname.width * scale,
+ height: Math.max(fontHeight, gname.height! * scale),
+ // height: gname.height === undefined ? undefined : gname.height * scale,
+ fontSize: gname.fontSize
+ }))))
};
}
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index fd9de90e0..8370af490 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -71,7 +71,7 @@
}
.presElementBox-name {
- font-size: 12px;
+ font-size: 12pxππ;
position: absolute;
display: inline-block;
width: calc(100% - 45px);