diff options
-rw-r--r-- | src/client/documents/Documents.ts | 5 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMasonryViewFieldRow.tsx | 12 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/FilterBox.tsx | 47 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 17 |
5 files changed, 58 insertions, 28 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ac600af8b..357b82cd6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1043,8 +1043,9 @@ export namespace DocUtils { const min = Number(docRangeFilters[i + 1]); const max = Number(docRangeFilters[i + 2]); const val = Cast(d[key], "number", null); - if (val === undefined || (val < min || val > max)) { - return false; + if (val < min || val > max) return false; + if (val === undefined) { + console.log("Should 'undefined' pass range filter or not?") } } return true; diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 077e50dd2..654727a82 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -2,22 +2,22 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, DataSym } from "../../../fields/Doc"; +import { DataSym, Doc, DocListCast } from "../../../fields/Doc"; +import { Id } from "../../../fields/FieldSymbols"; import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; import { ScriptField } from "../../../fields/ScriptField"; -import { StrCast, NumCast } from "../../../fields/Types"; -import { numberRange, setupMoveUpEvents, emptyFunction, returnEmptyString } from "../../../Utils"; +import { NumCast, StrCast } from "../../../fields/Types"; +import { emptyFunction, numberRange, returnEmptyString, setupMoveUpEvents } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; import { CompileScript } from "../../util/Scripting"; +import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { EditableView } from "../EditableView"; +import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; import { CollectionStackingView } from "./CollectionStackingView"; import "./CollectionStackingView.scss"; -import { SnappingManager } from "../../util/SnappingManager"; -import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; -import { Id } from "../../../fields/FieldSymbols"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 5bb3c0403..a8123b051 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -20,8 +20,9 @@ import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { EditableView } from "../EditableView"; +import { LightboxView } from "../LightboxView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; -import { DocumentView, DocumentViewProps, DocFocusOptions, ViewAdjustment } from "../nodes/DocumentView"; +import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView"; import { FieldViewProps } from "../nodes/FieldView"; import { StyleProp } from "../StyleProvider"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; @@ -29,8 +30,6 @@ import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; -import { LightboxView } from "../LightboxView"; -import { DocumentType } from "../../documents/DocumentTypes"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index bdd9334f4..003b3adbe 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -1,8 +1,8 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { computed } from "mobx"; +import { computed, observable, action, trace, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc"; +import { DataSym, Doc, DocListCast, Field, Opt, DocListCastAsync } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { RichTextField } from "../../../fields/RichTextField"; @@ -19,7 +19,6 @@ import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import './FilterBox.scss'; import { Scripting } from "../../util/Scripting"; -import { values } from "lodash"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -31,9 +30,19 @@ const FilterBoxDocument = makeInterface(documentSchema); export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDocument>(FilterBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } + @observable _loaded = false; + componentDidMount() { + reaction(() => DocListCastAsync(CollectionDockingView.Instance.props.Document.data), + async (activeTabsAsync) => { + const activeTabs = await activeTabsAsync; + activeTabs && (await SearchBox.foreachRecursiveDocAsync(activeTabs, emptyFunction)); + runInAction(() => this._loaded = true); + }, { fireImmediately: true }); + } @computed get allDocs() { + trace(); const allDocs = new Set<Doc>(); - if (CollectionDockingView.Instance) { + if (this._loaded && CollectionDockingView.Instance) { const activeTabs = DocListCast(CollectionDockingView.Instance.props.Document.data); SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc)); setTimeout(() => CollectionDockingView.Instance.props.Document.allDocuments = new List<Doc>(Array.from(allDocs))); @@ -42,6 +51,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc } @computed get _allFacets() { + trace(); const noviceReqFields = ["author", "tags", "text", "type"]; const noviceLayoutFields: string[] = [];//["_curPage"]; const noviceFields = [...noviceReqFields, ...noviceLayoutFields]; @@ -128,12 +138,12 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`; newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" }); } else if (facetHeader !== "tags" && nonNumbers / facetValues.strings.length < .1) { - newFacet = Docs.Create.SliderDocument({ title: facetHeader, _overflow: "visible", _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true }); + newFacet = Docs.Create.SliderDocument({ title: facetHeader, _overflow: "visible", _fitWidth: true, _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true }); const newFacetField = Doc.LayoutFieldKey(newFacet); const ranged = Doc.readDocRangeFilter(targetDoc, facetHeader); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox - const extendedMinVal = minVal - Math.min(1, Math.abs(maxVal - minVal) * .05); - const extendedMaxVal = maxVal + Math.min(1, Math.abs(maxVal - minVal) * .05); + const extendedMinVal = minVal - Math.min(1, Math.floor(Math.abs(maxVal - minVal) * .1)); + const extendedMaxVal = maxVal + Math.min(1, Math.ceil(Math.abs(maxVal - minVal) * .05)); newFacet[newFacetField + "-min"] = ranged === undefined ? extendedMinVal : ranged[0]; newFacet[newFacetField + "-max"] = ranged === undefined ? extendedMaxVal : ranged[1]; Doc.GetProto(newFacet)[newFacetField + "-minThumb"] = extendedMinVal; @@ -146,8 +156,8 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc newFacet.title = facetHeader; newFacet.treeViewOpen = true; newFacet.type = DocumentType.COL; - const capturedVariables = { layoutDoc: targetDoc, system: true, _stayInCollection: true, _hideContextMenu: true, dataDoc: (targetDoc.data as any)[0][DataSym] }; - newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, "${facetHeader}")`, {}, capturedVariables); + newFacet.target = targetDoc; + newFacet.data = ComputedField.MakeFunction(`readFacetData(self.target, "${facetHeader}")`); } newFacet && Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet); } @@ -159,19 +169,21 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc return script ? () => script : undefined; } suppressChildClick = () => ScriptField.MakeScript("")!; - render() { - const facetCollection = this.props.Document; - const flyout = <div className="filterBox-flyout" style={{ width: `100%`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}> + @computed get flyoutpanel() { + return <div className="filterBox-flyout" style={{ width: `100%`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}> {this._allFacets.map(facet => <label className="filterBox-flyout-facet" key={`${facet}`} onClick={e => this.facetClick(facet)}> - <input type="checkbox" onChange={e => { }} checked={DocListCast(this.props.Document[this.props.fieldKey]).some(d => d.title === facet)} /> + <input type="checkbox" onChange={emptyFunction} checked={DocListCast(this.props.Document[this.props.fieldKey]).some(d => d.title === facet)} /> <span className="checkmark" /> {facet} </label>)} </div>; + } + render() { + const facetCollection = this.props.Document; return this.props.dontRegisterView ? (null) : <div className="filterBox-treeView" style={{ width: "100%" }}> <div className="filterBox-addFacet" style={{ width: "100%" }} onPointerDown={e => e.stopPropagation()}> - <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}> + <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.flyoutpanel}> <div className="filterBox-addFacetButton"> <FontAwesomeIcon icon={"edit"} size={"lg"} /> <span className="filterBox-span">Choose Facets</span> @@ -233,7 +245,7 @@ Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: } return undefined; }); -Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) { +Scripting.addGlobal(function readFacetData(targetDoc: Doc, facetHeader: string) { const allCollectionDocs = DocListCast(CollectionDockingView.Instance?.props.Document.allDocuments); const set = new Set<string>(); if (facetHeader === "tags") allCollectionDocs.forEach(child => Field.toString(child[facetHeader] as Field).split(":").forEach(key => set.add(key))); @@ -246,7 +258,10 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) const doc = new Doc(); doc.system = true; doc.title = facetValue.toString(); - doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); + doc.target = targetDoc; + doc.facetHeader = facetHeader; + doc.facetValue = facetValue; + doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)"); return doc; }); return new List<Doc>(facetValueDocSet); diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index c82d03fce..899fac66d 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -3,7 +3,7 @@ import { Tooltip } from '@material-ui/core'; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc'; +import { Doc, DocListCast, Field, Opt, DocListCastAsync } from '../../../fields/Doc'; import { documentSchema } from "../../../fields/documentSchemas"; import { Copy, Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; @@ -185,6 +185,21 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc return finalDocs; } + static async foreachRecursiveDocAsync(docs: Doc[], func: (doc: Doc) => void) { + let newarray: Doc[] = []; + while (docs.length > 0) { + newarray = []; + await Promise.all(docs.filter(d => d).map(async d => { + const fieldKey = Doc.LayoutFieldKey(d); + const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); + const data = d[annos ? fieldKey + "-annotations" : fieldKey]; + const docs = await DocListCastAsync(data); + docs && newarray.push(...docs); + func(d); + })); + docs = newarray; + } + } static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) { let newarray: Doc[] = []; while (docs.length > 0) { |