refactor(tabs): centralize tab wiring in base Component.setupTabs with onChange hook; persist and restore NodeDetails active tab; reuse base tabs in ClusterMembersComponent

This commit is contained in:
2025-08-31 11:06:39 +02:00
parent c0aef5b8d5
commit f18907d9e4
2 changed files with 20 additions and 42 deletions

View File

@@ -571,32 +571,14 @@ class ClusterMembersComponent extends Component {
} }
setupTabs(container) { setupTabs(container) {
const tabButtons = container.querySelectorAll('.tab-button'); super.setupTabs(container, {
const tabContents = container.querySelectorAll('.tab-content'); onChange: (targetTab) => {
tabButtons.forEach(button => {
this.addEventListener(button, 'click', (e) => {
e.stopPropagation();
const targetTab = button.dataset.tab;
// Use base helper to set active tab
this.setActiveTab(targetTab, container);
// Store active tab state
const memberCard = container.closest('.member-card'); const memberCard = container.closest('.member-card');
if (memberCard) { if (memberCard) {
const memberIp = memberCard.dataset.memberIp; const memberIp = memberCard.dataset.memberIp;
this.viewModel.storeActiveTab(memberIp, targetTab); this.viewModel.storeActiveTab(memberIp, targetTab);
} }
}); }
});
// Also prevent event propagation on tab content areas
tabContents.forEach(content => {
this.addEventListener(content, 'click', (e) => {
e.stopPropagation();
});
}); });
} }
@@ -884,6 +866,11 @@ class NodeDetailsComponent extends Component {
this.setHTML('', html); this.setHTML('', html);
this.setupTabs(); this.setupTabs();
// Restore last active tab from view model if available
const restored = this.viewModel && typeof this.viewModel.get === 'function' ? this.viewModel.get('activeTab') : null;
if (restored) {
this.setActiveTab(restored);
}
this.setupFirmwareUpload(); this.setupFirmwareUpload();
} }
@@ -1158,26 +1145,13 @@ class NodeDetailsComponent extends Component {
setupTabs() { setupTabs() {
console.log('NodeDetailsComponent: Setting up tabs'); console.log('NodeDetailsComponent: Setting up tabs');
const tabButtons = this.findAllElements('.tab-button'); super.setupTabs(this.container, {
const tabContents = this.findAllElements('.tab-content'); onChange: (tab) => {
// Persist active tab in the view model for restoration
tabButtons.forEach(button => { if (this.viewModel && typeof this.viewModel.setActiveTab === 'function') {
this.addEventListener(button, 'click', (e) => { this.viewModel.setActiveTab(tab);
e.stopPropagation(); }
}
const targetTab = button.dataset.tab;
console.log('NodeDetailsComponent: Tab clicked:', targetTab);
// Update tab UI locally, don't store in view model
this.setActiveTab(targetTab);
});
});
// Also prevent event propagation on tab content areas
tabContents.forEach(content => {
this.addEventListener(content, 'click', (e) => {
e.stopPropagation();
});
}); });
} }

View File

@@ -570,7 +570,8 @@ class Component {
} }
// Tab helpers // Tab helpers
setupTabs(container = this.container) { setupTabs(container = this.container, options = {}) {
const { onChange } = options;
const tabButtons = container.querySelectorAll('.tab-button'); const tabButtons = container.querySelectorAll('.tab-button');
const tabContents = container.querySelectorAll('.tab-content'); const tabContents = container.querySelectorAll('.tab-content');
tabButtons.forEach(button => { tabButtons.forEach(button => {
@@ -578,6 +579,9 @@ class Component {
e.stopPropagation(); e.stopPropagation();
const targetTab = button.dataset.tab; const targetTab = button.dataset.tab;
this.setActiveTab(targetTab, container); this.setActiveTab(targetTab, container);
if (typeof onChange === 'function') {
try { onChange(targetTab); } catch (_) {}
}
}); });
}); });
tabContents.forEach(content => { tabContents.forEach(content => {