FinTech & Expense Tracking Analytics Dashboard

A responsive online store & personal finance dashboard featuring interactive expense charts, category breakdowns, transaction filters, and CSV exporter.

Dashboards & Web Apps

FinTech & Expense Tracking Analytics Dashboard

334 views • 156 downloads

💳 Executive Project Overview

The FinTech & Expense Tracking Analytics Dashboard is a modern, responsive web application template designed for financial technology startups, SaaS platforms, and personal budgeting management. Built with Tailwind CSS and Chart.js, it provides real-time income and expense visualization, KPI metric tracking, filterable data tables, and 1-click CSV reporting.

📊

Chart.js Cashflow Visualization

Interactive bar and doughnut charts rendering monthly cash flows, income streams, and expense category distributions with smooth animations.

📈

Real-Time KPI Financial Cards

Automated calculation of Total Net Balance, Monthly Income, Total Expenses, and Savings Target percentages dynamically updated upon transaction entry.

🔎

Searchable Data Table

Instant search and category dropdown filters allowing users to quickly look up past transactions, merchant names, or payment types.

📄

CSV Export & Modal Form

Pop-up modal dialog for adding new financial logs along with instant 1-click CSV data export for spreadsheet integration in Excel or Google Sheets.

Key Advantages & Benefits

  • Production-Ready Template: Fully structured UI components easily adaptable for Laravel, Vue.js, or React SaaS projects.
  • Sleek Glassmorphic Dark Aesthetics: Premium visual design tailored for modern financial and crypto applications.
  • Mobile-First Responsive Layout: Flawless grid responsiveness across mobile smartphones, tablets, and desktop displays.
  • 100% Free Open-Source Code: Full source code included with standard MIT license for commercial reuse.

🛠️ How to Use the FinTech Dashboard

  1. Click Add Transaction in the top header to open the modal entry form.
  2. Enter the merchant title, choose income or expense type, pick a category, and specify the amount.
  3. Watch your KPI Net Balance cards and Chart.js graphs update automatically in real-time.
  4. Use the search box or dropdown filter to inspect specific transaction logs.
  5. Click Export CSV to save your complete transaction ledger as a spreadsheet file.
<!DOCTYPE html>
<html lang="en" class="h-full dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FinTech & Expense Tracking Analytics Dashboard - Web App</title>
    
    <!-- Fonts & Icons -->
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Outfit:wght@600;700;800&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
    
    <!-- Tailwind CSS & Chart.js CDN -->
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script>
        tailwind.config = {
            darkMode: 'class',
            theme: {
                extend: {
                    fontFamily: {
                        sans: ['Inter', 'sans-serif'],
                        outfit: ['Outfit', 'sans-serif']
                    }
                }
            }
        }
    </script>
    <style>
        body { margin: 0; padding: 0; min-height: 100vh; }
        ::-webkit-scrollbar { width: 6px; height: 6px; }
        ::-webkit-scrollbar-track { background: rgba(15, 23, 42, 0.1); }
        .dark ::-webkit-scrollbar-track { background: rgba(15, 23, 42, 0.6); }
        ::-webkit-scrollbar-thumb { background: rgba(6, 182, 212, 0.4); border-radius: 4px; }
    </style>
