feat: Command Bar (#2669)

This commit is contained in:
Tom Moor
2021-10-24 12:30:27 -07:00
committed by GitHub
parent dc92e1ead4
commit 33b6fbdee9
55 changed files with 1373 additions and 400 deletions

View File

@@ -4,9 +4,10 @@ import { ArchiveIcon } from "outline-icons";
import * as React from "react";
import { useDrop } from "react-dnd";
import { useTranslation } from "react-i18next";
import useStores from "../../../hooks/useStores";
import SidebarLink from "./SidebarLink";
import useStores from "hooks/useStores";
import useToasts from "hooks/useToasts";
import { archivePath } from "utils/routeHelpers";
function ArchiveLink({ documents }) {
const { policies } = useStores();
@@ -29,7 +30,7 @@ function ArchiveLink({ documents }) {
return (
<div ref={dropToArchiveDocument}>
<SidebarLink
to="/archive"
to={archivePath()}
icon={<ArchiveIcon color="currentColor" open={isDocumentDropping} />}
exact={false}
label={t("Archive")}

View File

@@ -1,7 +1,7 @@
// @flow
import fractionalIndex from "fractional-index";
import { observer } from "mobx-react";
import { PlusIcon, CollapsedIcon } from "outline-icons";
import { CollapsedIcon } from "outline-icons";
import * as React from "react";
import { useDrop } from "react-dnd";
import { useTranslation } from "react-i18next";
@@ -12,15 +12,12 @@ import useStores from "../../../hooks/useStores";
import CollectionLink from "./CollectionLink";
import DropCursor from "./DropCursor";
import PlaceholderCollections from "./PlaceholderCollections";
import SidebarAction from "./SidebarAction";
import SidebarLink from "./SidebarLink";
import useCurrentTeam from "hooks/useCurrentTeam";
import { createCollection } from "actions/definitions/collections";
import useToasts from "hooks/useToasts";
type Props = {
onCreateCollection: () => void,
};
function Collections({ onCreateCollection }: Props) {
function Collections() {
const [isFetching, setFetching] = React.useState(false);
const [fetchError, setFetchError] = React.useState();
const { ui, policies, documents, collections } = useStores();
@@ -28,9 +25,7 @@ function Collections({ onCreateCollection }: Props) {
const [expanded, setExpanded] = React.useState(true);
const isPreloaded: boolean = !!collections.orderedData.length;
const { t } = useTranslation();
const team = useCurrentTeam();
const orderedCollections = collections.orderedData;
const can = policies.abilities(team.id);
const [isDraggingAnyCollection, setIsDraggingAnyCollection] = React.useState(
false
);
@@ -93,16 +88,7 @@ function Collections({ onCreateCollection }: Props) {
belowCollection={orderedCollections[index + 1]}
/>
))}
{can.createCollection && (
<SidebarLink
to="/collections"
onClick={onCreateCollection}
icon={<PlusIcon color="currentColor" />}
label={`${t("New collection")}`}
exact
depth={0.5}
/>
)}
<SidebarAction action={createCollection} depth={0.5} />
</>
);

View File

@@ -0,0 +1,44 @@
// @flow
import invariant from "invariant";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router";
import SidebarLink from "./SidebarLink";
import { actionToMenuItem } from "actions";
import useStores from "hooks/useStores";
import type { Action } from "types";
type Props = {|
action: Action,
|};
function SidebarAction({ action, ...rest }: Props) {
const stores = useStores();
const { t } = useTranslation();
const location = useLocation();
const context = {
isContextMenu: false,
isCommandBar: false,
activeCollectionId: undefined,
activeDocumentId: undefined,
location,
stores,
t,
};
const menuItem = actionToMenuItem(action, context);
invariant(menuItem.onClick, "passed action must have perform");
return (
<SidebarLink
onClick={menuItem.onClick}
icon={menuItem.icon}
label={menuItem.title}
{...rest}
/>
);
}
export default observer(SidebarAction);

View File

@@ -7,8 +7,9 @@ import { useDrop } from "react-dnd";
import { useTranslation } from "react-i18next";
import DocumentDelete from "scenes/DocumentDelete";
import Modal from "components/Modal";
import useStores from "../../../hooks/useStores";
import SidebarLink from "./SidebarLink";
import useStores from "hooks/useStores";
import { trashPath } from "utils/routeHelpers";
function TrashLink({ documents }) {
const { policies } = useStores();
@@ -33,7 +34,7 @@ function TrashLink({ documents }) {
<>
<div ref={dropToTrashDocument}>
<SidebarLink
to="/trash"
to={trashPath()}
icon={<TrashIcon color="currentColor" open={isDocumentDropping} />}
exact={false}
label={t("Trash")}