aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-04-06 11:09:26 -0400
committerbobzel <zzzman@gmail.com>2021-04-06 11:09:26 -0400
commite675858cfab46300a543b1013c7f88c8233ed7ad (patch)
tree3eeb090df98947d800358dca56ed467d3351be99 /src
parent00127a4fccbd00eb3d05699a3a14f52feb7b57db (diff)
added ability to remove filters using inline context menu
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/TreeView.tsx12
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/FilterBox.tsx34
4 files changed, 24 insertions, 29 deletions
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<Document, Partial<coll
const targetDataDoc = this.doc[DataSym];
const value = DocListCast(targetDataDoc[this.props.fieldKey]);
const result = value.filter(v => !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<TreeViewProps> {
}
@computed get headerElements() {
- return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null)
+ return this.props.treeViewHideHeaderFields() ? (null)
: <>
<FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />
- {this.doc.treeViewExpandedViewLock ? (null) :
+ {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) :
<span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
{this.treeViewExpandedView}
</span>}
</>;
}
- 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<DocumentViewInternalProps
const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>
- 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<DocumentViewInternalProps
if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event
cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15);
- !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.
+ 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<FieldViewProps, FilterBoxDoc
});
return { strings: Array.from(valueSet.keys()), rtFields };
}
-
+ removeFilterDoc = (doc: Doc | Doc[]) => (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<FieldViewProps, FilterBoxDoc
}
}
}
+ return true;
}
-
/**
* Responds to clicking the check box in the flyout menu
*/
@@ -199,22 +199,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
const targetDoc = FilterBox.targetDoc;
const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader);
if (found !== -1) {
- // comment this bit out later once the x works in treeview
- (this.dataDoc[this.props.fieldKey] as List<Doc>).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<FieldViewProps, FilterBoxDoc
});
let newFacet: Opt<Doc>;
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<FieldViewProps, FilterBoxDoc
newFacet.target = targetDoc;
newFacet.data = ComputedField.MakeFunction(`readFacetData(self.target, "${facetHeader}")`);
}
- newFacet && Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet);
+ this.props.docViewPath()[0].ComponentView
+ const remove = ScriptField.MakeScript(`documentView.props.removeDocument(self)`, { documentView: "any" });
+ newFacet.contextMenuScripts = new List<ScriptField>([remove!]);
+ newFacet.contextMenuLabels = new List<string>(["Remove"]);
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet);
}
}
@@ -450,7 +439,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
whenChildContentsActiveChanged={returnFalse}
treeViewHideTitle={true}
focus={returnFalse}
- treeViewHideHeaderFields={true}
+ treeViewHideHeaderFields={false}
onCheckedClick={this.scriptField}
dontRegisterView={true}
styleProvider={this.props.styleProvider}
@@ -458,7 +447,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
docViewPath={this.props.docViewPath}
scriptContext={this.props.scriptContext}
moveDocument={returnFalse}
- removeDocument={returnFalse}
+ removeDocument={this.removeFilterDoc}
addDocument={returnFalse} />
</div>
<div className="filterBox-bottom">
@@ -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();