Gen and copy share link from frontend
This commit is contained in:
@ -5,8 +5,8 @@ import copy from 'copy-to-clipboard';
|
||||
type Props = {
|
||||
text: string,
|
||||
children?: React.Node,
|
||||
onClick?: () => void,
|
||||
onCopy: () => void,
|
||||
onClick?: () => *,
|
||||
onCopy: () => *,
|
||||
};
|
||||
|
||||
class CopyToClipboard extends React.PureComponent<Props> {
|
||||
|
@ -7,6 +7,7 @@ import CollectionNew from 'scenes/CollectionNew';
|
||||
import CollectionEdit from 'scenes/CollectionEdit';
|
||||
import CollectionDelete from 'scenes/CollectionDelete';
|
||||
import DocumentDelete from 'scenes/DocumentDelete';
|
||||
import DocumentShare from 'scenes/DocumentShare';
|
||||
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
|
||||
|
||||
type Props = {
|
||||
@ -44,6 +45,9 @@ class Modals extends React.Component<Props> {
|
||||
<Modal name="collection-delete" title="Delete collection">
|
||||
<CollectionDelete onSubmit={this.handleClose} />
|
||||
</Modal>
|
||||
<Modal name="document-share" title="Share document">
|
||||
<DocumentShare onSubmit={this.handleClose} />
|
||||
</Modal>
|
||||
<Modal name="document-delete" title="Delete document">
|
||||
<DocumentDelete onSubmit={this.handleClose} />
|
||||
</Modal>
|
||||
|
@ -31,10 +31,6 @@ class MainSidebar extends React.Component<Props> {
|
||||
this.props.ui.setActiveModal('collection-new');
|
||||
};
|
||||
|
||||
handleEditCollection = () => {
|
||||
this.props.ui.setActiveModal('collection-edit');
|
||||
};
|
||||
|
||||
render() {
|
||||
const { auth, documents } = this.props;
|
||||
const { user, team } = auth;
|
||||
|
@ -56,6 +56,13 @@ class DocumentMenu extends React.Component<Props> {
|
||||
this.props.document.download();
|
||||
};
|
||||
|
||||
handleShareLink = async (ev: SyntheticEvent<*>) => {
|
||||
const { document } = this.props;
|
||||
if (!document.shareUrl) await document.share();
|
||||
|
||||
this.props.ui.setActiveModal('document-share', { document });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { document, label, className, showPrint } = this.props;
|
||||
const isDraft = !document.publishedAt;
|
||||
@ -80,6 +87,12 @@ class DocumentMenu extends React.Component<Props> {
|
||||
Star
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleShareLink}
|
||||
title="Create a public share link"
|
||||
>
|
||||
Share link
|
||||
</DropdownMenuItem>
|
||||
<hr />
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleNewChild}
|
||||
|
@ -40,6 +40,7 @@ class Document extends BaseModel {
|
||||
parentDocument: ?string;
|
||||
publishedAt: ?string;
|
||||
url: string;
|
||||
shareUrl: ?string;
|
||||
views: number;
|
||||
revision: number;
|
||||
|
||||
@ -101,6 +102,18 @@ class Document extends BaseModel {
|
||||
|
||||
/* Actions */
|
||||
|
||||
@action
|
||||
share = async () => {
|
||||
try {
|
||||
const res = await client.post('/shares.create', { id: this.id });
|
||||
invariant(res && res.data, 'Document API response should be available');
|
||||
|
||||
this.shareUrl = res.data.url;
|
||||
} catch (e) {
|
||||
this.errors.add('Document failed to share');
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
pin = async () => {
|
||||
this.pinned = true;
|
||||
|
58
app/scenes/DocumentShare/DocumentShare.js
Normal file
58
app/scenes/DocumentShare/DocumentShare.js
Normal file
@ -0,0 +1,58 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import Input from 'components/Input';
|
||||
import Button from 'components/Button';
|
||||
import CopyToClipboard from 'components/CopyToClipboard';
|
||||
import HelpText from 'components/HelpText';
|
||||
import Document from 'models/Document';
|
||||
|
||||
type Props = {
|
||||
document: Document,
|
||||
};
|
||||
|
||||
@observer
|
||||
class DocumentShare extends React.Component<Props> {
|
||||
@observable isCopied: boolean;
|
||||
timeout: TimeoutID;
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
handleCopied = () => {
|
||||
this.isCopied = true;
|
||||
this.timeout = setTimeout(() => (this.isCopied = false), 3000);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { document } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<HelpText>
|
||||
The link below allows anyone to access a read-only version of the
|
||||
document <strong>{document.title}</strong>. You can revoke this link
|
||||
at any point in the future.
|
||||
</HelpText>
|
||||
<Input
|
||||
type="text"
|
||||
label="Share link"
|
||||
value={document.shareUrl || 'Loading…'}
|
||||
disabled
|
||||
/>
|
||||
<CopyToClipboard
|
||||
text={document.shareUrl || ''}
|
||||
onCopy={this.handleCopied}
|
||||
>
|
||||
<Button type="submit" disabled={this.isCopied} primary>
|
||||
{this.isCopied ? 'Copied!' : 'Copy Link'}
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DocumentShare;
|
3
app/scenes/DocumentShare/index.js
Normal file
3
app/scenes/DocumentShare/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
// @flow
|
||||
import DocumentShare from './DocumentShare';
|
||||
export default DocumentShare;
|
@ -7,6 +7,7 @@ function present(ctx: Object, share: Share) {
|
||||
id: share.id,
|
||||
user: presentUser(ctx, share.user),
|
||||
documentTitle: share.document.title,
|
||||
url: `${process.env.URL}/share/${share.id}`,
|
||||
createdAt: share.createdAt,
|
||||
updatedAt: share.updatedAt,
|
||||
};
|
||||
|
Reference in New Issue
Block a user