From c8e8cbe52a97835342c3a3d04033462f4497cd72 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Oct 2020 11:36:56 -0400 Subject: trying to get group updates to work automatically --- src/fields/util.ts | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'src/fields') diff --git a/src/fields/util.ts b/src/fields/util.ts index 7293db0c2..1e6707a9a 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -4,7 +4,7 @@ import { SerializationHelper } from "../client/util/SerializationHelper"; import { ProxyField, PrefetchProxy } from "./Proxy"; import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; -import { action, trace } from "mobx"; +import { action, trace, observable, reaction } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self, HandleUpdate, ToString, ToScriptString } from "./FieldSymbols"; import { DocServer } from "../client/DocServer"; import { ComputedField } from "./ScriptField"; @@ -22,6 +22,24 @@ export function TraceMobx() { tracing && trace(); } +// the list of groups that the current user is a member of +export class UserGroups { + @observable static Current: string[]; + @action static setCurrentUserGroups(groupList: List) { + reaction(() => groupList, + groupList => { + UserGroups.Current = [ + "Public", + ...(groupList as List). + filter(group => group instanceof Doc). + map(group => group as Doc). + filter(group => JSON.parse(StrCast(group.members))?.includes(Doc.CurrentUserEmail)). + map(group => StrCast(group.title)) + ]; + }, { fireImmediately: true }); + } +} + export interface GetterResult { value: FieldResult; shouldReturn?: boolean; @@ -130,14 +148,6 @@ export function denormalizeEmail(email: string) { // playgroundMode = !playgroundMode; // } -// the list of groups that the current user is a member of -let currentUserGroups: string[] = []; - -// called from GroupManager once the groups have been fetched from the server -export function setGroups(groups: string[]) { - currentUserGroups = groups; -} - /** * These are the various levels of access a user can have to a document. * @@ -164,6 +174,7 @@ export enum SharingPermissions { */ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { if (!target) return AclPrivate; + if (target[Id] === "groupdbProto" || target[Id]?.startsWith("GROUP:")) return AclAdmin; // all changes received fromt the server must be processed as Admin if (in_prop === UpdatingFromServer || target[UpdatingFromServer]) return AclAdmin; @@ -171,7 +182,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, // if the current user is the author of the document / the current user is a member of the admin group const userChecked = user || Doc.CurrentUserEmail; if (userChecked === (target.__fields?.author || target.author)) return AclAdmin; - if (currentUserGroups.includes("Admin")) return AclAdmin; + if (UserGroups.Current?.includes("Admin")) return AclAdmin; if (target[AclSym] && Object.keys(target[AclSym]).length) { @@ -192,7 +203,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, // there are issues with storing fields with . in the name, so they are replaced with _ during creation // as a result we need to restore them again during this comparison. const entity = denormalizeEmail(key.substring(4)); // an individual or a group - if (currentUserGroups.includes(entity) || userChecked === entity) { + if (UserGroups.Current?.includes(entity) || userChecked === entity) { if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) { effectiveAcl = value as symbol; if (effectiveAcl === AclAdmin) return effectiveAcl; @@ -308,12 +319,10 @@ export function setter(target: any, in_prop: string | symbol | number, value: an export function getter(target: any, in_prop: string | symbol | number, receiver: any): any { let prop = in_prop; - if (in_prop === "toString" || in_prop === ToString || in_prop === ToScriptString || in_prop === FieldsSym || in_prop === Id || in_prop === HandleUpdate || in_prop === CachedUpdates) return target.__fields[prop] || target[prop]; if (in_prop === AclSym) return _overrideAcl ? undefined : target[AclSym]; + if (in_prop === "toString" || (in_prop !== HeightSym && in_prop !== WidthSym && in_prop !== LayoutSym && typeof prop === "symbol")) return target.__fields[prop] || target[prop]; if (GetEffectiveAcl(target) === AclPrivate && !_overrideAcl) return prop === HeightSym || prop === WidthSym ? returnZero : undefined; - if (prop === LayoutSym) { - return target.__LAYOUT__; - } + if (prop === LayoutSym) return target.__LAYOUT__; if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) { if (!prop.startsWith("_")) { console.log(prop + " is deprecated - switch to _" + prop); -- cgit v1.2.3-70-g09d2 From 2608cc4dbf852a318b9d6a453bdaf64249917cda Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Oct 2020 16:54:21 -0400 Subject: fixed updating groups to take effect immediately --- src/client/util/CurrentUserUtils.ts | 6 +++--- src/client/util/SharingManager.tsx | 12 +++++++----- src/fields/util.ts | 26 +++++++++++++++++--------- 3 files changed, 27 insertions(+), 17 deletions(-) (limited to 'src/fields') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 759fd6eca..580c6040e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -956,6 +956,9 @@ export class CurrentUserUtils { } static async updateUserDocument(doc: Doc, sharingDocumentId: string) { + if (!doc.globalGroupDatabase) doc.globalGroupDatabase = Docs.Prototypes.MainGroupDocument(); + await DocListCastAsync((doc.globalGroupDatabase as Doc).data); + UserGroups.Current; doc.system = true; doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode; doc.title = Doc.CurrentUserEmail; @@ -989,10 +992,7 @@ export class CurrentUserUtils { await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels await this.setupMenuPanel(doc, sharingDocumentId); if (!doc.globalScriptDatabase) doc.globalScriptDatabase = Docs.Prototypes.MainScriptDocument(); - doc.globalGroupDatabase = Docs.Prototypes.MainGroupDocument(); if (!doc.myLinkDatabase) doc.myLinkDatabase = new List([]); - const x = await DocListCastAsync((doc.globalGroupDatabase as Doc).data); - UserGroups.setCurrentUserGroups((doc.globalGroupDatabase as Doc).data as List); setTimeout(() => this.setupDefaultPresentation(doc), 0); // presentation that's initially triggered diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 729742890..ee397ab4f 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import Select from "react-select"; import * as RequestPromise from "request-promise"; -import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly } from "../../fields/Doc"; +import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly, DocListCastAsync } from "../../fields/Doc"; import { List } from "../../fields/List"; import { Cast, StrCast } from "../../fields/Types"; import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail } from "../../fields/util"; @@ -189,7 +189,9 @@ export class SharingManager extends React.Component<{}> { const self = this; if (group.docsShared) { if (!user) retry && this.populateUsers().then(() => self.shareWithAddedMember(group, emailId, false)); - else DocListCast(group.docsShared).forEach(doc => Doc.IndexOf(doc, DocListCast(user.sharingDoc[storage])) === -1 && Doc.AddDocToList(user.sharingDoc, storage, doc)); + else DocListCastAsync(group.docsShared).then(dl => dl?.forEach(doc => { + Doc.AddDocToList(user.sharingDoc, storage, doc); + })); } } @@ -220,9 +222,9 @@ export class SharingManager extends React.Component<{}> { const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!; if (group.docsShared) { - DocListCast(group.docsShared).forEach(doc => { - Doc.IndexOf(doc, DocListCast(user.sharingDoc[storage])) !== -1 && Doc.RemoveDocFromList(user.sharingDoc, storage, doc); // remove the doc only if it is in the list - }); + DocListCastAsync(group.docsShared).then(dl => dl?.forEach(doc => { + Doc.RemoveDocFromList(user.sharingDoc, storage, doc); + })); } } diff --git a/src/fields/util.ts b/src/fields/util.ts index 1e6707a9a..791b98b83 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -4,7 +4,7 @@ import { SerializationHelper } from "../client/util/SerializationHelper"; import { ProxyField, PrefetchProxy } from "./Proxy"; import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; -import { action, trace, observable, reaction } from "mobx"; +import { action, trace, observable, reaction, computed } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self, HandleUpdate, ToString, ToScriptString } from "./FieldSymbols"; import { DocServer } from "../client/DocServer"; import { ComputedField } from "./ScriptField"; @@ -24,19 +24,28 @@ export function TraceMobx() { // the list of groups that the current user is a member of export class UserGroups { - @observable static Current: string[]; - @action static setCurrentUserGroups(groupList: List) { - reaction(() => groupList, - groupList => { - UserGroups.Current = [ + static computing = false; + static cachedGroups: string[] = []; + static globalGroupDoc: Doc | undefined; + static get Current() { + if (!Doc.UserDoc() || UserGroups.computing) return UserGroups.cachedGroups; + UserGroups.computing = true; + if (!UserGroups.globalGroupDoc) UserGroups.globalGroupDoc = Doc.UserDoc().globalGroupDatabase as Doc; + if (UserGroups.globalGroupDoc) { + const dbgroups = DocListCast(UserGroups.globalGroupDoc.data); + if (dbgroups.length !== UserGroups.cachedGroups.length - 1) { + UserGroups.cachedGroups = [ "Public", - ...(groupList as List). + ...dbgroups?. filter(group => group instanceof Doc). map(group => group as Doc). filter(group => JSON.parse(StrCast(group.members))?.includes(Doc.CurrentUserEmail)). map(group => StrCast(group.title)) ]; - }, { fireImmediately: true }); + } + } + UserGroups.computing = false; + return UserGroups.cachedGroups; } } @@ -174,7 +183,6 @@ export enum SharingPermissions { */ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { if (!target) return AclPrivate; - if (target[Id] === "groupdbProto" || target[Id]?.startsWith("GROUP:")) return AclAdmin; // all changes received fromt the server must be processed as Admin if (in_prop === UpdatingFromServer || target[UpdatingFromServer]) return AclAdmin; -- cgit v1.2.3-70-g09d2