2017-05-18 02:36:31 +00:00
|
|
|
// @flow
|
2020-06-20 20:59:15 +00:00
|
|
|
import { observable } from "mobx";
|
|
|
|
import { inject, observer } from "mobx-react";
|
2020-08-09 05:53:59 +00:00
|
|
|
import * as React from "react";
|
|
|
|
import { Redirect } from "react-router-dom";
|
2020-06-20 20:59:15 +00:00
|
|
|
|
|
|
|
import AuthStore from "stores/AuthStore";
|
|
|
|
import CollectionStore from "stores/CollectionsStore";
|
|
|
|
import PoliciesStore from "stores/PoliciesStore";
|
2020-08-09 05:53:59 +00:00
|
|
|
import UiStore from "stores/UiStore";
|
|
|
|
import Document from "models/Document";
|
2020-08-08 22:18:37 +00:00
|
|
|
import DocumentDelete from "scenes/DocumentDelete";
|
2020-08-12 17:49:15 +00:00
|
|
|
import DocumentShare from "scenes/DocumentShare";
|
2020-08-08 22:18:37 +00:00
|
|
|
import DocumentTemplatize from "scenes/DocumentTemplatize";
|
2020-08-09 05:53:59 +00:00
|
|
|
import { DropdownMenu, DropdownMenuItem } from "components/DropdownMenu";
|
|
|
|
import Modal from "components/Modal";
|
2019-04-18 02:11:23 +00:00
|
|
|
import {
|
2019-10-16 04:42:07 +00:00
|
|
|
documentUrl,
|
2019-04-18 02:11:23 +00:00
|
|
|
documentMoveUrl,
|
2020-08-08 22:18:37 +00:00
|
|
|
editDocumentUrl,
|
2019-04-18 02:11:23 +00:00
|
|
|
documentHistoryUrl,
|
|
|
|
newDocumentUrl,
|
2020-06-20 20:59:15 +00:00
|
|
|
} from "utils/routeHelpers";
|
2017-05-18 02:36:31 +00:00
|
|
|
|
2018-05-05 23:16:08 +00:00
|
|
|
type Props = {
|
|
|
|
ui: UiStore,
|
2018-08-19 23:06:39 +00:00
|
|
|
auth: AuthStore,
|
2020-06-20 20:59:15 +00:00
|
|
|
position?: "left" | "right" | "center",
|
2018-05-05 23:16:08 +00:00
|
|
|
document: Document,
|
2019-04-18 02:11:23 +00:00
|
|
|
collections: CollectionStore,
|
2019-10-06 01:42:03 +00:00
|
|
|
policies: PoliciesStore,
|
2018-05-05 23:16:08 +00:00
|
|
|
className: string,
|
2019-10-16 04:42:07 +00:00
|
|
|
isRevision?: boolean,
|
2018-05-06 05:45:10 +00:00
|
|
|
showPrint?: boolean,
|
2018-12-15 22:06:29 +00:00
|
|
|
showToggleEmbeds?: boolean,
|
2019-04-09 04:47:27 +00:00
|
|
|
showPin?: boolean,
|
2019-07-13 17:15:38 +00:00
|
|
|
onOpen?: () => void,
|
|
|
|
onClose?: () => void,
|
2018-05-05 23:16:08 +00:00
|
|
|
};
|
2017-05-18 02:36:31 +00:00
|
|
|
|
2018-05-05 23:16:08 +00:00
|
|
|
@observer
|
|
|
|
class DocumentMenu extends React.Component<Props> {
|
2019-01-19 08:23:39 +00:00
|
|
|
@observable redirectTo: ?string;
|
2020-08-12 17:49:15 +00:00
|
|
|
@observable showDeleteModal = false;
|
|
|
|
@observable showTemplateModal = false;
|
|
|
|
@observable showShareModal = false;
|
2019-01-19 08:23:39 +00:00
|
|
|
|
2019-01-19 09:31:34 +00:00
|
|
|
componentDidUpdate() {
|
|
|
|
this.redirectTo = undefined;
|
|
|
|
}
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleNewChild = (ev: SyntheticEvent<>) => {
|
2019-01-19 08:23:39 +00:00
|
|
|
const { document } = this.props;
|
2020-08-08 22:18:37 +00:00
|
|
|
this.redirectTo = newDocumentUrl(document.collectionId, {
|
|
|
|
parentDocumentId: document.id,
|
|
|
|
});
|
2017-05-18 02:36:31 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleDelete = (ev: SyntheticEvent<>) => {
|
2020-08-08 22:18:37 +00:00
|
|
|
this.showDeleteModal = true;
|
2017-05-18 02:36:31 +00:00
|
|
|
};
|
|
|
|
|
2018-09-30 04:24:07 +00:00
|
|
|
handleDocumentHistory = () => {
|
2019-10-16 04:42:07 +00:00
|
|
|
if (this.props.isRevision) {
|
|
|
|
this.redirectTo = documentUrl(this.props.document);
|
|
|
|
} else {
|
|
|
|
this.redirectTo = documentHistoryUrl(this.props.document);
|
|
|
|
}
|
2018-09-30 04:24:07 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleMove = (ev: SyntheticEvent<>) => {
|
2019-01-19 08:23:39 +00:00
|
|
|
this.redirectTo = documentMoveUrl(this.props.document);
|
2017-09-15 04:59:59 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleEdit = (ev: SyntheticEvent<>) => {
|
2020-08-08 22:18:37 +00:00
|
|
|
this.redirectTo = editDocumentUrl(this.props.document);
|
2019-08-09 03:00:56 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleDuplicate = async (ev: SyntheticEvent<>) => {
|
2018-07-21 19:55:40 +00:00
|
|
|
const duped = await this.props.document.duplicate();
|
2019-04-06 23:20:27 +00:00
|
|
|
|
|
|
|
// when duplicating, go straight to the duplicated document content
|
2019-01-19 08:23:39 +00:00
|
|
|
this.redirectTo = duped.url;
|
2020-06-20 20:59:15 +00:00
|
|
|
this.props.ui.showToast("Document duplicated");
|
2019-04-06 23:20:27 +00:00
|
|
|
};
|
|
|
|
|
2020-08-08 22:18:37 +00:00
|
|
|
handleOpenTemplateModal = () => {
|
|
|
|
this.showTemplateModal = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCloseTemplateModal = () => {
|
|
|
|
this.showTemplateModal = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCloseDeleteModal = () => {
|
|
|
|
this.showDeleteModal = false;
|
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleArchive = async (ev: SyntheticEvent<>) => {
|
2019-04-06 23:20:27 +00:00
|
|
|
await this.props.document.archive();
|
2020-06-20 20:59:15 +00:00
|
|
|
this.props.ui.showToast("Document archived");
|
2019-04-06 23:20:27 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleRestore = async (ev: SyntheticEvent<>) => {
|
2019-04-06 23:20:27 +00:00
|
|
|
await this.props.document.restore();
|
2020-06-20 20:59:15 +00:00
|
|
|
this.props.ui.showToast("Document restored");
|
2018-06-05 13:57:26 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handlePin = (ev: SyntheticEvent<>) => {
|
2018-03-01 07:28:36 +00:00
|
|
|
this.props.document.pin();
|
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleUnpin = (ev: SyntheticEvent<>) => {
|
2018-03-01 07:28:36 +00:00
|
|
|
this.props.document.unpin();
|
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleStar = (ev: SyntheticEvent<>) => {
|
2019-10-16 06:14:14 +00:00
|
|
|
ev.stopPropagation();
|
2017-09-15 04:59:59 +00:00
|
|
|
this.props.document.star();
|
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleUnstar = (ev: SyntheticEvent<>) => {
|
2019-10-16 06:14:14 +00:00
|
|
|
ev.stopPropagation();
|
2017-09-15 04:59:59 +00:00
|
|
|
this.props.document.unstar();
|
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleExport = (ev: SyntheticEvent<>) => {
|
2017-09-09 23:55:02 +00:00
|
|
|
this.props.document.download();
|
2017-05-18 02:36:31 +00:00
|
|
|
};
|
|
|
|
|
2019-08-09 06:09:09 +00:00
|
|
|
handleShareLink = async (ev: SyntheticEvent<>) => {
|
2018-05-17 06:07:33 +00:00
|
|
|
const { document } = this.props;
|
2020-07-29 02:14:32 +00:00
|
|
|
await document.share();
|
2020-08-12 17:49:15 +00:00
|
|
|
this.showShareModal = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCloseShareModal = () => {
|
|
|
|
this.showShareModal = false;
|
2018-05-17 06:07:33 +00:00
|
|
|
};
|
|
|
|
|
2017-05-18 02:36:31 +00:00
|
|
|
render() {
|
2019-01-26 13:01:33 +00:00
|
|
|
if (this.redirectTo) return <Redirect to={this.redirectTo} push />;
|
2019-01-19 08:23:39 +00:00
|
|
|
|
2019-07-13 17:15:38 +00:00
|
|
|
const {
|
2019-10-06 01:42:03 +00:00
|
|
|
policies,
|
2019-07-13 17:15:38 +00:00
|
|
|
document,
|
|
|
|
position,
|
|
|
|
className,
|
2020-04-22 04:43:01 +00:00
|
|
|
showToggleEmbeds,
|
2019-07-13 17:15:38 +00:00
|
|
|
showPrint,
|
|
|
|
showPin,
|
|
|
|
auth,
|
|
|
|
onOpen,
|
|
|
|
onClose,
|
|
|
|
} = this.props;
|
2019-10-06 01:42:03 +00:00
|
|
|
|
|
|
|
const can = policies.abilities(document.id);
|
|
|
|
const canShareDocuments = can.share && auth.team && auth.team.sharing;
|
2019-11-19 02:51:32 +00:00
|
|
|
const canViewHistory = can.read && !can.restore;
|
2019-04-06 23:20:27 +00:00
|
|
|
|
2017-09-09 23:55:02 +00:00
|
|
|
return (
|
2020-08-09 16:48:04 +00:00
|
|
|
<>
|
2020-08-08 22:18:37 +00:00
|
|
|
<DropdownMenu
|
|
|
|
className={className}
|
|
|
|
position={position}
|
|
|
|
onOpen={onOpen}
|
|
|
|
onClose={onClose}
|
|
|
|
>
|
|
|
|
{(can.unarchive || can.restore) && (
|
|
|
|
<DropdownMenuItem onClick={this.handleRestore}>
|
|
|
|
Restore
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{showPin &&
|
|
|
|
(document.pinned
|
|
|
|
? can.unpin && (
|
|
|
|
<DropdownMenuItem onClick={this.handleUnpin}>
|
|
|
|
Unpin
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)
|
|
|
|
: can.pin && (
|
|
|
|
<DropdownMenuItem onClick={this.handlePin}>
|
|
|
|
Pin to collection
|
|
|
|
</DropdownMenuItem>
|
|
|
|
))}
|
|
|
|
{document.isStarred
|
|
|
|
? can.unstar && (
|
|
|
|
<DropdownMenuItem onClick={this.handleUnstar}>
|
|
|
|
Unstar
|
2019-04-09 04:47:27 +00:00
|
|
|
</DropdownMenuItem>
|
2019-10-06 01:42:03 +00:00
|
|
|
)
|
2020-08-08 22:18:37 +00:00
|
|
|
: can.star && (
|
|
|
|
<DropdownMenuItem onClick={this.handleStar}>
|
|
|
|
Star
|
2019-04-09 04:47:27 +00:00
|
|
|
</DropdownMenuItem>
|
2020-08-08 22:18:37 +00:00
|
|
|
)}
|
|
|
|
{canShareDocuments && (
|
|
|
|
<DropdownMenuItem
|
|
|
|
onClick={this.handleShareLink}
|
|
|
|
title="Create a public share link"
|
|
|
|
>
|
|
|
|
Share link…
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{showToggleEmbeds && (
|
2020-08-09 16:48:04 +00:00
|
|
|
<>
|
2020-08-08 22:18:37 +00:00
|
|
|
{document.embedsDisabled ? (
|
|
|
|
<DropdownMenuItem onClick={document.enableEmbeds}>
|
|
|
|
Enable embeds
|
|
|
|
</DropdownMenuItem>
|
|
|
|
) : (
|
|
|
|
<DropdownMenuItem onClick={document.disableEmbeds}>
|
|
|
|
Disable embeds
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
2020-08-09 16:48:04 +00:00
|
|
|
</>
|
2020-08-08 22:18:37 +00:00
|
|
|
)}
|
|
|
|
{!can.restore && <hr />}
|
|
|
|
|
|
|
|
{can.createChildDocument && (
|
|
|
|
<DropdownMenuItem
|
|
|
|
onClick={this.handleNewChild}
|
|
|
|
title="Create a nested document inside the current document"
|
|
|
|
>
|
|
|
|
New nested document
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
2020-08-09 01:53:11 +00:00
|
|
|
{can.update && !document.isTemplate && (
|
|
|
|
<DropdownMenuItem onClick={this.handleOpenTemplateModal}>
|
|
|
|
Create template…
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
2020-08-08 22:18:37 +00:00
|
|
|
{can.update && (
|
|
|
|
<DropdownMenuItem onClick={this.handleEdit}>Edit</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{can.update && (
|
|
|
|
<DropdownMenuItem onClick={this.handleDuplicate}>
|
|
|
|
Duplicate
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{can.archive && (
|
|
|
|
<DropdownMenuItem onClick={this.handleArchive}>
|
|
|
|
Archive
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{can.delete && (
|
|
|
|
<DropdownMenuItem onClick={this.handleDelete}>
|
|
|
|
Delete…
|
|
|
|
</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
{can.move && (
|
|
|
|
<DropdownMenuItem onClick={this.handleMove}>Move…</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
<hr />
|
|
|
|
{canViewHistory && (
|
2020-08-09 16:48:04 +00:00
|
|
|
<>
|
2020-08-08 22:18:37 +00:00
|
|
|
<DropdownMenuItem onClick={this.handleDocumentHistory}>
|
|
|
|
History
|
2020-04-22 04:43:01 +00:00
|
|
|
</DropdownMenuItem>
|
2020-08-09 16:48:04 +00:00
|
|
|
</>
|
2020-08-08 22:18:37 +00:00
|
|
|
)}
|
|
|
|
{can.download && (
|
|
|
|
<DropdownMenuItem onClick={this.handleExport}>
|
|
|
|
Download
|
2019-11-19 02:51:32 +00:00
|
|
|
</DropdownMenuItem>
|
2020-08-08 22:18:37 +00:00
|
|
|
)}
|
|
|
|
{showPrint && (
|
|
|
|
<DropdownMenuItem onClick={window.print}>Print</DropdownMenuItem>
|
|
|
|
)}
|
|
|
|
</DropdownMenu>
|
|
|
|
<Modal
|
|
|
|
title={`Delete ${this.props.document.noun}`}
|
|
|
|
onRequestClose={this.handleCloseDeleteModal}
|
|
|
|
isOpen={this.showDeleteModal}
|
|
|
|
>
|
|
|
|
<DocumentDelete
|
|
|
|
document={this.props.document}
|
|
|
|
onSubmit={this.handleCloseDeleteModal}
|
|
|
|
/>
|
|
|
|
</Modal>
|
|
|
|
<Modal
|
|
|
|
title="Create template"
|
|
|
|
onRequestClose={this.handleCloseTemplateModal}
|
|
|
|
isOpen={this.showTemplateModal}
|
|
|
|
>
|
|
|
|
<DocumentTemplatize
|
|
|
|
document={this.props.document}
|
|
|
|
onSubmit={this.handleCloseTemplateModal}
|
|
|
|
/>
|
|
|
|
</Modal>
|
2020-08-12 17:49:15 +00:00
|
|
|
<Modal
|
|
|
|
title="Share document"
|
|
|
|
onRequestClose={this.handleCloseShareModal}
|
|
|
|
isOpen={this.showShareModal}
|
|
|
|
>
|
|
|
|
<DocumentShare
|
|
|
|
document={this.props.document}
|
|
|
|
onSubmit={this.handleCloseShareModal}
|
|
|
|
/>
|
|
|
|
</Modal>
|
2020-08-09 16:48:04 +00:00
|
|
|
</>
|
2017-09-09 23:55:02 +00:00
|
|
|
);
|
2017-05-18 02:36:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 20:59:15 +00:00
|
|
|
export default inject("ui", "auth", "collections", "policies")(DocumentMenu);
|