feat: implement Puzzel Dashboard Edge App - #1
Conversation
Builds out the dashboard rendering pipeline: settings are read at their point of use instead of threaded through function parameters, templates are decoupled from data-fetching via lit-html, and a chart.js bar chart is added per queue. The mock server is split into separate Puzzel- and Screenly-mimicking route groups, and a failover cache keeps the last known-good data on screen if a fetch fails.
There was a problem hiding this comment.
Pull request overview
Implements the initial working Puzzel Dashboard Edge App by moving rendering into lit-html templates, adding per-queue Chart.js visualizations, and introducing a cached failover path so the dashboard can keep showing last-known data on fetch failures.
Changes:
- Adds
src/templates/*rendering (queue cards + agent tiles) and mounts Chart.js bar charts per queue. - Reworks refresh flow into
src/dashboard.ts(settings read at point-of-use + cache write/read failover). - Splits mock server routes into
/puzzel/*and/screenly/*and documents the new local settings needed.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/templates/queue-chart.ts | New Chart.js mounting helper for per-queue bar charts. |
| src/templates/queue-card.ts | New lit-html queue card rendering + chart mounting. |
| src/templates/index.ts | New templates entrypoint exporting renderDashboard. |
| src/templates/agent-tile.ts | New lit-html agent tile rendering. |
| src/style.css | Adds @layer components styles for queue cards and agent tiles. |
| src/render.ts | Removed old imperative DOM rendering + data fetching module. |
| src/main.ts | Switches app startup to use refresh() from the new dashboard module. |
| src/dashboard.ts | New refresh/data-fetch + failover cache integration. |
| src/credentials.ts | New access token fetch via Screenly OAuth broker endpoint with dev-token fallback. |
| src/constants.ts | Adds cache namespace constant. |
| src/auth.ts | Removes old “refresh token on AuthError” wrapper logic. |
| src/app.ts | Removes old error-screen and formatting/status helper functions. |
| src/api.ts | Extends queue stats shape and reformats queue stats error throw. |
| package.json | Adds Chart.js and moves lit-html into dependencies. |
| mock-server/src/routes/screenly.ts | Adds mock Screenly OAuth broker route group. |
| mock-server/src/routes/puzzel.ts | Adds mock Puzzel API route group with bearer-token requirement middleware. |
| mock-server/src/index.ts | Wires new mock route groups under /puzzel and /screenly. |
| mock-server/src/data.ts | Extends mock queue stats with CIQ/Callback counters and jitter behavior. |
| mock-server/README.md | Updates docs for new endpoint prefixes and required local settings. |
| index.html | Removes legacy error screen markup and minor formatting changes. |
| bun.lock | Updates lockfile for new dependencies. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Adds credential caching (broker -> cache -> dev setting fallback, gated by display_errors) matching the same data-flow shape used for dashboard data, and replaces .catch() chaining with try/catch per PR review feedback.
- Add override_locale/override_timezone settings (and track the previously-untracked screenly_qc.yml) so <app-header show-date> can be configured instead of relying solely on GPS-based detection. - Apply locale-aware number formatting to queue card stats. - Split agent-tile.ts and queue-card.ts into presentation (lit-html) and .lib.ts (pure helpers) files, matching the salesforce-app convention. - Fold the one-line showDashboard helper into renderDashboard, and use non-null assertions for DOM lookups guaranteed by static markup. - Update README's Configuration table to match.
Adds a Connect/Disconnect flow that exchanges real credentials for a token and proxies real ContactCentre data, falling back to synthetic data when disconnected.
Local dev now proxies real API calls another way, so the setting is no longer needed.
Split mock setup/helpers into screenshots.lib.ts, keeping screenshots.spec.ts to just the test cases.
Also drops the formatNumber wrapper in favor of Intl.NumberFormat directly, and runs bun test with --isolate so mocked modules in one test file don't leak into another.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 40 out of 53 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
package.json:41
chart.jsis imported by runtime app code (src/templates/queue-chart.ts), but it’s listed underdevDependencies. If the build/deploy environment installs production-only deps, this can break the build (or later local installs) because the module won’t be available. Movechart.jstodependenciesand regeneratebun.lock.
"devDependencies": {
"@screenly/edge-apps": "^1.4.0",
"typescript": "^5.9.3",
"prettier": "^3.8.1",
"@types/node": "^25.4.0",
"npm-run-all2": "^8.0.4",
"@playwright/test": "^1.58.0",
"@types/bun": "^1.3.13",
"bun-types": "^1.3.13",
"jsdom": "^28.1.0",
"@types/jsdom": "^28.0.0",
"chart.js": "^4.5.1"
},
"dependencies": {
"lit-html": "^3.3.3"
}
src/credentials.ts:48
- When the Screenly token fetch fails and there’s no cached token, this returns
devAccessTokeneven if it’s an empty string. That makes callers proceed with an invalidAuthorization: Bearerheader and can mask the real configuration problem (especially when there’s also no dashboard-data cache). Consider throwing when no non-empty token is available after fallback.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 40 out of 53 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/credentials.ts:15
fetchAccessToken()reads theaccess_tokensetting but still always calls the broker first. Whenaccess_tokenis set for testing, this causes an unnecessary network request and can override the intended manual token override behavior.
src/credentials.ts:49- In the error path, this can return an empty string token when neither the broker nor cache provides credentials. Returning an empty bearer token masks the credential error and can trigger avoidable downstream 401s; it’s better to throw so the caller can fall back to cached dashboard data (or surface the error).
src/templates/queue-chart.ts:18 - The chart is rendered into a
<canvas>without any accessibility metadata. Adding an ARIA label (and optionallyrole="img") makes the chart content discoverable to assistive technologies.
It's imported by runtime app code, so it needs to be available in production installs that skip devDependencies.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 40 out of 53 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/credentials.ts:48
- When the token fetch fails and there’s no cached token, this can return an empty string (if the
access_tokendev setting is also blank). That leads to downstream requests being sent withAuthorization: Bearer, which is hard to diagnose. Prefer throwing a clear error when no fallback token is available.
Summary
lit-htmltemplates undersrc/templates/, and each queue now renders a chart.js bar chart (Offered/Answered/Callback) alongside its stats.mock-server/src/routes/puzzel.ts,mock-server/src/routes/screenly.ts), and adds a mock credentials endpoint standing in for a not-yet-built production auth broker.Test plan
bun run type-checkpassesbun run lint/bun run format:checkpassbun run devrenders queue cards (with chart), agent tiles, and recovers gracefully on a simulated fetch failureapi.ts,credentials.ts,dashboard.ts, and the template helper functionse2e/screenshots.spec.tswritten and passing across all standard resolutions