aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-05-04 16:03:51 -0400
committerbobzel <zzzman@gmail.com>2022-05-04 16:03:51 -0400
commit32d46a0b641022cf0dd1fe0cf15629cf75057b59 (patch)
tree4120c2c42de16e7dcb680634ef9daa7550935480 /src
parenta969d0212c69844cbbe82b24f124a496145a1d9b (diff)
cleaned up treeview sorting.
Diffstat (limited to 'src')
-rw-r--r--src/client/views/StyleProvider.tsx10
-rw-r--r--src/client/views/collections/TreeView.tsx46
-rw-r--r--src/client/views/nodes/FilterBox.tsx2
3 files changed, 37 insertions, 21 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index a530ff90a..ca9826ab9 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -24,6 +24,7 @@ import { SliderBox } from './nodes/SliderBox';
import "./StyleProvider.scss";
import React = require("react");
import { InkingStroke } from './InkingStroke';
+import { TreeSort } from './collections/TreeView';
export enum StyleLayers {
Background = "background"
@@ -31,6 +32,7 @@ export enum StyleLayers {
export enum StyleProp {
TreeViewIcon = "treeViewIcon",
+ TreeViewSortings = "treeViewSortings",// options for how to sort tree view items
DocContents = "docContents", // when specified, the JSX returned will replace the normal rendering of the document view
Opacity = "opacity", // opacity of the document view
Hidden = "hidden", // whether the document view should not be isplayed
@@ -98,6 +100,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
return <img src={url} width={20} height={15} style={{ margin: "auto", display: "block", objectFit: "contain" }} />;
}
return Doc.toIcon(doc, isOpen);
+
+ case StyleProp.TreeViewSortings:
+ const allSorts: { [key: string]: { color: string, label: string } | undefined } = {};
+ allSorts[TreeSort.Down] = { color: "blue", label: "↓" };
+ allSorts[TreeSort.Up] = { color: "crimson", label: "↑" };
+ if (doc?._viewType === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: "green", label: "z" };
+ allSorts[TreeSort.None] = { color: "darkgray", label: '\u00A0\u00A0\u00A0' };
+ return allSorts;
case StyleProp.DocContents: return undefined;
case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? "lightgrey" : "dimgrey";
case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null));
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 647476784..72480b094 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -67,7 +67,12 @@ export interface TreeViewProps {
const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("px", "")); };
-@observer
+export enum TreeSort {
+ Up = "up",
+ Down = "down",
+ Zindex = "z",
+ None = "none"
+};
/**
* Renders a treeView of a collection of documents
*
@@ -75,11 +80,11 @@ const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("p
* treeViewOpen : flag denoting whether the documents sub-tree (contents) is visible or hidden
* treeViewExpandedView : name of field whose contents are being displayed as the document's subtree
*/
+@observer
export class TreeView extends React.Component<TreeViewProps> {
static _editTitleOnLoad: Opt<{ id: string, parent: TreeView | CollectionTreeView | undefined }>;
static _openTitleScript: Opt<ScriptField | undefined>;
static _openLevelScript: Opt<ScriptField | undefined>;
- static _sortUIMap = [["up", "crimson", "↑"], ["down", "blue", "↓"], ["z", "green", "z"], ["x", "darkgray", '\u00A0\u00A0\u00A0']];
private _header: React.RefObject<HTMLDivElement> = React.createRef();
private _tref = React.createRef<HTMLDivElement>();
@observable _docRef: Opt<DocumentView>;
@@ -410,17 +415,18 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get renderContent() {
TraceMobx();
const expandKey = this.treeViewExpandedView;
+ const sortings = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string, label: string } };
if (["links", "annotations", "aliases", this.fieldKey].includes(expandKey)) {
- const sorting = StrCast(this.doc.treeViewSortCriterion);
- const color = (TreeView._sortUIMap.find((sortUIfields) => sortUIfields[0] === sorting) ?? TreeView._sortUIMap.lastElement())[1];
- const label = (TreeView._sortUIMap.find((sortUIfields) => sortUIfields[0] === sorting) ?? TreeView._sortUIMap.lastElement())[2];
+ const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
+ const sortKeys = Object.keys(sortings);
+ const curSortIndex = Math.max(0, sortKeys.findIndex(val => val === sorting));
const key = (expandKey === "annotations" ? `${this.fieldKey}-` : "") + expandKey;
const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
// if there's a sort ordering specified that can be modified on drop (eg, zorder can be modified, alphabetical can't),
// then the modification would be done here
const ordering = StrCast(this.doc.treeViewSortCriterion);
- if (ordering === "z") {
+ if (ordering === TreeSort.Zindex) {
const docs = TreeView.sortDocs(this.childDocs || ([] as Doc[]), ordering);
doc.zIndex = addBefore ? NumCast(addBefore.zIndex) + (before ? -0.5 : 0.5) : 1000;
docs.push(doc);
@@ -433,17 +439,15 @@ export class TreeView extends React.Component<TreeViewProps> {
const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
const docs = expandKey === "aliases" ? this.childAliases : expandKey === "links" ? this.childLinks : expandKey === "annotations" ? this.childAnnos : this.childDocs;
let downX = 0, downY = 0;
- const sortings = this.props.treeView.rootDoc === Doc.UserDoc().myFilesystem ? ["up", "down", "x"] : ["up", "down", "z", "x"];
- const curSort = Math.max(0, sortings.indexOf(Cast(this.doc.treeViewSortCriterion, "string", null)));
return <>
- {!docs?.length ? (null) : <div className={'treeView-sorting'} style={{ background: color }} >
- {label}
+ {!docs?.length ? (null) : <div className={'treeView-sorting'} style={{ background: sortings[sorting]?.color }} >
+ {sortings[sorting]?.label}
</div>}
<ul key={expandKey + "more"} title="click to change sort order" className={this.doc.treeViewHideTitle ? "no-indent" : ""}
onPointerDown={e => { downX = e.clientX; downY = e.clientY; e.stopPropagation(); }}
onClick={(e) => {
if (this.props.isContentActive() && Math.abs(e.clientX - downX) < 3 && Math.abs(e.clientY - downY) < 3) {
- !this.props.treeView.outlineMode && (this.doc.treeViewSortCriterion = sortings[(curSort + 1) % sortings.length]);
+ !this.props.treeView.outlineMode && (this.doc.treeViewSortCriterion = sortKeys[(curSortIndex + 1) % sortKeys.length]);
e.stopPropagation();
}
}}>
@@ -791,9 +795,9 @@ export class TreeView extends React.Component<TreeViewProps> {
}
@computed get renderBorder() {
- const sorting = StrCast(this.doc.treeViewSortCriterion);
- const color = (TreeView._sortUIMap.find((sortUIfields) => sortUIfields[0] === sorting) ?? TreeView._sortUIMap.lastElement())[1];
- return <div className={`treeView-border${this.props.treeView.outlineMode ? "outline" : ""}`} style={{ borderColor: color }}>
+ const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
+ const sortings = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string, label: string } };
+ return <div className={`treeView-border${this.props.treeView.outlineMode ? "outline" : ""}`} style={{ borderColor: sortings[sorting]?.color }}>
{!this.treeViewOpen ? (null) : this.renderContent}
</div>;
}
@@ -827,11 +831,11 @@ export class TreeView extends React.Component<TreeViewProps> {
public static sortDocs(childDocs: Doc[], criterion: string | undefined) {
const docs = childDocs.slice();
- if (criterion) {
+ if (criterion !== TreeSort.None) {
const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
const reN = /[0-9]*$/;
- const aA = a.replace(reN, ""); // get rid of trailing numbers
- const bA = b.replace(reN, "");
+ const aA = a.replace(reN, "") ? a.replace(reN, "") : +a; // get rid of trailing numbers
+ const bA = b.replace(reN, "") ? b.replace(reN, "") : +b;
if (aA === bA) { // if header string matches, then compare numbers numerically
const aN = parseInt(a.match(reN)![0], 10);
const bN = parseInt(b.match(reN)![0], 10);
@@ -841,10 +845,10 @@ export class TreeView extends React.Component<TreeViewProps> {
}
};
docs.sort(function (d1, d2): 0 | 1 | -1 {
- const a = (criterion === "up" ? d2 : d1);
- const b = (criterion === "down" ? d1 : d2);
- const first = a[criterion === "z" ? "zIndex" : "title"];
- const second = b[criterion === "z" ? "zIndex" : "title"];
+ const a = (criterion === TreeSort.Up ? d2 : d1);
+ const b = (criterion === TreeSort.Up ? d1 : d2);
+ const first = a[criterion === TreeSort.Zindex ? "zIndex" : "title"];
+ const second = b[criterion === TreeSort.Zindex ? "zIndex" : "title"];
if (typeof first === 'number' && typeof second === 'number') return (first - second) > 0 ? 1 : -1;
if (typeof first === 'string' && typeof second === 'string') return sortAlphaNum(first, second);
return criterion ? 1 : -1;
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index ba65acee0..dc0ab5ec2 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -386,6 +386,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps>() {
options={options}
isMulti={false}
onChange={val => this.facetClick((val as UserOptions).value)}
+ onKeyDown={e => e.stopPropagation()}
value={null}
closeMenuOnSelect={true}
/>
@@ -420,6 +421,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps>() {
whenChildContentsActiveChanged={returnFalse}
treeViewHideTitle={true}
focus={returnFalse}
+ onCheckedClick={this.scriptField}
treeViewHideHeaderFields={false}
dontRegisterView={true}
styleProvider={this.FilterStyleProvider}