Make the command center stable and workspace-aware (#2749)
* feat(app): expand command center actions Keep command center navigation stable by revealing only clipped rows without smooth centering. Prioritize a concise default list while making workspace, Git, pane, and creation actions searchable through the existing contribution and action-policy paths. * test(app): search for query-only command action Add project is intentionally absent from the unfiltered command center. Exercise the overlay flow through search before selecting it.
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import { useMemo, type ReactElement } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Columns2, Globe, Rows2, SquarePen, SquareTerminal } from "lucide-react-native";
|
||||
import { getIsElectron } from "@/constants/platform";
|
||||
import { supportsDesktopPaneSplits, useIsCompactFormFactor } from "@/constants/layout";
|
||||
import { GIT_ACTION_ICONS } from "@/git/action-icons";
|
||||
import { useGitActionRunner, useGitActions } from "@/git/use-actions";
|
||||
import { useKeyboardShortcutOverrides } from "@/hooks/use-keyboard-shortcut-overrides";
|
||||
import { resolveShortcutKeysForAction } from "@/keyboard/keyboard-shortcuts";
|
||||
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
|
||||
import { useActiveWorkspaceSelection } from "@/stores/navigation-active-workspace-store";
|
||||
import { useWorkspaceDirectory } from "@/stores/session-store-hooks";
|
||||
import { clearCommandCenterFocusRestoreElement } from "@/utils/command-center-focus-restore";
|
||||
import { getShortcutOs } from "@/utils/shortcut-platform";
|
||||
import { getCommandCenterIcon } from "./icon";
|
||||
import type { CommandCenterIcon } from "./contributions";
|
||||
import { useCommandCenterActions } from "./provider";
|
||||
import {
|
||||
buildWorkspaceCommandCenterContributions,
|
||||
type WorkspaceCommandCenterShortcuts,
|
||||
} from "./workspace-contributions";
|
||||
|
||||
const WORKSPACE_COMMAND_CENTER_ICONS = {
|
||||
newAgent: getCommandCenterIcon(SquarePen),
|
||||
newTerminal: getCommandCenterIcon(SquareTerminal),
|
||||
newBrowser: getCommandCenterIcon(Globe),
|
||||
splitRight: getCommandCenterIcon(Columns2),
|
||||
splitDown: getCommandCenterIcon(Rows2),
|
||||
};
|
||||
|
||||
function staticIcon(element: ReactElement | undefined): CommandCenterIcon | undefined {
|
||||
if (!element) return undefined;
|
||||
function StaticIcon() {
|
||||
return element;
|
||||
}
|
||||
return StaticIcon;
|
||||
}
|
||||
|
||||
function resolveWorkspaceShortcuts(
|
||||
overrides: Readonly<Record<string, string>>,
|
||||
): WorkspaceCommandCenterShortcuts {
|
||||
const platform = { isMac: getShortcutOs() === "mac", isDesktop: getIsElectron() };
|
||||
return {
|
||||
newAgent: resolveShortcutKeysForAction("workspace-tab-new", overrides, platform) ?? undefined,
|
||||
newTerminal:
|
||||
resolveShortcutKeysForAction("workspace-terminal-new", overrides, platform) ?? undefined,
|
||||
splitRight:
|
||||
resolveShortcutKeysForAction("workspace-pane-split-right", overrides, platform) ?? undefined,
|
||||
splitDown:
|
||||
resolveShortcutKeysForAction("workspace-pane-split-down", overrides, platform) ?? undefined,
|
||||
archiveWorkspace:
|
||||
resolveShortcutKeysForAction("archive-workspace", overrides, platform) ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function useWorkspaceCommandCenterActions(): void {
|
||||
const { t } = useTranslation();
|
||||
const selection = useActiveWorkspaceSelection();
|
||||
const serverId = selection?.serverId ?? null;
|
||||
const workspaceId = selection?.workspaceId ?? null;
|
||||
const cwd = useWorkspaceDirectory(serverId, workspaceId);
|
||||
const isCompact = useIsCompactFormFactor();
|
||||
const { overrides } = useKeyboardShortcutOverrides();
|
||||
const { gitActions } = useGitActions({
|
||||
serverId: serverId ?? "",
|
||||
cwd: cwd ?? "",
|
||||
icons: GIT_ACTION_ICONS,
|
||||
});
|
||||
const runGitAction = useGitActionRunner();
|
||||
|
||||
const actions = useMemo(
|
||||
() =>
|
||||
buildWorkspaceCommandCenterContributions({
|
||||
gitActions,
|
||||
labels: {
|
||||
section: t("workspace.header.actions.workspaceActions"),
|
||||
newAgent: t("workspace.tabs.actions.newAgent"),
|
||||
newTerminal: t("workspace.tabs.actions.newTerminal"),
|
||||
newBrowser: t("workspace.tabs.actions.newBrowser"),
|
||||
splitRight: t("workspace.tabs.actions.splitRight"),
|
||||
splitDown: t("workspace.tabs.actions.splitDown"),
|
||||
},
|
||||
icons: {
|
||||
...WORKSPACE_COMMAND_CENTER_ICONS,
|
||||
git: (action) => staticIcon(action.icon),
|
||||
},
|
||||
shortcuts: resolveWorkspaceShortcuts(overrides),
|
||||
capabilities: {
|
||||
canSplitPanes: supportsDesktopPaneSplits() && !isCompact,
|
||||
canOpenBrowserTabs: getIsElectron(),
|
||||
},
|
||||
dispatch: (action) => {
|
||||
clearCommandCenterFocusRestoreElement();
|
||||
keyboardActionDispatcher.dispatch(action);
|
||||
},
|
||||
runGitAction,
|
||||
}),
|
||||
[gitActions, isCompact, overrides, runGitAction, t],
|
||||
);
|
||||
|
||||
useCommandCenterActions({
|
||||
sourceId: "workspace",
|
||||
enabled: Boolean(serverId && cwd),
|
||||
actions,
|
||||
});
|
||||
}
|
||||
|
||||
export function CommandCenterWorkspaceActions() {
|
||||
useWorkspaceCommandCenterActions();
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user