DEV Community

linou518
linou518

Posted on

How I Eliminated Button Hell in Node Management UI — Implementing an Accordion-Style Control Panel

How I Eliminated Button Hell in Node Management UI — Implementing an Accordion-Style Control Panel

Managing a growing dashboard inevitably leads to one problem: too many buttons.

Techsfree's Dashboard has a node management screen for controlling each server running OpenClaw. It started with just "Restart" and "Backup" buttons. Before I knew it, there were 9 actions: Backup, Restore, Restart, Add Bot, Backup List, Diagnostics, Logs, Retire, Remove Bot.

22 nodes. 22 cards. 9 buttons per card.

Vertical scrolling was a nightmare.


The Problem

The node management UI displays each node as a card. Each card contains:

  • Node name, hostname, port
  • Running Agent tag list
  • Status like disk usage
  • Action buttons

The "action buttons" were the problem. In practice, "Restart" and "Backup" are the only frequently-used actions. "Retire" and "Remove Bot" are rarely touched. Yet all 9 buttons were always fully expanded and visible.

/* Before: buttons just laid out in a grid */
.nm-node-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
Enter fullscreen mode Exit fullscreen mode

Solution: Accordion with Default Collapsed State

The fix was simple: add a "⚙️ Actions ▼" toggle button that expands the action panel only when clicked.

HTML Structure

<button class="nm-actions-toggle" onclick="nmToggleActions('${n.id}', this)">
  <span>⚙️ Actions</span>
  <span class="nm-toggle-arrow"></span>
</button>
<div class="nm-actions-body" id="nmActionsBody-${n.id}">
  <div class="nm-node-actions">
    <!-- action buttons -->
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS

.nm-actions-toggle {
  width: 100%;
  padding: 5px 0;
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: background 0.15s;
}

.nm-actions-toggle:hover {
  background: var(--bg);
  color: var(--text);
}

/* Hidden by default */
.nm-actions-body {
  display: none;
  overflow: hidden;
}

/* Expanded when .open class is present */
.nm-actions-body.open {
  display: block;
}
Enter fullscreen mode Exit fullscreen mode

JavaScript

function nmToggleActions(nodeId, btn) {
  const body = document.getElementById('nmActionsBody-' + nodeId);
  const arrow = btn.querySelector('.nm-toggle-arrow');
  if (!body) return;
  const isOpen = body.classList.contains('open');
  body.classList.toggle('open', !isOpen);
  if (arrow) arrow.textContent = isOpen ? '' : '';
}
Enter fullscreen mode Exit fullscreen mode

Just 20 lines of change, but the impact was significant.


Why Use display: none Instead of Animation?

There are several approaches to accordion implementation:

Method Pros Cons
display: none/block toggle Simple, fast No animation
max-height animation Smooth open/close Height calculation is tricky, misaligns with dynamic content
height + overflow Accurate animation Need to get/set height via JS

For an admin dashboard, reliability trumps animation. The max-height animation is prone to bugs when content height varies — and in our case, the number of agent tags per node changes dynamically. A simple display toggle was the right call.


Results After Implementation

  • Per-card height reduced by ~40%
  • All 22 cards visible without painful vertical scrolling
  • "Open only when needed" UX reduces accidental clicks
  • ▼ / ▲ arrows give clear visual state feedback

This pattern works well beyond admin dashboards — card-based UIs with high information density like settings pages, table row expansion, and any dashboard where you want progressive disclosure.

A rough guideline: if there are 3 or fewer buttons, collapsing is unnecessary. At 5 or more, start thinking about it.


Tags: JavaScript, CSS, frontend, UI, accordion, admin-panel, SPA, dashboard, openclaw

Top comments (0)