(core) annotate shares listed in UserManager for documents

Summary:
This gives more guidance to users when editing document shares in the UserManager dialog.

  * For a document on a team site, any shares with team members are marked `Team member`.
  * Shares that count as external collaborators are marked for documents on a team or personal site as `collaborator` (personal site) or `outside collaborator` (team site).
  * Collaborators are marked `1 of 2`, `2 of 2`, and then `limit exceeded`.
  * On a team site, links are offered for each collaborator to add them to the team. The links lead to a prefilled dialog for managing team membership which can be confirmed immediately, allowing the user to continue without interruption.
  * On a personal site, for the last collaborator and beyond, a link is added for creating a team. This isn't seamless since creating a team involves billing etc.

There's a small unrelated tweak in tests to remove a confusing import from `test/browser` in `test/server`.

One thing I didn't get to is checking if owner of doc is owner of site. If they aren't, they may try to add a member and be denied at that point - it would be more polite to change messaging earlier for them.

Test Plan: added and updated tests

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3083
This commit is contained in:
Paul Fitzpatrick
2021-10-25 12:54:04 -04:00
parent f2f4fe0eca
commit f7c9919120
9 changed files with 302 additions and 25 deletions

View File

@@ -2054,18 +2054,24 @@ export class HomeDBManager extends EventEmitter {
const wsMap = getMemberUserRoles(doc.workspace, this.defaultBasicGroupNames);
// The orgMap gives the org access inherited by each user.
const orgMap = getMemberUserRoles(doc.workspace.org, this.defaultBasicGroupNames);
// The orgMapWithMembership gives the full access to the org for each user, including
// the "members" level, which grants no default inheritable access but allows the user
// to be added freely to workspaces and documents.
const orgMapWithMembership = getMemberUserRoles(doc.workspace.org, this.defaultGroupNames);
const wsMaxInheritedRole = this._getMaxInheritedRole(doc.workspace);
// Iterate through the org since all users will be in the org.
let users: UserAccessData[] = getResourceUsers([doc, doc.workspace, doc.workspace.org]).map(u => {
// Merge the strongest roles from the resource and parent resources. Note that the parent
// resource access levels must be tempered by the maxInheritedRole values of their children.
const inheritFromOrg = roles.getWeakestRole(orgMap[u.id] || null, wsMaxInheritedRole);
const orgAccess = orgMapWithMembership[u.id] || null;
return {
...this.makeFullUser(u),
access: docMap[u.id] || null,
parentAccess: roles.getEffectiveRole(
roles.getStrongestRole(wsMap[u.id] || null, inheritFromOrg)
)
),
isMember: orgAccess !== 'guests' && orgAccess !== null,
};
});
let maxInheritedRole = this._getMaxInheritedRole(doc);