Skip to content

feat: add plant overview header and live line states to the dashboard - #379

Merged
jakub-przepiora merged 2 commits into
developfrom
cez/5785ecc8
Oct 25, 2026
Merged

jakub-przepiora merged 2 commits into
developfrom
cez/5785ecc8

Conversation

@jakub-przepiora

Copy link
Copy Markdown
Contributor

What

The admin dashboard had no at-a-glance view of the current shift or of what each line is doing right now. This adds the foundation of the "Plant overview" redesign.

  • Admin → Dashboard now opens with a "Plant overview" header: a green "Live" dot, the current shift name with its time window and time left (for example "Morning · 06:00–14:00 · 3 h left"), and a "+ New work order" button.
  • The button goes to the new work order form. It is shown only to users who have access to the Orders tab.
  • The dot turns grey when the last background refresh failed. The overview refreshes every 60 s, only while the browser tab is visible.
  • With no shifts configured, the header shows the fallback window and says no shift is running.
  • Below the header is an empty container for overview sections, laid out as in the mockup. Follow-up work adds sections to it with one import and one entry each.
  • All existing widgets (KPIs, OEE gauge, Inbound QC, Materials, Scrap, Non-conformance, Top customers, recent orders, open issues, module widgets) are unchanged. They now sit under a "Last 30 days" heading, with the "All lines" filter and the Settings → Widgets toggles intact.
  • Fixed the "today" date in the old OEE overview. It used the UTC date and now uses the plant's timezone.

Why

The redesign needs a shared base before individual sections are built: a single source for the current shift and for per-line state, and a page layout that sections can be added to without merge conflicts.

  • PlantOverviewService is the single source for shift and line state. It is separate from the controller, reuses ShiftWindow for shifts and extends ShiftMonitorService with a new method only.
  • Line state maps to running, idle, blocked or down.
    • Machine stations drive the state where a collector exists.
    • Lines without a collector use work orders and manually reported downtime.
    • Kanban LineStatus is deliberately not used.
  • The OEE date bug: new Date().toISOString() returns the UTC date, which is wrong around midnight for plants outside UTC.

How it was verified

Laravel feature tests in tests/Feature/Web/DashboardPlantOverviewTest.php:

  • Happy path:
    • The overview prop returns { shift, lines }.
    • Shift name, window and minutes left are correct.
    • The fallback window is flagged as the default when no shifts exist.
    • Each state mapping is covered: running, down (fault, stopped with an open stop, maintenance, open maintenance event), blocked (waiting, blocked work order) and idle.
    • Lines without a collector take their state from work orders and manual downtime.
    • The maintenance module being switched off is covered.
  • Authorization:
    • A guest is redirected to login.
    • A user without tab:dashboard is redirected as before.
    • The orders tab being absent is covered.
  • Tenant isolation: another tenant's lines and stops never appear.
  • Query count: 1 line and 10 lines issue the same number of queries, at most 12 (no N+1).
  • Refresh: the partial reload returns only overview.
  • Date helper: a JS unit test covers the plant-timezone "today".
  • The existing dashboard tests, the API dashboard test and the Playwright specs are unchanged.
  • No new validation: there are no new inputs or routes.

Click-through demo recorded by an independent QA agent on a fresh instance. The demo video will be added in a follow-up comment.

Review notes

  • No migrations and no new dependencies. 7 new i18n keys were added to both en.json and pl.json.
  • GET /api/v1/admin/dashboard, the shared synced collections, OeeGauge, OeeCalculationService and the existing ShiftMonitorService payloads are untouched. Only one method was added to ShiftMonitorService.
  • Code review verdict: approve, with no blockers or majors. These minor points are left for a follow-up:
  • Hours left are rounded down, so 179 minutes shows "2 h left" while the mockup suggests "3h". Consider Math.round or "2 h 59 min".
  • Open stops on stations are queried twice (once in ShiftMonitorService::currentStates(), once in PlantOverviewService). This is one extra query and the count stays fixed.
  • currentStates() keeps only the latest open stop per station. An older open stop on a station that reports machine data is dropped, so its reason is never shown. It is rare, and needs documenting or a test.
  • A station in MAINTENANCE whose stop has a placeholder reason does not set needs_reason, unlike FAULT and STOPPED.
  • In useOverviewRefresh.js, the start handler skips setting visiting when navigation begins during a background refresh. It is harmless, but the comment promises more than the code does.
  • A collector that went silent leaves an open state row, so the line keeps its last machine state indefinitely. Out of scope here; consider an "unknown / stale" state in phase 2.

🤖 Generated with Claude Code

jakub-przepiora and others added 2 commits October 24, 2026 15:59
Foundation for the "Plant overview" dashboard rebuild.

- PlantOverviewService: current plant shift via ShiftWindow (fallback window
  flagged is_default) and per-line state (running / idle / blocked / down)
  with since, reason and source (machine / manual), in a fixed number of
  queries regardless of line count, constrained to tenant-scoped lines.
- ShiftMonitorService::currentStates(): open state + open stop per station,
  without board()'s counters/OEE. Existing payloads unchanged.
- DashboardController: new lazy `overview` prop; existing props untouched.
- Dashboard.jsx: new header (title, Live dot, shift and time left,
  "+ New work order" for users with the orders tab), empty section
  registry + grid under components/dashboard/overview, 60 s partial
  reload of `overview` while the tab is visible (dot greys on failure).
  Existing widgets and line filter moved under a "Last 30 days" heading.
- fix: OEE overview widget matched "today" by the UTC date; it now uses
  the plant date (todayInPlant) and tolerates datetime-shaped record_date.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one): 1
  • cla-signed

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jakub-przepiora
jakub-przepiora marked this pull request as ready for review October 25, 2026 09:33
@jakub-przepiora
jakub-przepiora merged commit f631ef3 into develop Oct 25, 2026
2 of 3 checks passed
jakub-przepiora added a commit that referenced this pull request Oct 25, 2026
Resolve conflicts with develop's plant overview header (#379) and the
translation update (#378): keep both CHANGELOG entries; lang files merged
per key with the i18n-lang-files resolver (en/pl parity 7136/7136).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant