Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions apps/desktop/src/lib/trpc/routers/settings/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
BRANCH_PREFIX_MODES,
EXECUTION_MODES,
FILE_OPEN_MODES,
settings,
TERMINAL_LINK_BEHAVIORS,
type TerminalPreset,
Expand All @@ -12,6 +13,7 @@ import { localDb } from "main/lib/local-db";
import {
DEFAULT_AUTO_APPLY_DEFAULT_PRESET,
DEFAULT_CONFIRM_ON_QUIT,
DEFAULT_FILE_OPEN_MODE,
DEFAULT_TERMINAL_LINK_BEHAVIOR,
} from "shared/constants";
import { DEFAULT_RINGTONE_ID, RINGTONES } from "shared/ringtones";
Expand Down Expand Up @@ -362,6 +364,26 @@ export const createSettingsRouter = () => {
return { success: true };
}),

getFileOpenMode: publicProcedure.query(() => {
const row = getSettings();
return row.fileOpenMode ?? DEFAULT_FILE_OPEN_MODE;
}),

setFileOpenMode: publicProcedure
.input(z.object({ mode: z.enum(FILE_OPEN_MODES) }))
.mutation(({ input }) => {
localDb
.insert(settings)
.values({ id: 1, fileOpenMode: input.mode })
.onConflictDoUpdate({
target: settings.id,
set: { fileOpenMode: input.mode },
})
.run();

return { success: true };
}),

getAutoApplyDefaultPreset: publicProcedure.query(() => {
const row = getSettings();
return row.autoApplyDefaultPreset ?? DEFAULT_AUTO_APPLY_DEFAULT_PRESET;
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/renderer/hooks/useFileOpenMode/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useFileOpenMode } from "./useFileOpenMode";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { electronTrpc } from "renderer/lib/electron-trpc";

export function useFileOpenMode() {
const { data } = electronTrpc.settings.getFileOpenMode.useQuery();
return data ?? "split-pane";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BranchPrefixMode } from "@superset/local-db";
import type { BranchPrefixMode, FileOpenMode } from "@superset/local-db";
import { Input } from "@superset/ui/input";
import { Label } from "@superset/ui/label";
import {
Expand Down Expand Up @@ -40,6 +40,10 @@ export function BehaviorSettings({ visibleItems }: BehaviorSettingsProps) {
SETTING_ITEM_ID.BEHAVIOR_TELEMETRY,
visibleItems,
);
const showFileOpenMode = isItemVisible(
SETTING_ITEM_ID.BEHAVIOR_FILE_OPEN_MODE,
visibleItems,
);

const utils = electronTrpc.useUtils();

Expand Down Expand Up @@ -160,6 +164,25 @@ export function BehaviorSettings({ visibleItems }: BehaviorSettingsProps) {
});
};

const { data: fileOpenMode, isLoading: isFileOpenModeLoading } =
electronTrpc.settings.getFileOpenMode.useQuery();
const setFileOpenMode = electronTrpc.settings.setFileOpenMode.useMutation({
onMutate: async ({ mode }) => {
await utils.settings.getFileOpenMode.cancel();
const previous = utils.settings.getFileOpenMode.getData();
utils.settings.getFileOpenMode.setData(undefined, mode);
return { previous };
},
onError: (_err, _vars, context) => {
if (context?.previous !== undefined) {
utils.settings.getFileOpenMode.setData(undefined, context.previous);
}
},
onSettled: () => {
utils.settings.getFileOpenMode.invalidate();
},
});

