diff --git a/app/components/ContextMenu/MenuItem.tsx b/app/components/ContextMenu/MenuItem.tsx
index 372141c8b..59416e54b 100644
--- a/app/components/ContextMenu/MenuItem.tsx
+++ b/app/components/ContextMenu/MenuItem.tsx
@@ -11,6 +11,7 @@ type Props = {
children?: React.ReactNode;
selected?: boolean;
disabled?: boolean;
+ dangerous?: boolean;
to?: string;
href?: string;
target?: "_blank";
@@ -92,7 +93,11 @@ const Spacer = styled.svg`
flex-shrink: 0;
`;
-export const MenuAnchorCSS = css<{ level?: number; disabled?: boolean }>`
+export const MenuAnchorCSS = css<{
+ level?: number;
+ disabled?: boolean;
+ dangerous?: boolean;
+}>`
display: flex;
margin: 0;
border: 0;
@@ -128,7 +133,7 @@ export const MenuAnchorCSS = css<{ level?: number; disabled?: boolean }>`
&:focus,
&.focus-visible {
color: ${props.theme.white};
- background: ${props.theme.primary};
+ background: ${props.dangerous ? props.theme.danger : props.theme.primary};
box-shadow: none;
cursor: pointer;
diff --git a/app/components/ContextMenu/Template.tsx b/app/components/ContextMenu/Template.tsx
index 981b58690..185fd77da 100644
--- a/app/components/ContextMenu/Template.tsx
+++ b/app/components/ContextMenu/Template.tsx
@@ -163,6 +163,7 @@ function Template({ items, actions, context, ...menu }: Props) {
onClick={item.onClick}
disabled={item.disabled}
selected={item.selected}
+ dangerous={item.dangerous}
key={index}
icon={item.icon}
{...menu}
diff --git a/app/menus/CollectionGroupMemberMenu.tsx b/app/menus/CollectionGroupMemberMenu.tsx
index 15065bbe2..97c8078eb 100644
--- a/app/menus/CollectionGroupMemberMenu.tsx
+++ b/app/menus/CollectionGroupMemberMenu.tsx
@@ -34,6 +34,7 @@ function CollectionGroupMemberMenu({ onMembers, onRemove }: Props) {
{
type: "button",
title: t("Remove"),
+ dangerous: true,
onClick: onRemove,
},
]}
diff --git a/app/menus/CollectionMenu.tsx b/app/menus/CollectionMenu.tsx
index 92ec314bf..2aa28d959 100644
--- a/app/menus/CollectionMenu.tsx
+++ b/app/menus/CollectionMenu.tsx
@@ -171,6 +171,7 @@ function CollectionMenu({
{
type: "button",
title: `${t("Delete")}…`,
+ dangerous: true,
visible: !!(collection && can.delete),
onClick: () => setShowCollectionDelete(true),
icon: ,
diff --git a/app/menus/DocumentMenu.tsx b/app/menus/DocumentMenu.tsx
index a648e20bf..bf3731a3d 100644
--- a/app/menus/DocumentMenu.tsx
+++ b/app/menus/DocumentMenu.tsx
@@ -385,9 +385,17 @@ function DocumentMenu({
visible: !!can.archive,
icon: ,
},
+ {
+ type: "button",
+ title: `${t("Move")}…`,
+ onClick: () => setShowMoveModal(true),
+ visible: !!can.move,
+ icon: ,
+ },
{
type: "button",
title: `${t("Delete")}…`,
+ dangerous: true,
onClick: () => setShowDeleteModal(true),
visible: !!can.delete,
icon: ,
@@ -395,17 +403,11 @@ function DocumentMenu({
{
type: "button",
title: `${t("Permanently delete")}…`,
+ dangerous: true,
onClick: () => setShowPermanentDeleteModal(true),
visible: can.permanentDelete,
icon: ,
},
- {
- type: "button",
- title: `${t("Move")}…`,
- onClick: () => setShowMoveModal(true),
- visible: !!can.move,
- icon: ,
- },
{
type: "button",
title: t("Enable embeds"),
diff --git a/app/menus/FileOperationMenu.tsx b/app/menus/FileOperationMenu.tsx
index 6f3098531..7b9b7bcbd 100644
--- a/app/menus/FileOperationMenu.tsx
+++ b/app/menus/FileOperationMenu.tsx
@@ -1,3 +1,4 @@
+import { DownloadIcon, TrashIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useMenuState } from "reakit/Menu";
@@ -26,6 +27,7 @@ function FileOperationMenu({ id, onDelete }: Props) {
{
type: "link",
title: t("Download"),
+ icon: ,
href: "/api/fileOperations.redirect?id=" + id,
},
{
@@ -34,6 +36,8 @@ function FileOperationMenu({ id, onDelete }: Props) {
{
type: "button",
title: t("Delete"),
+ icon: ,
+ dangerous: true,
onClick: onDelete,
},
]}
diff --git a/app/menus/GroupMemberMenu.tsx b/app/menus/GroupMemberMenu.tsx
index 180c048c5..bda9c24eb 100644
--- a/app/menus/GroupMemberMenu.tsx
+++ b/app/menus/GroupMemberMenu.tsx
@@ -24,6 +24,7 @@ function GroupMemberMenu({ onRemove }: Props) {
items={[
{
type: "button",
+ dangerous: true,
title: t("Remove"),
onClick: onRemove,
},
diff --git a/app/menus/GroupMenu.tsx b/app/menus/GroupMenu.tsx
index 0f9a648ed..16b993c8b 100644
--- a/app/menus/GroupMenu.tsx
+++ b/app/menus/GroupMenu.tsx
@@ -1,4 +1,5 @@
import { observer } from "mobx-react";
+import { EditIcon, GroupIcon, TrashIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useMenuState } from "reakit/Menu";
@@ -50,6 +51,7 @@ function GroupMenu({ group, onMembers }: Props) {
{
type: "button",
title: `${t("Members")}…`,
+ icon: ,
onClick: onMembers,
visible: !!(group && can.read),
},
@@ -59,12 +61,15 @@ function GroupMenu({ group, onMembers }: Props) {
{
type: "button",
title: `${t("Edit")}…`,
+ icon: ,
onClick: () => setEditModalOpen(true),
visible: !!(group && can.update),
},
{
type: "button",
title: `${t("Delete")}…`,
+ icon: ,
+ dangerous: true,
onClick: () => setDeleteModalOpen(true),
visible: !!(group && can.delete),
},
diff --git a/app/menus/MemberMenu.tsx b/app/menus/MemberMenu.tsx
index cf15d7dbd..038149b82 100644
--- a/app/menus/MemberMenu.tsx
+++ b/app/menus/MemberMenu.tsx
@@ -24,6 +24,7 @@ function MemberMenu({ onRemove }: Props) {
{
type: "button",
title: t("Remove"),
+ dangerous: true,
onClick: onRemove,
},
]}
diff --git a/app/menus/ShareMenu.tsx b/app/menus/ShareMenu.tsx
index c0888da82..0747eb0ba 100644
--- a/app/menus/ShareMenu.tsx
+++ b/app/menus/ShareMenu.tsx
@@ -1,4 +1,5 @@
import { observer } from "mobx-react";
+import { ArrowIcon, CopyIcon, TrashIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
@@ -62,15 +63,22 @@ function ShareMenu({ share }: Props) {
-
+ }>
+ {t("Copy link")}
+
-
{can.revoke && (
<>
-
+ }
+ dangerous
+ >
{t("Revoke link")}
>
diff --git a/app/menus/UserMenu.tsx b/app/menus/UserMenu.tsx
index 74bd4ccdc..f8acc85e4 100644
--- a/app/menus/UserMenu.tsx
+++ b/app/menus/UserMenu.tsx
@@ -157,6 +157,7 @@ function UserMenu({ user }: Props) {
{
type: "button",
title: `${t("Revoke invite")}…`,
+ dangerous: true,
onClick: handleRevoke,
visible: user.isInvited,
},
@@ -169,6 +170,7 @@ function UserMenu({ user }: Props) {
{
type: "button",
title: `${t("Suspend account")}…`,
+ dangerous: true,
onClick: handleSuspend,
visible: !user.isInvited && !user.isSuspended,
},
diff --git a/app/types.ts b/app/types.ts
index ea7960a9d..6563d7edc 100644
--- a/app/types.ts
+++ b/app/types.ts
@@ -7,6 +7,7 @@ export type MenuItemButton = {
type: "button";
title: React.ReactNode;
onClick: React.MouseEventHandler;
+ dangerous?: boolean;
visible?: boolean;
selected?: boolean;
disabled?: boolean;