diff options
| author | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-02-18 16:31:21 -0500 |
|---|---|---|
| committer | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-02-18 16:31:21 -0500 |
| commit | ec18ae95005b9adc674a1ed6c3e976aa987ed7d2 (patch) | |
| tree | ae991bbfad86ca6230a21c86b40c274e2cfe6607 /src/client/views/collections/CollectionTimeView.tsx | |
| parent | 546540013de0a7cb647f30f1fcb513ce52048b72 (diff) | |
| parent | 0d59f6bc23c755c4eab2503add28699f5a5b1992 (diff) | |
merging
Diffstat (limited to 'src/client/views/collections/CollectionTimeView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionTimeView.tsx | 129 |
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 |
