aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/SharingManager.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
committerbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
commit9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch)
treebc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/util/SharingManager.tsx
parent9dae453967183b294bf4f7444b948023a1d52d39 (diff)
parent8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff)
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/util/SharingManager.tsx')
-rw-r--r--src/client/util/SharingManager.tsx97
1 files changed, 36 insertions, 61 deletions
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 895bd3374..3c05af4bb 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -5,9 +5,10 @@ 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 { Cast, NumCast, PromiseValue, StrCast } from '../../fields/Types';
import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from '../../fields/util';
import { Utils } from '../../Utils';
import { DocServer } from '../DocServer';
@@ -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;
// }
@@ -140,35 +130,21 @@ export class SharingManager extends React.Component<{}> {
if (!this.populating && Doc.UserDoc()[Id] !== '__guest__') {
this.populating = true;
const userList = await RequestPromise.get(Utils.prepend('/getUsers'));
- const raw = JSON.parse(userList) as User[];
- const sharingDocs: ValidatedUser[] = [];
- const evaluating = raw.map(async user => {
- const isCandidate = user.email !== Doc.CurrentUserEmail;
- if (isCandidate) {
- const sharingDoc = await DocServer.GetRefField(user.sharingDocumentId);
- const linkDatabase = await DocServer.GetRefField(user.linkDatabaseId);
+ const raw = (JSON.parse(userList) as User[]).filter(user => user.email !== 'guest' && user.email !== Doc.CurrentUserEmail);
+ const docs = await DocServer.GetRefFields(raw.reduce((list, user) => [...list, user.sharingDocumentId, user.linkDatabaseId], [] as string[]));
+ raw.map(
+ action((newUser: User) => {
+ const sharingDoc = docs[newUser.sharingDocumentId];
+ const linkDatabase = docs[newUser.linkDatabaseId];
if (sharingDoc instanceof Doc && linkDatabase instanceof Doc) {
- await DocListCastAsync(linkDatabase.data);
- (await DocListCastAsync(Cast(linkDatabase, Doc, null).data))?.forEach(async link => {
- // makes sure link anchors are loaded to avoid incremental updates to computedFns in LinkManager
- const a1 = await Cast(link?.anchor1, Doc, null);
- const a2 = await Cast(link?.anchor2, Doc, null);
- });
- sharingDocs.push({ user, sharingDoc, linkDatabase, userColor: StrCast(sharingDoc.userColor) });
- }
- }
- });
- return Promise.all(evaluating).then(() => {
- 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);
+ if (!this.users.find(user => user.user.email === newUser.email)) {
+ this.users.push({ user: newUser, sharingDoc, linkDatabase, userColor: StrCast(sharingDoc.userColor) });
+ // LinkManager.addLinkDB(sharer.linkDatabase);
}
}
- });
- this.populating = false;
- });
+ })
+ );
+ this.populating = false;
}
};
@@ -184,6 +160,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 +194,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 +261,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 +269,18 @@ 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)
+ .filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && key !== 'acl-Me')
+ .every(key => [AclUnset, AclPrivate].includes(acls[key]))
+ ) {
doc.isShared = undefined;
doc.backgroundColor = undefined;
}
@@ -372,9 +355,9 @@ 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.View, SharingPermissions.SelfEdit].includes(permission as any))
+ .filter(permission => !Doc.noviceMode || ![SharingPermissions.SelfEdit].includes(permission as any))
.map(permission => (
<option key={permission} value={permission}>
{permission}
@@ -392,7 +375,7 @@ export class SharingManager extends React.Component<{}> {
onClick={() => {
let context: Opt<CollectionView>;
if (this.targetDoc && this.targetDocView && docs.length === 1 && (context = this.targetDocView.props.ContainingCollectionView)) {
- DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, [context.props.Document]);
+ DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
}
}}
onPointerEnter={action(() => {
@@ -458,17 +441,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 +463,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 +496,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 +546,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 +557,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 : (