const previewPrefix =
resolveBranchPrefix({
mode: branchPrefix?.mode ?? "none",
Expand Down Expand Up @@ -276,6 +299,32 @@ export function BehaviorSettings({ visibleItems }: BehaviorSettingsProps) {
</div>
)}

{showFileOpenMode && (
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<Label className="text-sm font-medium">File open mode</Label>
<p className="text-xs text-muted-foreground">
Choose how files open when no preview pane exists
</p>
</div>
<Select
value={fileOpenMode ?? "split-pane"}
onValueChange={(value) =>
setFileOpenMode.mutate({ mode: value as FileOpenMode })
}
disabled={isFileOpenModeLoading || setFileOpenMode.isPending}
>
<SelectTrigger className="w-[180px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="split-pane">Split pane</SelectItem>
<SelectItem value="new-tab">New tab</SelectItem>
</SelectContent>
</Select>
</div>
)}

{false && showTelemetry && (
<div className="flex items-center justify-between">
<div className="space-y-0.5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const SETTING_ITEM_ID = {
BEHAVIOR_DELETE_LOCAL_BRANCH: "behavior-delete-local-branch",
BEHAVIOR_BRANCH_PREFIX: "behavior-branch-prefix",
BEHAVIOR_TELEMETRY: "behavior-telemetry",
BEHAVIOR_FILE_OPEN_MODE: "behavior-file-open-mode",

TERMINAL_PRESETS: "terminal-presets",
TERMINAL_QUICK_ADD: "terminal-quick-add",
Expand Down Expand Up @@ -364,6 +365,25 @@ export const SETTINGS_ITEMS: SettingsItem[] = [
"disable",
],
},
{
id: SETTING_ITEM_ID.BEHAVIOR_FILE_OPEN_MODE,
section: "behavior",
title: "File open mode",
description:
"Choose how files open when clicked in the file tree or changes view",
keywords: [
"file",
"open",
"mode",
"split",
"pane",
"tab",
"new tab",
"split pane",
"viewer",
"behavior",
],
},
{
id: SETTING_ITEM_ID.TERMINAL_PRESETS,
section: "terminal",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useParams } from "@tanstack/react-router";
import { useCallback } from "react";
import { LuDiff } from "react-icons/lu";
import { HotkeyTooltipContent } from "renderer/components/HotkeyTooltipContent";
import { useFileOpenMode } from "renderer/hooks/useFileOpenMode";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { useSidebarStore } from "renderer/stores";
import { useChangesStore } from "renderer/stores/changes";
Expand Down Expand Up @@ -46,6 +47,7 @@ export function SidebarControl() {
);

const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane);
const fileOpenMode = useFileOpenMode();
const trpcUtils = electronTrpc.useUtils();

const invalidateFileContent = useCallback(
Expand Down Expand Up @@ -92,6 +94,7 @@ export function SidebarControl() {
diffCategory: category,
oldPath: firstFile.oldPath,
isPinned: false,
openInNewTab: fileOpenMode === "new-tab",
});
invalidateFileContent(firstFile.path);
}
Expand All @@ -102,6 +105,7 @@ export function SidebarControl() {
selectFile,
addFileViewerPane,
invalidateFileContent,
fileOpenMode,
]);

const handleClick = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { toast } from "@superset/ui/sonner";
import { useCallback } from "react";
import { useFileOpenMode } from "renderer/hooks/useFileOpenMode";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client";
import { useTabsStore } from "renderer/stores/tabs/store";
Expand All @@ -25,6 +26,7 @@ export function useFileLinkClick({
workspaceCwd,
}: UseFileLinkClickOptions): UseFileLinkClickReturn {
const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane);
const fileOpenMode = useFileOpenMode();

// Query terminal link behavior setting
const { data: terminalLinkBehavior } =
Expand Down Expand Up @@ -85,12 +87,23 @@ export function useFileLinkClick({
});
return;
}
addFileViewerPane(workspaceId, { filePath, line, column });
addFileViewerPane(workspaceId, {
filePath,
line,
column,
openInNewTab: fileOpenMode === "new-tab",
});
} else {
openInExternalEditor();
}
},
[terminalLinkBehavior, workspaceId, workspaceCwd, addFileViewerPane],
[
terminalLinkBehavior,
workspaceId,
workspaceCwd,
addFileViewerPane,
fileOpenMode,
],
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { useParams } from "@tanstack/react-router";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { LuFile, LuFolder } from "react-icons/lu";
import { useFileOpenMode } from "renderer/hooks/useFileOpenMode";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { useFileExplorerStore } from "renderer/stores/file-explorer";
import { useTabsStore } from "renderer/stores/tabs/store";
Expand Down Expand Up @@ -148,6 +149,7 @@ export function FilesView() {
});

