feat: redesign settings pages to match canonical flat UI patterns (#493)

* refactor(settings): new IA shell + projects section + skills catalog discoverability

* chore(settings): split providers list by scope; show user before project

* fix: navigation flow in mobile Settings

* feat: redesign settings pages to use modern elevated surface patterns

* feat: replace helper text with tooltips in settings

* ui: redesign update dialog and fix external link routing

- Restructures UpdateDialog to focus on changelog readability with a wider max-w-4xl canvas
- Highlights @username contributor mentions with theme primary color
- Strips excessive vertical padding and right-aligns compact action buttons
- Disables streamdown's internal link safety dialog in favor of direct Tauri shell routing

* feat: refactor Git identities into dedicated Git settings page

* feat: unify sidebar background styling across VS Code and web/mobile

* fix: adjust button styling and layout for mobile settings pages

* feat: add MCP settings page and sidebar

* feat: hide models in provider view (thanks to @nguyenngothuong)

* feat: add "Add new provider" option to model selector dropdown

* fix: local evroc logo + provider dropdown icons

* fix: increase width of provider menu

* fix: dark theme background color for better contrast

* feat: update @opencode-ai/sdk dependency to v1.2.10

* fix: restore session sorting to only use updated time

* fix: added settings for sessions deletion dialog

* fix: adjust padding on settings pages for better layout

* fix: standardize select dropdown height across UI

* fix: agent selector UI and notification settings

* fix: remove redundant helper text from settings pages

* fix: update UI layout for description fields

* fix: remove border-none and shadow-none from textarea classes

* fix: enable context menu on sidebar items

* feat: refactor UI controls and layout patterns across settings pages

* fix: use headerless blocks when page title already provides context

* fix: remove subtask option from command settings

* fix: refactor mcp page settings

* fix: reduce spacing in skills configuration pages

* feat: refactor voice settings

* feat: refactor settings sidebar sections
This commit is contained in:
Bohdan Triapitsyn
2026-02-24 03:28:30 +02:00
committed by GitHub
parent d2d39c48ac
commit d2358c2c03
90 changed files with 8062 additions and 7128 deletions
@@ -15,6 +15,7 @@ import type {
import { refreshSkillsAfterOpenCodeRestart, useSkillsStore } from '@/stores/useSkillsStore';
import { opencodeClient } from '@/lib/opencode/client';
import { startConfigUpdate, finishConfigUpdate, updateConfigUpdateMessage } from '@/lib/configUpdate';
const FALLBACK_SOURCES: SkillsCatalogSource[] = [
{
@@ -79,7 +80,7 @@ export interface SkillsCatalogState {
loadSource: (sourceId: string, options?: { refresh?: boolean }) => Promise<boolean>;
loadMoreClawdHub: () => Promise<boolean>;
scanRepo: (request: SkillsRepoScanRequest) => Promise<SkillsRepoScanResponse>;
installSkills: (request: SkillsInstallRequest) => Promise<SkillsInstallResponse>;
installSkills: (request: SkillsInstallRequest, options?: { directory?: string | null }) => Promise<SkillsInstallResponse>;
}
export const useSkillsCatalogStore = create<SkillsCatalogState>()(
@@ -348,10 +349,15 @@ export const useSkillsCatalogStore = create<SkillsCatalogState>()(
}
},
installSkills: async (request) => {
installSkills: async (request, options) => {
startConfigUpdate('Installing skills…');
set({ isInstalling: true, lastInstallError: null });
let requiresReload = false;
try {
const currentDirectory = getCurrentDirectory();
const directoryOverride = typeof options?.directory === 'string' && options.directory.trim().length > 0
? options.directory.trim()
: null;
const currentDirectory = directoryOverride ?? getCurrentDirectory();
const queryParams = currentDirectory ? `?directory=${encodeURIComponent(currentDirectory)}` : '';
const response = await fetch(`/api/config/skills/install${queryParams}`, {
@@ -364,21 +370,25 @@ export const useSkillsCatalogStore = create<SkillsCatalogState>()(
if (!payload) {
const error = { kind: 'unknown', message: 'Failed to install skills' } as SkillsInstallError;
set({ lastInstallError: error });
updateConfigUpdateMessage('Failed to install skills. Please retry.');
return { ok: false, error };
}
if (!response.ok || !payload.ok) {
const error = payload.error || ({ kind: 'unknown', message: 'Failed to install skills' } as SkillsInstallError);
set({ lastInstallError: error });
updateConfigUpdateMessage(error.message || 'Failed to install skills. Please retry.');
return { ok: false, error };
}
if (payload.requiresReload) {
requiresReload = true;
await refreshSkillsAfterOpenCodeRestart({
message: payload.message,
delayMs: payload.reloadDelayMs,
});
} else {
updateConfigUpdateMessage(payload.message || 'Refreshing skills…');
void useSkillsStore.getState().loadSkills();
}
@@ -386,9 +396,13 @@ export const useSkillsCatalogStore = create<SkillsCatalogState>()(
} catch (error) {
const err = { kind: 'unknown', message: error instanceof Error ? error.message : String(error) } as SkillsInstallError;
set({ lastInstallError: err });
updateConfigUpdateMessage('Failed to install skills. Please retry.');
return { ok: false, error: err };
} finally {
set({ isInstalling: false });
if (!requiresReload) {
finishConfigUpdate();
}
}
},
}),