From e675858cfab46300a543b1013c7f88c8233ed7ad Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 11:09:26 -0400 Subject: added ability to remove filters using inline context menu --- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 12 +++++--- src/client/views/nodes/DocumentView.tsx | 5 ++-- src/client/views/nodes/FilterBox.tsx | 34 ++++++++-------------- 4 files changed, 24 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 959864a60..55fe84835 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -101,7 +101,7 @@ export class CollectionTreeView extends CollectionSubView !docs.includes(v)); - SelectionManager.DeselectAll(); + if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views().some(dv => Doc.AreProtosEqual(dv.rootDoc, doc)))) SelectionManager.DeselectAll(); if (result.length !== value.length) { const ind = targetDataDoc[this.props.fieldKey].indexOf(doc); const prev = ind && targetDataDoc[this.props.fieldKey][ind - 1]; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 5df33afe0..8a5425992 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -21,7 +21,7 @@ import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from '../../util/UndoManager'; import { EditableView } from "../EditableView"; import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss'; -import { DocumentView, DocumentViewProps, StyleProviderFunc } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewProps, StyleProviderFunc, DocumentViewInternal } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { KeyValueBox } from '../nodes/KeyValueBox'; @@ -483,17 +483,21 @@ export class TreeView extends React.Component { } @computed get headerElements() { - return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null) + return this.props.treeViewHideHeaderFields() ? (null) : <> { this.showContextMenu(e); e.stopPropagation(); }} /> - {this.doc.treeViewExpandedViewLock ? (null) : + {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) : {this.treeViewExpandedView} } ; } - showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + showContextMenu = (e: React.MouseEvent) => { + DocumentViewInternal.SelectOnContextsMenu = false; + simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + DocumentViewInternal.SelectOnContextsMenu = true; + } contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 1c4008a55..703e78470 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -658,7 +658,7 @@ export class DocumentViewInternal extends DocComponent - cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); + cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); this.props.contextMenuItems?.().forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); @@ -746,8 +746,9 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + DocumentViewInternal.SelectOnContextsMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } + public static SelectOnContextsMenu = true; rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 30d7ed187..0a010c105 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -167,7 +167,7 @@ export class FilterBox extends ViewBoxBaseComponent (doc instanceof Doc ? [doc] : doc).map(doc => this.removeFilter(StrCast(doc.title))).length ? true : false; public removeFilter = (filterName: string) => { const targetDoc = FilterBox.targetDoc; const filterDoc = targetDoc.currentFilter as Doc; @@ -190,8 +190,8 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === facetHeader); if (found !== -1) { - // comment this bit out later once the x works in treeview - (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); - const docFilter = Cast(targetDoc._docFilters, listSpec("string")); - if (docFilter) { - let index: number; - while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - docFilter.splice(index, 1); - } - } - const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); - if (docRangeFilters) { - let index: number; - while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - docRangeFilters.splice(index, 3); - } - } + this.removeFilter(facetHeader); } else { const allCollectionDocs = DocListCast((targetDoc.data as any)[0].data); const facetValues = this.gatherFieldValues(targetDoc, facetHeader); @@ -232,7 +217,7 @@ export class FilterBox extends ViewBoxBaseComponent; if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { - newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); + newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`; @@ -261,7 +246,11 @@ export class FilterBox extends ViewBoxBaseComponent([remove!]); + newFacet.contextMenuLabels = new List(["Remove"]); + Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet); } } @@ -450,7 +439,7 @@ export class FilterBox extends ViewBoxBaseComponent
@@ -519,6 +508,7 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) const facetValues = Array.from(set).filter(v => v); let nonNumbers = 0; + facetValues.map(val => Number.isNaN(Number(val)) && nonNumbers++); const facetValueDocSet = (nonNumbers / facetValues.length > .1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2))).map(facetValue => { const doc = new Doc(); -- cgit v1.2.3-70-g09d2 From d01fdacae8e96c99a095dd2c97f62144ab81def5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 13:01:12 -0400 Subject: fix to get text filtering to work. --- src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ca8777de8..a8a2aaa5a 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -67,7 +67,7 @@ export class CollectionTreeView extends CollectionSubView disposer?.()); } - componentWillMount() { + componentDidMount() { this._disposers.autoheight = reaction(() => this.rootDoc.autoHeight, auto => auto && this.computeHeight(), { fireImmediately: true }); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 8a5425992..827dadae2 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -730,7 +730,7 @@ export class TreeView extends React.Component { return this.props.renderedIds.indexOf(this.doc[Id]) !== -1 ? "<" + this.doc.title + ">" : // just print the title of documents we've previously rendered in this hierarchical path to avoid cycles
this.props.isContentActive(true) && SelectionManager.DeselectAll()} + //onPointerDown={e => this.props.isContentActive(true) && SelectionManager.DeselectAll()} // bcz: this breaks entering a text filter in a filterBox since it deselects the filter's target document onKeyDown={this.onKeyDown}>
  • {hideTitle && this.doc.type !== DocumentType.RTF ? diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 0a010c105..718ebca28 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -217,13 +217,19 @@ export class FilterBox extends ViewBoxBaseComponent; if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { - newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); + newFacet = Docs.Create.TextDocument("", { + _width: 100, _height: 25, system: true, _stayInCollection: true, target: targetDoc, + treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true + }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; 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", _fitWidth: true, _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true }); + newFacet = Docs.Create.SliderDocument({ + title: facetHeader, _overflow: "visible", _fitWidth: true, + _height: 40, _stayInCollection: 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 -- cgit v1.2.3-70-g09d2