fix: properly preserve UI state in settings panel
This fixes the issues introduced in the previous commit where: - Authentication section would collapse when switching config tabs and couldn't be reopened - Notification toggle would disappear after enabling notifications Root cause: The previous update methods were removing or re-querying DOM elements incorrectly. Solution: - Store direct references to configContainerEl and notificationToggleEl - Wrap notification toggle in dedicated container to preserve it during updates - updateNotificationSection() now preserves both summary AND toggle, only removes additional settings - updateConfigSection() uses stored reference instead of querying, preventing collapse Both sections now maintain their open/closed state correctly during targeted updates.
This commit is contained in:
@@ -6,7 +6,9 @@ import { generateApiKey } from './utils/auth-utils';
|
||||
export class MCPServerSettingTab extends PluginSettingTab {
|
||||
plugin: MCPServerPlugin;
|
||||
private notificationDetailsEl: HTMLDetailsElement | null = null;
|
||||
private notificationToggleEl: HTMLElement | null = null;
|
||||
private authDetailsEl: HTMLDetailsElement | null = null;
|
||||
private configContainerEl: HTMLElement | null = null;
|
||||
private activeConfigTab: 'windsurf' | 'claude-code' = 'windsurf';
|
||||
|
||||
constructor(app: App, plugin: MCPServerPlugin) {
|
||||
@@ -121,7 +123,9 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
|
||||
// Clear references for fresh render
|
||||
this.notificationDetailsEl = null;
|
||||
this.notificationToggleEl = null;
|
||||
this.authDetailsEl = null;
|
||||
this.configContainerEl = null;
|
||||
|
||||
containerEl.createEl('h2', {text: 'MCP Server Settings'});
|
||||
|
||||
@@ -259,6 +263,9 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
const configContainer = authDetails.createDiv({cls: 'mcp-config-snippet'});
|
||||
configContainer.style.marginBottom = '20px';
|
||||
|
||||
// Store reference for targeted updates
|
||||
this.configContainerEl = configContainer;
|
||||
|
||||
// Tab buttons for switching between clients
|
||||
const tabContainer = configContainer.createDiv({cls: 'mcp-config-tabs'});
|
||||
tabContainer.style.display = 'flex';
|
||||
@@ -358,8 +365,11 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
// Store reference for targeted updates
|
||||
this.notificationDetailsEl = notifDetails;
|
||||
|
||||
// Enable notifications
|
||||
new Setting(notifDetails)
|
||||
// Enable notifications - create container for the toggle setting
|
||||
const notificationToggleContainer = notifDetails.createDiv({cls: 'mcp-notification-toggle'});
|
||||
this.notificationToggleEl = notificationToggleContainer;
|
||||
|
||||
new Setting(notificationToggleContainer)
|
||||
.setName('Enable notifications')
|
||||
.setDesc('Show when MCP tools are called')
|
||||
.addToggle(toggle => toggle
|
||||
@@ -381,7 +391,7 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
* Update only the notification section without re-rendering entire page
|
||||
*/
|
||||
private updateNotificationSection(): void {
|
||||
if (!this.notificationDetailsEl) {
|
||||
if (!this.notificationDetailsEl || !this.notificationToggleEl) {
|
||||
// Fallback to full re-render if reference lost
|
||||
this.display();
|
||||
return;
|
||||
@@ -390,17 +400,16 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
// Store current open state
|
||||
const wasOpen = this.notificationDetailsEl.open;
|
||||
|
||||
// Find and remove all child elements except the summary
|
||||
// Remove all children except the summary and the toggle container
|
||||
const summary = this.notificationDetailsEl.querySelector('summary');
|
||||
// Remove children that come after the summary
|
||||
const children = Array.from(this.notificationDetailsEl.children);
|
||||
for (const child of children) {
|
||||
if (child !== summary) {
|
||||
if (child !== summary && child !== this.notificationToggleEl) {
|
||||
this.notificationDetailsEl.removeChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild notification settings
|
||||
// Rebuild notification settings only if enabled
|
||||
if (this.plugin.settings.notificationsEnabled) {
|
||||
this.renderNotificationSettings(this.notificationDetailsEl);
|
||||
}
|
||||
@@ -413,28 +422,20 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
* Update only the config section without re-rendering entire page
|
||||
*/
|
||||
private updateConfigSection(): void {
|
||||
if (!this.authDetailsEl) {
|
||||
if (!this.configContainerEl) {
|
||||
// Fallback to full re-render if reference lost
|
||||
this.display();
|
||||
return;
|
||||
}
|
||||
|
||||
// Store current open state
|
||||
const wasOpen = this.authDetailsEl.open;
|
||||
|
||||
// Find the config container element (it's under the authDetails)
|
||||
const configContainer = this.authDetailsEl.querySelector('.mcp-config-snippet');
|
||||
if (!configContainer) {
|
||||
// If we can't find it, just do a full re-render
|
||||
this.display();
|
||||
return;
|
||||
}
|
||||
// Store current open state of the auth details
|
||||
const wasOpen = this.authDetailsEl?.open ?? false;
|
||||
|
||||
// Clear the config container
|
||||
configContainer.empty();
|
||||
this.configContainerEl.empty();
|
||||
|
||||
// Tab buttons for switching between clients
|
||||
const tabContainer = configContainer.createDiv({cls: 'mcp-config-tabs'});
|
||||
const tabContainer = this.configContainerEl.createDiv({cls: 'mcp-config-tabs'});
|
||||
tabContainer.style.display = 'flex';
|
||||
tabContainer.style.gap = '8px';
|
||||
tabContainer.style.marginBottom = '16px';
|
||||
@@ -474,7 +475,7 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
const {filePath, config, usageNote} = this.generateConfigForClient(this.activeConfigTab);
|
||||
|
||||
// Tab content area
|
||||
const tabContent = configContainer.createDiv({cls: 'mcp-config-content'});
|
||||
const tabContent = this.configContainerEl.createDiv({cls: 'mcp-config-content'});
|
||||
tabContent.style.marginTop = '16px';
|
||||
|
||||
// File location label
|
||||
@@ -519,7 +520,9 @@ export class MCPServerSettingTab extends PluginSettingTab {
|
||||
usageNoteDisplay.style.color = 'var(--text-muted)';
|
||||
usageNoteDisplay.style.fontStyle = 'italic';
|
||||
|
||||
// Restore open state
|
||||
this.authDetailsEl.open = wasOpen;
|
||||
// Restore open state (only if authDetailsEl is available)
|
||||
if (this.authDetailsEl) {
|
||||
this.authDetailsEl.open = wasOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user