From 32d46a0b641022cf0dd1fe0cf15629cf75057b59 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 May 2022 16:03:51 -0400
Subject: cleaned up treeview sorting.

---
 src/client/views/collections/TreeView.tsx | 46 +++++++++++++++++--------------
 1 file changed, 25 insertions(+), 21 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

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;
-- 
cgit v1.2.3-70-g09d2

