feat: Templates (#1399)
* Migrations * New from template * fix: Don't allow public share of template * chore: Template badges * fix: Collection active * feat: New doc button on template list item * feat: New template menu * fix: Sorting * feat: Templates onboarding notice * fix: New doc button showing on archived/deleted templates
This commit is contained in:
@@ -9,10 +9,13 @@ import UiStore from "stores/UiStore";
|
||||
import AuthStore from "stores/AuthStore";
|
||||
import CollectionStore from "stores/CollectionsStore";
|
||||
import PoliciesStore from "stores/PoliciesStore";
|
||||
import Modal from "components/Modal";
|
||||
import DocumentDelete from "scenes/DocumentDelete";
|
||||
import DocumentTemplatize from "scenes/DocumentTemplatize";
|
||||
import {
|
||||
documentUrl,
|
||||
documentMoveUrl,
|
||||
documentEditUrl,
|
||||
editDocumentUrl,
|
||||
documentHistoryUrl,
|
||||
newDocumentUrl,
|
||||
} from "utils/routeHelpers";
|
||||
@@ -37,6 +40,8 @@ type Props = {
|
||||
@observer
|
||||
class DocumentMenu extends React.Component<Props> {
|
||||
@observable redirectTo: ?string;
|
||||
@observable showDeleteModal: boolean = false;
|
||||
@observable showTemplateModal: boolean = false;
|
||||
|
||||
componentDidUpdate() {
|
||||
this.redirectTo = undefined;
|
||||
@@ -44,12 +49,13 @@ class DocumentMenu extends React.Component<Props> {
|
||||
|
||||
handleNewChild = (ev: SyntheticEvent<>) => {
|
||||
const { document } = this.props;
|
||||
this.redirectTo = newDocumentUrl(document.collectionId, document.id);
|
||||
this.redirectTo = newDocumentUrl(document.collectionId, {
|
||||
parentDocumentId: document.id,
|
||||
});
|
||||
};
|
||||
|
||||
handleDelete = (ev: SyntheticEvent<>) => {
|
||||
const { document } = this.props;
|
||||
this.props.ui.setActiveModal("document-delete", { document });
|
||||
this.showDeleteModal = true;
|
||||
};
|
||||
|
||||
handleDocumentHistory = () => {
|
||||
@@ -65,7 +71,7 @@ class DocumentMenu extends React.Component<Props> {
|
||||
};
|
||||
|
||||
handleEdit = (ev: SyntheticEvent<>) => {
|
||||
this.redirectTo = documentEditUrl(this.props.document);
|
||||
this.redirectTo = editDocumentUrl(this.props.document);
|
||||
};
|
||||
|
||||
handleDuplicate = async (ev: SyntheticEvent<>) => {
|
||||
@@ -76,6 +82,18 @@ class DocumentMenu extends React.Component<Props> {
|
||||
this.props.ui.showToast("Document duplicated");
|
||||
};
|
||||
|
||||
handleOpenTemplateModal = () => {
|
||||
this.showTemplateModal = true;
|
||||
};
|
||||
|
||||
handleCloseTemplateModal = () => {
|
||||
this.showTemplateModal = false;
|
||||
};
|
||||
|
||||
handleCloseDeleteModal = () => {
|
||||
this.showDeleteModal = false;
|
||||
};
|
||||
|
||||
handleArchive = async (ev: SyntheticEvent<>) => {
|
||||
await this.props.document.archive();
|
||||
this.props.ui.showToast("Document archived");
|
||||
@@ -135,108 +153,137 @@ class DocumentMenu extends React.Component<Props> {
|
||||
const canViewHistory = can.read && !can.restore;
|
||||
|
||||
return (
|
||||
<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
|
||||
<React.Fragment>
|
||||
<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
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
: can.pin && (
|
||||
<DropdownMenuItem onClick={this.handlePin}>
|
||||
Pin to collection
|
||||
: can.star && (
|
||||
<DropdownMenuItem onClick={this.handleStar}>
|
||||
Star
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
{document.isStarred
|
||||
? can.unstar && (
|
||||
<DropdownMenuItem onClick={this.handleUnstar}>
|
||||
Unstar
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
: can.star && (
|
||||
<DropdownMenuItem onClick={this.handleStar}>
|
||||
Star
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{canShareDocuments && (
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleShareLink}
|
||||
title="Create a public share link"
|
||||
>
|
||||
Share link…
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{showToggleEmbeds && (
|
||||
<React.Fragment>
|
||||
{document.embedsDisabled ? (
|
||||
<DropdownMenuItem onClick={document.enableEmbeds}>
|
||||
Enable embeds
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem onClick={document.disableEmbeds}>
|
||||
Disable embeds
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
{canViewHistory && (
|
||||
<React.Fragment>
|
||||
<hr />
|
||||
<DropdownMenuItem onClick={this.handleDocumentHistory}>
|
||||
Document history
|
||||
)}
|
||||
{canShareDocuments && (
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleShareLink}
|
||||
title="Create a public share link"
|
||||
>
|
||||
Share link…
|
||||
</DropdownMenuItem>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{can.createChildDocument && (
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleNewChild}
|
||||
title="Create a nested document inside the current document"
|
||||
>
|
||||
New nested document
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{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 />
|
||||
{can.download && (
|
||||
<DropdownMenuItem onClick={this.handleExport}>
|
||||
Download
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{showPrint && (
|
||||
<DropdownMenuItem onClick={window.print}>Print</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenu>
|
||||
)}
|
||||
{showToggleEmbeds && (
|
||||
<React.Fragment>
|
||||
{document.embedsDisabled ? (
|
||||
<DropdownMenuItem onClick={document.enableEmbeds}>
|
||||
Enable embeds
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem onClick={document.disableEmbeds}>
|
||||
Disable embeds
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!can.restore && <hr />}
|
||||
|
||||
{can.createChildDocument && (
|
||||
<DropdownMenuItem
|
||||
onClick={this.handleNewChild}
|
||||
title="Create a nested document inside the current document"
|
||||
>
|
||||
New nested document
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{can.update &&
|
||||
!document.isTemplate && (
|
||||
<DropdownMenuItem onClick={this.handleOpenTemplateModal}>
|
||||
Create template…
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{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 && (
|
||||
<React.Fragment>
|
||||
<DropdownMenuItem onClick={this.handleDocumentHistory}>
|
||||
History
|
||||
</DropdownMenuItem>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{can.download && (
|
||||
<DropdownMenuItem onClick={this.handleExport}>
|
||||
Download
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{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>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user