Skip to content
Closed
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
79 changes: 63 additions & 16 deletions src/components/SettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1050,22 +1050,29 @@ export function SettingsDialog(props: SettingsDialogProps) {
<div style={{ display: "flex", "flex-direction": "column", gap: "24px" }}>
<SectionHeader
title="General"
description={settingsScope() === "workspace" ? "Override theme for this workspace" : "General application settings"}
description={settingsScope() === "workspace" ? "Override theme for this workspace" : settingsScope() === "folder" ? "Override theme for this folder" : "General application settings"}
icon={<Icon name="desktop" class="h-4 w-4" />}
/>
<div>
<Text as="h3" size="sm" weight="medium" style={{ "margin-bottom": "12px", color: "var(--jb-text-body-color)" }}>Theme</Text>
<div style={{ display: "flex", gap: "8px" }}>
<For each={themes}>
{(t) => {
const hasOverride = () => settings.hasWorkspaceOverride("theme", "theme");
const hasOverride = () => {
if (settingsScope() === "folder" && selectedFolder()) {
return settings.hasFolderOverride(selectedFolder()!, "theme", "theme");
}
return settings.hasWorkspaceOverride("theme", "theme");
};
const isSelected = () => safeThemeSettings(settings.effectiveSettings()).theme === t.value;

return (
<div style={{ position: "relative" }}>
<UIButton
onClick={() => {
if (settingsScope() === "workspace") {
if (settingsScope() === "folder" && selectedFolder()) {
settings.setFolderSetting(selectedFolder()!, "theme", "theme", t.value);
} else if (settingsScope() === "workspace") {
settings.setWorkspaceSetting("theme", "theme", t.value);
} else {
setTheme(t.value);
Expand Down Expand Up @@ -1095,7 +1102,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
</div>
</div>

{/* Reset workspace theme override */}
{/* Reset workspace/folder theme override */}
<Show when={settingsScope() === "workspace" && settings.hasWorkspaceOverride("theme", "theme")}>
<UIButton
onClick={() => settings.resetWorkspaceSetting("theme", "theme")}
Expand All @@ -1107,6 +1114,17 @@ export function SettingsDialog(props: SettingsDialogProps) {
Reset to user theme
</UIButton>
</Show>
<Show when={settingsScope() === "folder" && selectedFolder() && settings.hasFolderOverride(selectedFolder()!, "theme", "theme")}>
<UIButton
onClick={() => settings.resetFolderSetting(selectedFolder()!, "theme", "theme")}
variant="ghost"
size="sm"
icon={<Icon name="rotate-left" style={{ width: "12px", height: "12px" }} />}
style={{ color: "var(--cortex-success)" }}
>
Reset to workspace/user theme
</UIButton>
</Show>

{/* Divider */}
<div style={{ "border-top": "1px solid var(--jb-border-default)", "margin": "24px 0" }} />
Expand All @@ -1119,7 +1137,9 @@ export function SettingsDialog(props: SettingsDialogProps) {
selected={safeThemeSettings(settings.effectiveSettings()).wrapTabs}
onSelect={async () => {
const currentValue = safeThemeSettings(settings.effectiveSettings()).wrapTabs;
if (settingsScope() === "workspace") {
if (settingsScope() === "folder" && selectedFolder()) {
await settings.setFolderSetting(selectedFolder()!, "theme", "wrapTabs", !currentValue);
} else if (settingsScope() === "workspace") {
await settings.setWorkspaceSetting("theme", "wrapTabs", !currentValue);
} else {
await settings.updateThemeSetting("wrapTabs", !currentValue);
Expand All @@ -1128,21 +1148,24 @@ export function SettingsDialog(props: SettingsDialogProps) {
title="Wrap Tabs"
description="When enabled, tabs wrap to multiple lines instead of showing scroll buttons"
/>
<Show when={settings.hasWorkspaceOverride("theme", "wrapTabs")}>
<Show when={
(settingsScope() === "folder" && selectedFolder() && settings.hasFolderOverride(selectedFolder()!, "theme", "wrapTabs")) ||
(settingsScope() !== "folder" && settings.hasWorkspaceOverride("theme", "wrapTabs"))
}>
<span style={{
position: "absolute",
top: "8px",
right: "8px",
width: "8px",
height: "8px",
"border-radius": "var(--cortex-radius-full)",
background: "var(--cortex-info)",
background: settingsScope() === "folder" ? "var(--cortex-success)" : "var(--cortex-info)",
}} />
</Show>
</div>
</div>

{/* Reset workspace wrapTabs override */}
{/* Reset workspace/folder wrapTabs override */}
<Show when={settingsScope() === "workspace" && settings.hasWorkspaceOverride("theme", "wrapTabs")}>
<UIButton
onClick={() => settings.resetWorkspaceSetting("theme", "wrapTabs")}
Expand All @@ -1154,6 +1177,17 @@ export function SettingsDialog(props: SettingsDialogProps) {
Reset to user setting
</UIButton>
</Show>
<Show when={settingsScope() === "folder" && selectedFolder() && settings.hasFolderOverride(selectedFolder()!, "theme", "wrapTabs")}>
<UIButton
onClick={() => settings.resetFolderSetting(selectedFolder()!, "theme", "wrapTabs")}
variant="ghost"
size="sm"
icon={<Icon name="rotate-left" style={{ width: "12px", height: "12px" }} />}
style={{ color: "var(--cortex-success)" }}
>
Reset to workspace/user setting
</UIButton>
</Show>

{/* Settings Location Info */}
<Card variant="outlined" padding="md" style={{ "margin-top": "24px" }}>
Expand Down Expand Up @@ -1202,7 +1236,9 @@ export function SettingsDialog(props: SettingsDialogProps) {
<Select
value={safeExplorerSettings(settings.effectiveSettings()).sortOrder}
onChange={async (value) => {
if (settingsScope() === "workspace") {
if (settingsScope() === "folder" && selectedFolder()) {
await settings.setFolderSetting(selectedFolder()!, "explorer", "sortOrder", value as ExplorerSortOrder);
} else if (settingsScope() === "workspace") {
await settings.setWorkspaceSetting("explorer", "sortOrder", value as ExplorerSortOrder);
} else {
await settings.updateExplorerSetting("sortOrder", value as ExplorerSortOrder);
Expand All @@ -1219,7 +1255,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
/>
</FormGroup>

{/* Reset workspace sort order override */}
{/* Reset workspace/folder sort order override */}
<Show when={settingsScope() === "workspace" && settings.hasWorkspaceOverride("explorer", "sortOrder")}>
<UIButton
onClick={() => settings.resetWorkspaceSetting("explorer", "sortOrder")}
Expand All @@ -1231,6 +1267,17 @@ export function SettingsDialog(props: SettingsDialogProps) {
Reset to user setting
</UIButton>
</Show>
<Show when={settingsScope() === "folder" && selectedFolder() && settings.hasFolderOverride(selectedFolder()!, "explorer", "sortOrder")}>
<UIButton
onClick={() => settings.resetFolderSetting(selectedFolder()!, "explorer", "sortOrder")}
variant="ghost"
size="sm"
icon={<Icon name="rotate-left" style={{ width: "12px", height: "12px" }} />}
style={{ color: "var(--cortex-success)", "margin-top": "8px" }}
>
Reset to workspace/user setting
</UIButton>
</Show>
</div>

</div>
Expand All @@ -1244,7 +1291,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
description="File associations, auto save, and formatting settings"
icon={<Icon name="file-lines" class="h-4 w-4" />}
/>
<FilesSettingsPanel scope={settingsScope()} />
<FilesSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand Down Expand Up @@ -1358,7 +1405,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
icon={<Icon name="globe" class="h-4 w-4" />}
/>
<div style={{ "margin-top": "16px" }}>
<NetworkSettingsPanel scope={settingsScope()} />
<NetworkSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand Down Expand Up @@ -1422,7 +1469,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
<div class="border-t border-border my-6" />

{/* Full Editor Settings Panel */}
<EditorSettingsPanel scope={settingsScope()} />
<EditorSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand Down Expand Up @@ -1631,7 +1678,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
icon={<Icon name="terminal" class="h-4 w-4" />}
/>
<div style={{ "margin-top": "16px" }}>
<TerminalSettingsPanel scope={settingsScope()} />
<TerminalSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand All @@ -1643,7 +1690,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
icon={<Icon name="code-branch" class="h-4 w-4" />}
/>
<div style={{ "margin-top": "16px" }}>
<GitSettingsPanel scope={settingsScope()} />
<GitSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand All @@ -1655,7 +1702,7 @@ export function SettingsDialog(props: SettingsDialogProps) {
icon={<Icon name="bug" class="h-4 w-4" />}
/>
<div style={{ "margin-top": "16px" }}>
<DebugSettingsPanel scope={settingsScope()} />
<DebugSettingsPanel scope={settingsScope()} folderPath={settingsScope() === "folder" ? selectedFolder() || undefined : undefined} />
</div>
</div>

Expand Down
36 changes: 29 additions & 7 deletions src/components/settings/DebugSettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Icon } from "../ui/Icon";

interface DebugSettingsPanelProps {
scope?: SettingsScope;
folderPath?: string;
}

/** Row with workspace override indicator and modified from default indicator */
Expand Down Expand Up @@ -79,26 +80,42 @@ export function DebugSettingsPanel(props: DebugSettingsPanelProps) {
const scope = () => props.scope || "user";

// Use effective settings for display, but update based on scope
const debug = () => settings.effectiveSettings().debug;
const debug = () => {
if (scope() === "folder" && props.folderPath) {
return settings.getEffectiveSettingsForPath(props.folderPath).debug;
}
return settings.effectiveSettings().debug;
};

// Helper to update setting based on current scope
const updateSetting = <K extends keyof DebugSettings>(key: K, value: DebugSettings[K]) => {
if (scope() === "workspace" && settings.hasWorkspace()) {
if (scope() === "folder" && props.folderPath) {
settings.setFolderSetting(props.folderPath, "debug", key, value);
} else if (scope() === "workspace" && settings.hasWorkspace()) {
settings.setWorkspaceSetting("debug", key, value);
} else {
settings.updateDebugSetting(key, value);
}
};

// Check if setting has workspace override
const hasOverride = (key: keyof DebugSettings) => settings.hasWorkspaceOverride("debug", key);
// Check if setting has workspace or folder override
const hasOverride = (key: keyof DebugSettings) => {
if (scope() === "folder" && props.folderPath) {
return settings.hasFolderOverride(props.folderPath, "debug", key);
}
return settings.hasWorkspaceOverride("debug", key);
};

// Check if setting is modified from default
const isModified = (key: keyof DebugSettings) => settings.isSettingModified("debug", key);

// Reset workspace override
// Reset workspace or folder override
const resetOverride = (key: keyof DebugSettings) => {
settings.resetWorkspaceSetting("debug", key);
if (scope() === "folder" && props.folderPath) {
settings.resetFolderSetting(props.folderPath, "debug", key);
} else {
settings.resetWorkspaceSetting("debug", key);
}
};

// Reset setting to default value
Expand Down Expand Up @@ -130,6 +147,11 @@ export function DebugSettingsPanel(props: DebugSettingsPanelProps) {
Editing workspace-specific debug settings. Changes apply only to this workspace.
</div>
</Show>
<Show when={scope() === "folder" && props.folderPath}>
<div class="text-xs text-green-400 bg-green-500/10 rounded-lg px-3 py-2 mb-4">
Editing folder-specific debug settings. Changes apply only to this folder.
</div>
</Show>

{/* General Debug Settings */}
<SectionHeader title="General" />
Expand Down Expand Up @@ -298,7 +320,7 @@ export function DebugSettingsPanel(props: DebugSettingsPanelProps) {
});
}}
>
Reset All Workspace Debug Overrides
{scope() === "folder" ? "Reset All Folder Debug Overrides" : "Reset All Workspace Debug Overrides"}
</Button>
}
>
Expand Down
44 changes: 37 additions & 7 deletions src/components/settings/EditorSettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { tokens } from '@/design-system/tokens';

interface EditorSettingsPanelProps {
scope?: SettingsScope;
folderPath?: string;
}

/** Row with workspace override indicator and modified from default indicator */
Expand Down Expand Up @@ -136,26 +137,42 @@ export function EditorSettingsPanel(props: EditorSettingsPanelProps) {
const scope = () => props.scope || "user";

// Use effective settings for display, but update based on scope
const editor = () => settings.effectiveSettings().editor;
const editor = () => {
if (scope() === "folder" && props.folderPath) {
return settings.getEffectiveSettingsForPath(props.folderPath).editor;
}
return settings.effectiveSettings().editor;
};

// Helper to update setting based on current scope
const updateSetting = <K extends keyof EditorSettings>(key: K, value: EditorSettings[K]) => {
if (scope() === "workspace" && settings.hasWorkspace()) {
if (scope() === "folder" && props.folderPath) {
settings.setFolderSetting(props.folderPath, "editor", key, value);
} else if (scope() === "workspace" && settings.hasWorkspace()) {
settings.setWorkspaceSetting("editor", key, value);
} else {
settings.updateEditorSetting(key, value);
}
};

// Check if setting has workspace override
const hasOverride = (key: keyof EditorSettings) => settings.hasWorkspaceOverride("editor", key);
// Check if setting has workspace or folder override
const hasOverride = (key: keyof EditorSettings) => {
if (scope() === "folder" && props.folderPath) {
return settings.hasFolderOverride(props.folderPath, "editor", key);
}
return settings.hasWorkspaceOverride("editor", key);
};

// Check if setting is modified from default
const isModified = (key: keyof EditorSettings) => settings.isSettingModified("editor", key);

// Reset workspace override
// Reset workspace or folder override
const resetOverride = (key: keyof EditorSettings) => {
settings.resetWorkspaceSetting("editor", key);
if (scope() === "folder" && props.folderPath) {
settings.resetFolderSetting(props.folderPath, "editor", key);
} else {
settings.resetWorkspaceSetting("editor", key);
}
};

// Reset setting to default value
Expand Down Expand Up @@ -298,6 +315,19 @@ export function EditorSettingsPanel(props: EditorSettingsPanelProps) {
Editing workspace-specific editor settings. Changes apply only to this workspace.
</Badge>
</Show>
<Show when={scope() === "folder" && props.folderPath}>
<Badge variant="accent" style={{
padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,
"font-size": "var(--jb-text-muted-size)",
"border-radius": "var(--jb-radius-lg)",
"margin-bottom": "16px",
background: "rgba(16, 185, 129, 0.1)",
color: "rgb(16, 185, 129)",
border: "1px solid rgba(16, 185, 129, 0.3)",
}}>
Editing folder-specific editor settings. Changes apply only to files in this folder.
</Badge>
</Show>

{/* Font Settings */}
<Card variant="outlined" padding="none">
Expand Down Expand Up @@ -1159,7 +1189,7 @@ export function EditorSettingsPanel(props: EditorSettingsPanelProps) {
});
}}
>
Reset All Workspace Editor Overrides
{scope() === "folder" ? "Reset All Folder Editor Overrides" : "Reset All Workspace Editor Overrides"}
</Button>
}
>
Expand Down
Loading
Loading