Skip to content
68 changes: 68 additions & 0 deletions apps/desktop/src/lib/trpc/routers/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ function getSettings() {
return row;
}

/** Get presets tagged with a given auto-apply field, falling back to the isDefault preset */
export function getPresetsForTrigger(
field: "applyOnWorkspaceCreated" | "applyOnNewTab",
) {
const row = getSettings();
const presets = row.terminalPresets ?? [];
const tagged = presets.filter((p) => p[field]);
if (tagged.length > 0) return tagged;
const defaultPreset = presets.find((p) => p.isDefault);
return defaultPreset ? [defaultPreset] : [];
}

export const createSettingsRouter = () => {
return router({
getLastUsedApp: publicProcedure.query(() => {
Expand Down Expand Up @@ -159,6 +171,54 @@ export const createSettingsRouter = () => {
return { success: true };
}),

setPresetAutoApply: publicProcedure
.input(
z.object({
id: z.string(),
field: z.enum(["applyOnWorkspaceCreated", "applyOnNewTab"]),
enabled: z.boolean(),
}),
)
.mutation(({ input }) => {
const row = getSettings();
const presets = row.terminalPresets ?? [];

const updatedPresets = presets.map((p) => {
if (p.id !== input.id) return p;

// Migrate legacy isDefault preset to explicit fields on first toggle
const needsMigration =
p.isDefault &&
p.applyOnWorkspaceCreated === undefined &&
p.applyOnNewTab === undefined;

const base = needsMigration
? {
...p,
isDefault: undefined,
applyOnWorkspaceCreated: true as const,
applyOnNewTab: true as const,
}
: p;

return {
...base,
[input.field]: input.enabled ? true : undefined,
};
});

localDb
.insert(settings)
.values({ id: 1, terminalPresets: updatedPresets })
.onConflictDoUpdate({
target: settings.id,
set: { terminalPresets: updatedPresets },
})
.run();

return { success: true };
}),

reorderTerminalPresets: publicProcedure
.input(
z.object({
Expand Down Expand Up @@ -206,6 +266,14 @@ export const createSettingsRouter = () => {
return presets.find((p) => p.isDefault) ?? null;
}),

getWorkspaceCreationPresets: publicProcedure.query(() =>
getPresetsForTrigger("applyOnWorkspaceCreated"),
),

getNewTabPresets: publicProcedure.query(() =>
getPresetsForTrigger("applyOnNewTab"),
),

getSelectedRingtoneId: publicProcedure.query(() => {
const row = getSettings();
const storedId = row.selectedRingtoneId;
Expand Down
14 changes: 3 additions & 11 deletions apps/desktop/src/lib/trpc/routers/workspaces/procedures/init.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import { settings } from "@superset/local-db";
import { observable } from "@trpc/server/observable";
import { localDb } from "main/lib/local-db";
import { workspaceInitManager } from "main/lib/workspace-init-manager";
import type { WorkspaceInitProgress } from "shared/types/workspace-init";
import { z } from "zod";
import { publicProcedure, router } from "../../..";
import { getPresetsForTrigger } from "../../settings";
import { getProject, getWorkspaceWithRelations } from "../utils/db-helpers";
import { loadSetupConfig } from "../utils/setup";
import { initializeWorkspaceWorktree } from "../utils/workspace-init";

function getDefaultPreset() {
const row = localDb.select().from(settings).get();
if (!row) return null;
const presets = row.terminalPresets ?? [];
return presets.find((p) => p.isDefault) ?? null;
}

export const createInitProcedures = () => {
return router({
onInitProgress: publicProcedure
Expand Down Expand Up @@ -120,12 +112,12 @@ export const createInitProcedures = () => {
worktreePath: relations.worktree?.path,
projectName: project.name,
});
const defaultPreset = getDefaultPreset();
const defaultPresets = getPresetsForTrigger("applyOnWorkspaceCreated");

return {
projectId: project.id,
initialCommands: setupConfig?.setup ?? null,
defaultPreset,
defaultPresets,
};
}),
});
Expand Down
21 changes: 7 additions & 14 deletions apps/desktop/src/renderer/react-query/presets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,19 @@ function useDeleteTerminalPreset(
});
}

function useSetDefaultPreset(
function useSetPresetAutoApply(
options?: Parameters<
typeof electronTrpc.settings.setDefaultPreset.useMutation
typeof electronTrpc.settings.setPresetAutoApply.useMutation
>[0],
) {
const utils = electronTrpc.useUtils();

return electronTrpc.settings.setDefaultPreset.useMutation({
return electronTrpc.settings.setPresetAutoApply.useMutation({
...options,
onSuccess: async (...args) => {
await utils.settings.getTerminalPresets.invalidate();
await utils.settings.getDefaultPreset.invalidate();
await utils.settings.getWorkspaceCreationPresets.invalidate();
await utils.settings.getNewTabPresets.invalidate();
await options?.onSuccess?.(...args);
},
});
Expand All @@ -81,31 +82,23 @@ function useReorderTerminalPresets(
});
}

/**
* Combined hook for accessing terminal presets with all CRUD operations
* Provides easy access to presets data and mutations from anywhere in the app
*/
export function usePresets() {
const { data: presets = [], isLoading } =
electronTrpc.settings.getTerminalPresets.useQuery();

const { data: defaultPreset } =
electronTrpc.settings.getDefaultPreset.useQuery();

const createPreset = useCreateTerminalPreset();
const updatePreset = useUpdateTerminalPreset();
const deletePreset = useDeleteTerminalPreset();
const setDefaultPreset = useSetDefaultPreset();
const setPresetAutoApply = useSetPresetAutoApply();
const reorderPresets = useReorderTerminalPresets();

return {
presets,
defaultPreset,
isLoading,
createPreset,
updatePreset,
deletePreset,
setDefaultPreset,
setPresetAutoApply,
reorderPresets,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function useCreateBranchWorkspace(
workspaceId: data.workspace.id,
projectId: data.projectId,
initialCommands: setupData?.initialCommands ?? null,
defaultPreset: setupData?.defaultPreset ?? null,
defaultPresets: setupData?.defaultPresets ?? [],
});

// Branch workspaces skip git init, so mark ready immediately to trigger terminal setup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ async function execute(
workspaceId: workspace.id,
projectId: pending?.projectId ?? workspace.projectId,
initialCommands: [...(pending?.initialCommands ?? []), params.command],
// Preserve undefined (signals "fetch from backend") vs null (no preset needed)
defaultPreset: pending ? pending.defaultPreset : null,
defaultPresets: pending?.defaultPresets,
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface PresetColumnConfig {
label: string;
placeholder: string;
mono?: boolean;
tooltip?: string;
}

export const PRESET_COLUMNS: PresetColumnConfig[] = [
Expand All @@ -20,9 +21,11 @@ export const PRESET_COLUMNS: PresetColumnConfig[] = [
},
{
key: "cwd",
label: "CWD",
label: "Directory",
placeholder: "e.g. ./src (optional)",
mono: true,
tooltip:
"Working directory for the terminal session (relative to workspace root)",
},
{
key: "commands",
Expand Down
Loading