// @flow import { observable } from "mobx"; import { observer, inject } from "mobx-react"; import { NewDocumentIcon, PlusIcon, PinIcon } from "outline-icons"; import * as React from "react"; import { withTranslation, Trans, type TFunction } from "react-i18next"; import { Redirect, Link, Switch, Route, type Match } from "react-router-dom"; import styled, { withTheme } from "styled-components"; import CollectionsStore from "stores/CollectionsStore"; import DocumentsStore from "stores/DocumentsStore"; import PoliciesStore from "stores/PoliciesStore"; import UiStore from "stores/UiStore"; import Collection from "models/Collection"; import CollectionEdit from "scenes/CollectionEdit"; import CollectionMembers from "scenes/CollectionMembers"; import Search from "scenes/Search"; import Actions, { Action, Separator } from "components/Actions"; import Button from "components/Button"; import CenteredContent from "components/CenteredContent"; import CollectionIcon from "components/CollectionIcon"; import DocumentList from "components/DocumentList"; import Editor from "components/Editor"; import Flex from "components/Flex"; import Heading from "components/Heading"; import HelpText from "components/HelpText"; import InputSearch from "components/InputSearch"; import { ListPlaceholder } from "components/LoadingPlaceholder"; import Mask from "components/Mask"; import Modal from "components/Modal"; import PageTitle from "components/PageTitle"; import PaginatedDocumentList from "components/PaginatedDocumentList"; import Subheading from "components/Subheading"; import Tab from "components/Tab"; import Tabs from "components/Tabs"; import Tooltip from "components/Tooltip"; import CollectionMenu from "menus/CollectionMenu"; import { type Theme } from "types"; import { AuthorizationError } from "utils/errors"; import { newDocumentUrl, collectionUrl } from "utils/routeHelpers"; type Props = { ui: UiStore, documents: DocumentsStore, collections: CollectionsStore, policies: PoliciesStore, match: Match, theme: Theme, t: TFunction, }; @observer class CollectionScene extends React.Component { @observable collection: ?Collection; @observable isFetching: boolean = true; @observable permissionsModalOpen: boolean = false; @observable editModalOpen: boolean = false; @observable redirectTo: ?string; componentDidMount() { const { id } = this.props.match.params; if (id) { this.loadContent(id); } } componentDidUpdate(prevProps: Props) { const { id } = this.props.match.params; if (this.collection) { const { collection } = this; const policy = this.props.policies.get(collection.id); if (!policy) { this.loadContent(collection.id); } } if (id && id !== prevProps.match.params.id) { this.loadContent(id); } } componentWillUnmount() { this.props.ui.clearActiveCollection(); } loadContent = async (id: string) => { try { const collection = await this.props.collections.fetch(id); if (collection) { this.props.ui.setActiveCollection(collection); this.collection = collection; await this.props.documents.fetchPinned({ collectionId: id, }); } } catch (error) { if (error instanceof AuthorizationError) { this.collection = null; } } finally { this.isFetching = false; } }; onNewDocument = (ev: SyntheticEvent<>) => { ev.preventDefault(); if (this.collection) { this.redirectTo = newDocumentUrl(this.collection.id); } }; onPermissions = (ev: SyntheticEvent<>) => { ev.preventDefault(); this.permissionsModalOpen = true; }; handlePermissionsModalClose = () => { this.permissionsModalOpen = false; }; handleEditModalOpen = () => { this.editModalOpen = true; }; handleEditModalClose = () => { this.editModalOpen = false; }; renderActions() { const { match, policies, t } = this.props; const can = policies.abilities(match.params.id || ""); return ( {can.update && ( <> )} ); } render() { const { documents, theme, t } = this.props; if (this.redirectTo) return ; if (!this.isFetching && !this.collection) return ; const pinnedDocuments = this.collection ? documents.pinnedInCollection(this.collection.id) : []; const hasPinnedDocuments = !!pinnedDocuments.length; const collection = this.collection; const collectionName = collection ? collection.name : ""; return ( {collection ? ( <> {collection.isEmpty ? ( {{ collectionName }} doesn’t contain any documents yet.
Get started by creating a new one!
   {collection.private && ( )}
) : ( <> {" "} {collection.name} {collection.description && ( Loading…

}>
)} {hasPinnedDocuments && ( <> {t("Pinned")} )} {t("Recently updated")} {t("Recently published")} {t("Least recently updated")} {t("A–Z")} )} {this.renderActions()} ) : ( <> )}
); } } 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 Wrapper = styled(Flex)` justify-content: center; margin: 10px 0; `; export default withTranslation()( inject( "collections", "policies", "documents", "ui" )(withTheme(CollectionScene)) );