aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2021-02-20 20:26:36 -0500
committerusodhi <61431818+usodhi@users.noreply.github.com>2021-02-20 20:26:36 -0500
commiteff29ee31afdaf683fbd33d84833872c027c8a6c (patch)
tree23eade31af8ad70b8466cbce83769fde76900471
parentc2bcb4ac83ecafb0bf23f72ed1bc2d05b877da6d (diff)
parenta2abfb07b783769094414c39e300b88c31cfc450 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into filters
-rw-r--r--src/client/documents/Documents.ts11
-rw-r--r--src/client/util/CurrentUserUtils.ts23
-rw-r--r--src/client/util/LinkManager.ts16
-rw-r--r--src/client/views/LightboxView.tsx23
-rw-r--r--src/client/views/collections/CollectionSubView.tsx44
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/TreeView.tsx8
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/search/SearchBox.tsx4
9 files changed, 90 insertions, 45 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d1a77f2ec..1a51f7a4b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -937,6 +937,9 @@ export namespace DocUtils {
}
export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField) {
const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
+ if (!docFilters?.length && !docRangeFilters?.length) {
+ return childDocs.filter(d => !d.cookies); // remove documents that need a cookie if there are no filters to provide one
+ }
const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields
docFilters.forEach(filter => {
@@ -952,9 +955,13 @@ export namespace DocUtils {
const filteredDocs = docFilters.length ? childDocs.filter(d => {
if (d.z) return true;
- for (const facetKey of Object.keys(filterFacets)) {
+ // if the document needs a cookie but no filter provides the cookie, then the document does not pass the filter
+ if (d["cookies"] && (!filterFacets["cookies"] || !Object.keys(filterFacets["cookies"]).some(key => d["cookies"] === key))) {
+ return false;
+ }
+ for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== "cookies")) {
const facet = filterFacets[facetKey];
- const matches = Object.keys(facet).filter(value => facet[value] === "match");
+ const matches = Object.keys(facet).filter(value => value !== "cookies" && facet[value] === "match");
const checks = Object.keys(facet).filter(value => facet[value] === "check");
const xs = Object.keys(facet).filter(value => facet[value] === "x");
const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value));
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 2cba99355..ae22320f3 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -524,7 +524,7 @@ export class CurrentUserUtils {
{ title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
// { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' },
{ title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
- { title: "Catalog", target: undefined as any, icon: "file", click: 'selectMainMenu(self)' },
+ { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' },
{ title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' },
{ title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' },
{ title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' },
@@ -580,6 +580,10 @@ export class CurrentUserUtils {
btn.color = "white";
btn._backgroundColor = "";
btn.dontUndo = true;
+ if (btn.title === "Catalog" || btn.title === "My Files") { // migration from Catalog to My Files
+ btn.target = Doc.UserDoc().myFilesystem;
+ btn.title = "My Files";
+ }
}));
});
});
@@ -772,6 +776,22 @@ export class CurrentUserUtils {
return doc.myPresentations as any as Doc;
}
+ static async setupFilesystem(doc: Doc) {
+ await doc.myFilesystem;
+ if (doc.myFilesystem === undefined) {
+ doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "file orphans", _stayInCollection: true, system: true, isFolder: true });
+ doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
+ doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileRoot as Doc, doc.myFileOrphans as Doc], {
+ title: "My Documents", _height: 100,
+ treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
+ treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true,
+ isFolder: true, treeViewType: "fileSystem",
+ lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true
+ }));
+ }
+ return doc.myFilesystem as any as Doc;
+ }
+
static setupRecentlyClosedDocs(doc: Doc) {
// setup Recently Closed library item
doc.myRecentlyClosedDocs === undefined;
@@ -831,6 +851,7 @@ export class CurrentUserUtils {
await CurrentUserUtils.setupToolsBtnPanel(doc);
CurrentUserUtils.setupDashboards(doc);
CurrentUserUtils.setupPresentations(doc);
+ CurrentUserUtils.setupFilesystem(doc);
CurrentUserUtils.setupRecentlyClosedDocs(doc);
// CurrentUserUtils.setupFilterDocs(doc);
CurrentUserUtils.setupUserDoc(doc);
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 402cbdd68..0512864df 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -149,10 +149,18 @@ export class LinkManager {
const target = (sourceDoc === linkDoc.anchor1 ? linkDoc.anchor2 : sourceDoc === linkDoc.anchor2 ? linkDoc.anchor1 :
(Doc.AreProtosEqual(sourceDoc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, sourceDoc) ? linkDoc.anchor2 : linkDoc.anchor1)) as Doc;
if (target) {
- const containerDoc = Cast(target.annotationOn, Doc, null) || target;
- const targetContext = Cast(containerDoc?.context, Doc, null);
- const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
- DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "add:right"), finished), targetNavContext, linkDoc, undefined, sourceDoc, finished);
+ if (target.TourMap) {
+ const fieldKey = Doc.LayoutFieldKey(target);
+ const tour = DocListCast(target[fieldKey]).reverse();
+ LightboxView.SetLightboxDoc(currentContext, undefined, tour);
+ setTimeout(LightboxView.Next);
+ finished?.();
+ } else {
+ const containerDoc = Cast(target.annotationOn, Doc, null) || target;
+ const targetContext = Cast(containerDoc?.context, Doc, null);
+ const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
+ DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "add:right"), finished), targetNavContext, linkDoc, undefined, sourceDoc, finished);
+ }
} else {
finished?.();
}
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index af07ead97..5e810d335 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -24,6 +24,7 @@ interface LightboxViewProps {
@observer
export class LightboxView extends React.Component<LightboxViewProps> {
+
@computed public static get LightboxDoc() { return this._doc; }
@observable private static _doc: Opt<Doc>;
@observable private static _docTarget: Opt<Doc>;
@@ -45,6 +46,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
}
this._future = this._history = [];
} else {
+ TabDocView.PinDoc(doc, { hidePresBox: true });
this._history ? this._history.push({ doc, target }) : this._history = [{ doc, target }];
this._savedState = {
panX: Cast(doc._panX, "number", null),
@@ -88,9 +90,11 @@ export class LightboxView extends React.Component<LightboxViewProps> {
public static GetSavedState(doc: Doc) {
return this.LightboxDoc === doc && this._savedState ? this._savedState : undefined;
}
- public static SetDocFilter(filter: string) {
- if (this.LightboxDoc && filter) {
- this._docFilters = [`cookies:${filter}:match`];
+
+ // adds a cookie to the lightbox view - the cookie becomes part of a filter which will display any documents whose cookie metadata field matches this cookie
+ public static SetCookie(cookie: string) {
+ if (this.LightboxDoc && cookie) {
+ this._docFilters = (f => this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f])(`cookies:${cookie}:provide`);
}
}
public static AddDocTab = (doc: Doc, location: string) => {
@@ -104,8 +108,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
}
docFilters = () => LightboxView._docFilters || [];
addDocTab = LightboxView.AddDocTab;
- @action
- stepForward = () => {
+ @action public static Next() {
const doc = LightboxView._doc!;
const target = LightboxView._docTarget = LightboxView._future?.pop();
const docView = target && DocumentManager.Instance.getLightboxDocumentView(target);
@@ -138,8 +141,8 @@ export class LightboxView extends React.Component<LightboxViewProps> {
return opp?.TourMap ? opp : undefined;
}).filter(m => m).map(m => m!);
}
- @action
- stepBackward = () => {
+
+ @action public static Previous() {
const previous = LightboxView._history?.pop();
if (!previous || !LightboxView._history?.length) {
LightboxView.SetLightboxDoc(undefined);
@@ -182,7 +185,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
TabDocView.PinDoc(coll, { hidePresBox: true });
}
}
- setTimeout(() => this.stepForward());
+ setTimeout(LightboxView.Next);
}
fitToBox = () => LightboxView._docTarget === LightboxView.LightboxDoc;
@@ -242,12 +245,12 @@ export class LightboxView extends React.Component<LightboxViewProps> {
{this.navBtn(0, undefined, this.props.PanelHeight / 2 - 12.50, "chevron-left",
() => LightboxView.LightboxDoc && LightboxView._history?.length ? "" : "none", e => {
e.stopPropagation();
- this.stepBackward();
+ LightboxView.Previous();
})}
{this.navBtn(this.props.PanelWidth - Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]), undefined, this.props.PanelHeight / 2 - 12.50, "chevron-right",
() => LightboxView.LightboxDoc && LightboxView._future?.length ? "" : "none", e => {
e.stopPropagation();
- this.stepForward();
+ LightboxView.Next();
})}
{this.navBtn("50%", 0, 0, "chevron-down",
() => LightboxView.LightboxDoc && LightboxView._future?.length ? "" : "none", e => {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 3cbda37e2..2ba45df2c 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -113,13 +113,13 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
const docRangeFilters = this.docRangeFilters();
const searchDocs = this.searchFilterDocs();
if (this.props.Document.dontRegisterView || (!docFilters.length && !docRangeFilters.length && !searchDocs.length)) {
- return childDocs;
+ return childDocs.filter(cd => !cd.cookies); // remove any documents that require a cookie if there are no filters to provide one
}
const docsforFilter: Doc[] = [];
childDocs.forEach((d) => {
if (DocUtils.Excluded(d, docFilters)) return;
- let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0));
+ let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0));
const fieldKey = Doc.LayoutFieldKey(d);
const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
const data = d[annos ? fieldKey + "-annotations" : fieldKey];
@@ -127,7 +127,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
let subDocs = DocListCast(data);
if (subDocs.length > 0) {
let newarray: Doc[] = [];
- notFiltered = notFiltered || (!searchDocs.length && (!docFilters.length && !docRangeFilters.length) && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript).length);
+ notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript).length);
while (subDocs.length > 0 && !notFiltered) {
newarray = [];
subDocs.forEach((t) => {
@@ -252,9 +252,11 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
e.stopPropagation();
e.preventDefault();
- if (!this.addDocument) {
- alert("this.props.addDocument does not exist. Aborting drop operation.");
- return;
+
+ const addDocument = (doc: Doc | Doc[]) => {
+ const docs = doc instanceof Doc ? [doc] : doc;
+ docs.forEach(doc => Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", doc));
+ this.addDocument(doc);
}
if (html) {
@@ -266,14 +268,14 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
DocServer.GetRefField(docid).then(f => {
if (f instanceof Doc) {
if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
- (f instanceof Doc) && this.addDocument(f);
+ (f instanceof Doc) && addDocument(f);
}
});
} else {
- this.addDocument(Docs.Create.WebDocument(href, { ...options, title: href }));
+ addDocument(Docs.Create.WebDocument(href, { ...options, title: href }));
}
} else if (text) {
- this.addDocument(Docs.Create.TextDocument(text, { ...options, _showTitle: StrCast(Doc.UserDoc().showTitle), _width: 100, _height: 25 }));
+ addDocument(Docs.Create.TextDocument(text, { ...options, _showTitle: StrCast(Doc.UserDoc().showTitle), _width: 100, _height: 25 }));
}
return;
}
@@ -293,7 +295,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (source.startsWith("http")) {
const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 });
ImageUtils.ExtractExif(doc);
- this.addDocument(doc);
+ addDocument(doc);
}
return;
} else {
@@ -303,7 +305,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
DocServer.GetRefField(docid).then(f => {
if (f instanceof Doc) {
if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
- (f instanceof Doc) && this.addDocument(f);
+ (f instanceof Doc) && addDocument(f);
}
});
} else {
@@ -317,7 +319,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
const modHtml = srcUrl ? html.replace(reg, srcUrl) : html;
const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: "-web page-", _width: 300, _height: 300 });
Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text;
- this.addDocument(htmlDoc);
+ addDocument(htmlDoc);
if (srcWeb) {
const iframe = SelectionManager.Views()[0].ContentDiv?.getElementsByTagName("iframe")?.[0];
const focusNode = (iframe?.contentDocument?.getSelection()?.focusNode as any);
@@ -345,7 +347,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if ((uriList || text).includes("www.youtube.com/watch") || text.includes("www.youtube.com/embed")) {
const url = (uriList || text).replace("youtube.com/watch?v=", "youtube.com/embed/").split("&")[0];
console.log("Video URI = ", uriList);
- console.log("Add:" + this.addDocument(Docs.Create.VideoDocument(url, {
+ console.log("Add:" + addDocument(Docs.Create.VideoDocument(url, {
...options,
title: url,
_width: 400,
@@ -382,7 +384,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
alias._nativeWidth = 850;
alias._height = 512;
alias._width = 400;
- this.addDocument(alias);
+ addDocument(alias);
} else {
console.log("Adding ...");
const newDoc = Docs.Create.WebDocument(uriList.split("#annotations:")[0], {// clean hypothes.is URLs that reference a specific annotation (eg. https://en.wikipedia.org/wiki/Cartoon#annotations:t7qAeNbCEeqfG5972KR2Ig)
@@ -394,7 +396,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
useCors: true
});
console.log(" ... " + newDoc.title);
- console.log(" ... " + this.addDocument(newDoc) + " " + newDoc.title);
+ console.log(" ... " + addDocument(newDoc) + " " + newDoc.title);
}
return;
}
@@ -425,7 +427,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
file?.type === "application/json" && Utils.readUploadedFileAsText(file).then(result => {
const json = JSON.parse(result as string);
- this.addDocument(Docs.Create.TreeDocument(
+ addDocument(Docs.Create.TreeDocument(
json["rectangular-puzzle"].crossword.clues[0].clue.map((c: any) => {
const label = Docs.Create.LabelDocument({ title: c["#text"], _width: 120, _height: 20 });
const proto = Doc.GetProto(label);
@@ -437,10 +439,10 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
});
}
}
- this.slowLoadDocuments(files, options, generatedDocuments, text, completed, e.clientX, e.clientY);
+ this.slowLoadDocuments(files, options, generatedDocuments, text, completed, e.clientX, e.clientY, addDocument);
batch.end();
}
- slowLoadDocuments = async (files: File[], options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: (() => void) | undefined, clientX: number, clientY: number) => {
+ slowLoadDocuments = async (files: File[], options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: (() => void) | undefined, clientX: number, clientY: number, addDocument: (doc: Doc | Doc[]) => boolean) => {
runInAction(() => CollectionSubViewLoader.Waiting = "block");
const disposer = OverlayView.Instance.addElement(
<ReactLoading type={"spinningBubbles"} color={"green"} height={250} width={250} />, { x: clientX - 125, y: clientY - 125 });
@@ -448,14 +450,14 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (generatedDocuments.length) {
const set = generatedDocuments.length > 1 && generatedDocuments.map(d => DocUtils.iconify(d));
if (set) {
- UndoManager.RunInBatch(() => this.addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!), "drop");
+ UndoManager.RunInBatch(() => addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!), "drop");
} else {
- UndoManager.RunInBatch(() => generatedDocuments.forEach(this.addDocument), "drop");
+ UndoManager.RunInBatch(() => generatedDocuments.forEach(addDocument), "drop");
}
completed?.();
} else {
if (text && !text.includes("https://")) {
- UndoManager.RunInBatch(() => this.addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop");
+ UndoManager.RunInBatch(() => addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop");
} else {
alert("Document upload failed - possibly an unsupported file type.");
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 564b41a89..d67fa75e9 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -73,9 +73,9 @@ export class
SelectionManager.DeselectAll();
if (result.length !== value.length) {
const ind = targetDataDoc[this.props.fieldKey].indexOf(doc);
+ const prev = ind && targetDataDoc[this.props.fieldKey][ind - 1];
targetDataDoc[this.props.fieldKey] = new List<Doc>(result);
if (ind > 0) {
- const prev = targetDataDoc[this.props.fieldKey][ind - 1];
FormattedTextBox.SelectOnLoad = prev[Id];
const prevView = DocumentManager.Instance.getDocumentView(prev, this.props.CollectionView);
prevView?.select(false);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index f3def9a23..d091e477a 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -32,6 +32,7 @@ import { CollectionTreeView } from './CollectionTreeView';
import { CollectionView, CollectionViewType } from './CollectionView';
import "./TreeView.scss";
import React = require("react");
+import { ContextMenu } from '../ContextMenu';
export interface TreeViewProps {
document: Doc;
@@ -93,7 +94,7 @@ export class TreeView extends React.Component<TreeViewProps> {
get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); }
get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive
get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; }
- get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.noviceMode || this.outlineMode || this.fileSysMode ? "layout" : "fields"); }
+ get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.fileSysMode ? "data" : this.noviceMode || this.outlineMode ? "layout" : "fields"); }
get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs && !this.fileSysMode ? this.fieldKey : this.defaultExpandedView); }
@observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
set treeViewOpen(c: boolean) {
@@ -212,9 +213,10 @@ export class TreeView extends React.Component<TreeViewProps> {
bullet.context = this.props.treeView.Document;
return added;
}
+
makeFolder = () => {
Doc.SetInPlace(this.doc, "editTitle", undefined, false);
- const folder = Docs.Create.FreeformDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true });
+ const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true });
const added = this.props.addDocument(folder);
folder.context = this.props.treeView.Document;
return added;
@@ -511,7 +513,7 @@ export class TreeView extends React.Component<TreeViewProps> {
}
showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef.current?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
- contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }];
+ contextMenuItems = () => this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }];
truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth());
onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
onChildDoubleClick = () => (!this.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 5afbec7e6..161469e24 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -46,6 +46,7 @@ import { PresBox } from './PresBox';
import { RadialMenu } from './RadialMenu';
import React = require("react");
import { ObjectField } from "../../../fields/ObjectField";
+import { LightboxView } from "../LightboxView";
const { Howl } = require('howler');
interface Window {
@@ -411,6 +412,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
focus = (anchor: Doc, options?: DocFocusOptions) => {
+ LightboxView.SetCookie(StrCast(anchor["cookies-set"]));
// copying over _VIEW fields immediately allows the view type to switch to create the right _componentView
Array.from(Object.keys(Doc.GetProto(anchor))).filter(key => key.startsWith(ViewSpecPrefix)).forEach(spec => this.layoutDoc[spec.replace(ViewSpecPrefix, "")] = ((field) => field instanceof ObjectField ? ObjectField.MakeCopy(field) : field)(anchor[spec]));
// after a timeout, the right _componentView should have been created, so call it to update its view spec values
@@ -665,10 +667,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : [];
!Doc.UserDoc().noviceMode && templateDoc && appearanceItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "add:right"), icon: "eye" });
DocListCast(this.Document.links).length && appearanceItems.splice(0, 0, { description: `${this.layoutDoc.hideLinkButton ? "Show" : "Hide"} Link Button`, event: action(() => this.layoutDoc.hideLinkButton = !this.layoutDoc.hideLinkButton), icon: "eye" });
- !Doc.UserDoc().noviceMode && appearanceItems.splice(0, 0, { description: `${!this.layoutDoc._showAudio ? "Show" : "Hide"} Audio Button`, event: action(() => this.layoutDoc._showAudio = !this.layoutDoc._showAudio), icon: "microphone" });
!appearance && cm.addItem({ description: "UI Controls...", subitems: appearanceItems, icon: "compass" });
if (!Doc.IsSystem(this.rootDoc) && this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Tree) {
+ !Doc.UserDoc().noviceMode && appearanceItems.splice(0, 0, { description: `${!this.layoutDoc._showAudio ? "Show" : "Hide"} Audio Button`, event: action(() => this.layoutDoc._showAudio = !this.layoutDoc._showAudio), icon: "microphone" });
const existingOnClick = cm.findByDescription("OnClick...");
const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index d10afdcf9..553443931 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -63,7 +63,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
@observable _deletedDocsStatus: boolean = false;
@observable _onlyAliases: boolean = true;
@observable _searchbarOpen = false;
- @observable _searchFullDB = "DB";
+ @observable _searchFullDB = "DB"; // "DB" means searh the entire database. "My Stuff" adds a flag that selects only documents that the current user has authored
@observable _noResults = "";
@observable _pageStart = 0;
@observable open = false;
@@ -466,7 +466,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
@computed get scopeButtons() {
- return <div style={{ height: 25, paddingLeft: "4px", paddingRight: "4px"}}>
+ return <div style={{ height: 25, paddingLeft: "4px", paddingRight: "4px" }}>
<form className="beta" style={{ justifyContent: "space-evenly", display: "flex" }}>
<div style={{ display: "contents" }}>
<div className="radio" style={{ margin: 0 }}>