diff --git a/app/menus/DocumentMenu.js b/app/menus/DocumentMenu.js
index 73b60a432..f128e0b87 100644
--- a/app/menus/DocumentMenu.js
+++ b/app/menus/DocumentMenu.js
@@ -4,6 +4,7 @@ import * as React from "react";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { useMenuState, MenuButton } from "reakit/Menu";
+import { VisuallyHidden } from "reakit/VisuallyHidden";
import styled from "styled-components";
import Document from "models/Document";
import DocumentDelete from "scenes/DocumentDelete";
@@ -17,6 +18,7 @@ import Flex from "components/Flex";
import Modal from "components/Modal";
import useCurrentTeam from "hooks/useCurrentTeam";
import useStores from "hooks/useStores";
+import getDataTransferFiles from "utils/getDataTransferFiles";
import {
documentHistoryUrl,
documentMoveUrl,
@@ -51,7 +53,7 @@ function DocumentMenu({
onClose,
}: Props) {
const team = useCurrentTeam();
- const { policies, collections, ui } = useStores();
+ const { policies, collections, ui, documents } = useStores();
const menu = useMenuState({ modal });
const history = useHistory();
const { t } = useTranslation();
@@ -59,6 +61,7 @@ function DocumentMenu({
const [showDeleteModal, setShowDeleteModal] = React.useState(false);
const [showTemplateModal, setShowTemplateModal] = React.useState(false);
const [showShareModal, setShowShareModal] = React.useState(false);
+ const file = React.useRef();
const handleOpen = React.useCallback(() => {
setRenderModals(true);
@@ -137,8 +140,71 @@ function DocumentMenu({
const canShareDocuments = !!(can.share && team.sharing);
const canViewHistory = can.read && !can.restore;
+ const stopPropagation = React.useCallback((ev: SyntheticEvent<>) => {
+ ev.stopPropagation();
+ }, []);
+
+ const handleImportDocument = React.useCallback(
+ (ev: SyntheticEvent<>) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ // simulate a click on the file upload input element
+ if (file.current) {
+ file.current.click();
+ }
+ },
+ [file]
+ );
+
+ const handleFilePicked = React.useCallback(
+ async (ev: SyntheticEvent<>) => {
+ const files = getDataTransferFiles(ev);
+
+ // Because this is the onChange handler it's possible for the change to be
+ // from previously selecting a file to not selecting a file – aka empty
+ if (!files.length) {
+ return;
+ }
+
+ if (!collection) {
+ return;
+ }
+
+ try {
+ const file = files[0];
+ const importedDocument = await documents.import(
+ file,
+ document.id,
+ collection.id,
+ {
+ publish: true,
+ }
+ );
+ history.push(importedDocument.url);
+ } catch (err) {
+ ui.showToast(err.message, {
+ type: "error",
+ });
+
+ throw err;
+ }
+ },
+ [history, ui, collection, documents, document.id]
+ );
+
return (
<>
+
+
+
{label ? (
{label}
) : (
@@ -243,6 +309,11 @@ function DocumentMenu({
}),
visible: !!can.createChildDocument,
},
+ {
+ title: t("Import document"),
+ visible: can.createChildDocument,
+ onClick: handleImportDocument,
+ },
{
title: `${t("Create template")}…`,
onClick: () => setShowTemplateModal(true),