// @flow
import { observer } from "mobx-react";
import { NewDocumentIcon, PlusIcon, PinIcon, MoreIcon } from "outline-icons";
import * as React from "react";
import Dropzone from "react-dropzone";
import { useTranslation, Trans } from "react-i18next";
import {
useParams,
Redirect,
Link,
Switch,
Route,
useHistory,
useRouteMatch,
} from "react-router-dom";
import styled, { css } from "styled-components";
import CollectionPermissions from "scenes/CollectionPermissions";
import Search from "scenes/Search";
import { Action, Separator } from "components/Actions";
import Badge from "components/Badge";
import Button from "components/Button";
import CenteredContent from "components/CenteredContent";
import CollectionDescription from "components/CollectionDescription";
import CollectionIcon from "components/CollectionIcon";
import DocumentList from "components/DocumentList";
import Flex from "components/Flex";
import Heading from "components/Heading";
import HelpText from "components/HelpText";
import InputSearchPage from "components/InputSearchPage";
import PlaceholderList from "components/List/Placeholder";
import LoadingIndicator from "components/LoadingIndicator";
import Modal from "components/Modal";
import PaginatedDocumentList from "components/PaginatedDocumentList";
import PlaceholderText from "components/PlaceholderText";
import Scene from "components/Scene";
import Subheading from "components/Subheading";
import Tab from "components/Tab";
import Tabs from "components/Tabs";
import Tooltip from "components/Tooltip";
import Collection from "../models/Collection";
import { updateCollectionUrl } from "../utils/routeHelpers";
import useBoolean from "hooks/useBoolean";
import useCurrentTeam from "hooks/useCurrentTeam";
import useImportDocument from "hooks/useImportDocument";
import useStores from "hooks/useStores";
import useToasts from "hooks/useToasts";
import CollectionMenu from "menus/CollectionMenu";
import { newDocumentUrl, collectionUrl } from "utils/routeHelpers";
function CollectionScene() {
const params = useParams();
const history = useHistory();
const match = useRouteMatch();
const { t } = useTranslation();
const { documents, policies, collections, ui } = useStores();
const { showToast } = useToasts();
const team = useCurrentTeam();
const [isFetching, setFetching] = React.useState();
const [error, setError] = React.useState();
const [
permissionsModalOpen,
handlePermissionsModalOpen,
handlePermissionsModalClose,
] = useBoolean();
const id = params.id || "";
const collection: ?Collection =
collections.getByUrl(id) || collections.get(id);
const can = policies.abilities(collection?.id || "");
const canUser = policies.abilities(team.id);
const { handleFiles, isImporting } = useImportDocument(collection?.id || "");
React.useEffect(() => {
if (collection) {
const canonicalUrl = updateCollectionUrl(match.url, collection);
if (match.url !== canonicalUrl) {
history.replace(canonicalUrl);
}
}
}, [collection, history, id, match.url]);
React.useEffect(() => {
if (collection) {
ui.setActiveCollection(collection);
}
}, [ui, collection]);
React.useEffect(() => {
setError(null);
if (collection) {
documents.fetchPinned({ collectionId: collection.id });
}
}, [documents, collection]);
React.useEffect(() => {
async function load() {
if ((!can || !collection) && !error && !isFetching) {
try {
setError(null);
setFetching(true);
await collections.fetch(id);
} catch (err) {
setError(err);
} finally {
setFetching(false);
}
}
}
load();
}, [collections, isFetching, collection, error, id, can]);
const handleRejection = React.useCallback(() => {
showToast(
t("Document not supported – try Markdown, Plain text, HTML, or Word"),
{ type: "error" }
);
}, [t, showToast]);
if (!collection && error) {
return ;
}
const pinnedDocuments = collection
? documents.pinnedInCollection(collection.id)
: [];
const collectionName = collection ? collection.name : "";
const hasPinnedDocuments = !!pinnedDocuments.length;
return collection ? (
{collection.name}
>
}
actions={
<>
{can.update && (
<>
}
>
{t("New doc")}
>
)}
(
}
{...props}
borderOnHover
neutral
small
/>
)}
/>
>
}
>
{({
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject,
}) => (
{isImporting && }
{collection.isEmpty ? (
}}
/>
{canUser.createDocument && (
Get started by creating a new one!
)}
{canUser.createDocument && (
}>
{t("Create a document")}
)}
) : (
<>
{" "}
{collection.name}{" "}
{!collection.permission && (
{t("Private")}
)}
{hasPinnedDocuments && (
<>
{" "}
{t("Pinned")}
>
)}
{t("Documents")}
{t("Recently updated")}
{t("Recently published")}
{t("Least recently updated")}
{t("A–Z")}
>
)}
{t("Drop documents to import")}
)}
) : (
);
}
const DropMessage = styled(HelpText)`
opacity: 0;
pointer-events: none;
`;
const DropzoneContainer = styled.div`
min-height: calc(100% - 56px);
position: relative;
${({ isDragActive, theme }) =>
isDragActive &&
css`
&:after {
display: block;
content: "";
position: absolute;
top: 24px;
right: 24px;
bottom: 24px;
left: 24px;
background: ${theme.background};
border-radius: 8px;
border: 1px dashed ${theme.divider};
z-index: 1;
}
${DropMessage} {
opacity: 1;
z-index: 2;
position: absolute;
text-align: center;
top: 50%;
left: 50%;
transform: translateX(-50%);
}
`}
`;
const Centered = styled(Flex)`
text-align: center;
margin: 40vh auto 0;
max-width: 380px;
transform: translateY(-50%);
`;
const TinyPinIcon = styled(PinIcon)`
position: relative;
top: 4px;
opacity: 0.8;
`;
const Empty = styled(Flex)`
justify-content: center;
margin: 10px 0;
`;
export default observer(CollectionScene);