</head>
<body class="min-h-full text-slate-900 dark:text-slate-100 flex flex-col font-sans select-none bg-slate-50 dark:bg-slate-950 transition-colors duration-200">

    <!-- Header Navigation -->
    <header class="h-16 bg-white/90 dark:bg-slate-900/90 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 px-4 sm:px-6 flex items-center justify-between shrink-0 z-30 sticky top-0 transition-colors duration-200">
        <div class="flex items-center gap-3">
            <div class="w-9 h-9 rounded-xl bg-gradient-to-tr from-cyan-500 to-blue-600 flex items-center justify-center text-white font-outfit font-extrabold text-lg shadow-lg shadow-cyan-500/20">
                💳
            </div>
            <div>
                <h1 class="font-outfit font-bold text-sm sm:text-base text-slate-900 dark:text-white tracking-wide">FinTech & Expense Tracking Analytics</h1>
                <p class="text-[10px] text-cyan-600 dark:text-cyan-400 font-mono font-semibold">Personal & Business Financial Dashboard</p>
            </div>
        </div>

        <div class="flex items-center gap-3">
            <button id="addTxBtn" class="px-3.5 py-1.5 rounded-xl bg-cyan-500 hover:bg-cyan-400 text-slate-950 font-outfit font-bold text-xs transition flex items-center gap-1.5 shadow-md shadow-cyan-500/20">
                <i class="fa-solid fa-plus"></i>
                <span>Add Transaction</span>
            </button>
            <button id="exportCsvBtn" class="px-3.5 py-1.5 rounded-xl bg-slate-100 dark:bg-slate-800 hover:bg-slate-200 dark:hover:bg-slate-700 text-slate-800 dark:text-white font-outfit font-bold text-xs transition flex items-center gap-1.5 border border-slate-300 dark:border-slate-700">
                <i class="fa-solid fa-file-csv text-emerald-600 dark:text-emerald-400"></i>
                <span>Export CSV</span>
            </button>
        </div>
    </header>

    <!-- Main Dashboard Container -->
    <main class="flex-1 p-4 sm:p-6 max-w-7xl w-full mx-auto space-y-6">

        <!-- 1. KPI Top Summary Cards -->
        <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            <!-- Card 1: Total Balance -->
            <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-2 transition-colors duration-200">
                <div class="flex items-center justify-between text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider">
                    <span>Total Net Balance</span>
                    <span class="p-2 rounded-xl bg-cyan-500/10 text-cyan-600 dark:text-cyan-400"><i class="fa-solid fa-wallet"></i></span>
                </div>
                <div class="font-outfit font-extrabold text-2xl sm:text-3xl text-slate-900 dark:text-white font-mono" id="totalBalanceVal">$24,850.00</div>
                <div class="text-[11px] font-semibold text-emerald-600 dark:text-emerald-400 flex items-center gap-1">
                    <i class="fa-solid fa-arrow-trend-up"></i> +12.5% from last month
                </div>
            </div>

            <!-- Card 2: Total Income -->
            <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-2 transition-colors duration-200">
                <div class="flex items-center justify-between text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider">
                    <span>Monthly Income</span>
                    <span class="p-2 rounded-xl bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"><i class="fa-solid fa-money-bill-wave"></i></span>
                </div>
                <div class="font-outfit font-extrabold text-2xl sm:text-3xl text-emerald-600 dark:text-emerald-400 font-mono" id="totalIncomeVal">$8,400.00</div>
                <div class="text-[11px] font-semibold text-emerald-600 dark:text-emerald-400 flex items-center gap-1">
                    <i class="fa-solid fa-circle-check"></i> 100% Verified Payroll
                </div>
            </div>

            <!-- Card 3: Total Expense -->
            <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-2 transition-colors duration-200">
                <div class="flex items-center justify-between text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider">
                    <span>Monthly Expenses</span>
                    <span class="p-2 rounded-xl bg-rose-500/10 text-rose-600 dark:text-rose-400"><i class="fa-solid fa-credit-card"></i></span>
                </div>
                <div class="font-outfit font-extrabold text-2xl sm:text-3xl text-rose-600 dark:text-rose-400 font-mono" id="totalExpenseVal">$3,150.00</div>
                <div class="text-[11px] font-semibold text-rose-600 dark:text-rose-400 flex items-center gap-1">
                    <i class="fa-solid fa-arrow-trend-down"></i> -4.2% lower budget target
                </div>
            </div>

            <!-- Card 4: Savings Rate -->
            <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-2 transition-colors duration-200">
                <div class="flex items-center justify-between text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider">
                    <span>Savings Rate</span>
                    <span class="p-2 rounded-xl bg-purple-500/10 text-purple-600 dark:text-purple-400"><i class="fa-solid fa-piggy-bank"></i></span>
                </div>
                <div class="font-outfit font-extrabold text-2xl sm:text-3xl text-purple-600 dark:text-purple-300 font-mono" id="savingsRateVal">62.5%</div>
                <div class="text-[11px] font-semibold text-cyan-600 dark:text-cyan-400 flex items-center gap-1">
                    <i class="fa-solid fa-bullseye"></i> Goal: 60% Monthly Target
                </div>
            </div>
        </div>

        <!-- 2. Charts Section (Cashflow & Category Breakdown) -->
        <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
            <!-- Main Bar Chart (Monthly Cash Flow) -->
            <div class="lg:col-span-2 bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 sm:p-6 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-4 transition-colors duration-200">
                <div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800/80 pb-3">
                    <h2 class="font-outfit font-extrabold text-lg text-slate-900 dark:text-white">Monthly Cashflow Analytics</h2>
                    <span class="text-xs text-slate-500 dark:text-slate-400 font-mono">Income vs Expenses (2026)</span>
                </div>
                <div class="h-64 relative">
                    <canvas id="cashflowChart"></canvas>
                </div>
            </div>

            <!-- Donut Chart (Expenses by Category) -->
            <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 sm:p-6 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-4 transition-colors duration-200">
                <div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800/80 pb-3">
                    <h2 class="font-outfit font-extrabold text-lg text-slate-900 dark:text-white">Expense Breakdown</h2>
                    <span class="text-xs text-cyan-600 dark:text-cyan-400 font-mono font-semibold">By Category</span>
                </div>
                <div class="h-64 relative flex items-center justify-center">
                    <canvas id="categoryChart"></canvas>
                </div>
            </div>
        </div>

        <!-- 3. Recent Transactions Data Table -->
        <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl p-5 sm:p-6 shadow-xl shadow-slate-200/50 dark:shadow-none space-y-4 transition-colors duration-200">
            <div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 border-b border-slate-200 dark:border-slate-800/80 pb-4">
                <div>
                    <h2 class="font-outfit font-extrabold text-lg text-slate-900 dark:text-white">Recent Transactions</h2>
                    <p class="text-xs text-slate-500 dark:text-slate-400">Manage and filter recent income and expense logs</p>
                </div>

                <div class="flex items-center gap-2 w-full sm:w-auto">
                    <input type="text" id="txSearch" placeholder="Search transaction..." class="bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 text-xs rounded-xl px-3.5 py-2 text-slate-800 dark:text-slate-200 focus:outline-none focus:border-cyan-500 w-full sm:w-48 transition-colors">
                    <select id="txFilter" class="bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 text-xs rounded-xl px-3 py-2 text-slate-800 dark:text-slate-300 focus:outline-none focus:border-cyan-500 transition-colors">
                        <option value="all">All Types</option>
                        <option value="income">Income Only</option>
                        <option value="expense">Expenses Only</option>
                    </select>
                </div>
            </div>

            <!-- Table -->
            <div class="overflow-x-auto">
                <table class="w-full text-left text-xs text-slate-700 dark:text-slate-300">
                    <thead class="bg-slate-100 dark:bg-slate-950 text-slate-500 dark:text-slate-400 font-bold uppercase text-[10px] tracking-wider border-b border-slate-200 dark:border-slate-800">
                        <tr>
                            <th class="p-3">Title / Merchant</th>
                            <th class="p-3">Category</th>
                            <th class="p-3">Date</th>
                            <th class="p-3">Type</th>
                            <th class="p-3 text-right">Amount</th>
                        </tr>
                    </thead>
                    <tbody id="txTableBody" class="divide-y divide-slate-200 dark:divide-slate-800/60 font-medium">
                        <!-- Rendered by JS -->
                    </tbody>
                </table>
            </div>
        </div>

    </main>

    <!-- Modal Form (Add Transaction) -->
    <div id="txModal" class="fixed inset-0 bg-slate-900/60 dark:bg-slate-950/80 backdrop-blur-md hidden z-50 items-center justify-center p-4">
        <div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-3xl max-w-md w-full p-6 space-y-4 shadow-2xl transition-colors duration-200">
            <div class="flex items-center justify-between border-b border-slate-200 dark:border-slate-800 pb-3">
                <h3 class="font-outfit font-extrabold text-base text-slate-900 dark:text-white">Add New Transaction</h3>
                <button id="closeModalBtn" class="text-slate-400 hover:text-slate-600 dark:hover:text-white text-base"><i class="fa-solid fa-xmark"></i></button>
            </div>
            <form id="txForm" class="space-y-4 text-xs">
                <div>
                    <label class="block font-bold text-slate-600 dark:text-slate-400 mb-1">Title / Description</label>
                    <input type="text" id="inputTitle" required placeholder="e.g. AWS Cloud Hosting" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2.5 text-slate-900 dark:text-white focus:outline-none focus:border-cyan-500">
                </div>
                <div class="grid grid-cols-2 gap-3">
                    <div>
                        <label class="block font-bold text-slate-600 dark:text-slate-400 mb-1">Type</label>
                        <select id="inputType" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2.5 text-slate-900 dark:text-white focus:outline-none focus:border-cyan-500">
                            <option value="expense">Expense (-)</option>
                            <option value="income">Income (+)</option>
                        </select>
                    </div>
                    <div>
                        <label class="block font-bold text-slate-600 dark:text-slate-400 mb-1">Category</label>
                        <select id="inputCategory" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2.5 text-slate-900 dark:text-white focus:outline-none focus:border-cyan-500">
                            <option value="Infrastructure">Infrastructure</option>
                            <option value="Salary">Salary / Revenue</option>
                            <option value="Marketing">Marketing</option>
                            <option value="Office">Office & Software</option>
                        </select>
                    </div>
                </div>
                <div>
                    <label class="block font-bold text-slate-600 dark:text-slate-400 mb-1">Amount ($ USD)</label>
                    <input type="number" step="0.01" id="inputAmount" required placeholder="149.99" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2.5 text-slate-900 dark:text-white focus:outline-none focus:border-cyan-500">
                </div>
                <button type="submit" class="w-full py-3 bg-cyan-500 hover:bg-cyan-400 text-slate-950 font-outfit font-extrabold rounded-xl text-xs uppercase tracking-wider transition shadow-lg shadow-cyan-500/20">
                    Save Transaction
                </button>
            </form>
        </div>
    </div>

    <!-- JS Logic & Chart Initialization -->
    <script>
        let transactions = [
            { id: 1, title: 'Client Monthly Retainer', category: 'Salary', date: '2026-09-01', type: 'income', amount: 4500.00 },
            { id: 2, title: 'AWS Cloud Server Hosting', category: 'Infrastructure', date: '2026-08-30', type: 'expense', amount: 320.50 },
            { id: 3, title: 'Google Ads Campaign', category: 'Marketing', date: '2026-08-28', type: 'expense', amount: 650.00 },
            { id: 4, title: 'SaaS Software Subscriptions', category: 'Office', date: '2026-08-25', type: 'expense', amount: 185.00 },
            { id: 5, title: 'UI Component Sales', category: 'Salary', date: '2026-08-20', type: 'income', amount: 3900.00 }
        ];

        const txTableBody = document.getElementById('txTableBody');
        const txFilter = document.getElementById('txFilter');
        const txSearch = document.getElementById('txSearch');
        const txModal = document.getElementById('txModal');

        // Render Table Rows
        function renderTransactions() {
            const filterVal = txFilter.value;
            const searchVal = txSearch.value.toLowerCase().trim();

            const filtered = transactions.filter(t => {
                const matchesFilter = filterVal === 'all' || t.type === filterVal;
                const matchesSearch = t.title.toLowerCase().includes(searchVal) || t.category.toLowerCase().includes(searchVal);
                return matchesFilter && matchesSearch;
            });

            txTableBody.innerHTML = '';
            filtered.forEach(t => {
                const isIncome = t.type === 'income';
                const tr = document.createElement('tr');
                tr.className = 'hover:bg-slate-100/70 dark:hover:bg-slate-950/40 transition';
                tr.innerHTML = `
                    <td class="p-3 font-bold text-slate-900 dark:text-white">${t.title}</td>
                    <td class="p-3"><span class="px-2 py-0.5 rounded-full text-[10px] bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 border border-slate-200 dark:border-slate-700">${t.category}</span></td>
                    <td class="p-3 text-slate-500 dark:text-slate-400 font-mono">${t.date}</td>
                    <td class="p-3"><span class="px-2 py-0.5 rounded-full text-[10px] ${isIncome ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20' : 'bg-rose-500/10 text-rose-600 dark:text-rose-400 border border-rose-500/20'} uppercase font-bold">${t.type}</span></td>
                    <td class="p-3 text-right font-mono font-bold ${isIncome ? 'text-emerald-600 dark:text-emerald-400' : 'text-rose-600 dark:text-rose-400'}">${isIncome ? '+' : '-'}\$${t.amount.toFixed(2)}</td>
                `;
                txTableBody.appendChild(tr);
            });

            updateTotals();
        }

        // Update KPI Totals
        function updateTotals() {
            const income = transactions.filter(t => t.type === 'income').reduce((acc, t) => acc + t.amount, 0);
            const expense = transactions.filter(t => t.type === 'expense').reduce((acc, t) => acc + t.amount, 0);
            const balance = income - expense;
            const rate = income > 0 ? ((balance / income) * 100).toFixed(1) : 0;

            document.getElementById('totalBalanceVal').innerText = '$' + balance.toLocaleString('en-US', { minimumFractionDigits: 2 });
            document.getElementById('totalIncomeVal').innerText = '$' + income.toLocaleString('en-US', { minimumFractionDigits: 2 });
            document.getElementById('totalExpenseVal').innerText = '$' + expense.toLocaleString('en-US', { minimumFractionDigits: 2 });
            document.getElementById('savingsRateVal').innerText = rate + '%';
        }

        // Chart.js Setup
        let cashflowChart, categoryChart;
        function initCharts() {
            const isDark = document.documentElement.classList.contains('dark');
            const legendColor = isDark ? '#94a3b8' : '#475569';
            const gridColor = isDark ? '#1e293b' : '#e2e8f0';
            const tickColor = isDark ? '#64748b' : '#64748b';

            const ctx1 = document.getElementById('cashflowChart').getContext('2d');
            cashflowChart = new Chart(ctx1, {
                type: 'bar',
                data: {
                    labels: ['May', 'Jun', 'Jul', 'Aug', 'Sep'],
                    datasets: [
                        { label: 'Income', data: [7200, 7800, 8100, 8400, 8900], backgroundColor: '#10b981', borderRadius: 6 },
                        { label: 'Expenses', data: [3400, 3100, 3500, 3150, 2900], backgroundColor: '#f43f5e', borderRadius: 6 }
                    ]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: { legend: { labels: { color: legendColor } } },
                    scales: {
                        x: { grid: { display: false }, ticks: { color: tickColor } },
                        y: { grid: { color: gridColor }, ticks: { color: tickColor } }
                    }
                }
            });

            const ctx2 = document.getElementById('categoryChart').getContext('2d');
            categoryChart = new Chart(ctx2, {
                type: 'doughnut',
                data: {
                    labels: ['Infrastructure', 'Marketing', 'Office & Tools', 'Others'],
                    datasets: [{
                        data: [320, 650, 185, 200],
                        backgroundColor: ['#06b6d4', '#a855f7', '#f59e0b', '#64748b'],
                        borderWidth: 0
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: { legend: { position: 'bottom', labels: { color: legendColor } } }
                }
            });
        }

        // Modal Controls
        document.getElementById('addTxBtn').addEventListener('click', () => txModal.classList.remove('hidden'));
        document.getElementById('closeModalBtn').addEventListener('click', () => txModal.classList.add('hidden'));

        document.getElementById('txForm').addEventListener('submit', (e) => {
            e.preventDefault();
            const title = document.getElementById('inputTitle').value;
            const type = document.getElementById('inputType').value;
            const category = document.getElementById('inputCategory').value;
            const amount = parseFloat(document.getElementById('inputAmount').value);

            transactions.unshift({
                id: Date.now(),
                title,
                category,
                date: new Date().toISOString().split('T')[0],
                type,
                amount
            });

            renderTransactions();
            txModal.classList.add('hidden');
            document.getElementById('txForm').reset();
        });

        txFilter.addEventListener('change', renderTransactions);
        txSearch.addEventListener('input', renderTransactions);

        // Export CSV
        document.getElementById('exportCsvBtn').addEventListener('click', () => {
            let csv = 'Title,Category,Date,Type,Amount\n';
            transactions.forEach(t => {
                csv += `"${t.title}","${t.category}","${t.date}","${t.type}",${t.amount}\n`;
            });
            const blob = new Blob([csv], { type: 'text/csv' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'fintech-transactions-export.csv';
            a.click();
            URL.revokeObjectURL(url);
        });

        // Init
        renderTransactions();
        initCharts();
    </script>
</body>
</html>
/* Supports both Dark and Light mode via Tailwind class variant */
// Interactive scripts included inside demo view file

Related Projects

SaaS Analytics & Crypto Dashboard Template

Featured

A modern, responsive SaaS analytics dashboard featuring live HTML5 canvas charts, real-time KPI metrics, dark mode, and transaction data tables.

Dashboards & Web Apps • 76

E-Commerce Sales & Inventory Management Portal

Featured

A responsive online store administration dashboard with low stock inventory alerts, order status filters, and sales revenue analytics.

Dashboards & Web Apps • 84

AI Prompt Engineering Workspace & Log Manager

Featured

A developer dashboard for creating, testing, versioning, and organizing AI prompts for LLMs with token parameter controls.

Dashboards & Web Apps • 92