(core) Fix "Copy Link" in UserManager when its opened from a DocMenu page.

Test Plan: Added a check to the test case verifying the copied link.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2673
This commit is contained in:
Dmitry S 2020-11-25 21:29:13 -05:00
parent 5172cae1c2
commit 9a7a42bc59
3 changed files with 14 additions and 12 deletions

View File

@ -310,7 +310,8 @@ export function makeDocOptionsMenu(home: HomeModel, doc: Document, renaming: Obs
permissionData: api.getDocAccess(doc.id), permissionData: api.getDocAccess(doc.id),
activeEmail: user ? user.email : null, activeEmail: user ? user.email : null,
resourceType: 'document', resourceType: 'document',
resourceId: doc.id resourceId: doc.id,
linkToCopy: urlState().makeUrl(docUrl(doc)),
}); });
} }

View File

@ -1,7 +1,7 @@
import {loadUserManager} from 'app/client/lib/imports'; import {loadUserManager} from 'app/client/lib/imports';
import {AppModel, reportError} from 'app/client/models/AppModel'; import {AppModel, reportError} from 'app/client/models/AppModel';
import {DocInfo, DocPageModel} from 'app/client/models/DocPageModel'; import {DocInfo, DocPageModel} from 'app/client/models/DocPageModel';
import {urlState} from 'app/client/models/gristUrlState'; import {docUrl, urlState} from 'app/client/models/gristUrlState';
import {makeCopy, replaceTrunkWithFork} from 'app/client/ui/MakeCopyMenu'; import {makeCopy, replaceTrunkWithFork} from 'app/client/ui/MakeCopyMenu';
import {cssHoverCircle, cssTopBarBtn} from 'app/client/ui/TopBarCss'; import {cssHoverCircle, cssTopBarBtn} from 'app/client/ui/TopBarCss';
import {primaryButton} from 'app/client/ui2018/buttons'; import {primaryButton} from 'app/client/ui2018/buttons';
@ -224,6 +224,7 @@ async function manageUsers(doc: DocInfo, docPageModel: DocPageModel) {
resourceType: 'document', resourceType: 'document',
resourceId: doc.id, resourceId: doc.id,
docPageModel, docPageModel,
linkToCopy: urlState().makeUrl(docUrl(doc)),
// On save, re-fetch the document info, to toggle the "Public Access" icon if it changed. // On save, re-fetch the document info, to toggle the "Public Access" icon if it changed.
onSave: () => docPageModel.refreshCurrentDoc(doc), onSave: () => docPageModel.refreshCurrentDoc(doc),
}); });

View File

