From e373e66f8ed06f4501e00af8348f15ad113c7424 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 21 Dec 2022 11:11:39 -0500
Subject: cleaning up ACLs for performance and clarity

---
 src/client/util/SharingManager.tsx | 49 +++++++++++++-------------------------
 1 file changed, 17 insertions(+), 32 deletions(-)

(limited to 'src/client/util/SharingManager.tsx')

diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 6cbc76014..54ee691bc 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -5,7 +5,8 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import Select from 'react-select';
 import * as RequestPromise from 'request-promise';
-import { AclAugment, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, Opt, AclSelfEdit } from '../../fields/Doc';
+import { AclAdmin, AclPrivate, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, HierarchyMapping, Opt } from '../../fields/Doc';
+import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
 import { Cast, NumCast, StrCast } from '../../fields/Types';
 import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from '../../fields/util';
@@ -20,10 +21,9 @@ import { SearchBox } from '../views/search/SearchBox';
 import { DocumentManager } from './DocumentManager';
 import { GroupManager, UserOptions } from './GroupManager';
 import { GroupMemberView } from './GroupMemberView';
+import { LinkManager } from './LinkManager';
 import { SelectionManager } from './SelectionManager';
 import './SharingManager.scss';
-import { LinkManager } from './LinkManager';
-import { Id } from '../../fields/FieldSymbols';
 
 export interface User {
     email: string;
@@ -82,16 +82,6 @@ export class SharingManager extends React.Component<{}> {
     @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
     @observable private myDocAcls: boolean = false; // whether the My Docs checkbox is selected or not
 
-    // maps acl symbols to SharingPermissions
-    private AclMap = new Map<symbol, string>([
-        [AclPrivate, SharingPermissions.None],
-        [AclReadonly, SharingPermissions.View],
-        [AclAugment, SharingPermissions.Augment],
-        [AclSelfEdit, SharingPermissions.SelfEdit],
-        [AclEdit, SharingPermissions.Edit],
-        [AclAdmin, SharingPermissions.Admin],
-    ]);
-
     // private get linkVisible() {
     //     return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
     // }
@@ -184,6 +174,7 @@ export class SharingManager extends React.Component<{}> {
 
         const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
         return !docs
+            .map(doc => (this.layoutDocAcls ? doc : doc[DataSym]))
             .map(doc => {
                 doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc, undefined, undefined, isDashboard);
 
@@ -217,6 +208,7 @@ export class SharingManager extends React.Component<{}> {
 
         // ! ensures it returns true if document has been shared successfully, false otherwise
         return !docs
+            .map(doc => (this.layoutDocAcls ? doc : doc[DataSym]))
             .map(doc => {
                 doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc, undefined, undefined, isDashboard);
 
@@ -283,6 +275,7 @@ export class SharingManager extends React.Component<{}> {
             docs.forEach(doc => {
                 const isDashboard = dashboards.indexOf(doc) !== -1;
                 if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc, undefined, undefined, isDashboard);
+                this.setDashboardBackground(doc, permission as SharingPermissions);
             });
         }
     };
@@ -290,14 +283,14 @@ 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) => {
+    setDashboardBackground = (doc: Doc, permission: SharingPermissions) => {
         if (Doc.IndexOf(doc, DocListCast(Doc.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])))) {
+                if (Object.keys(acls).every(key => (key === `acl-${Doc.CurrentUserEmailNormalized}` || key === 'acl-Me' ? true : [AclUnset, AclPrivate].includes(acls[key])))) {
                     doc.isShared = undefined;
                     doc.backgroundColor = undefined;
                 }
@@ -372,7 +365,7 @@ export class SharingManager extends React.Component<{}> {
     private sharingOptions(uniform: boolean, override?: boolean) {
         const dropdownValues: string[] = Object.values(SharingPermissions);
         if (!uniform) dropdownValues.unshift('-multiple-');
-        if (override) dropdownValues.unshift('None');
+        if (!override) dropdownValues.splice(dropdownValues.indexOf(SharingPermissions.Unset), 1);
         return dropdownValues
             .filter(permission => !Doc.noviceMode || ![SharingPermissions.SelfEdit].includes(permission as any))
             .map(permission => (
@@ -458,17 +451,6 @@ export class SharingManager extends React.Component<{}> {
         }
     };
 
-    // 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);
-    //         }
-    //     });
-    // }
-
     /**
      * Sorting algorithm to sort users.
      */
@@ -491,6 +473,7 @@ export class SharingManager extends React.Component<{}> {
      * @returns the main interface of the SharingManager.
      */
     @computed get sharingInterface() {
+        if (!this.targetDoc) return null;
         TraceMobx();
         const groupList = GroupManager.Instance?.allGroups || [];
         const sortedUsers = this.users
@@ -523,21 +506,21 @@ export class SharingManager extends React.Component<{}> {
             docs = newDocs.filter(doc => GetEffectiveAcl(doc) === AclAdmin);
         }
 
-        const targetDoc = docs[0];
+        const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DataSym];
 
         // tslint:disable-next-line: no-unnecessary-callback-wrapper
         const effectiveAcls = docs.map(doc => GetEffectiveAcl(doc));
         const admin = this.myDocAcls ? Boolean(docs.length) : 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 = intersection(...docs.map(doc => (this.layoutDocAcls ? doc : doc[DataSym])).map(doc => doc?.[AclSym] && Object.keys(doc[AclSym])));
 
         // the list of users shared with
         const userListContents: (JSX.Element | null)[] = users
             .filter(({ user }) => (docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email))
             .map(({ user, linkDatabase, sharingDoc, userColor }) => {
                 const userKey = `acl-${normalizeEmail(user.email)}`;
-                const uniform = docs.every(doc => (this.layoutDocAcls ? doc?.[AclSym]?.[userKey] === docs[0]?.[AclSym]?.[userKey] : doc?.[DataSym]?.[AclSym]?.[userKey] === docs[0]?.[DataSym]?.[AclSym]?.[userKey]));
+                const uniform = docs.map(doc => (this.layoutDocAcls ? doc : doc[DataSym])).every(doc => doc?.[AclSym]?.[userKey] === docs[0]?.[AclSym]?.[userKey]);
                 const permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-';
 
                 return !permissions ? null : (
@@ -573,7 +556,7 @@ export class SharingManager extends React.Component<{}> {
                 <div key={'me'} className={'container'}>
                     <span className={'padding'}>Me</span>
                     <div className="edit-actions">
-                        <div className={'permissions-dropdown'}>{effectiveAcls.every(acl => acl === effectiveAcls[0]) ? this.AclMap.get(effectiveAcls[0])! : '-multiple-'}</div>
+                        <div className={'permissions-dropdown'}>{effectiveAcls.every(acl => acl === effectiveAcls[0]) ? HierarchyMapping.get(effectiveAcls[0])!.name : '-multiple-'}</div>
                     </div>
                 </div>
             ) : null
@@ -584,7 +567,9 @@ export class SharingManager extends React.Component<{}> {
         groupListMap.unshift({ title: 'Public' }); //, { title: "ALL" });
         const groupListContents = groupListMap.map(group => {
             const groupKey = `acl-${StrCast(group.title)}`;
-            const uniform = docs.every(doc => (this.layoutDocAcls ? doc?.[AclSym]?.[groupKey] === docs[0]?.[AclSym]?.[groupKey] : doc?.[DataSym]?.[AclSym]?.[groupKey] === docs[0]?.[DataSym]?.[AclSym]?.[groupKey]));
+            const uniform = docs
+                .map(doc => (this.layoutDocAcls ? doc : doc[DataSym]))
+                .every(doc => (this.layoutDocAcls ? doc?.[AclSym]?.[groupKey] === docs[0]?.[AclSym]?.[groupKey] : doc?.[DataSym]?.[AclSym]?.[groupKey] === docs[0]?.[DataSym]?.[AclSym]?.[groupKey]));
             const permissions = uniform ? StrCast(targetDoc?.[`acl-${StrCast(group.title)}`]) : '-multiple-';
 
             return !permissions ? null : (
-- 
cgit v1.2.3-70-g09d2

