mirror of
https://github.com/outline/outline.git
synced 2025-12-21 10:39:41 -06:00
fix: Cannot ctrl-click to open in a new tab some menu items (#9542)
* wip * done
This commit is contained in:
@@ -47,7 +47,7 @@ export const openCollection = createAction({
|
||||
name: collection.name,
|
||||
icon: <ColorCollectionIcon collection={collection} />,
|
||||
section: CollectionSection,
|
||||
perform: () => history.push(collection.path),
|
||||
to: collection.path,
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -98,7 +98,7 @@ export const openDocument = createAction({
|
||||
<DocumentIcon />
|
||||
),
|
||||
section: DocumentSection,
|
||||
perform: () => history.push(item.url),
|
||||
to: item.url,
|
||||
}));
|
||||
},
|
||||
});
|
||||
@@ -840,7 +840,7 @@ export const searchDocumentsForQuery = (query: string) =>
|
||||
analyticsName: "Search documents",
|
||||
section: DocumentSection,
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath({ query })),
|
||||
to: searchPath({ query }),
|
||||
visible: ({ location }) => location.pathname !== searchPath(),
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import KeyboardShortcuts from "~/scenes/KeyboardShortcuts";
|
||||
import { createAction } from "~/actions";
|
||||
import { NavigationSection, RecentSearchesSection } from "~/actions/sections";
|
||||
import Desktop from "~/utils/Desktop";
|
||||
import history from "~/utils/history";
|
||||
import isCloudHosted from "~/utils/isCloudHosted";
|
||||
import {
|
||||
homePath,
|
||||
@@ -38,7 +37,7 @@ export const navigateToHome = createAction({
|
||||
section: NavigationSection,
|
||||
shortcut: ["d"],
|
||||
icon: <HomeIcon />,
|
||||
perform: () => history.push(homePath()),
|
||||
to: homePath(),
|
||||
visible: ({ location }) => location.pathname !== homePath(),
|
||||
});
|
||||
|
||||
@@ -48,7 +47,7 @@ export const navigateToRecentSearchQuery = (searchQuery: SearchQuery) =>
|
||||
name: searchQuery.query,
|
||||
analyticsName: "Navigate to recent search query",
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath({ query: searchQuery.query })),
|
||||
to: searchPath({ query: searchQuery.query }),
|
||||
});
|
||||
|
||||
export const navigateToDrafts = createAction({
|
||||
@@ -56,7 +55,7 @@ export const navigateToDrafts = createAction({
|
||||
analyticsName: "Navigate to drafts",
|
||||
section: NavigationSection,
|
||||
icon: <DraftsIcon />,
|
||||
perform: () => history.push(draftsPath()),
|
||||
to: draftsPath(),
|
||||
visible: ({ location }) => location.pathname !== draftsPath(),
|
||||
});
|
||||
|
||||
@@ -65,7 +64,7 @@ export const navigateToSearch = createAction({
|
||||
analyticsName: "Navigate to search",
|
||||
section: NavigationSection,
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath()),
|
||||
to: searchPath(),
|
||||
visible: ({ location }) => location.pathname !== searchPath(),
|
||||
});
|
||||
|
||||
@@ -75,7 +74,7 @@ export const navigateToArchive = createAction({
|
||||
section: NavigationSection,
|
||||
shortcut: ["g", "a"],
|
||||
icon: <ArchiveIcon />,
|
||||
perform: () => history.push(archivePath()),
|
||||
to: archivePath(),
|
||||
visible: ({ location }) => location.pathname !== archivePath(),
|
||||
});
|
||||
|
||||
@@ -84,7 +83,7 @@ export const navigateToTrash = createAction({
|
||||
analyticsName: "Navigate to trash",
|
||||
section: NavigationSection,
|
||||
icon: <TrashIcon />,
|
||||
perform: () => history.push(trashPath()),
|
||||
to: trashPath(),
|
||||
visible: ({ location }) => location.pathname !== trashPath(),
|
||||
});
|
||||
|
||||
@@ -95,7 +94,7 @@ export const navigateToSettings = createAction({
|
||||
shortcut: ["g", "s"],
|
||||
icon: <SettingsIcon />,
|
||||
visible: () => stores.policies.abilities(stores.auth.team?.id || "").update,
|
||||
perform: () => history.push(settingsPath()),
|
||||
to: settingsPath(),
|
||||
});
|
||||
|
||||
export const navigateToWorkspaceSettings = createAction({
|
||||
@@ -104,7 +103,7 @@ export const navigateToWorkspaceSettings = createAction({
|
||||
section: NavigationSection,
|
||||
icon: <SettingsIcon />,
|
||||
visible: () => stores.policies.abilities(stores.auth.team?.id || "").update,
|
||||
perform: () => history.push(settingsPath("details")),
|
||||
to: settingsPath("details"),
|
||||
});
|
||||
|
||||
export const navigateToProfileSettings = createAction({
|
||||
@@ -113,7 +112,7 @@ export const navigateToProfileSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <ProfileIcon />,
|
||||
perform: () => history.push(settingsPath()),
|
||||
to: settingsPath(),
|
||||
});
|
||||
|
||||
export const navigateToTemplateSettings = createAction({
|
||||
@@ -122,7 +121,7 @@ export const navigateToTemplateSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <ShapesIcon />,
|
||||
perform: () => history.push(settingsPath("templates")),
|
||||
to: settingsPath("templates"),
|
||||
});
|
||||
|
||||
export const navigateToNotificationSettings = createAction({
|
||||
@@ -131,7 +130,7 @@ export const navigateToNotificationSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <EmailIcon />,
|
||||
perform: () => history.push(settingsPath("notifications")),
|
||||
to: settingsPath("notifications"),
|
||||
});
|
||||
|
||||
export const navigateToAccountPreferences = createAction({
|
||||
@@ -140,7 +139,7 @@ export const navigateToAccountPreferences = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <SettingsIcon />,
|
||||
perform: () => history.push(settingsPath("preferences")),
|
||||
to: settingsPath("preferences"),
|
||||
});
|
||||
|
||||
export const openDocumentation = createAction({
|
||||
@@ -149,7 +148,10 @@ export const openDocumentation = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.guide),
|
||||
to: {
|
||||
url: UrlHelper.guide,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openAPIDocumentation = createAction({
|
||||
@@ -158,7 +160,10 @@ export const openAPIDocumentation = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.developers),
|
||||
to: {
|
||||
url: UrlHelper.developers,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const toggleSidebar = createAction({
|
||||
@@ -175,14 +180,20 @@ export const openFeedbackUrl = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <EmailIcon />,
|
||||
perform: () => window.open(UrlHelper.contact),
|
||||
to: {
|
||||
url: UrlHelper.contact,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openBugReportUrl = createAction({
|
||||
name: ({ t }) => t("Report a bug"),
|
||||
analyticsName: "Open bug report",
|
||||
section: NavigationSection,
|
||||
perform: () => window.open(UrlHelper.github),
|
||||
to: {
|
||||
url: UrlHelper.github,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openChangelog = createAction({
|
||||
@@ -191,7 +202,10 @@ export const openChangelog = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.changelog),
|
||||
to: {
|
||||
url: UrlHelper.changelog,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openKeyboardShortcuts = createAction({
|
||||
@@ -219,8 +233,9 @@ export const downloadApp = createAction({
|
||||
iconInContextMenu: false,
|
||||
icon: <BrowserIcon />,
|
||||
visible: () => !Desktop.isElectron() && isMac() && isCloudHosted,
|
||||
perform: () => {
|
||||
window.open("https://desktop.getoutline.com");
|
||||
to: {
|
||||
url: "https://desktop.getoutline.com",
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,10 @@ export const switchTeamsList = ({ stores }: { stores: RootStore }) =>
|
||||
);
|
||||
},
|
||||
visible: ({ currentTeamId }: ActionContext) => currentTeamId !== session.id,
|
||||
perform: () => (window.location.href = session.url),
|
||||
to: {
|
||||
url: session.url,
|
||||
target: "_self",
|
||||
},
|
||||
})) ?? [];
|
||||
|
||||
export const switchTeam = createAction({
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
Action,
|
||||
ActionContext,
|
||||
CommandBarAction,
|
||||
MenuExternalLink,
|
||||
MenuInternalLink,
|
||||
MenuItemButton,
|
||||
MenuItemWithChildren,
|
||||
} from "~/types";
|
||||
@@ -31,7 +33,6 @@ export function createAction(definition: Optional<Action, "id">): Action {
|
||||
: "contextmenu",
|
||||
});
|
||||
}
|
||||
|
||||
return definition.perform?.(context);
|
||||
}
|
||||
: undefined,
|
||||
@@ -42,7 +43,7 @@ export function createAction(definition: Optional<Action, "id">): Action {
|
||||
export function actionToMenuItem(
|
||||
action: Action,
|
||||
context: ActionContext
|
||||
): MenuItemButton | MenuItemWithChildren {
|
||||
): MenuItemButton | MenuExternalLink | MenuInternalLink | MenuItemWithChildren {
|
||||
const resolvedIcon = resolve<React.ReactElement<any>>(action.icon, context);
|
||||
const resolvedChildren = resolve<Action[]>(action.children, context);
|
||||
const visible = action.visible ? action.visible(context) : true;
|
||||
@@ -67,6 +68,26 @@ export function actionToMenuItem(
|
||||
};
|
||||
}
|
||||
|
||||
if (action.to) {
|
||||
return typeof action.to === "string"
|
||||
? {
|
||||
type: "route",
|
||||
title,
|
||||
icon,
|
||||
visible,
|
||||
to: action.to,
|
||||
selected: action.selected?.(context),
|
||||
}
|
||||
: {
|
||||
type: "link",
|
||||
title,
|
||||
icon,
|
||||
visible,
|
||||
href: action.to,
|
||||
selected: action.selected?.(context),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: "button",
|
||||
title,
|
||||
|
||||
@@ -4,7 +4,6 @@ import Icon from "@shared/components/Icon";
|
||||
import { createAction } from "~/actions";
|
||||
import { RecentSection } from "~/actions/sections";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import history from "~/utils/history";
|
||||
import { documentPath } from "~/utils/routeHelpers";
|
||||
|
||||
const useRecentDocumentActions = (count = 6) => {
|
||||
@@ -25,7 +24,7 @@ const useRecentDocumentActions = (count = 6) => {
|
||||
) : (
|
||||
<DocumentIcon />
|
||||
),
|
||||
perform: () => history.push(documentPath(item)),
|
||||
to: documentPath(item),
|
||||
})
|
||||
),
|
||||
[count, ui.activeDocumentId, documents.recentlyViewed]
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useMemo } from "react";
|
||||
import { createAction } from "~/actions";
|
||||
import { NavigationSection } from "~/actions/sections";
|
||||
import useSettingsConfig from "~/hooks/useSettingsConfig";
|
||||
import history from "~/utils/history";
|
||||
|
||||
const useSettingsAction = () => {
|
||||
const config = useSettingsConfig();
|
||||
@@ -16,7 +15,7 @@ const useSettingsAction = () => {
|
||||
name: item.name,
|
||||
icon: <Icon />,
|
||||
section: NavigationSection,
|
||||
perform: () => history.push(item.path),
|
||||
to: item.path,
|
||||
};
|
||||
}),
|
||||
[config]
|
||||
|
||||
@@ -20,7 +20,7 @@ type Props = {
|
||||
dangerous?: boolean;
|
||||
to?: LocationDescriptor;
|
||||
href?: string;
|
||||
target?: "_blank";
|
||||
target?: string;
|
||||
as?: string | React.ComponentType<any>;
|
||||
hide?: () => void;
|
||||
level?: number;
|
||||
|
||||
@@ -155,12 +155,14 @@ function Template({ items, actions, context, showIcons, ...menu }: Props) {
|
||||
return (
|
||||
<MenuItem
|
||||
id={`${item.title}-${index}`}
|
||||
href={item.href}
|
||||
href={typeof item.href === "string" ? item.href : item.href.url}
|
||||
key={`${item.type}-${item.title}-${index}`}
|
||||
disabled={item.disabled}
|
||||
selected={item.selected}
|
||||
level={item.level}
|
||||
target={item.href.startsWith("#") ? undefined : "_blank"}
|
||||
target={
|
||||
typeof item.href === "string" ? undefined : item.href.target
|
||||
}
|
||||
icon={showIcons !== false ? item.icon : undefined}
|
||||
{...menu}
|
||||
>
|
||||
|
||||
@@ -65,7 +65,7 @@ export type MenuInternalLink = {
|
||||
export type MenuExternalLink = {
|
||||
type: "link";
|
||||
title: React.ReactNode;
|
||||
href: string;
|
||||
href: string | { url: string; target?: string };
|
||||
visible?: boolean;
|
||||
selected?: boolean;
|
||||
disabled?: boolean;
|
||||
@@ -117,6 +117,7 @@ export type Action = {
|
||||
* instead. Errors will be caught and displayed to the user as a toast message.
|
||||
*/
|
||||
perform?: (context: ActionContext) => any;
|
||||
to?: string | { url: string; target?: string };
|
||||
children?: ((context: ActionContext) => Action[]) | Action[];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user