aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/StyleProvider.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.scss5
-rw-r--r--src/client/views/collections/TreeView.scss11
-rw-r--r--src/client/views/collections/TreeView.tsx74
4 files changed, 63 insertions, 29 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 5c10c2344..34418e170 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -213,7 +213,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
}
export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) {
- return <div className={`styleProvider-treeView-icon${doc[field] ? "-active" : ""}`}
+ return <div title={field} className={`styleProvider-treeView-icon${doc[field] ? "-active" : ""}`}
onClick={undoBatch(action((e: React.MouseEvent) => {
e.stopPropagation();
clickFunc ? clickFunc() : (doc[field] = doc[field] ? undefined : true);
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index a8eee9c19..93523a6cf 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,5 +1,6 @@
@import "../global/globalCssVariables";
+
.collectionTreeView-container {
transform-origin: top left;
height: 100%;
@@ -31,9 +32,11 @@
width: unset;
height: unset;
}
+ &:hover {
+ cursor: ns-resize;
+ }
}
-
.no-indent {
padding-left: 0;
width: max-content;
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 4707ebb80..b91737a1d 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -62,6 +62,17 @@
}
}
+.treeView-sorting {
+ position: absolute;
+ height: max-content;
+ pointer-events: none;
+ color: white;
+ border-radius: 4px;
+ font-size: 10px;
+}
+.treeView-container-active {
+ cursor: default;
+}
.treeView-container-outline-active
.treeView-container-active {
z-index: 100;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 9108acfcf..3a49297f8 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -79,6 +79,7 @@ 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>;
@@ -156,6 +157,17 @@ export class TreeView extends React.Component<TreeViewProps> {
docView.select(false);
}
}
+ @action
+ openLevel = (docView: DocumentView) => {
+ if (this.props.document.isFolder || Doc.IsSystem(this.props.document)) {
+ this.treeViewOpen = !this.treeViewOpen;
+ } else {
+ // choose an appropriate alias or make one. --- choose the first alias that (1) user owns, (2) has no context field ... otherwise make a new alias
+ const bestAlias = docView.props.Document.author === Doc.CurrentUserEmail ? docView.props.Document : DocListCast(this.props.document.aliases).find(doc => !doc.context && doc.author === Doc.CurrentUserEmail);
+ const nextBestAlias = DocListCast(this.props.document.aliases).find(doc => doc.author === Doc.CurrentUserEmail);
+ this.props.addDocTab(bestAlias ?? nextBestAlias ?? Doc.MakeAlias(this.props.document), "lightbox");
+ }
+ }
constructor(props: any) {
super(props);
@@ -399,13 +411,16 @@ export class TreeView extends React.Component<TreeViewProps> {
TraceMobx();
const expandKey = this.treeViewExpandedView;
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 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 === "z") {
const docs = TreeView.sortDocs(this.childDocs || ([] as Doc[]), ordering);
doc.zIndex = addBefore ? NumCast(addBefore.zIndex) + (before ? -0.5 : 0.5) : 1000;
docs.push(doc);
@@ -418,24 +433,29 @@ 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 = ["up", "down", "Z", undefined];
+ 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 <ul key={expandKey + "more"} title={"sort: " + sortings[curSort]} 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]);
- e.stopPropagation();
- }
- }}>
- {!docs ? (null) :
- TreeView.GetChildElements(docs, this.props.treeView, this, this.layoutDoc,
- this.dataDoc, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move,
- StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform,
- this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields,
- [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged,
- this.props.dontRegisterView, emptyFunction, emptyFunction, this.childContextMenuItems())}
- </ul >;
+ return <>
+ {!docs?.length ? (null) : <div className={'treeView-sorting'} style={{ background: color }} >
+ {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]);
+ e.stopPropagation();
+ }
+ }}>
+ {!docs ? (null) :
+ TreeView.GetChildElements(docs, this.props.treeView, this, this.layoutDoc,
+ this.dataDoc, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move,
+ StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform,
+ this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields,
+ [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged,
+ this.props.dontRegisterView, emptyFunction, emptyFunction, this.childContextMenuItems())}
+ </ul >
+ </>;
} else if (this.treeViewExpandedView === "fields") {
return <ul key={this.doc[Id] + this.doc.title}>
<div style={{ display: "inline-block" }} >
@@ -497,7 +517,7 @@ export class TreeView extends React.Component<TreeViewProps> {
const data = () => this.childDocs || this.props.treeView.dashboardMode ? this.fieldKey : "";
const aliases = () => this.props.treeView.dashboardMode ? "" : "aliases";
const fields = () => Doc.UserDoc().noviceMode ? "" : "fields";
- const layout = (this.props.treeView.dashboardMode && Doc.UserDoc().noviceMode) || this.doc.viewType === CollectionViewType.Docking ? [] : ["layout"];
+ const layout = (Doc.UserDoc().noviceMode) || this.doc.viewType === CollectionViewType.Docking ? [] : ["layout"];
return [data(), ...layout, ...(this.props.treeView.fileSysMode ? [aliases(), links(), annos()] : []), fields()].filter(m => m);
}
@action
@@ -512,9 +532,9 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get headerElements() {
return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? (null)
: <>
- {this.doc.hideContextMenu ? (null) : <FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />}
+ {this.doc.hideContextMenu ? (null) : <FontAwesomeIcon title="context menu" key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />}
{this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) :
- <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
+ <span className="collectionTreeView-keyHeader" title="type of expanded data" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
{this.treeViewExpandedView}
</span>}
</>;
@@ -771,9 +791,9 @@ export class TreeView extends React.Component<TreeViewProps> {
}
@computed get renderBorder() {
- const sorting = this.doc[`${this.fieldKey}-sortCriterion`];
- return <div className={`treeView-border${this.props.treeView.outlineMode ? "outline" : ""}`}
- style={{ borderColor: sorting === undefined ? undefined : sorting === "up" ? "crimson" : sorting === "down" ? "blue" : "green" }}>
+ 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 }}>
{!this.treeViewOpen ? (null) : this.renderContent}
</div>;
}
@@ -822,9 +842,9 @@ export class TreeView extends React.Component<TreeViewProps> {
};
docs.sort(function (d1, d2): 0 | 1 | -1 {
const a = (criterion === "up" ? d2 : d1);
- const b = (criterion === "up" ? d1 : d2);
- const first = a[criterion === "Z" ? "zIndex" : "title"];
- const second = b[criterion === "Z" ? "zIndex" : "title"];
+ const b = (criterion === "down" ? d1 : d2);
+ const first = a[criterion === "z" ? "zIndex" : "title"];
+ const second = b[criterion === "z" ? "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;