From bd6b9c40f150fab76e8907c45e29fa809f9acae0 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Fri, 2 Apr 2021 19:04:09 -0400 Subject: dashboard sharing initial setup, inherits acls from dashboard - looks like it works --- src/client/util/CurrentUserUtils.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 849020392..f1357e3d7 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -35,6 +35,7 @@ import { UndoManager } from "./UndoManager"; import { SnappingManager } from "./SnappingManager"; import { InkTool } from "../../fields/InkField"; import { computedFn } from "mobx-utils"; +import { SharingManager } from "./SharingManager"; export let resolvedPorts: { server: number, socket: number }; @@ -907,9 +908,9 @@ export class CurrentUserUtils { if (doc.mySharedDocs === undefined) { let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer"); if (!sharedDocs) { - sharedDocs = Docs.Create.StackingDocument([], { - title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true, + sharedDocs = Docs.Create.TreeDocument([], { + title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, + _showTitle: "title", ignoreClick: false, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true, }, sharingDocumentId + "outer", sharingDocumentId); (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Add; } @@ -1188,8 +1189,10 @@ export class CurrentUserUtils { const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`); const createDashboard = ScriptField.MakeScript(`createNewDashboard()`); - dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!]); - dashboardDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard"]); + const shareDashboard = ScriptField.MakeScript(`shareDashboard()`); + const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`); + dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!, shareDashboard!, addToDashboards!]); + dashboardDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard", "Share Dashboard", "Add to Dashboards"]); Doc.AddDocToList(dashboards, "data", dashboardDoc); CurrentUserUtils.openDashboard(userDoc, dashboardDoc); @@ -1241,3 +1244,10 @@ Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Insta "returns all the links to the document or its annotations", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); +Scripting.addGlobal(function shareDashboard() { + CurrentUserUtils.ActiveDashboard.isShared = true; + SharingManager.Instance.open(undefined, CurrentUserUtils.ActiveDashboard); +}, + "opens sharing dialog for Dashboard"); +Scripting.addGlobal(function addToDashboards(dashboard: Doc) { Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboard); }, + "adds Dashboard to set of Dashboards"); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d252d6dba8b789215ed8da5b66889a26b06a2a18 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 3 Apr 2021 20:13:58 -0400 Subject: dashboard sharing works, aliases to go --- src/client/util/CurrentUserUtils.ts | 7 +++---- src/client/util/SharingManager.tsx | 24 +++++++++++++++++++++++- src/client/views/PropertiesView.tsx | 2 +- src/fields/Doc.ts | 2 +- 4 files changed, 28 insertions(+), 7 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f1357e3d7..fdceb60f3 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1189,7 +1189,7 @@ export class CurrentUserUtils { const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`); const createDashboard = ScriptField.MakeScript(`createNewDashboard()`); - const shareDashboard = ScriptField.MakeScript(`shareDashboard()`); + const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`); const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`); dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!, shareDashboard!, addToDashboards!]); dashboardDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard", "Share Dashboard", "Add to Dashboards"]); @@ -1244,9 +1244,8 @@ Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Insta "returns all the links to the document or its annotations", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); -Scripting.addGlobal(function shareDashboard() { - CurrentUserUtils.ActiveDashboard.isShared = true; - SharingManager.Instance.open(undefined, CurrentUserUtils.ActiveDashboard); +Scripting.addGlobal(function shareDashboard(dashboard: Doc) { + SharingManager.Instance.open(undefined, dashboard); }, "opens sharing dialog for Dashboard"); Scripting.addGlobal(function addToDashboards(dashboard: Doc) { Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboard); }, diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index ded56d1da..ca14154b2 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -5,7 +5,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import Select from "react-select"; import * as RequestPromise from "request-promise"; -import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; +import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; import { List } from "../../fields/List"; import { Cast, StrCast } from "../../fields/Types"; import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from "../../fields/util"; @@ -17,6 +17,7 @@ import { MainViewModal } from "../views/MainViewModal"; import { DocumentView } from "../views/nodes/DocumentView"; import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; import { SearchBox } from "../views/search/SearchBox"; +import { CurrentUserUtils } from "./CurrentUserUtils"; import { DocumentManager } from "./DocumentManager"; import { GroupManager, UserOptions } from "./GroupManager"; import { GroupMemberView } from "./GroupMemberView"; @@ -170,6 +171,7 @@ export class SharingManager extends React.Component<{}> { doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); distributeAcls(acl, permission as SharingPermissions, doc); + this.setDashboardBackground(doc, permission as SharingPermissions); if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc); else return GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); }).some(success => !success); @@ -192,6 +194,7 @@ export class SharingManager extends React.Component<{}> { return !docs.map(doc => { doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc); distributeAcls(acl, permission as SharingPermissions, doc); + this.setDashboardBackground(doc, permission as SharingPermissions); if (group instanceof Doc) { const members: string[] = JSON.parse(StrCast(group.members)); @@ -246,6 +249,25 @@ export class SharingManager extends React.Component<{}> { } } + /** + * Sets the background of the Dashboard if it has been shared as a visual indicator + */ + setDashboardBackground = async (doc: Doc, permission: SharingPermissions) => { + if (Doc.IndexOf(doc, DocListCast(CurrentUserUtils.MyDashboards.data)) !== -1) { + if (permission !== SharingPermissions.None) { + doc.isShared = true; + doc.backgroundColor = "green"; + } + else { + const acls = doc[DataSym][AclSym]; + if (Object.keys(acls).every(key => key === `acl-${Doc.CurrentUserEmailNormalized}` ? true : [AclUnset, AclPrivate].includes(acls[key]))) { + doc.isShared = undefined; + doc.backgroundColor = undefined; + } + } + } + } + /** * Removes the documents shared with a user through a group when the user is removed from the group. * @param group diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c8ce8bfeb..0fc6c75d0 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -400,7 +400,7 @@ export class PropertiesView extends React.Component { const showAdmin = effectiveAcls.every(acl => acl === AclAdmin); // users in common between all docs - const commonKeys = intersection(...docs.map(doc => this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym][AclSym] && Object.keys(doc[DataSym][AclSym]))); + const commonKeys: string[] = intersection(...docs.map(doc => this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym][AclSym] && Object.keys(doc[DataSym][AclSym]))); const tableEntries = []; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index b37c2fdfe..1719a6445 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -22,7 +22,7 @@ import { listSpec } from "./Schema"; import { ComputedField, ScriptField } from "./ScriptField"; import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types"; import { AudioField, ImageField, PdfField, VideoField, WebField } from "./URLField"; -import { deleteProperty, getField, getter, inheritParentAcls, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util"; +import { deleteProperty, GetEffectiveAcl, getField, getter, inheritParentAcls, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util"; import JSZip = require("jszip"); import { CurrentUserUtils } from "../client/util/CurrentUserUtils"; -- cgit v1.2.3-70-g09d2 From 95a42c92c9b4b2af8703afe85ece4e32975a3047 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 13 Apr 2021 10:39:36 -0400 Subject: typos and minor changes --- src/client/DocServer.ts | 2 +- src/client/util/CurrentUserUtils.ts | 1 - src/fields/Doc.ts | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 1d7497cf8..59278d2af 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -225,7 +225,7 @@ export namespace DocServer { * the server if the document has not been cached. * @param id the id of the requested document */ - const _GetRefFieldImpl = (id: string, force: boolean = false): Promise> => { + const _GetRefFieldImpl = async (id: string, force: boolean = false): Promise> => { // an initial pass through the cache to determine whether the document needs to be fetched, // is already in the process of being fetched or already exists in the // cache diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b7c2d60d8..86f563b7e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -516,7 +516,6 @@ export class CurrentUserUtils { { title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' }, { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, - // { 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: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' }, { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' }, diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 30e8b60bd..478334038 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -539,7 +539,7 @@ export namespace Doc { const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate, asBranch))); !dontCreate && assignKey(new List(clones)); } else if (doc[key] instanceof Doc) { - assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded teplate fields + assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded template fields } else { !dontCreate && assignKey(ObjectField.MakeCopy(field)); if (field instanceof RichTextField) { @@ -562,7 +562,7 @@ export namespace Doc { } else if (field instanceof ObjectField) { await copyObjectField(field); } else if (field instanceof Promise) { - debugger; //This shouldn't happend... + debugger; //This shouldn't happen... } else { assignKey(field); } -- cgit v1.2.3-70-g09d2 From 2e76877dc1c9c5b1c226f5bd0394d17cabfec0b4 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 17 May 2021 18:01:44 -0400 Subject: trying dynamic off screen docs --- src/client/documents/Documents.ts | 20 ++++++++-- src/client/util/CurrentUserUtils.ts | 33 ++++++++++++++--- src/client/util/SharingManager.tsx | 40 ++++++++++++-------- .../views/collections/CollectionDockingView.tsx | 43 ++++++++++++++-------- src/client/views/collections/TreeView.tsx | 9 ++++- src/fields/util.ts | 18 +++++---- 6 files changed, 115 insertions(+), 48 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1e2919bad..906603d78 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -648,8 +648,9 @@ export namespace Docs { * constructor just generates a new GUID. This is currently used * only when creating a DockDocument from the current user's already existing * main document. + * @param layoutData whether the fieldKey field on the layout doc should store the data or the data doc */ - function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { + function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string, layoutData?: boolean) { const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); @@ -660,7 +661,17 @@ export namespace Docs { dataProps[`${fieldKey}-lastModified`] = new DateField; dataProps["acl-Override"] = "None"; dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; - dataProps[fieldKey] = data; + + if (layoutData) { + viewProps[fieldKey] = data; + const list = new List(); + console.log(DocListCast(data)); + DocListCast(data).forEach(doc => { + list.push(...DocListCast(doc.data)); + }); + dataProps[fieldKey + "-all"] = list; + } + else dataProps[fieldKey] = data; // so that the list of annotations is already initialised, prevents issues in addonly. // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do. dataProps[fieldKey + "-annotations"] = new List(); @@ -891,7 +902,7 @@ export namespace Docs { export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true }); - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id, undefined, undefined, true); } export function DirectoryImportDocument(options: DocumentOptions = {}) { @@ -1426,4 +1437,7 @@ Scripting.addGlobal(function generateLinkTitle(self: Doc) { const anchor2title = self.anchor2 && self.anchor2 !== self ? Cast(self.anchor2, Doc, null).title : ""; const relation = self.linkRelationship || "to"; return `${anchor1title} (${relation}) ${anchor2title}`; +}); +Scripting.addGlobal(function openTabAlias(tab: Doc) { + CollectionDockingView.AddSplit(Doc.MakeAlias(tab), "right"); }); \ No newline at end of file diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 5dbded00e..6fdf649a4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -750,7 +750,7 @@ export class CurrentUserUtils { title: "My Dashboards", _height: 400, childHideLinkButton: true, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, - _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true })); const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`); (doc.myDashboards as any as Doc).contextMenuScripts = new List([newDashboard!]); @@ -851,7 +851,6 @@ export class CurrentUserUtils { CurrentUserUtils.setupPresentations(doc); CurrentUserUtils.setupFilesystem(doc); CurrentUserUtils.setupRecentlyClosedDocs(doc); - // CurrentUserUtils.setupFilterDocs(doc); CurrentUserUtils.setupUserDoc(doc); } @@ -1186,7 +1185,11 @@ export class CurrentUserUtils { title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`, }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); - const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); + const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); // add isFolder:true here? + freeformDoc.context = dashboardDoc; + + DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(dashboardDoc)`, { dashboardDoc: Doc.name }, { dashboardDoc }) as any; + Doc.AddDocToList(myPresentations, "data", presentation); userDoc.activePresentation = presentation; const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); @@ -1252,7 +1255,25 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) { SharingManager.Instance.open(undefined, dashboard); }, "opens sharing dialog for Dashboard"); -Scripting.addGlobal(function addToDashboards(dashboard: Doc) { Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboard); }, +Scripting.addGlobal(function addToDashboards(dashboard: Doc) { + const dashboardAlias = Doc.MakeAlias(dashboard); + dashboardAlias.data = new List(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder))); + // DocListCast(dashboardAlias.data).forEach(tabFolder => { + // tabFolder.data = new List(DocListCast(tabFolder.data).map(tab => Doc.MakeAlias(tab))); + // }); + Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboardAlias); + CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboardAlias); +}, "adds Dashboard to set of Dashboards"); -Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, - "toggle between regular rendeing and an informal sketch/comic style"); + +Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) { + const allDocs = DocListCast(dashboard[DataSym]["data-all"]); + console.log(allDocs); + const onScreenTab = DocListCast(dashboard.data)[0]; + const onScreenDocs = DocListCast(onScreenTab.data); + return allDocs.reduce((result: Doc[], doc) => { + !onScreenDocs.includes(doc) && (result.push(doc)); + // console.log(doc); + return result; + }, []); +}); diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 2f8ecd4ee..18f254cd6 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -173,10 +173,14 @@ export class SharingManager extends React.Component<{}> { const target = targetDoc || this.targetDoc!; const acl = `acl-${normalizeEmail(user.email)}`; const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; + console.log(DocListCast(CurrentUserUtils.MyDashboards.data)); + console.log(target); + console.log(DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target)); + const isDashboard = DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target) !== -1; const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); return !docs.map(doc => { - doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); + doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc, undefined, undefined, isDashboard); if (permission === SharingPermissions.None) { if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 1) - 1; @@ -185,7 +189,7 @@ export class SharingManager extends React.Component<{}> { if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 0) + 1; } - distributeAcls(acl, permission as SharingPermissions, doc); + distributeAcls(acl, permission as SharingPermissions, doc, undefined, undefined, isDashboard); this.setDashboardBackground(doc, permission as SharingPermissions); if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc); @@ -203,12 +207,13 @@ export class SharingManager extends React.Component<{}> { const target = targetDoc || this.targetDoc!; const key = normalizeEmail(StrCast(group.title)); const acl = `acl-${key}`; + const isDashboard = DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target) !== -1; const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); // ! ensures it returns true if document has been shared successfully, false otherwise return !docs.map(doc => { - doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc); + doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc, undefined, undefined, isDashboard); if (permission === SharingPermissions.None) { if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 1) - 1; @@ -217,7 +222,7 @@ export class SharingManager extends React.Component<{}> { if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 0) + 1; } - distributeAcls(acl, permission as SharingPermissions, doc); + distributeAcls(acl, permission as SharingPermissions, doc, undefined, undefined, isDashboard); this.setDashboardBackground(doc, permission as SharingPermissions); if (group instanceof Doc) { @@ -267,8 +272,10 @@ export class SharingManager extends React.Component<{}> { }); } else { + const dashboards = DocListCast(CurrentUserUtils.MyDashboards.data); docs.forEach(doc => { - if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc); + const isDashboard = dashboards.indexOf(doc) !== -1; + if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc, undefined, undefined, isDashboard); }); } } @@ -316,10 +323,11 @@ export class SharingManager extends React.Component<{}> { */ removeGroup = (group: Doc) => { if (group.docsShared) { + const dashboards = DocListCast(CurrentUserUtils.MyDashboards.data); DocListCast(group.docsShared).forEach(doc => { const acl = `acl-${StrCast(group.title)}`; - - distributeAcls(acl, SharingPermissions.None, doc); + const isDashboard = dashboards.indexOf(doc) !== -1; + distributeAcls(acl, SharingPermissions.None, doc, undefined, undefined, isDashboard); const members: string[] = JSON.parse(StrCast(group.members)); const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email)); @@ -445,16 +453,16 @@ export class SharingManager extends React.Component<{}> { } } - distributeOverCollection = (targetDoc?: Doc) => { - const target = targetDoc || this.targetDoc!; + // distributeOverCollection = (targetDoc?: Doc) => { + // const target = targetDoc || this.targetDoc!; - const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); - docs.forEach(doc => { - for (const [key, value] of Object.entries(doc[AclSym])) { - distributeAcls(key, this.AclMap.get(value)! as SharingPermissions, target); - } - }); - } + // const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); + // docs.forEach(doc => { + // for (const [key, value] of Object.entries(doc[AclSym])) { + // distributeAcls(key, this.AclMap.get(value)! as SharingPermissions, target); + // } + // }); + // } /** * Sorting algorithm to sort users. diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 388f9a909..819667834 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -4,7 +4,7 @@ import { action, IReactionDisposer, observable, reaction, runInAction } from "mo import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import * as GoldenLayout from "../../../client/goldenLayout"; -import { Doc, DocListCast, Opt, DocListCastAsync } from "../../../fields/Doc"; +import { Doc, DocListCast, Opt, DocListCastAsync, DataSym } from "../../../fields/Doc"; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; @@ -24,6 +24,7 @@ import React = require("react"); import { DocumentType } from '../../documents/DocumentTypes'; import { listSpec } from '../../../fields/Schema'; import { LightboxView } from '../LightboxView'; +import { inheritParentAcls } from '../../../fields/util'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -160,6 +161,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { } const instance = CollectionDockingView.Instance; if (!instance) return false; + else Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document); const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName); if (!pullSide && stack) { @@ -381,15 +383,22 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { setTimeout(async () => { const sublists = await DocListCastAsync(this.props.Document[this.props.fieldKey]); const tabs = sublists && Cast(sublists[0], Doc, null); - const other = sublists && Cast(sublists[1], Doc, null); + // const other = sublists && Cast(sublists[1], Doc, null); const tabdocs = await DocListCastAsync(tabs?.data); - const otherdocs = await DocListCastAsync(other?.data); - tabs && (Doc.GetProto(tabs).data = new List(docs)); - const otherSet = new Set(); - otherdocs?.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc)); - tabdocs?.filter(doc => !docs.includes(doc) && doc.type !== DocumentType.KVP).forEach(doc => otherSet.add(doc)); - const vals = Array.from(otherSet.values()).filter(val => val instanceof Doc).map(d => d).filter(d => d.type !== DocumentType.KVP); - other && (Doc.GetProto(other).data = new List(vals)); + // const otherdocs = await DocListCastAsync(other?.data); + if (tabs) { + tabs.data = new List(docs); + // DocListCast(tabs.aliases).forEach(tab => tab !== tabs && (tab.data = new List(docs))); + } + // const otherSet = new Set(); + // otherdocs?.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc)); + // tabdocs?.filter(doc => !docs.includes(doc) && doc.type !== DocumentType.KVP).forEach(doc => otherSet.add(doc)); + // const vals = Array.from(otherSet.values()).filter(val => val instanceof Doc).map(d => d).filter(d => d.type !== DocumentType.KVP); + // this.props.Document[DataSym][this.props.fieldKey + "-all"] = new List([...docs, ...vals]); + // if (other) { + // other.data = new List(vals); + // // DocListCast(other.aliases).forEach(tab => tab !== other && (tab.data = new List(vals))); + // } }, 0); } @@ -399,7 +408,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele)); } tabCreated = (tab: any) => { - tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous abs (ie, when dragging a tab around a new tab is created for the old content) + tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content) } stackCreated = (stack: any) => { @@ -407,9 +416,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { if (e.target === stack.header?.element[0] && e.button === 2) { const emptyPane = CurrentUserUtils.EmptyPane; emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1; - CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([], { - _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}` - }), "", stack); + const docToAdd = Docs.Create.FreeformDocument([], { + _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`, + }); + this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd); + CollectionDockingView.AddSplit(docToAdd, "", stack); } }); @@ -430,9 +441,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { // stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size const emptyPane = CurrentUserUtils.EmptyPane; emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1; - CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([], { + const docToAdd = Docs.Create.FreeformDocument([], { _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}` - }), "", stack); + }); + this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd); + CollectionDockingView.AddSplit(docToAdd, "", stack); })); } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 2e98fb508..ba4af2a6d 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -151,7 +151,10 @@ export class TreeView extends React.Component { 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 + // this.props.addDocTab(CurrentUserUtils.ActiveDashboard.isShared ? Doc.MakeAlias(this.props.document) : this.props.document, "add:right"); + // choose an appropriate alias or make one -- -- choose the first alias that (1) the user owns, (2) has no context field - if I own it and someone else does not have it open,, otherwise create an alias this.props.addDocTab(this.props.document, "add:right"); + } } constructor(props: any) { @@ -507,7 +510,11 @@ export class TreeView extends React.Component { [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }]; } onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); - onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); + + onChildDoubleClick = () => { + console.log(this.props.document.onChildDoubleClick); + return (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick) + }; refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document); ignoreEvent = (e: any) => { diff --git a/src/fields/util.ts b/src/fields/util.ts index a4c99928a..882c7fee8 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -136,11 +136,9 @@ export function denormalizeEmail(email: string) { * Copies parent's acl fields to the child */ export function inheritParentAcls(parent: Doc, child: Doc) { - if (parent.isShared) { - const dataDoc = parent[DataSym]; - for (const key of Object.keys(dataDoc)) { - key.startsWith("acl") && distributeAcls(key, dataDoc[key], child); - } + const dataDoc = parent[DataSym]; + for (const key of Object.keys(dataDoc)) { + key.startsWith("acl") && distributeAcls(key, dataDoc[key], child); } } @@ -228,7 +226,7 @@ function getEffectiveAcl(target: any, user?: string): symbol { * @param inheritingFromCollection whether the target is being assigned rights after being dragged into a collection (and so is inheriting the acls from the collection) * inheritingFromCollection is not currently being used but could be used if acl assignment defaults change */ -export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[]) { +export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[], isDashboard?: boolean) { if (!visited) visited = [] as Doc[]; if (visited.includes(target)) return; visited.push(target); @@ -249,6 +247,12 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc if (GetEffectiveAcl(target) === AclAdmin && (!inheritingFromCollection || !target[key] || HierarchyMapping.get(StrCast(target[key]))! > HierarchyMapping.get(acl)!)) { target[key] = acl; layoutDocChanged = true; + + if (isDashboard) { + DocListCast(target[Doc.LayoutFieldKey(target)]).forEach(d => { + distributeAcls(key, acl, d, inheritingFromCollection, visited); + }); + } } if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || HierarchyMapping.get(StrCast(dataDoc[key]))! > HierarchyMapping.get(acl)!)) { @@ -263,7 +267,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc links.forEach(link => distributeAcls(key, acl, link, inheritingFromCollection, visited)); // maps over the children of the document - DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).map(d => { + DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc) + (isDashboard ? "-all" : "")]).map(d => { // this is now on the layoutdoc instead - figure out the "data-all" approach for the datadoc // if (GetEffectiveAcl(d) === AclAdmin && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) { distributeAcls(key, acl, d, inheritingFromCollection, visited); // } -- cgit v1.2.3-70-g09d2 From 7c18243dd38656b63334f48d9270d912ce6384fa Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 17 May 2021 18:45:01 -0400 Subject: fixes for offscreen tabs --- src/client/util/CurrentUserUtils.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 6fdf649a4..a8327ae93 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1187,8 +1187,8 @@ export class CurrentUserUtils { const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); // add isFolder:true here? freeformDoc.context = dashboardDoc; - - DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(dashboardDoc)`, { dashboardDoc: Doc.name }, { dashboardDoc }) as any; + DocListCast(dashboardDoc.data).forEach(doc => doc.dashboard = dashboardDoc); + DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any; Doc.AddDocToList(myPresentations, "data", presentation); userDoc.activePresentation = presentation; @@ -1267,13 +1267,16 @@ Scripting.addGlobal(function addToDashboards(dashboard: Doc) { "adds Dashboard to set of Dashboards"); Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) { - const allDocs = DocListCast(dashboard[DataSym]["data-all"]); - console.log(allDocs); - const onScreenTab = DocListCast(dashboard.data)[0]; - const onScreenDocs = DocListCast(onScreenTab.data); - return allDocs.reduce((result: Doc[], doc) => { - !onScreenDocs.includes(doc) && (result.push(doc)); - // console.log(doc); - return result; - }, []); + if (dashboard[DataSym] instanceof Doc) { + const allDocs = DocListCast(dashboard[DataSym]["data-all"]); + console.log(allDocs); + const onScreenTab = DocListCast(dashboard.data)[0]; + const onScreenDocs = DocListCast(onScreenTab.data); + return new List(allDocs.reduce((result: Doc[], doc) => { + !onScreenDocs.includes(doc) && (result.push(doc)); + // console.log(doc); + return result; + }, [])); + } + return []; }); -- cgit v1.2.3-70-g09d2 From 77c16aa9f00a9d1b5e31ddf5a68d56f183f13691 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 20 May 2021 12:47:46 -0400 Subject: dashboard sharing, aliases now work? needs more testing --- src/client/util/CurrentUserUtils.ts | 19 +++++++++++++------ .../views/collections/CollectionDockingView.tsx | 6 +++++- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index a8327ae93..e143887fa 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1255,12 +1255,20 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) { SharingManager.Instance.open(undefined, dashboard); }, "opens sharing dialog for Dashboard"); -Scripting.addGlobal(function addToDashboards(dashboard: Doc) { +Scripting.addGlobal(async function addToDashboards(dashboard: Doc) { const dashboardAlias = Doc.MakeAlias(dashboard); + const dockingConfig = JSON.parse(StrCast(dashboardAlias.dockingConfig)); + dockingConfig.content = []; + dashboardAlias.dockingConfig = JSON.stringify(dockingConfig); + + const allDocs = await DocListCastAsync(dashboard[DataSym]["data-all"]); + + dashboardAlias["data-all"] = new List((allDocs || []).map(doc => Doc.MakeAlias(doc))); + dashboardAlias.data = new List(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder))); - // DocListCast(dashboardAlias.data).forEach(tabFolder => { - // tabFolder.data = new List(DocListCast(tabFolder.data).map(tab => Doc.MakeAlias(tab))); - // }); + DocListCast(dashboardAlias.data).forEach(doc => doc.dashboard = dashboardAlias); + DocListCast(dashboardAlias.data)[0].data = new List(); + DocListCast(dashboardAlias.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any; Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboardAlias); CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboardAlias); }, @@ -1268,13 +1276,12 @@ Scripting.addGlobal(function addToDashboards(dashboard: Doc) { Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) { if (dashboard[DataSym] instanceof Doc) { - const allDocs = DocListCast(dashboard[DataSym]["data-all"]); + const allDocs = DocListCast(dashboard["data-all"]); console.log(allDocs); const onScreenTab = DocListCast(dashboard.data)[0]; const onScreenDocs = DocListCast(onScreenTab.data); return new List(allDocs.reduce((result: Doc[], doc) => { !onScreenDocs.includes(doc) && (result.push(doc)); - // console.log(doc); return result; }, [])); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 819667834..235fe8950 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -161,7 +161,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { } const instance = CollectionDockingView.Instance; if (!instance) return false; - else Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document); + else { + const docList = DocListCast(instance.props.Document[DataSym]["data-all"]); + !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document); + DocListCast(instance.props.Document[DataSym]["aliases"]).forEach(alias => !alias.aliasOf && alias !== instance.props.Document && Doc.AddDocToList(alias, "data-all", Doc.MakeAlias(document))); + } const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName); if (!pullSide && stack) { -- cgit v1.2.3-70-g09d2 From b85e7819ae46558a659cac73817be0b812d6abbe Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 31 May 2021 20:18:19 -0400 Subject: sharing dashboard works? pending fixing remnant on screen tabs --- src/client/documents/Documents.ts | 17 +++--------- src/client/util/CurrentUserUtils.ts | 30 +++++++++++++++++++--- .../views/collections/CollectionDockingView.tsx | 9 ++++++- 3 files changed, 38 insertions(+), 18 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6fb6f70b3..70541b559 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -648,9 +648,8 @@ export namespace Docs { * constructor just generates a new GUID. This is currently used * only when creating a DockDocument from the current user's already existing * main document. - * @param layoutData whether the fieldKey field on the layout doc should store the data or the data doc */ - function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string, layoutData?: boolean) { + function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); @@ -662,16 +661,8 @@ export namespace Docs { dataProps["acl-Override"] = "None"; dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; - if (layoutData) { - viewProps[fieldKey] = data; - const list = new List(); - console.log(DocListCast(data)); - DocListCast(data).forEach(doc => { - list.push(...DocListCast(doc.data)); - }); - dataProps[fieldKey + "-all"] = list; - } - else dataProps[fieldKey] = data; + dataProps[fieldKey] = data; + // so that the list of annotations is already initialised, prevents issues in addonly. // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do. dataProps[fieldKey + "-annotations"] = new List(); @@ -902,7 +893,7 @@ export namespace Docs { export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true }); - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id, undefined, undefined, true); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } export function DirectoryImportDocument(options: DocumentOptions = {}) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index e143887fa..90a2378fe 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1187,6 +1187,22 @@ export class CurrentUserUtils { const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); // add isFolder:true here? freeformDoc.context = dashboardDoc; + + // switching the tabs from the datadoc to the regular doc + const dashboardTabs = dashboardDoc[DataSym].data; + dashboardDoc[DataSym].data = new List(); + dashboardDoc.data = dashboardTabs; + + // collating all docs on the dashboard to make a data-all field + const allDocs = new List(); + const allDocs2 = new List(); // Array.from, spread, splice all cause so stack or acl issues for some reason + DocListCast(dashboardTabs).forEach(doc => { + const tabDocs = DocListCast(doc.data); + allDocs.push(...tabDocs); + allDocs2.push(...tabDocs); + }); + dashboardDoc[DataSym]["data-all"] = allDocs; + dashboardDoc["data-all"] = allDocs2; DocListCast(dashboardDoc.data).forEach(doc => doc.dashboard = dashboardDoc); DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any; @@ -1257,14 +1273,18 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) { "opens sharing dialog for Dashboard"); Scripting.addGlobal(async function addToDashboards(dashboard: Doc) { const dashboardAlias = Doc.MakeAlias(dashboard); - const dockingConfig = JSON.parse(StrCast(dashboardAlias.dockingConfig)); - dockingConfig.content = []; - dashboardAlias.dockingConfig = JSON.stringify(dockingConfig); const allDocs = await DocListCastAsync(dashboard[DataSym]["data-all"]); + // moves the data-all field from the datadoc to the layoutdoc, necessary for off screen docs tab to function properly + dashboard["data-all"] = new List(allDocs); dashboardAlias["data-all"] = new List((allDocs || []).map(doc => Doc.MakeAlias(doc))); + const dockingConfig = JSON.parse(StrCast(dashboardAlias.dockingConfig)); + dockingConfig.content = []; + dashboardAlias.dockingConfig = JSON.stringify(dockingConfig); + + dashboardAlias.data = new List(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder))); DocListCast(dashboardAlias.data).forEach(doc => doc.dashboard = dashboardAlias); DocListCast(dashboardAlias.data)[0].data = new List(); @@ -1274,10 +1294,12 @@ Scripting.addGlobal(async function addToDashboards(dashboard: Doc) { }, "adds Dashboard to set of Dashboards"); +/** + * Dynamically computes which docs should be rendered in the off-screen tabs tree of a dashboard. + */ Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) { if (dashboard[DataSym] instanceof Doc) { const allDocs = DocListCast(dashboard["data-all"]); - console.log(allDocs); const onScreenTab = DocListCast(dashboard.data)[0]; const onScreenDocs = DocListCast(onScreenTab.data); return new List(allDocs.reduce((result: Doc[], doc) => { diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 235fe8950..2e44b65e6 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -163,8 +163,15 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { if (!instance) return false; else { const docList = DocListCast(instance.props.Document[DataSym]["data-all"]); + // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document); - DocListCast(instance.props.Document[DataSym]["aliases"]).forEach(alias => !alias.aliasOf && alias !== instance.props.Document && Doc.AddDocToList(alias, "data-all", Doc.MakeAlias(document))); + // adds an alias of the doc to the data-all field of the layoutdocs of the aliases + DocListCast(instance.props.Document[DataSym].aliases).forEach(alias => { + const aliasDocList = DocListCast(alias["data-all"]); + // if aliasDocList contains the alias, don't do anything + // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias + !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data-all", alias !== instance.props.Document ? Doc.MakeAlias(document) : document); + }); } const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName); -- cgit v1.2.3-70-g09d2 From 16ecec059993f4f5ac3680afc0eb00eb559db91e Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 31 May 2021 21:31:30 -0400 Subject: folderised dashboards --- src/client/documents/Documents.ts | 4 ++-- src/client/util/CurrentUserUtils.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 70541b559..da4e926b4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -891,8 +891,8 @@ export namespace Docs { } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { - const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true }); - const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true }); + const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true, isFolder: true }); + const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true, isFolder: true }); return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index be99d6ce4..6236e1ac9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1185,7 +1185,7 @@ export class CurrentUserUtils { title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`, }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); - const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); // add isFolder:true here? + const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}`, isFolder: true }, id, "row"); freeformDoc.context = dashboardDoc; // switching the tabs from the datadoc to the regular doc -- cgit v1.2.3-70-g09d2 From fe672afad987b246b8be79366d2d9c45b6fba502 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 10 Jun 2021 00:15:56 -0400 Subject: removed isfolder flag from dashboard to allow double click to open dashboard --- src/client/util/CurrentUserUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 6236e1ac9..8b3597d57 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1185,7 +1185,7 @@ export class CurrentUserUtils { title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`, }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); - const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}`, isFolder: true }, id, "row"); + const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); freeformDoc.context = dashboardDoc; // switching the tabs from the datadoc to the regular doc -- cgit v1.2.3-70-g09d2 From 9d03a05ae686768a542da499b6d5e1ce4d9c20fd Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sun, 27 Jun 2021 16:18:55 -0400 Subject: can delete dashboards --- src/client/util/CurrentUserUtils.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8b3597d57..9f01b165f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1214,8 +1214,9 @@ export class CurrentUserUtils { const createDashboard = ScriptField.MakeScript(`createNewDashboard()`); const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`); const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`); - dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!, shareDashboard!, addToDashboards!]); - dashboardDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard", "Share Dashboard", "Add to Dashboards"]); + const removeDashboard = ScriptField.MakeScript('removeDashboard(self)'); + dashboardDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!, shareDashboard!, addToDashboards!, removeDashboard!]); + dashboardDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard", "Share Dashboard", "Add to Dashboards", "Remove Dashboard"]); Doc.AddDocToList(dashboards, "data", dashboardDoc); CurrentUserUtils.openDashboard(userDoc, dashboardDoc); @@ -1271,6 +1272,15 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) { SharingManager.Instance.open(undefined, dashboard); }, "opens sharing dialog for Dashboard"); +Scripting.addGlobal(async function removeDashboard(dashboard: Doc) { + console.log(dashboard); + const dashboards = await DocListCastAsync(CurrentUserUtils.MyDashboards.data); + if (dashboards && dashboards.length > 1) { + if (dashboard === CurrentUserUtils.ActiveDashboard) CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboards.find(doc => doc !== dashboard)!); + Doc.RemoveDocFromList(CurrentUserUtils.MyDashboards, "data", dashboard); + } +}, + "Remove Dashboard from Dashboards"); Scripting.addGlobal(async function addToDashboards(dashboard: Doc) { const dashboardAlias = Doc.MakeAlias(dashboard); -- cgit v1.2.3-70-g09d2 From d6e313be26323d7e8265714665c71e2d571764ae Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sun, 27 Jun 2021 17:20:59 -0400 Subject: whoops --- src/client/util/CurrentUserUtils.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 9f01b165f..4584d3282 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1273,7 +1273,6 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) { }, "opens sharing dialog for Dashboard"); Scripting.addGlobal(async function removeDashboard(dashboard: Doc) { - console.log(dashboard); const dashboards = await DocListCastAsync(CurrentUserUtils.MyDashboards.data); if (dashboards && dashboards.length > 1) { if (dashboard === CurrentUserUtils.ActiveDashboard) CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboards.find(doc => doc !== dashboard)!); -- cgit v1.2.3-70-g09d2 From 1291e8a45ec9e3aeccd2ca74c0f549a18a16f0d7 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 17 Jul 2021 16:23:29 -0400 Subject: preventing alias of on-screen doc from being added to off-screen doc list --- src/client/util/CurrentUserUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f3ba7334b..c96a6f656 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1319,7 +1319,7 @@ Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) { const onScreenTab = DocListCast(dashboard.data)[0]; const onScreenDocs = DocListCast(onScreenTab.data); return new List(allDocs.reduce((result: Doc[], doc) => { - !onScreenDocs.includes(doc) && (result.push(doc)); + !onScreenDocs.includes(doc) && !onScreenDocs.includes(doc.aliasOf as Doc) && (result.push(doc)); return result; }, [])); } -- cgit v1.2.3-70-g09d2 From c9f379adab864132e6cf044f808a43254601e4bb Mon Sep 17 00:00:00 2001 From: geireann Date: Fri, 30 Jul 2021 13:26:25 -0400 Subject: major UI / updates + refactoring --- deploy/assets/favicon.png | Bin 0 -> 22180 bytes deploy/index.html | 114 +- deploy/loader.css | 85 + deploy/loader.js | 14 + src/client/documents/Documents.ts | 4 +- src/client/util/CurrentUserUtils.ts | 44 +- src/client/views/AntimodeMenu.scss | 1 + src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/MainView.scss | 30 +- src/client/views/MainView.tsx | 29 +- src/client/views/PropertiesView.tsx | 2 +- src/client/views/_nodeModuleOverrides.scss | 4 +- src/client/views/collections/CollectionMenu.scss | 4 +- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 +- .../collections/collectionFreeForm/MarqueeView.tsx | 3 +- src/client/views/global/globalCssVariables.scss | 3 + src/client/views/nodes/DocumentContentsView.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FontIconBox.tsx | 3 +- src/client/views/nodes/PresBox.scss | 1243 ---------- src/client/views/nodes/PresBox.tsx | 2472 -------------------- .../views/nodes/formattedText/RichTextMenu.tsx | 10 +- src/client/views/nodes/trails/PresBox.scss | 1243 ++++++++++ src/client/views/nodes/trails/PresBox.tsx | 2440 +++++++++++++++++++ src/client/views/nodes/trails/PresElementBox.scss | 235 ++ src/client/views/nodes/trails/PresElementBox.tsx | 388 +++ src/client/views/nodes/trails/PresEnums.ts | 28 + src/client/views/nodes/trails/index.ts | 3 + .../views/presentationview/PresElementBox.scss | 235 -- .../views/presentationview/PresElementBox.tsx | 386 --- src/client/views/topbar/TopBar.scss | 12 +- src/client/views/topbar/TopBar.tsx | 89 +- tslint.json | 41 +- 35 files changed, 4587 insertions(+), 4600 deletions(-) create mode 100644 deploy/assets/favicon.png create mode 100644 deploy/loader.css create mode 100644 deploy/loader.js delete mode 100644 src/client/views/nodes/PresBox.scss delete mode 100644 src/client/views/nodes/PresBox.tsx create mode 100644 src/client/views/nodes/trails/PresBox.scss create mode 100644 src/client/views/nodes/trails/PresBox.tsx create mode 100644 src/client/views/nodes/trails/PresElementBox.scss create mode 100644 src/client/views/nodes/trails/PresElementBox.tsx create mode 100644 src/client/views/nodes/trails/PresEnums.ts create mode 100644 src/client/views/nodes/trails/index.ts delete mode 100644 src/client/views/presentationview/PresElementBox.scss delete mode 100644 src/client/views/presentationview/PresElementBox.tsx (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/deploy/assets/favicon.png b/deploy/assets/favicon.png new file mode 100644 index 000000000..59595b910 Binary files /dev/null and b/deploy/assets/favicon.png differ diff --git a/deploy/index.html b/deploy/index.html index dda0c6457..d96215391 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -1,114 +1,22 @@ - Dash Web - - + Dash + + + + - - - + + -
+
dashmesg("10%", "Loading Dash..."), load / 10); setTimeout(() => dashmesg("33%", "Preparing dashboards..."), load / 3); diff --git a/deploy/loader.css b/deploy/loader.css new file mode 100644 index 000000000..4be0cc98c --- /dev/null +++ b/deploy/loader.css @@ -0,0 +1,85 @@ +.dash-loader { + display: flex; + align-content: center; + justify-content: center; + background-color: #BDDDF5; + transition: 3s; + z-index: 10; + z-index:10; + width:100%; + height:100%; +} + +.dash-loader-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + align-content: center; +} + +.dash-progress-bar { + width: 200px; + height: 5px; + align-self: center; + margin-top: 20px; + background-color: #ececec; + border-radius: 5px; + overflow: hidden; +} + +.dash-progress { + width: 0%; + height: 20px; + background-color: #4476F7; + transition: 0.1s; +} + +.dash-animation-container { + width: 10vw; + height: 10vw; + display: flex; + align-items: center; + justify-content: center; + border-radius: 100%; + background-color: #4476F7; + justify-self: center; +} + +.dash-loader-text { + font-size: 15px; + font-family: "Roboto"; + font-weight: bold; + text-align: center; + color: #4476F7; + user-select: none; + -webkit-user-select: none; +} + +.dash-d-path { + stroke-dasharray: 1000; + stroke-dashoffset: 1000; + animation: dash-d-path 3s linear infinite; +} + +@keyframes dash-d-path { + 0% { + stroke-dashoffset: 1000; + } + + 20% { + stroke-dashoffset: 0; + } + + 70% { + stroke-dashoffset: 0; + } + + 90% { + stroke-dashoffset: 1000; + } + + 100% { + stroke-dashoffset: 1000; + } +} \ No newline at end of file diff --git a/deploy/loader.js b/deploy/loader.js new file mode 100644 index 000000000..0be421e14 --- /dev/null +++ b/deploy/loader.js @@ -0,0 +1,14 @@ +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return Number(c.substring(name.length, c.length)); + } + } + return 3000; +} \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f1db3e32c..81465a241 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -45,14 +45,14 @@ import { LabelBox } from "../views/nodes/LabelBox"; import { LinkBox } from "../views/nodes/LinkBox"; import { LinkDescriptionPopup } from "../views/nodes/LinkDescriptionPopup"; import { PDFBox } from "../views/nodes/PDFBox"; -import { PresBox } from "../views/nodes/PresBox"; +import { PresBox } from "../views/nodes/trails/PresBox"; import { ScreenshotBox } from "../views/nodes/ScreenshotBox"; import { ScriptingBox } from "../views/nodes/ScriptingBox"; import { SliderBox } from "../views/nodes/SliderBox"; import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; import { VideoBox } from "../views/nodes/VideoBox"; import { WebBox } from "../views/nodes/WebBox"; -import { PresElementBox } from "../views/presentationview/PresElementBox"; +import { PresElementBox } from "../views/nodes/trails/PresElementBox"; import { SearchBox } from "../views/search/SearchBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 22504f102..62fab1b23 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -35,6 +35,8 @@ import { UndoManager } from "./UndoManager"; import { SnappingManager } from "./SnappingManager"; import { InkTool } from "../../fields/InkField"; import { computedFn } from "mobx-utils"; +import { ColorScheme } from "./SettingsManager"; +import { Colors } from "../views/global/globalEnums"; export let resolvedPorts: { server: number, socket: number }; @@ -472,7 +474,7 @@ export class CurrentUserUtils { { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc }, { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true }, { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc }, - { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true }, + // { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true }, { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc }, { toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc }, @@ -534,8 +536,8 @@ export class CurrentUserUtils { { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, // { 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: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' }, - { title: "Settings", target: undefined as any, icon: "cog", 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)' }, ]; } @@ -561,7 +563,6 @@ export class CurrentUserUtils { dontUndo: true, title, target, - backgroundColor: "black", _dropAction: "alias", _removeDropProperties: new List(["dropAction", "_stayInCollection"]), _width: 60, @@ -576,8 +577,10 @@ export class CurrentUserUtils { title: "menuItemPanel", childDropAction: "alias", _chromeHidden: true, + backgroundColor: Colors.DARK_GRAY, + boxShadow: "rgba(0,0,0,0)", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), - backgroundColor: "black", ignoreClick: true, + ignoreClick: true, _gridGap: 0, _yMargin: 0, _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, system: true @@ -587,8 +590,6 @@ export class CurrentUserUtils { PromiseValue(Cast(doc.menuStack, Doc)).then(stack => { stack && PromiseValue(stack.data).then(btns => { DocListCastAsync(btns).then(bts => bts?.forEach(btn => { - btn.color = "white"; - btn._backgroundColor = ""; btn.dontUndo = true; btn.system = true; if (btn.title === "Catalog" || btn.title === "My Files") { // migration from Catalog to My Files @@ -759,7 +760,7 @@ export class CurrentUserUtils { await doc.myDashboards; if (doc.myDashboards === undefined) { doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "My Dashboards", _height: 400, childHideLinkButton: true, + title: "My Dashboards", _showTitle: "title", _height: 400, childHideLinkButton: true, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true @@ -775,7 +776,7 @@ export class CurrentUserUtils { await doc.myPresentations; if (doc.myPresentations === undefined) { doc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "My Presentations", _height: 100, + title: "My Trails", _showTitle: "title", _height: 100, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true @@ -794,7 +795,7 @@ export class CurrentUserUtils { doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _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, + title: "My Documents", _showTitle: "title", _height: 100, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true, @@ -808,7 +809,7 @@ export class CurrentUserUtils { // setup Recently Closed library item if (doc.myRecentlyClosedDocs === undefined) { doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "Recently Closed", treeViewShowClearButton: true, childHideLinkButton: true, + title: "Recently Closed", _showTitle: "title", treeViewShowClearButton: true, childHideLinkButton: true, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true @@ -839,7 +840,7 @@ export class CurrentUserUtils { doc.treeViewOpen = true; doc.treeViewExpandedView = "fields"; doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], { - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc", _showTitle: "title", treeViewTruncateTitleWidth: 150, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true })) as any as Doc; @@ -859,6 +860,7 @@ export class CurrentUserUtils { static async setupSidebarButtons(doc: Doc) { CurrentUserUtils.setupSidebarContainer(doc); await CurrentUserUtils.setupToolsBtnPanel(doc); + CurrentUserUtils.setupImportSidebar(doc); CurrentUserUtils.setupDashboards(doc); CurrentUserUtils.setupPresentations(doc); CurrentUserUtils.setupFilesystem(doc); @@ -891,6 +893,7 @@ export class CurrentUserUtils { (doc["dockedBtn-undo"] as Doc).dontUndo = true; (doc["dockedBtn-redo"] as Doc).dontUndo = true; } + // sets up the default set of documents to be shown in the Overlay layer static setupOverlays(doc: Doc) { if (doc.myOverlayDocs === undefined) { @@ -924,7 +927,8 @@ export class CurrentUserUtils { if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true, + _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, + _chromeHidden: true, boxShadow: "0 0", }, sharingDocumentId + "outer", sharingDocumentId); (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Add; } @@ -939,14 +943,14 @@ export class CurrentUserUtils { static setupImportSidebar(doc: Doc) { if (doc.myImportDocs === undefined) { doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { - title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, + title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true, _chromeHidden: true, })); } if (doc.myImportPanel === undefined) { const uploads = Cast(doc.myImportDocs, Doc, null); const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true }); - doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); + doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, _showTitle: "title", ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true, boxShadow: "0 0" })); } } @@ -1007,10 +1011,14 @@ export class CurrentUserUtils { const mygroups = groups?.filter(group => JSON.parse(StrCast(group.members)).includes(Doc.CurrentUserEmail)) || []; SnappingManager.SetCachedGroups(["Public", ...mygroups?.map(g => StrCast(g.title))]); }, { fireImmediately: true }); + // Document properties on load doc.system = true; + doc.darkScheme = ColorScheme.Dark; doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode; doc.title = Doc.CurrentUserEmail; doc._raiseWhenDragged = true; + doc._showLabel = false; + doc._showMenuLabel = true; doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)"); doc.activeInkWidth = StrCast(doc.activeInkWidth, "1"); doc.activeInkBezier = StrCast(doc.activeInkBezier, "0"); @@ -1201,7 +1209,7 @@ export class CurrentUserUtils { const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); Doc.AddDocToList(myPresentations, "data", presentation); userDoc.activePresentation = presentation; - const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); + const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`); const createDashboard = ScriptField.MakeScript(`createNewDashboard()`); @@ -1257,6 +1265,4 @@ Scripting.addGlobal(function createNewPresentation() { return MainView.Instance. Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, "returns all the links to the document or its annotations", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, - "imports files from device directly into the import sidebar"); -Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, - "toggle between regular rendeing and an informal sketch/comic style"); + "imports files from device directly into the import sidebar"); \ No newline at end of file diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index b509f9f54..e23bf27c1 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -6,6 +6,7 @@ z-index: 10001; height: $antimodemenu-height; background: $dark-gray; + border-bottom: $standard-border; // box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); // border-radius: 0px 6px 6px 6px; z-index: 1001; diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index a5d80cd22..b11aa99b0 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -24,7 +24,7 @@ import { DocumentView } from './nodes/DocumentView'; import { GoogleRef } from "./nodes/formattedText/FormattedTextBox"; import { TemplateMenu } from "./TemplateMenu"; import React = require("react"); -import { PresBox } from './nodes/PresBox'; +import { PresBox } from './nodes/trails/PresBox'; import { undoBatch } from '../util/UndoManager'; import { CollectionViewType } from './collections/CollectionView'; const higflyout = require("@hig/flyout"); diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 2069986ad..ba1c91720 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -22,10 +22,6 @@ height: 100%; } -.mainContent-div-flyout { - left: calc(-1 * var(--flyoutHandleWidth)); -} - // add nodes menu. Note that the + button is actually an input label, not an actual button. .mainView-docButtons { position: absolute; @@ -111,14 +107,21 @@ user-select: none; } +.properties-container { + height: 100%; + position: relative; + left: 100%; + top: calc(-100% - 36px); + z-index: 3000; +} + .mainView-propertiesDragger { //background-color: rgb(140, 139, 139); - background-color: $light-gray; + background-color: $medium-gray; height: 55px; width: 17px; position: absolute; top: 50%; - border: 1px black solid; border-radius: 0; border-top-left-radius: 10px; border-bottom-left-radius: 10px; @@ -141,18 +144,6 @@ } } -.mainiView-propertiesView { - display: flex; - flex-direction: column; - height: 100%; - position: absolute; - right: 0; - top: 0; - border-left: solid 1px; - z-index: 100000; - cursor: auto; -} - .mainView-innerContent, .mainView-innerContent-dark { display: contents; flex-direction: row; @@ -171,7 +162,7 @@ } .propertiesView { - right: 0; + left: 0; position: absolute; z-index: 2; background-color: $medium-gray; @@ -220,6 +211,7 @@ .mainView-menuPanel { min-width: var(--menuPanelWidth); background-color: $dark-gray; + border-right: $standard-border; .collectionStackingView { scrollbar-width: none; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 7d6bfbd40..49f4f7a6e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -64,6 +64,7 @@ import { PropertiesView } from './PropertiesView'; import { SearchBox } from './search/SearchBox'; import { DefaultStyleProvider, DashboardStyleProvider, StyleProp } from './StyleProvider'; import { TopBar } from './topbar/TopBar'; +import { Colors } from './global/globalEnums'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -179,12 +180,12 @@ export class MainView extends React.Component { const targets = document.elementsFromPoint(e.x, e.y); if (targets.length) { const targClass = targets[0].className.toString(); - if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) { - const check = targets.some((thing) => - (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || - thing.className === "collectionSchema-header-menuOptions")); - !check && SearchBox.Instance.resetSearch(true); - } + // if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) { + // const check = targets.some((thing) => + // (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || + // thing.className === "collectionSchema-header-menuOptions")); + // !check && SearchBox.Instance.resetSearch(true); + // } !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu(); !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu(); } @@ -193,7 +194,7 @@ export class MainView extends React.Component { initEventListeners = () => { window.addEventListener("drop", e => e.preventDefault(), false); // prevent default behavior of navigating to a new web page window.addEventListener("dragover", e => e.preventDefault(), false); - document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined)); + // document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined)); document.addEventListener("pointerdown", this.globalPointerDown); document.addEventListener("click", (e: MouseEvent) => { if (!e.cancelBubble) { @@ -405,22 +406,26 @@ export class MainView extends React.Component { } @computed get mainInnerContent() { + const width = this.propertiesWidth() + this._flyoutWidth + this.menuPanelWidth(); + const transform = this._flyoutWidth ? 'translate(-28px, 0px)' : undefined; return <> {this.menuPanel}
{this.flyout} -
+
-
+
{this.dockingContent} -
- +
+ +
+
+ {this.propertiesWidth() < 10 ? (null) : }
- {this.propertiesWidth() < 10 ? (null) : }
; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 4df3e4f00..8136edf04 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -24,7 +24,7 @@ import { EditableView } from "./EditableView"; import { InkStrokeProperties } from "./InkStrokeProperties"; import { DocumentView, StyleProviderFunc } from "./nodes/DocumentView"; import { KeyValueBox } from "./nodes/KeyValueBox"; -import { PresBox } from "./nodes/PresBox"; +import { PresBox } from "./nodes/trails/PresBox"; import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss index cb59489c0..140be2140 100644 --- a/src/client/views/_nodeModuleOverrides.scss +++ b/src/client/views/_nodeModuleOverrides.scss @@ -58,12 +58,10 @@ div .lm_header { .lm_header .lm_controls { align-items: center; position: absolute; - background-color: #000000; + background-color: $dark-gray; border-radius: 5px; display: flex; - top: 2px; justify-content: space-evenly; - right: 2px; height: 18px; width: 65px; } diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index c0fc774d3..f04b19ef7 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -38,10 +38,10 @@ border: unset; .collectionMenu-divider { - height: 85%; + height: 100%; margin-left: 3px; margin-right: 3px; - width: 1.5px; + width: 2px; background-color: $medium-gray; } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 6e6fabd0d..a9b978c4e 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -29,7 +29,7 @@ import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; import { RichTextMenu } from "../nodes/formattedText/RichTextMenu"; -import { PresBox } from "../nodes/PresBox"; +import { PresBox } from "../nodes/trails/PresBox"; import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { TabDocView } from "./TabDocView"; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 0e67bebd8..d82810652 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -25,7 +25,7 @@ import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { LightboxView } from '../LightboxView'; import { DocFocusOptions, DocumentView, DocumentViewProps } from "../nodes/DocumentView"; -import { PresBox, PinProps, PresMovement } from '../nodes/PresBox'; +import { PinProps, PresBox, PresMovement } from '../nodes/trails'; import { DefaultLayerProvider, DefaultStyleProvider, StyleLayers, StyleProp } from '../StyleProvider'; import { CollectionDockingView } from './CollectionDockingView'; import { CollectionDockingViewMenu } from './CollectionDockingViewMenu'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a4e310e6c..c5f6f7bf2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -38,7 +38,7 @@ import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDo import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { pageSchema } from "../../nodes/ImageBox"; -import { PresBox } from "../../nodes/PresBox"; +import { PresBox } from "../../nodes/trails/PresBox"; import { StyleLayers, StyleProp } from "../../StyleProvider"; import { CollectionDockingView } from "../CollectionDockingView"; import { CollectionSubView } from "../CollectionSubView"; @@ -834,10 +834,10 @@ export class CollectionFreeFormView extends CollectionSubView ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") })); if (measuredDocs.length) { const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) => // computes range of content - ({ - xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) }, - yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) } - }) + ({ + xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) }, + yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) } + }) , { xrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }, yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b1f2750c3..4fae961b1 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -19,7 +19,8 @@ import { Transform } from "../../../util/Transform"; import { undoBatch, UndoManager } from "../../../util/UndoManager"; import { ContextMenu } from "../../ContextMenu"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; -import { PresBox, PresMovement } from "../../nodes/PresBox"; +import { PresBox } from "../../nodes/trails/PresBox"; +import { PresMovement } from "../../nodes/trails/PresEnums"; import { PreviewCursor } from "../../PreviewCursor"; import { CollectionDockingView } from "../CollectionDockingView"; import { SubCollectionViewProps } from "../CollectionSubView"; diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss index a8d4235bd..72adc171b 100644 --- a/src/client/views/global/globalCssVariables.scss +++ b/src/client/views/global/globalCssVariables.scss @@ -38,6 +38,9 @@ $antimodemenu-height: 36px; $contextMenu-zindex: 100000; // context menu shows up over everything $radialMenu-zindex: 100000; // context menu shows up over everything +// borders +$standard-border: solid 1px #9F9F9F; + $searchpanel-height: 32px; $mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc $docDecorations-zindex: 998; // then doc decorations appear over everything else diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 9b75cd8f9..3d2cdf5a4 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -11,7 +11,7 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec import { CollectionSchemaView } from "../collections/collectionSchema/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; import { InkingStroke } from "../InkingStroke"; -import { PresElementBox } from "../presentationview/PresElementBox"; +import { PresElementBox } from "../nodes/trails/PresElementBox"; import { SearchBox } from "../search/SearchBox"; import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo"; import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; @@ -32,7 +32,7 @@ import { LabelBox } from "./LabelBox"; import { LinkAnchorBox } from "./LinkAnchorBox"; import { LinkBox } from "./LinkBox"; import { PDFBox } from "./PDFBox"; -import { PresBox } from "./PresBox"; +import { PresBox } from "./trails/PresBox"; import { ScreenshotBox } from "./ScreenshotBox"; import { ScriptingBox } from "./ScriptingBox"; import { SliderBox } from "./SliderBox"; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 60fa462ad..80a014926 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -43,7 +43,7 @@ import { DocumentLinksButton } from './DocumentLinksButton'; import "./DocumentView.scss"; import { LinkAnchorBox } from './LinkAnchorBox'; import { LinkDocPreview } from "./LinkDocPreview"; -import { PresBox } from './PresBox'; +import { PresBox } from './trails/PresBox'; import { RadialMenu } from './RadialMenu'; import React = require("react"); import { ScriptingBox } from "./ScriptingBox"; diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 6ae4b9726..0d415e238 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -14,6 +14,7 @@ import { DocComponent } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; import { FieldView, FieldViewProps } from './FieldView'; import './FontIconBox.scss'; +import { Colors } from '../global/globalEnums'; const FontIconSchema = createSchema({ icon: "string", }); @@ -47,7 +48,7 @@ export class FontIconBox extends DocComponent( const icon = StrCast(this.dataDoc.icon, "user") as any; const presSize = shape === 'round' ? 25 : 30; const presTrailsIcon = ; + style={{ width: presSize, height: presSize, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})`, marginBottom: "5px" }} />; const button =
- Doc.UserDoc().defaultAclPrivate = !Doc.UserDoc().defaultAclPrivate)} /> + Doc.UserDoc().defaultAclPrivate = !Doc.UserDoc().defaultAclPrivate)} />
Default access private
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index a8972b988..6c4556250 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -23,6 +23,7 @@ import { GroupManager, UserOptions } from "./GroupManager"; import { GroupMemberView } from "./GroupMemberView"; import { SelectionManager } from "./SelectionManager"; import "./SharingManager.scss"; +import { LinkManager } from "./LinkManager"; export interface User { email: string; @@ -154,10 +155,11 @@ export class SharingManager extends React.Component<{}> { } }); return Promise.all(evaluating).then(() => { - runInAction(() => { + runInAction(async () => { for (const sharer of sharingDocs) { if (!this.users.find(user => user.user.email === sharer.user.email)) { this.users.push(sharer); + LinkManager.addLinkDB(sharer.linkDatabase); } } }); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 2be3c3135..3d7446cbe 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -108,7 +108,7 @@ export class MainView extends React.Component { this._sidebarContent.proto = undefined; if (!MainView.Live) { DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition", - "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", + "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's } DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg))); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f7bed2fa1..9bba15b28 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -431,6 +431,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.ProseRef = ele; this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.layoutDoc)); + // if (this.autoHeight) this.tryUpdateScrollHeight(); } @undoBatch @@ -1438,16 +1439,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } } - tryUpdateScrollHeight() { + tryUpdateScrollHeight = () => { if (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath())) { const margins = 2 * NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0); - const proseHeight = !this.ProseRef ? 0 : Array.from(this.ProseRef.children[0].children).reduce((p, child) => p + Number(getComputedStyle(child).height.replace("px", "")), margins); - const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight); - if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation - const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight; - if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) { - setScrollHeight(); - } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... + const children = this.ProseRef?.children.length ? Array.from(this.ProseRef.children[0].children) : undefined; + if (children) { + const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + Number(getComputedStyle(child).height.replace("px", "")), margins); + const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight); + if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation + const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight; + if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) { + setScrollHeight(); + } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... + } } } } diff --git a/src/fields/util.ts b/src/fields/util.ts index 2bb6b45c2..439c4d333 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -141,7 +141,9 @@ export function denormalizeEmail(email: string) { export function inheritParentAcls(parent: Doc, child: Doc) { const dataDoc = parent[DataSym]; for (const key of Object.keys(dataDoc)) { - key.startsWith("acl") && distributeAcls(key, dataDoc[key], child); + // if the default acl mode is private, then don't inherit the acl-Public permission, but set it to private. + const permission = (key === "acl-Public" && Doc.UserDoc().defaultAclPrivate) ? AclPrivate : dataDoc[key]; + key.startsWith("acl") && distributeAcls(key, permission, child); } } -- cgit v1.2.3-70-g09d2