Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
acharneski committed Dec 8, 2024
1 parent c0dff25 commit 5987b0a
Show file tree
Hide file tree
Showing 19 changed files with 4,850 additions and 1,293 deletions.
88 changes: 65 additions & 23 deletions webapp/src/utils/tabHandling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,24 @@ export function setActiveTab(button: Element, container: Element) {
})
setActiveTabState(container.id, forTab);
saveTabState(container.id, forTab);
// Update to handle nested tab buttons correctly
const tabsContainer = container.querySelector('.tabs');
// First try to find direct .tabs child, then look for anchor-wrapped tabs
const tabsContainer = container.querySelector(':scope > .tabs') ||
container.querySelector(':scope > a > .tabs');
if (tabsContainer) {
tabsContainer.querySelectorAll('.tab-button').forEach(btn => {
tabsContainer.querySelectorAll(':scope > .tab-button').forEach(btn => {
if (btn.getAttribute('data-for-tab') === forTab) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
}
container.querySelectorAll(':scope > .tab-content').forEach(content => {
// Query both direct children and anchor-wrapped tab content
const tabContents = [
...container.querySelectorAll(':scope > .tab-content'),
...container.querySelectorAll(':scope > a > .tab-content')
];
tabContents.forEach(content => {
if (content.getAttribute('data-tab') === forTab) {
content.classList.add('active');
(content as HTMLElement).style.display = 'block';
Expand Down Expand Up @@ -205,9 +211,10 @@ function restoreTabState(container: Element) {
const savedTab = getActiveTab(containerId) ||
tabStates.get(containerId)?.activeTab;
if (savedTab) {
// Update button selector to handle nested structure
const tabsContainer = container.querySelector('.tabs');
const button = tabsContainer?.querySelector(`.tab-button[data-for-tab="${savedTab}"]`) as HTMLElement;
// First try direct child tabs, then anchor-wrapped tabs
const tabsContainer = container.querySelector(':scope > .tabs') ||
container.querySelector(':scope > a > .tabs');
const button = tabsContainer?.querySelector(`:scope > .tab-button[data-for-tab="${savedTab}"]`) as HTMLElement;
if (button) {
setActiveTab(button, container);
diagnostics.restoreSuccess++;
Expand Down Expand Up @@ -258,19 +265,23 @@ export const updateTabs = debounce(() => {
try {
const currentStates = getAllTabStates();
const processed = new Set<string>();
const tabsContainers = document.querySelectorAll('.tabs-container').values().toArray();
const tabsContainers = Array.from(document.querySelectorAll('.tabs-container'));
isMutating = true;
console.debug(`Starting tab update`, {
containersCount: document.querySelectorAll('.tabs-container').length,
existingStates: currentStates.size,
tabsContainers: tabsContainers.map(c => c.id)
});
tabsContainers.forEach(container => {
if (processed.has(container.id)) {
return;
}
processed.add(container.id);

setupTabContainer(container);
const activeTab = getActiveTab(container.id)
|| currentStates.get(container.id)?.activeTab
|| container.querySelector(':scope > .tab-button.active')?.getAttribute('data-for-tab')
;
const activeTab = getActiveTab(container.id) ||
currentStates.get(container.id)?.activeTab ||
container.querySelector(':scope > .tabs > .tab-button.active')?.getAttribute('data-for-tab');
if (activeTab) {
const state: TabState = {
containerId: container.id,
Expand All @@ -279,22 +290,35 @@ export const updateTabs = debounce(() => {
tabStates.set(container.id, state);
restoreTabState(container);
} else {
// console.warn(`No active tab found for container`, {
// containerId: container.id
// });
// Try to activate first tab if none active
const firstButton = container.querySelector(':scope > .tabs > .tab-button');
if (firstButton instanceof HTMLElement) {
const firstTabId = firstButton.getAttribute('data-for-tab');
if (firstTabId) {
setActiveTab(firstButton, container);
}
}
console.warn(`No active tab found for container`, {
containerId: container.id
});
}
});
document.querySelectorAll('.tabs-container').forEach((container: Element) => {
if (container instanceof HTMLElement) {
if (processed.has(container.id)) {
return;
}
processed.add(container.id);

let activeTab: string | undefined = getActiveTab(container.id);
if (!activeTab) {
// console.warn(`No active tab found`, {
// containerId: container.id,
// action: 'checking active button'
// });
// Update active button selector
const tabsContainer = container.querySelector('.tabs');
const activeButton = tabsContainer?.querySelector('.tab-button.active');
const tabsContainer = container.querySelector(':scope > .tabs, :scope > a > .tabs');
const activeButton = tabsContainer?.querySelector(':scope > .tab-button.active');
if (activeButton) {
activeTab = activeButton.getAttribute('data-for-tab') || '';
}
Expand All @@ -305,10 +329,11 @@ export const updateTabs = debounce(() => {
// action: 'defaulting to first tab'
// });
// Update first button selector
const tabsContainer = container.querySelector('.tabs');
const firstButton = tabsContainer?.querySelector('.tab-button') as HTMLElement;
const tabsContainer = container.querySelector(':scope > .tabs, :scope > a > .tabs');
const firstButton = tabsContainer?.querySelector(':scope > .tab-button') as HTMLElement;
if (firstButton) {
activeTab = firstButton.getAttribute('data-for-tab') || '';
setActiveTab(firstButton, container);
} else {
console.warn(`No tab buttons found`, {
containerId: container.id,
Expand All @@ -319,10 +344,11 @@ export const updateTabs = debounce(() => {

let activeCount = 0;
let inactiveCount = 0;
// Update button iteration
const tabsContainer = container.querySelector('.tabs');
// Handle both direct and anchor-wrapped tabs
const tabsContainer = container.querySelector(':scope > .tabs') ||
container.querySelector(':scope > a > .tabs');
if (tabsContainer) {
tabsContainer.querySelectorAll('.tab-button').forEach(button => {
tabsContainer.querySelectorAll(':scope > .tab-button').forEach(button => {
if (button.getAttribute('data-for-tab') === activeTab) {
button.classList.add('active');
activeCount++;
Expand All @@ -331,6 +357,21 @@ export const updateTabs = debounce(() => {
inactiveCount++;
}
});
// Also update tab content visibility
// Query both direct children and anchor-wrapped tab content
const tabContents = [
...container.querySelectorAll(':scope > .tab-content'),
...container.querySelectorAll(':scope > a > .tab-content')
];
tabContents.forEach(content => {
if (content.getAttribute('data-tab') === activeTab) {
content.classList.add('active');
(content as HTMLElement).style.display = 'block';
} else {
content.classList.remove('active');
(content as HTMLElement).style.display = 'none';
}
});
}
if (VERBOSE_LOGGING) console.debug(`${`Synchronized ${activeCount + inactiveCount} buttons`}`, {
activeTab,
Expand Down Expand Up @@ -369,9 +410,10 @@ function setupTabContainer(container: Element) {
})
container.addEventListener('click', (event: Event) => {
const button = (event.target as HTMLElement).closest('.tab-button');
if (button && container.contains(button)) {
if (button && (container.contains(button) || container.querySelector('a')?.contains(button))) {
setActiveTab(button, container);
event.stopPropagation();
event.preventDefault(); // Prevent anchor tag navigation
}
});
} catch (error) {
Expand Down
6 changes: 3 additions & 3 deletions webui/src/main/resources/application/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"files": {
"main.css": "/static/css/main.0b4c55b7.css",
"main.js": "/static/js/main.89ea7cbc.js",
"main.js": "/static/js/main.bb1fe951.js",
"static/js/9017.98ad007d.chunk.js": "/static/js/9017.98ad007d.chunk.js",
"static/js/5536.9c75127e.chunk.js": "/static/js/5536.9c75127e.chunk.js",
"static/js/7035.2bce51c5.chunk.js": "/static/js/7035.2bce51c5.chunk.js",
Expand Down Expand Up @@ -72,7 +72,7 @@
"static/js/5195.756798f5.chunk.js": "/static/js/5195.756798f5.chunk.js",
"index.html": "/index.html",
"main.0b4c55b7.css.map": "/static/css/main.0b4c55b7.css.map",
"main.89ea7cbc.js.map": "/static/js/main.89ea7cbc.js.map",
"main.bb1fe951.js.map": "/static/js/main.bb1fe951.js.map",
"9017.98ad007d.chunk.js.map": "/static/js/9017.98ad007d.chunk.js.map",
"5536.9c75127e.chunk.js.map": "/static/js/5536.9c75127e.chunk.js.map",
"7035.2bce51c5.chunk.js.map": "/static/js/7035.2bce51c5.chunk.js.map",
Expand Down Expand Up @@ -139,6 +139,6 @@
},
"entrypoints": [
"static/css/main.0b4c55b7.css",
"static/js/main.89ea7cbc.js"
"static/js/main.bb1fe951.js"
]
}
20 changes: 1 addition & 19 deletions webui/src/main/resources/application/index.html
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="icon" href="favicon.ico"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="theme-color" content="#000000"/>
<meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="logo192.png"/>
<link rel="manifest" href="manifest.json"/>
<title>React App</title>
<script defer="defer" src="static/js/main.89ea7cbc.js"></script>
<link href="static/css/main.0b4c55b7.css" rel="stylesheet">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.bb1fe951.js"></script><link href="/static/css/main.0b4c55b7.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
Loading

0 comments on commit 5987b0a

Please sign in to comment.