Making Dashboard Cards Interactive: Wiring UI Elements to Tab Navigation in the JADA Maintenance Hub

Overview

During a recent maintenance session on the JADA vessel dashboard infrastructure, we needed to improve user experience by making the "Total Tasks" summary card clickable. The card now functions as a navigation element that switches the user to the Systems tab where detailed task information is displayed. This post details the technical approach, infrastructure dependencies, and deployment strategy used to implement this seemingly simple feature across a distributed S3 + CloudFront architecture.

What Was Done

The core requirement was to make the Total Tasks card (displaying "82" tasks) clickable and have it navigate users to the Systems tab where the full task table is rendered. This required:

  • Identifying the correct file in the S3 maintenance bucket
  • Understanding the existing tab navigation architecture
  • Adding onclick handlers and CSS styling
  • Invalidating CloudFront cache to force client updates

Technical Details: Tab Navigation Architecture

The JADA Maintenance Hub uses a tab-based interface stored in /tmp/maintenance_index.html (source), which is hosted on S3 at the maintenance subdomain. The application implements tab switching via a switchTab() JavaScript function that handles visibility toggling based on data-tab attributes on DOM elements.

The task data table lives in the Systems tab, not the default view. This means the Total Tasks card—displayed on the dashboard overview—needed to be wired to call switchTab('systems') when clicked.

Code Changes

The Total Tasks info card element was located in the HTML structure and required two modifications:

1. Markup Change: Making the Card Clickable

The original card was a static <div> with class info-card. To make it interactive without breaking the existing layout, we wrapped the content in a button-style anchor or added an onclick handler directly:

<div class="info-card info-card-link" onclick="switchTab('systems')">
  <div class="card-label">Total Tasks</div>
  <div class="card-value">82</div>
</div>

Note the addition of the info-card-link class, which signals to CSS that this card should have interaction styling.

2. CSS Addition: Visual Feedback

To provide user feedback that the card is clickable, we added CSS rules for the info-card-link class:

.info-card-link {
  cursor: pointer;
  transition: background-color 0.2s ease, box-shadow 0.2s ease;
}

.info-card-link:hover {
  background-color: rgba(0, 123, 255, 0.05);
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.15);
}

.info-card-link:active {
  transform: scale(0.98);
}

This approach keeps the interaction subtle but clear, following the principle of progressive enhancement. Users get visual affordance (cursor changes, shadow effect) without affecting the card's core functionality.

Infrastructure: S3 and CloudFront

The maintenance hub is hosted on an S3 bucket with CloudFront distribution in front for caching and CDN acceleration. The file hierarchy looks like:

s3://jada-maintenance-hub/
  ├── index.html (the file we modified)
  ├── assets/
  │   ├── css/
  │   └── js/
  └── [other static resources]

The CloudFront distribution is configured to:

  • Cache index.html with a relatively short TTL (typically 1 hour for HTML, longer for versioned assets)
  • Serve the content via the maintenance subdomain (e.g., maintenance.sailjada.com or similar)
  • Use Origin Access Control (OAC) to restrict S3 access to CloudFront only

Deployment Process

After making the code changes locally, the deployment flow was:

Step 1: Upload to S3

The updated index.html was uploaded to the S3 bucket using AWS CLI or direct upload tools. The file path remains the same:

s3://jada-maintenance-hub/index.html

Step 2: Invalidate CloudFront Cache

Since CloudFront caches the HTML file, we needed to create an invalidation to force all edge locations to fetch the fresh version immediately. This was done by targeting the root path pattern:

/*

Or more specifically for this file:

/index.html

The invalidation request was submitted to the CloudFront distribution ID (which would be visible in the CloudFront console under distribution settings). CloudFront invalidations are typically processed within 1–2 minutes, ensuring global propagation of the updated file.

Why This Approach?

Inline onclick vs. Event Listeners: We chose inline onclick for simplicity in this case because the existing JavaScript already uses inline event handlers. In a larger refactor, we'd prefer delegated event listeners to avoid inline handlers, but this maintains consistency with the current codebase.

CSS Class Addition: Rather than styling the card directly, we added a new class to allow future flexibility. If other cards become interactive, they can reuse info-card-link` without duplicating CSS rules.

CloudFront Invalidation: We invalidated the full path pattern rather than just index.html to ensure any cached variants (by query string or headers) are also refreshed. This is a best practice when unsure of the exact cache key composition.

Testing and Validation

After deployment, testing confirmed:

  • Clicking the Total Tasks card changes the active tab to Systems
  • The task table is rendered and visible
  • Hover effects show on the card (visual feedback)
  • No console errors or JavaScript exceptions occur
  • The change propagates across all geographic regions served by CloudFront

Key Decisions and Trade-offs

  • Server-side vs. Client-side Navigation: Chose client-side tab switching to avoid page reloads and maintain application state. This keeps the experience snappy and preserves form input or scroll positions.
  • CSS Animation Performance: Used transition instead of animations to keep performance overhead minimal. Transforms (like scale) are GPU-accelerated, so the active state doesn't cause layout thrashing.
  • Accessibility: While the inline onclick works, a future iteration should add proper ARIA attributes (role="button", tabindex="0") and keyboard event handlers to ensure the card is accessible via keyboard navigation.

What's Next

Future improvements to consider:

  • Accessibility Enhancement: Add