A fully client-side reporting dashboard for AlexBank's Information Security Department. It transforms a structured Excel workbook into an interactive monthly report — tracking objectives, KPIs, planned activities, team performance, and monthly highlights — with no backend, no build step, and no external dependencies beyond a single CDN library.
- Objectives Dashboard — Displays strategic BCM objectives as cards, each with its assigned KPIs, progress bars, and colour-coded RAG status.
- Three-Tier KPI Tracking — Each KPI is evaluated against Minimum, Target, and Stretch thresholds with automatic status classification (EXCELLENT / GREEN / AMBER / RED / NO DATA).
- Activity Plan — Tracks planned activities with step-level progress, owner assignment, due dates, and the latest update comment per step.
- SWOT Analysis — A 4-quadrant analysis (Strengths, Weaknesses, Opportunities, Threats) linked to plan activities with org-unit filtering and modal detail popups.
- Monthly Summary — Displays key highlights and challenges pulled from the reporting period, filterable by organisational unit.
- Team Performance View — Per-member breakdown of completed, in-progress, and total assigned steps with an overall completion percentage.
- Ad-Hoc Activities — Captures unplanned reactive tasks alongside regular plan activities, with multi-owner support.
- Organisational Filtering — Three independent filter bars (Objectives, Summary, Plan) with hierarchical org-unit resolution.
- Excel Upload — Upload any correctly structured
.xlsxfile to refresh all dashboard sections in real time. - Standalone HTML Export — Generates a single self-contained
dashboard_report.htmlwith all data embedded and upload controls hidden — ready for SharePoint distribution. - Sample Excel Download — Downloads a pre-populated template workbook showing the exact sheet and column structure required.
| Layer | Technology |
|---|---|
| Markup | HTML5 |
| Styles | CSS3 (inline, CSS custom properties) |
| Logic | Vanilla JavaScript (ES6+, no framework) |
| Excel I/O | SheetJS / XLSX.js v0.18.5 (CDN) |
| Hosting | GitHub Pages |
| CI/CD | GitHub Actions (/.github/workflows/static.yml) |
| Build Tool | None |
The application follows a layered client-side MVC pattern. All layers are inlined into index.html for maximum portability — the file is the entire application.
┌─────────────────────────────────────────────┐
│ index.html │
│ │
│ ┌──────────┐ ┌──────────────────────┐ │
│ │ Excel │ │ Embedded JSON Data │ │
│ │ Upload │ │ <script id="dash... │ │
│ └────┬─────┘ └──────────┬───────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ DAL — dashboardRepository │ │
│ │ setDashboardData() / getDashboard │ │
│ └──────────────────┬──────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Service — dashboardService │ │
│ │ loadDashboardModel() │ │
│ │ KPI resolution · progress calc │ │
│ │ org-unit hierarchy · team metrics │ │
│ └──────────────────┬──────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ UI — DashboardView │ │
│ │ renderObjectives() · renderTeam() │ │
│ │ renderActivities() · renderPlan() │ │
│ └─────────────────────────────────────┘ │
│ │
│ Utils — formatters.js │
│ (date, percent, status, HTML escaping) │
└─────────────────────────────────────────────┘
Data flow:
- On load, the app checks
<script id="dashboard-data">for embedded JSON. - If populated (standalone export), that data is loaded immediately — no upload required.
- If empty, the app falls back to the built-in sample dataset.
- When a user uploads an Excel file,
parseExcelFile()parses all 15 sheets and callssetDashboardData(), which triggers a full re-render of all three model sections.
dashboard/
├── index.html # Main app — styles, markup, and all JS inlined
├── monthlyreport.xlsx # Current monthly Excel report (binary)
├── generate_excel.cjs # Node utility: generate monthlyreport.xlsx (CommonJS)
├── generate_excel.mjs # Node utility: generate monthlyreport.xlsx (ES module)
├── dump_data.mjs # Node utility: export sample data to dashboardData_cjs_temp.json
│
├── src/ # ES module source (mirrors the inlined logic)
│ ├── app.js # Entry point: init, event handlers, filter callbacks
│ ├── dal/
│ │ └── dashboardRepository.js # In-memory data store with deep-clone access
│ ├── models/
│ │ └── dashboardData.js # Static sample dataset (all 15 entities)
│ ├── services/
│ │ ├── dashboardService.js # Business logic: model building, KPI calc, team metrics
│ │ └── excelImporter.js # Excel parsing (15 sheets) and sample workbook generation
│ ├── styles/
│ │ └── dashboard.css # CSS custom properties and component styles
│ ├── ui/
│ │ └── dashboardView.js # DOM rendering and event binding
│ └── utils/
│ └── formatters.js # Date, percent, status, HTML escape helpers
│
└── .github/
└── workflows/
└── static.yml # GitHub Pages deploy on push to main
No installation or build step is required.
open index.htmlThe dashboard loads with sample data. Excel upload works via the file picker. The Generate Standalone HTML feature requires HTTP (see Option 2).
npx serve .
# or
python3 -m http.server 8080Then open http://localhost:3000 (or whichever port is reported).
Push to the main branch. GitHub Actions automatically deploys the entire repository to GitHub Pages. No configuration needed — see .github/workflows/static.yml.
- Open
index.htmlvia a local server or the GitHub Pages URL. - The dashboard loads immediately with the embedded default dataset.
- Use the org unit filter buttons at the top of each section to scope the view.
- Toggle between Summary and By Team in the monthly summary section.
- Click any SWOT item to view linked activities in a modal popup.
- Click any activity row in the Plan section to expand its step-level detail.
- Prepare
monthlyreport.xlsxwith the required sheet structure (see Excel Schema below). - Click Upload Report and select the file.
- All three dashboard sections refresh automatically.
- The status bar confirms the loaded filename.
- Upload your monthly Excel file (step above).
- Click Generate Standalone HTML.
- A file named
dashboard_report.htmlis downloaded. - Upload
dashboard_report.htmlto your SharePoint document library. - Recipients open the file and see the full dashboard — no upload required, upload controls hidden.
Click Download Sample Report to receive a pre-structured sample_report.xlsx containing one example row per sheet — use it as a starting template.
The Excel workbook must contain the following sheets. All column names are case-sensitive. Missing sheets fall back to the embedded sample data for that entity.
| Sheet | Required Columns |
|---|---|
config |
key, value |
owners |
owner_id, name, role |
org_units |
id, name, type, parent_id |
objectives |
id, name |
objective_assignments |
objective_id, org_unit_id |
kpis |
id, objective_id, name, measurement_type, measurement_unit |
kpi_thresholds |
kpi_id, org_unit_id, min, target, stretch, is_default |
kpi_values |
kpi_id, org_unit_id, date, value |
activities |
activity_id, name, description, due_date, org_unit_id, refs |
swot |
quadrant (or key), id, text, org_unit_id |
activity_kpi_map |
activity_id, kpi_id |
steps |
step_id, activity_id, name, description, due_date, owner_id |
step_updates |
update_id, step_id, period, status, progress, comment |
activity_updates |
update_id, activity_id, period, status, progress, comment |
adhoc_activities |
adhoc_id, owner_id, name, period, status, progress, comment |
monthly_summary |
id, type, org_unit_id, period, text |
Key notes:
configmust have a row withkey = "Period"andvalueset to an ISO date (e.g.,2026-04-30). This controls the report period label and KPI value filtering.kpi_thresholds: Setis_default = trueon the fallback row; org-unit-specific rows override defaults during rendering.step_updates.progressandactivity_updates.progress: Accepts values in0–1decimal or0–100integer range — both are normalised automatically.adhoc_activities.owner_id: Supports multiple owners as comma- or slash-separated IDs (e.g.,9790/14432).activities.refs: Supports multiple SWOT IDs as comma-, slash-, or space-separated values (e.g.,s1,w2).monthly_summary.type: Must be"Highlight"or"Challenge"(case-insensitive).
Each KPI value is compared against its resolved thresholds in this order:
| Status | Condition | Colour |
|---|---|---|
EXCELLENT |
value ≥ stretch threshold | Blue |
GREEN |
value ≥ target threshold | Green |
AMBER |
value ≥ minimum threshold | Orange |
RED |
value < minimum threshold | Red |
NO DATA |
no value recorded for current period | Grey |
Thresholds are resolved per org unit: an org-unit-specific threshold row takes precedence over the default (is_default = true) row. If no threshold exists at all, the KPI is shown without status colour.
There are no environment variables or external config files. The single runtime configuration value is the reporting period, stored in the config sheet of the Excel workbook:
| key | value |
|---|---|
Period |
2026-04-30 (ISO date — any day of the target month) |
The period is displayed in the dashboard header as "April 2026" and used to filter kpi_values, step_updates, activity_updates, and monthly_summary rows to the current reporting month.
These Node.js scripts are development utilities and are not required to run the dashboard.
# Generate monthlyreport.xlsx from the sample dataset (ES module)
node generate_excel.mjs
# CommonJS equivalent
node generate_excel.cjs
# Export sample dataset from src/models/dashboardData.js to dashboardData_cjs_temp.json
node dump_data.mjsThe dashboard is a single-page, scrollable report divided into three main sections:
| Section | Contents |
|---|---|
| Objectives Dashboard | Grid of objective cards. Each card lists the objective name, its assigned KPIs with threshold labels (Min / Target / Stretch), a colour-coded progress bar, and the actual value vs. target. |
| Monthly Progress Summary | Two tables — Key Highlights and Key Challenges — populated from the monthly_summary sheet. Includes a team view toggled by member selector buttons, showing per-member task metrics and ad-hoc activities. |
| SWOT Analysis | A 4-quadrant grid showing Strengths, Weaknesses, Opportunities, and Threats. Clicking an item opens a modal listing linked activities from the BCM Plan. |
| 2026 BCM Plan | Tabular activity list with overall plan progress, expandable activity detail sheets showing step-by-step progress, owner, due date, status, and latest update comment. |
The report header displays the org name, reporting period, and the Upload Report / Generate Standalone HTML toolbar.
- REST API backend — Replace client-side data loading with an authenticated API so data is always current without file uploads.
- Role-based access control — Differentiate read-only viewers from report editors.
- Chart visualisations — Trend lines for KPI values over multiple reporting periods.
- PDF export — Generate print-optimised PDF reports directly from the dashboard.
- Multi-period comparison — Side-by-side view of two reporting periods.
- SharePoint App integration — Surface the dashboard as a SharePoint web part using the SPFx framework to avoid manual file uploads entirely.
- Automated Excel ingestion — CI job to regenerate the standalone HTML on each commit when
monthlyreport.xlsxchanges.
- Fork the repository and create a feature branch from
main. - Make your changes to
index.html(the inlined version is the deployed artefact). - If you also modify source files under
src/, keep the inlined logic inindex.htmlin sync. - Open a pull request with a clear description of what changed and why.
- Ensure the dashboard renders correctly by opening it in a browser before submitting.
There is no test suite. Manual browser testing against a representative monthlyreport.xlsx is the verification step.
This project is licensed under the MIT License.
MIT License
Copyright (c) 2026 AlexBank BCM Unit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.