aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionTimeView.tsx
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2021-02-18 16:31:21 -0500
committerusodhi <61431818+usodhi@users.noreply.github.com>2021-02-18 16:31:21 -0500
commitec18ae95005b9adc674a1ed6c3e976aa987ed7d2 (patch)
treeae991bbfad86ca6230a21c86b40c274e2cfe6607 /src/client/views/collections/CollectionTimeView.tsx
parent546540013de0a7cb647f30f1fcb513ce52048b72 (diff)
parent0d59f6bc23c755c4eab2503add28699f5a5b1992 (diff)
merging
Diffstat (limited to 'src/client/views/collections/CollectionTimeView.tsx')
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx129
1 files changed, 98 insertions, 31 deletions
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index cc625e12e..8067e1d07 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,16 +1,21 @@
+import { toUpper } from "lodash";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Opt, DocCastAsync } from "../../../fields/Doc";
+import { Doc, DocCastAsync, Opt, StrListCast } from "../../../fields/Doc";
import { List } from "../../../fields/List";
import { ObjectField } from "../../../fields/ObjectField";
import { RichTextField } from "../../../fields/RichTextField";
+import { listSpec } from "../../../fields/Schema";
import { ComputedField, ScriptField } from "../../../fields/ScriptField";
-import { NumCast, StrCast, BoolCast, Cast } from "../../../fields/Types";
-import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents } from "../../../Utils";
+import { Docs, DocUtils } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
import { Scripting } from "../../util/Scripting";
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
import { EditableView } from "../EditableView";
+import { ViewSpecPrefix } from "../nodes/DocumentView";
import { ViewDefBounds } from "./collectionFreeForm/CollectionFreeFormLayoutEngines";
import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
import { CollectionSubView } from "./CollectionSubView";
@@ -19,7 +24,6 @@ const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
import React = require("react");
-import { DocUtils } from "../../documents/Documents";
@observer
export class CollectionTimeView extends CollectionSubView(doc => doc) {
@@ -28,15 +32,63 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
@observable _collapsed: boolean = false;
@observable _childClickedScript: Opt<ScriptField>;
@observable _viewDefDivClick: Opt<ScriptField>;
+ @observable _focusDocFilters: Opt<string[]>; // fields that get overridden by a focus anchor
+ @observable _focusPivotField: Opt<string>;
+ @observable _focusRangeFilters: Opt<string[]>;
+
+ getAnchor = () => {
+ const anchor = Docs.Create.TextanchorDocument({
+ title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any,
+ useLinkSmallAnchor: true,
+ hideLinkButton: true,
+ annotationOn: this.rootDoc
+ });
+
+ // save view spec information for anchor
+ const proto = Doc.GetProto(anchor);
+ proto.pivotField = this.pivotField;
+ proto.docFilters = ObjectField.MakeCopy(this.layoutDoc._docFilters as ObjectField) || new List<string>([]);
+ proto.docRangeFilters = ObjectField.MakeCopy(this.layoutDoc._docRangeFilters as ObjectField) || new List<string>([]);
+ proto[ViewSpecPrefix + "_viewType"] = this.layoutDoc._viewType;
+
+ // store anchor in annotations list of document (not technically needed since these anchors are never drawn)
+ if (Cast(this.dataDoc[this.props.fieldKey + "-annotations"], listSpec(Doc), null) !== undefined) {
+ Cast(this.dataDoc[this.props.fieldKey + "-annotations"], listSpec(Doc), []).push(anchor);
+ } else {
+ this.dataDoc[this.props.fieldKey + "-annotations"] = new List<Doc>([anchor]);
+ }
+ return anchor;
+ }
+
async componentDidMount() {
- const detailView = (await DocCastAsync(this.props.Document.childClickedOpenTemplateView)) || DocUtils.findTemplate("detailView", StrCast(this.props.Document.type), "");
- const childText = "const alias = getAlias(self); switchView(alias, detailView); alias.dropAction='alias'; alias.removeDropProperties=new List<string>(['dropAction']); useRightSplit(alias, shiftKey); ";
+ this.props.setContentView?.(this);
+ const detailView = (await DocCastAsync(this.props.Document.childClickedOpenTemplateView)) || DocUtils.findTemplate("detailView", StrCast(this.rootDoc.type), "");
+ ///const childText = "const alias = getAlias(self); switchView(alias, detailView); alias.dropAction='alias'; alias.removeDropProperties=new List<string>(['dropAction']); useRightSplit(alias, shiftKey); ";
+ const childText = "openInLightbox(self, shiftKey); ";
runInAction(() => {
this._childClickedScript = ScriptField.MakeScript(childText, { this: Doc.name, shiftKey: "boolean" }, { detailView: detailView! });
this._viewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" });
});
}
+ get pivotField() { return this._focusPivotField || StrCast(this.layoutDoc._pivotField); }
+ @action
+ setViewSpec = (anchor: Doc, preview: boolean) => {
+ if (preview) { // if in preview, then override document's fields with view spec
+ this._focusPivotField = StrCast(anchor.pivotField);
+ this._focusDocFilters = StrListCast(anchor.docFilters);
+ this._focusRangeFilters = StrListCast(anchor.docRangeFilters);
+ } else if (anchor.pivotField !== undefined) { // otherwise set document's fields based on anchor view spec
+ this.layoutDoc._prevFilterIndex = 1;
+ this.layoutDoc._pivotField = StrCast(anchor.pivotField);
+ this.layoutDoc._docFilters = new List<string>(StrListCast(anchor.docFilters));
+ this.layoutDoc._docRangeFilters = new List<string>(StrListCast(anchor.docRangeFilters));
+ }
+ return 0;
+ }
+
+ pivotDocFilters = () => this._focusDocFilters || this.props.docFilters();
+ pivotDocRangeFilters = () => this._focusRangeFilters || this.props.docRangeFilters();
layoutEngine = () => this._layoutEngine;
toggleVisibility = action(() => this._collapsed = !this._collapsed);
@@ -69,24 +121,31 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
}), returnFalse, emptyFunction);
}
- contentsDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, returnFalse, action(() => {
- let prevFilterIndex = NumCast(this.props.Document._prevFilterIndex);
- if (prevFilterIndex > 0) {
- prevFilterIndex--;
- this.props.Document._docFilters = ObjectField.MakeCopy(this.props.Document["_prevDocFilter" + prevFilterIndex] as ObjectField);
- this.props.Document._docRangeFilters = ObjectField.MakeCopy(this.props.Document["_prevDocRangeFilters" + prevFilterIndex] as ObjectField);
- this.props.Document._prevFilterIndex = prevFilterIndex;
- } else {
- this.props.Document._docFilters = new List([]);
- }
- }), false);
+ goTo = (prevFilterIndex: number) => {
+ this.layoutDoc._pivotField = this.layoutDoc["_prevPivotFields" + prevFilterIndex];
+ this.layoutDoc._docFilters = ObjectField.MakeCopy(this.layoutDoc["_prevDocFilter" + prevFilterIndex] as ObjectField);
+ this.layoutDoc._docRangeFilters = ObjectField.MakeCopy(this.layoutDoc["_prevDocRangeFilters" + prevFilterIndex] as ObjectField);
+ this.layoutDoc._prevFilterIndex = prevFilterIndex;
+ }
+
+ @action
+ contentsDown = (e: React.MouseEvent) => {
+ let prevFilterIndex = NumCast(this.layoutDoc._prevFilterIndex);
+ if (prevFilterIndex > 0) {
+ this.goTo(prevFilterIndex - 1);
+ } else {
+ this.layoutDoc._docFilters = new List([]);
+ }
}
@computed get contents() {
- return <div className="collectionTimeView-innards" key="timeline" style={{ width: "100%", pointerEvents: this.props.active() ? undefined : "none" }} onPointerDown={this.contentsDown}>
+ return <div className="collectionTimeView-innards" key="timeline" style={{ pointerEvents: this.props.active() ? undefined : "none" }}
+ onClick={this.contentsDown}>
<CollectionFreeFormView {...this.props}
- fitContentsToDoc={true}
+ engineProps={{ pivotField: this.pivotField, docFilters: this.docFilters, docRangeFilters: this.docRangeFilters }}
+ fitContentsToDoc={returnTrue}
+ docFilters={this.pivotDocFilters}
+ docRangeFilters={this.pivotDocRangeFilters}
childClickScript={this._childClickedScript}
viewDefDivClick={this._viewDefDivClick}
childFreezeDimensions={true}
@@ -100,7 +159,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
}
specificMenu = (e: React.MouseEvent) => {
const layoutItems: ContextMenuProps[] = [];
- const doc = this.props.Document;
+ const doc = this.layoutDoc;
layoutItems.push({ description: "Force Timeline", event: () => { doc._forceRenderEngine = "timeline"; }, icon: "compress-arrows-alt" });
layoutItems.push({ description: "Force Pivot", event: () => { doc._forceRenderEngine = "pivot"; }, icon: "compress-arrows-alt" });
@@ -123,10 +182,11 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
this.childLayoutPairs.map(pair => this._allFacets.filter(fieldKey =>
pair.layout[fieldKey] instanceof RichTextField ||
typeof (pair.layout[fieldKey]) === "number" ||
- typeof (pair.layout[fieldKey]) === "string").map(fieldKey => keySet.add(fieldKey)));
+ typeof (pair.layout[fieldKey]) === "boolean" ||
+ typeof (pair.layout[fieldKey]) === "string").filter(fieldKey => fieldKey[0] !== "_" && (fieldKey[0] !== "#" || fieldKey === "#") && (fieldKey === "tags" || fieldKey[0] === toUpper(fieldKey)[0])).map(fieldKey => keySet.add(fieldKey)));
Array.from(keySet).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" });
+ docItems.push({ description: ":" + fieldKey, event: () => this.layoutDoc._pivotField = fieldKey, icon: "compress-arrows-alt" }));
+ docItems.push({ description: ":(null)", event: () => this.layoutDoc._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, ":");
@@ -137,13 +197,13 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
GetValue: () => "",
SetValue: (value: any) => {
if (value?.length) {
- this.props.Document._pivotField = value;
+ this.layoutDoc._pivotField = value;
return true;
}
return false;
},
showMenuOnLoad: true,
- contents: ":" + StrCast(this.props.Document._pivotField),
+ contents: ":" + StrCast(this.layoutDoc._pivotField),
toggle: this.toggleVisibility,
color: "#f1efeb" // this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
};
@@ -155,12 +215,12 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
render() {
let nonNumbers = 0;
this.childDocs.map(doc => {
- const num = NumCast(doc[StrCast(this.props.Document._pivotField)], Number(StrCast(doc[StrCast(this.props.Document._pivotField)])));
+ const num = NumCast(doc[this.pivotField], Number(StrCast(doc[this.pivotField])));
if (Number.isNaN(num)) {
nonNumbers++;
}
});
- const forceLayout = StrCast(this.props.Document._forceRenderEngine);
+ const forceLayout = StrCast(this.layoutDoc._forceRenderEngine);
const doTimeline = forceLayout ? (forceLayout === "timeline") : nonNumbers / this.childDocs.length < 0.1 && this.props.PanelWidth() / this.props.PanelHeight() > 6;
if (doTimeline !== (this._layoutEngine === "timeline")) {
if (!this._changing) {
@@ -173,7 +233,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
}
return <div className={"collectionTimeView" + (doTimeline ? "" : "-pivot")} onContextMenu={this.specificMenu}
- style={{ width: this.props.PanelWidth(), height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
+ style={{ width: this.props.PanelWidth(), height: `calc(100% - ${this.layoutDoc._chromeStatus === "enabled" ? 51 : 0}px)` }}>
{this.pivotKeyUI}
{this.contents}
{!this.props.isSelected() || !doTimeline ? (null) : <>
@@ -189,10 +249,17 @@ Scripting.addGlobal(function pivotColumnClick(pivotDoc: Doc, bounds: ViewDefBoun
let prevFilterIndex = NumCast(pivotDoc._prevFilterIndex);
pivotDoc["_prevDocFilter" + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._docFilters as ObjectField);
pivotDoc["_prevDocRangeFilters" + prevFilterIndex] = ObjectField.MakeCopy(pivotDoc._docRangeFilters as ObjectField);
+ pivotDoc["_prevPivotFields" + prevFilterIndex] = pivotDoc._pivotField;
pivotDoc._prevFilterIndex = ++prevFilterIndex;
runInAction(() => {
pivotDoc._docFilters = new List();
- (bounds.payload as string[]).map(filterVal =>
- Doc.setDocFilter(pivotDoc, StrCast(pivotDoc._pivotField), filterVal, "check"));
+ const filterVals = (bounds.payload as string[]);
+ filterVals.map(filterVal => Doc.setDocFilter(pivotDoc, StrCast(pivotDoc._pivotField), filterVal, "check"));
+ const pivotView = DocumentManager.Instance.getDocumentView(pivotDoc);
+ if (pivotDoc && pivotView?.ComponentView instanceof CollectionTimeView && filterVals.length === 1) {
+ if (pivotView?.ComponentView.childDocs.length && pivotView.ComponentView.childDocs[0][filterVals[0]]) {
+ pivotDoc._pivotField = filterVals[0];
+ }
+ }
});
}); \ No newline at end of file