const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane);
const fileOpenMode = useFileOpenMode();
const openFileInEditorMutation =
electronTrpc.external.openFileInEditor.useMutation();

Expand All @@ -162,9 +164,10 @@ export function FilesView() {
if (!workspaceId || !worktreePath || entry.isDirectory) return;
addFileViewerPane(workspaceId, {
filePath: entry.relativePath,
openInNewTab: fileOpenMode === "new-tab",
});
},
[workspaceId, worktreePath, addFileViewerPane],
[workspaceId, worktreePath, addFileViewerPane, fileOpenMode],
);

const handleOpenInEditor = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
LuX,
} from "react-icons/lu";
import { HotkeyTooltipContent } from "renderer/components/HotkeyTooltipContent";
import { useFileOpenMode } from "renderer/hooks/useFileOpenMode";
import { electronTrpc } from "renderer/lib/electron-trpc";
import {
RightSidebarTab,
Expand Down Expand Up @@ -101,6 +102,7 @@ export function RightSidebar() {
};

const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane);
const fileOpenMode = useFileOpenMode();
const trpcUtils = electronTrpc.useUtils();
const { scrollToFile } = useScrollContext();

Expand Down Expand Up @@ -135,10 +137,17 @@ export function RightSidebar() {
diffCategory: category,
commitHash,
oldPath: file.oldPath,
openInNewTab: fileOpenMode === "new-tab",
});
invalidateFileContent(file.path);
},
[workspaceId, worktreePath, addFileViewerPane, invalidateFileContent],
[
workspaceId,
worktreePath,
addFileViewerPane,
invalidateFileContent,
fileOpenMode,
],
);

const handleFileScrollTo = useCallback(
Expand Down
42 changes: 42 additions & 0 deletions apps/desktop/src/renderer/stores/tabs/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,48 @@ export const useTabsStore = create<TabsStore>()(
}

// No reusable pane found, create a new one
if (options.openInNewTab) {
const workspaceId = activeTab.workspaceId;
const newTabId = generateId("tab");
const newPane = createFileViewerPane(newTabId, options);

const newTab = {
id: newTabId,
workspaceId,
name: newPane.name,
layout: newPane.id as MosaicNode<string>,
createdAt: Date.now(),
};

const currentActiveId = state.activeTabIds[workspaceId];
const historyStack = state.tabHistoryStacks[workspaceId] || [];
const newHistoryStack = currentActiveId
? [
currentActiveId,
...historyStack.filter((id) => id !== currentActiveId),
]
: historyStack;

set({
tabs: [...state.tabs, newTab],
panes: { ...state.panes, [newPane.id]: newPane },
activeTabIds: {
...state.activeTabIds,
[workspaceId]: newTab.id,
},
focusedPaneIds: {
...state.focusedPaneIds,
[newTab.id]: newPane.id,
},
tabHistoryStacks: {
...state.tabHistoryStacks,
[workspaceId]: newHistoryStack,
},
});

return newPane.id;
}

const newPane = createFileViewerPane(activeTab.id, options);

const newLayout: MosaicNode<string> = {
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/renderer/stores/tabs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export interface AddFileViewerPaneOptions {
column?: number;
/** If true, opens pinned (permanent). If false/undefined, opens in preview mode (can be replaced) */
isPinned?: boolean;
/** If true, opens in a new tab instead of splitting the current tab */
openInNewTab?: boolean;
}

/**
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/shared/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const MOCK_ORG_ID = "mock-org-id";
// Default user preference values
export const DEFAULT_CONFIRM_ON_QUIT = true;
export const DEFAULT_TERMINAL_LINK_BEHAVIOR = "external-editor" as const;
export const DEFAULT_FILE_OPEN_MODE = "split-pane" as const;
export const DEFAULT_AUTO_APPLY_DEFAULT_PRESET = true;
export const DEFAULT_TELEMETRY_ENABLED = true;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `settings` ADD `file_open_mode` text;
Loading