@ -17,7 +17,7 @@ import {copyToClipboard} from 'app/client/lib/copyToClipboard';
import {setTestState} from 'app/client/lib/testState'; import {setTestState} from 'app/client/lib/testState';
import {DocPageModel} from 'app/client/models/DocPageModel'; import {DocPageModel} from 'app/client/models/DocPageModel';
import {reportError} from 'app/client/models/errors'; import {reportError} from 'app/client/models/errors';
import {getCurrentDocUrl, urlState} from 'app/client/models/gristUrlState'; import {urlState} from 'app/client/models/gristUrlState';
import {IEditableMember, IMemberSelectOption, IOrgMemberSelectOption} from 'app/client/models/UserManagerModel'; import {IEditableMember, IMemberSelectOption, IOrgMemberSelectOption} from 'app/client/models/UserManagerModel';
import {UserManagerModel, UserManagerModelImpl} from 'app/client/models/UserManagerModel'; import {UserManagerModel, UserManagerModelImpl} from 'app/client/models/UserManagerModel';
import {getResourceParent, ResourceType} from 'app/client/models/UserManagerModel'; import {getResourceParent, ResourceType} from 'app/client/models/UserManagerModel';
@ -37,6 +37,7 @@ export interface IUserManagerOptions {
resourceType: ResourceType; resourceType: ResourceType;
resourceId: string|number; resourceId: string|number;
docPageModel?: DocPageModel; docPageModel?: DocPageModel;
linkToCopy?: string;
onSave?: () => Promise<unknown>; onSave?: () => Promise<unknown>;
} }
@ -74,7 +75,7 @@ export function showUserManagerModal(userApi: UserAPI, options: IUserManagerOpti
['Access Rules'] : ['Access Rules'] :
[ [
`Invite people to ${renderType(options.resourceType)}`, `Invite people to ${renderType(options.resourceType)}`,
(options.resourceType === 'document' ? makeCopyBtn(cssCopyBtn.cls('-header')) : null), (options.resourceType === 'document' ? makeCopyBtn(options.linkToCopy, cssCopyBtn.cls('-header')) : null),
] ]
), ),
testId('um-header') testId('um-header')
@ -84,7 +85,7 @@ export function showUserManagerModal(userApi: UserAPI, options: IUserManagerOpti
dom.autoDispose(accessRules), dom.autoDispose(accessRules),
cssUserManagerBody( cssUserManagerBody(
// TODO: Show a loading indicator before the model is loaded. // TODO: Show a loading indicator before the model is loaded.
dom.maybe(modelObs, model => new UserManager(model).buildDom()), dom.maybe(modelObs, model => new UserManager(model, options.linkToCopy).buildDom()),
dom.hide(accessRulesOpen), dom.hide(accessRulesOpen),
), ),
cssUserManagerBody( cssUserManagerBody(
@ -146,7 +147,7 @@ export function showUserManagerModal(userApi: UserAPI, options: IUserManagerOpti
* um.buildDom(); * um.buildDom();
*/ */
export class UserManager extends Disposable { export class UserManager extends Disposable {
constructor(private _model: UserManagerModel) { constructor(private _model: UserManagerModel, private _linkToCopy: string|undefined) {
super(); super();
} }
@ -244,7 +245,7 @@ export class UserManager extends Disposable {
cssPublicMemberIcon('PublicFilled'), cssPublicMemberIcon('PublicFilled'),
cssMemberText( cssMemberText(
cssMemberPrimary('Public Access'), cssMemberPrimary('Public Access'),
cssMemberSecondary('Anyone with link ', makeCopyBtn()), cssMemberSecondary('Anyone with link ', makeCopyBtn(this._linkToCopy)),
), ),
this._memberRoleSelector(publicMember.effectiveAccess, publicMember.inheritedAccess, false, this._memberRoleSelector(publicMember.effectiveAccess, publicMember.inheritedAccess, false,
// Only show the Editor and Viewer options for the role of the "Public Access" member. // Only show the Editor and Viewer options for the role of the "Public Access" member.
@ -418,9 +419,9 @@ function getFullUser(member: IEditableMember): FullUser {
} }
// Create a "Copy Link" button. // Create a "Copy Link" button.
function makeCopyBtn(...domArgs: DomElementArg[]) { function makeCopyBtn(linkToCopy: string|undefined, ...domArgs: DomElementArg[]) {
return cssCopyBtn(cssCopyIcon('Copy'), 'Copy Link', return linkToCopy && cssCopyBtn(cssCopyIcon('Copy'), 'Copy Link',
dom.on('click', copyLink), dom.on('click', (ev, elem) => copyLink(elem, linkToCopy)),
testId('um-copy-link'), testId('um-copy-link'),
...domArgs, ...domArgs,
); );
@ -428,8 +429,7 @@ function makeCopyBtn(...domArgs: DomElementArg[]) {
// Copy the current document link to clipboard, and notify the user with a transient popup near // Copy the current document link to clipboard, and notify the user with a transient popup near
// the given element. // the given element.
async function copyLink(ev: MouseEvent, elem: HTMLElement) { async function copyLink(elem: HTMLElement, link: string) {
const link = getCurrentDocUrl();
await copyToClipboard(link); await copyToClipboard(link);
setTestState({clipboard: link}); setTestState({clipboard: link});
showTransientTooltip(elem, 'Link copied to clipboard', {key: 'copy-doc-link'}); showTransientTooltip(elem, 'Link copied to clipboard', {key: 'copy-doc-link'});