Skip to content

feat(dashboard): specialized dashboard — actions, role gating, clickable links#626

Open
arifulhoque7 wants to merge 8 commits into
weDevsOfficial:developfrom
arifulhoque7:feat/specialized-dashboard
Open

feat(dashboard): specialized dashboard — actions, role gating, clickable links#626
arifulhoque7 wants to merge 8 commits into
weDevsOfficial:developfrom
arifulhoque7:feat/specialized-dashboard

Conversation

@arifulhoque7

@arifulhoque7 arifulhoque7 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Wires up the specialized dashboard header actions, role gating, and clickable links.

  • New Task button opens NewTaskSheet inline (was navigating to /my-tasks); refetches dashboard on create
  • New Project button opens the shared ProjectCreateSheet via Redux; preloads categories/roles so dropdowns aren't empty when opened cold
  • Per-button role gating — New Task (any user), New Project (canCreate), Milestone (manager) — matches the rest of the app
  • Active Projects rows now open /task-lists to match the projects list
  • Recent Activity actor + project are clickable: controller emits project_id/task_id, frontend deep-links to the task / project task list

Test

  • Build: pnpm build
  • Reload dashboard: New Task opens modal + refetches; New Project opens create sheet; rows + activity links navigate; buttons show per role.

Refs weDevsOfficial/pm-pro#357

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new Dashboard at /dashboard with personalized KPI tiles, performance trends, project status, active projects, mini calendar, productivity heatmap, recent activity, upcoming milestones, overdue prioritization, and (for Pro) team workload visibility.
    • Added supporting REST endpoints for dashboard data and heatmap.
    • Updated sidebar navigation to include Dashboard.
  • Style

    • Updated typography to prioritize Mona Sans.
    • Improved accent theming with HSL-based opacity support.

arifulhoque7 and others added 7 commits June 23, 2026 19:23
Add a new React dashboard (landing page) backed by a single role-scoped
REST endpoint, plus a WP-admin "Dashboard" submenu link.

Backend (pm/v2/dashboard, pm/v2/dashboard/heatmap):
- Aggregates: KPIs, project status, task performance (7/30d), distribution,
  upcoming tasks, overdue/priority, milestones, recent activity, team, and a
  GitHub-style productivity heatmap with a year filter.
- Three scope tiers: admin -> full org, manager -> their projects, member ->
  own assigned tasks. All figures read live from pm_* tables (no mock data).

Frontend (views/assets/src/components/dashboard):
- shadcn/ui + Recharts; brand-accent theme; Mona Sans font (matches WP ERP).
- Local shadcn Calendar wrapper (react-day-picker v9) for the mini calendar.
- Every card lazy-loaded behind its own Suspense boundary.
- New /dashboard route is the landing page; sidebar + WP submenu link added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pm-accent was 'var(--pm-accent)' (a hex), so utilities like bg-pm-accent/10
emitted an invalid color and rendered nothing (e.g. avatar fallbacks in
Activities/Progress). Add --pm-accent-hsl channels and define the token as
hsl(var(--pm-accent-hsl) / <alpha-value>) so opacity modifiers work app-wide.
Solid bg-pm-accent and direct var(--pm-accent) CSS uses are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New Task button opens NewTaskSheet inline (was navigating to /my-tasks);
  refetches dashboard on create
- New Project button opens the shared ProjectCreateSheet via Redux and
  preloads categories/roles so dropdowns aren't empty when opened cold
- Per-button role gating: New Task (any user), New Project (canCreate),
  Milestone (manager) — matches the rest of the app
- Active Projects rows now open /task-lists to match the projects list
- Recent Activity actor + project are clickable: emit project_id/task_id
  from the controller and deep-link to the task / project task list

Refs weDevsOfficial/pm-pro#357
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: efdb99f4-f13f-42e2-98d2-f5322f9f6d21

📥 Commits

Reviewing files that changed from the base of the PR and between 7f638ff and 81c1cb0.

📒 Files selected for processing (3)
  • views/assets/src/components/dashboard/DashboardPage.jsx
  • views/assets/src/components/dashboard/parts/StatCard.jsx
  • views/assets/src/tailwind.css
🚧 Files skipped from review as they are similar to previous changes (3)
  • views/assets/src/components/dashboard/parts/StatCard.jsx
  • views/assets/src/components/dashboard/DashboardPage.jsx
  • views/assets/src/tailwind.css

Walkthrough

Introduces a PM dashboard with a scoped REST backend, a new /dashboard React route and sidebar entry, a dashboard page composed of lazy-loaded cards, and supporting calendar, font, and color-token updates.

Changes

Dashboard Feature

Layer / File(s) Summary
PHP REST controller, routes, and admin menu
routes/dashboard.php, src/Dashboard/Controllers/Dashboard_Controller.php, core/WP/Menu.php
Registers two authenticated REST endpoints, implements the dashboard controller with scoped query helpers and widget methods, and adds the Dashboard admin submenu entry plus the Projects submenu URL fragment update.
Design tokens, font, and Calendar UI primitive
package.json, views/assets/src/components/ui/calendar.jsx, views/assets/src/tailwind.css, tailwind.config.js
Adds react-day-picker v9 and a local Calendar wrapper, imports Mona Sans and updates font stacks, introduces --pm-accent-hsl theme variables, and changes the pm-accent Tailwind token to an HSL expression.
App routing and sidebar navigation
views/assets/src/index.jsx, views/assets/src/components/layout/AppSidebar.jsx
Adds the /dashboard route, changes the default and catch-all redirects to /dashboard, and adds Dashboard navigation and active-route detection in the sidebar.
Shared StatCard tile
views/assets/src/components/dashboard/parts/StatCard.jsx
Adds the reusable KPI tile component with icon, label, value, trend, and optional accent styling.
DashboardPage orchestration
views/assets/src/components/dashboard/DashboardPage.jsx
Implements dashboard data loading, loading/error states, lazy card wrappers, and the conditional layout that wires fetched data into all dashboard sections.
Dashboard header with quick actions
views/assets/src/components/dashboard/parts/DashboardHeader.jsx
Implements the greeting header with user info, permission-gated actions, and task/project sheet controls.
KPI cards and task performance chart
views/assets/src/components/dashboard/parts/KpiCards.jsx, views/assets/src/components/dashboard/parts/TaskPerformanceCard.jsx
Adds KPI tiles with navigation and a task performance bar chart with 7d/30d range controls.
Project status and active projects cards
views/assets/src/components/dashboard/parts/ProjectStatusCard.jsx, views/assets/src/components/dashboard/parts/ActiveProjectsCard.jsx
Adds the project status pie chart and the active projects list with risk, progress, and task-count display.
Task distribution, overdue/priority, and upcoming schedule cards
views/assets/src/components/dashboard/parts/TaskDistributionCard.jsx, views/assets/src/components/dashboard/parts/OverduePriorityCard.jsx, views/assets/src/components/dashboard/parts/UpcomingScheduleCard.jsx
Adds the task distribution pie chart, overdue task list, and upcoming tasks list.
Mini calendar and productivity heatmap cards
views/assets/src/components/dashboard/parts/MiniCalendarCard.jsx, views/assets/src/components/dashboard/parts/ProductivityHeatmapCard.jsx
Adds the mini calendar with due-day markers and the productivity heatmap with year selection and loading state.
Recent activity and milestones cards
views/assets/src/components/dashboard/parts/RecentActivityCard.jsx, views/assets/src/components/dashboard/parts/MilestonesCard.jsx
Adds the recent activity timeline and upcoming milestones list with progress indicators.
Pro insights, team status, and upgrade card
views/assets/src/components/dashboard/parts/ProInsightsRow.jsx, views/assets/src/components/dashboard/parts/TeamStatusCard.jsx, views/assets/src/components/dashboard/parts/ProUpgradeCard.jsx
Adds the Pro insights tiles, team workload card, and Pro upgrade card.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

Needs Dev Review, Needs Testing

Suggested reviewers

  • iftakharul-islam

Poem

🐇 A dashboard sprung from burrowed code,
With charts and cards along the road.
The moonlit calendar marks each day,
While Mona Sans hops in style today.
From heatmaps bright to tasks in line —
This rabbit says: “The dashboard’s mine!” 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main dashboard changes around actions, role gating, and clickable navigation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Stylelint (17.13.0)
views/assets/src/tailwind.css

Error: ENOENT: no such file or directory, open '/.stylelintrc.json'
at async open (node:internal/fs/promises:640:25)
at async Object.readFile (node:internal/fs/promises:1287:14)
at async #readConfiguration (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:83:26)
at async load (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:20:48)
at async Explorer.load (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:23:20)
at async getConfigForFile (file:///usr/local/lib/node_modules/stylelint/lib/getConfigForFile.mjs:72:5)
at async resolveOptionValue (file:///usr/local/lib/node_modules/stylelint/lib/utils/resolveOptionValue.mjs:27:24)
at async standalone (file:///usr/local/lib/node_modules/stylelint/lib/standalone.mjs:127:22)


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@routes/dashboard.php`:
- Around line 8-13: Both the 'dashboard' and 'dashboard/heatmap' routes in the
router configuration are missing the required validator and sanitizer method
chains. Add ->validator() and ->sanitizer() method calls to each route
definition, chaining them after the existing ->permission() method. These
methods are mandatory for all REST endpoints in the codebase to ensure proper
input validation and sanitization of request data.

In `@src/Dashboard/Controllers/Dashboard_Controller.php`:
- Around line 64-82: The Dashboard_Controller is returning raw associative
arrays directly via rest_ensure_response instead of using Fractal transformers
for serialization. Replace the raw array construction and response return in
this method with proper Fractal transformer implementation. Create or use an
existing Fractal transformer class to serialize the dashboard data array that
includes user, range, kpis, projects_status, performance, task_distribution,
upcoming, overdue_list, calendar, active_projects, recent_activity, milestones,
team, and generated_at fields, then pass the transformed data through Fractal
before returning the response to ensure compliance with the project's API
serialization standards.
- Line 163: The task status aggregation in the Dashboard_Controller where clause
is using the Task::PENDING constant, but task status is defined as a 2-state
integer model with values 0 or 1. Replace the Task::PENDING constant in the
where clause with the correct integer value (0 or 1) that represents pending
status according to the task status contract, ensuring consistency between the
aggregated KPI data and persisted task values. Apply the same fix to line 382
where this pattern also occurs.
- Around line 209-212: The integer casting (int) on $p->status is incorrect
because project status is a STRING value, not an integer, and casting will
misclassify statuses and break the counter logic. Remove the (int) casting from
both comparisons in the if and elseif conditions that check against
Project::COMPLETE and Project::ARCHIVED constants, comparing the status directly
as a string instead.

In `@views/assets/src/components/dashboard/DashboardPage.jsx`:
- Around line 57-77: The load function in DashboardPage has a race condition
where rapid range changes can cause stale responses to overwrite newer data. Fix
this by implementing request tracking: create a ref to store the current request
ID or timestamp, increment it at the start of the load function, and only update
setData and setError if the current request ID matches the stored one when the
API response returns. Alternatively, use an AbortController to cancel the
previous api.get request when a new load call is made, ensuring only the latest
request completes and updates the state.

In `@views/assets/src/components/dashboard/parts/StatCard.jsx`:
- Line 43: The ternary operator on line 43 in the StatCard component currently
defaults all non-down trend directions to emerald-500 (positive color), which
incorrectly treats flat trends as positive. Update the conditional logic to
explicitly check for trend.direction === 'flat' and apply a neutral/muted color
(such as text-slate-500 or text-gray-500), then check for 'down' to apply
rose-500, and finally default to text-emerald-500 for positive trends. This
ensures flat trends are visually represented with a neutral tone separate from
positive and negative indicators.
- Around line 13-18: The StatCard component uses a non-interactive `<div>`
element with an onClick handler, which lacks keyboard accessibility and prevents
non-pointer users from navigating KPIs. Replace the `<div>` element that wraps
the card content with a `<button>` element, which will inherently provide
keyboard accessibility and proper semantic meaning for clickable content. Ensure
the button still applies the same className and onClick handler as before to
maintain styling and functionality.

In `@views/assets/src/tailwind.css`:
- Around line 514-516: The z-index values in the tailwind.css file exceed the
project's maximum allowed z-index of 700 for plugin styles. Update the z-index
property in the [data-radix-popper-content-wrapper] selector from 3000 to 700,
and also reduce the z-index values at the locations around lines 551 and 580 to
comply with the 700 maximum limit. Ensure all three z-index declarations (3000,
2001, and 2501) are replaced with values that do not exceed 700 to prevent
breaking expected layering behavior.
- Line 2: The `@import` statement in tailwind.css uses the url() notation which
does not comply with the configured Stylelint rules. Remove the url() wrapper
from the Google Fonts import statement for Mona Sans and use plain string
notation instead, keeping the quoted URL string directly in the `@import`
declaration to satisfy Stylelint requirements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9918b550-13c6-41ac-889a-5fcdb155157d

📥 Commits

Reviewing files that changed from the base of the PR and between fd1a3af and 7f638ff.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (26)
  • core/WP/Menu.php
  • package.json
  • routes/dashboard.php
  • src/Dashboard/Controllers/Dashboard_Controller.php
  • tailwind.config.js
  • views/assets/src/components/dashboard/DashboardPage.jsx
  • views/assets/src/components/dashboard/parts/ActiveProjectsCard.jsx
  • views/assets/src/components/dashboard/parts/DashboardHeader.jsx
  • views/assets/src/components/dashboard/parts/KpiCards.jsx
  • views/assets/src/components/dashboard/parts/MilestonesCard.jsx
  • views/assets/src/components/dashboard/parts/MiniCalendarCard.jsx
  • views/assets/src/components/dashboard/parts/OverduePriorityCard.jsx
  • views/assets/src/components/dashboard/parts/ProInsightsRow.jsx
  • views/assets/src/components/dashboard/parts/ProUpgradeCard.jsx
  • views/assets/src/components/dashboard/parts/ProductivityHeatmapCard.jsx
  • views/assets/src/components/dashboard/parts/ProjectStatusCard.jsx
  • views/assets/src/components/dashboard/parts/RecentActivityCard.jsx
  • views/assets/src/components/dashboard/parts/StatCard.jsx
  • views/assets/src/components/dashboard/parts/TaskDistributionCard.jsx
  • views/assets/src/components/dashboard/parts/TaskPerformanceCard.jsx
  • views/assets/src/components/dashboard/parts/TeamStatusCard.jsx
  • views/assets/src/components/dashboard/parts/UpcomingScheduleCard.jsx
  • views/assets/src/components/layout/AppSidebar.jsx
  • views/assets/src/components/ui/calendar.jsx
  • views/assets/src/index.jsx
  • views/assets/src/tailwind.css

Comment thread routes/dashboard.php
Comment on lines +8 to +13
$wedevs_pm_router->get( 'dashboard', 'WeDevs/PM/Dashboard/Controllers/Dashboard_Controller@index' )
->permission( ['WeDevs\PM\Core\Permissions\Authentic'] );

// GET /wp-json/pm/v2/dashboard/heatmap?year=YYYY — productivity heatmap (self-fetched by the card).
$wedevs_pm_router->get( 'dashboard/heatmap', 'WeDevs/PM/Dashboard/Controllers/Dashboard_Controller@heatmap_data' )
->permission( ['WeDevs\PM\Core\Permissions\Authentic'] );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add validator and sanitizer to both dashboard endpoints.

Both routes are missing ->validator() and ->sanitizer(), which are mandatory for all REST endpoints in this codebase.

🔧 Proposed fix
 $wedevs_pm_router->get( 'dashboard', 'WeDevs/PM/Dashboard/Controllers/Dashboard_Controller@index' )
-    ->permission( ['WeDevs\PM\Core\Permissions\Authentic'] );
+    ->permission( ['WeDevs\PM\Core\Permissions\Authentic'] )
+    ->validator( ['WeDevs\PM\Dashboard\Validators\Dashboard_Validator'] )
+    ->sanitizer( ['WeDevs\PM\Dashboard\Sanitizers\Dashboard_Sanitizer'] );

 $wedevs_pm_router->get( 'dashboard/heatmap', 'WeDevs/PM/Dashboard/Controllers/Dashboard_Controller@heatmap_data' )
-    ->permission( ['WeDevs\PM\Core\Permissions\Authentic'] );
+    ->permission( ['WeDevs\PM\Core\Permissions\Authentic'] )
+    ->validator( ['WeDevs\PM\Dashboard\Validators\Dashboard_Heatmap_Validator'] )
+    ->sanitizer( ['WeDevs\PM\Dashboard\Sanitizers\Dashboard_Heatmap_Sanitizer'] );

As per coding guidelines, “Every REST endpoint must have a validator via ->validator() and sanitizer via ->sanitizer() methods.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@routes/dashboard.php` around lines 8 - 13, Both the 'dashboard' and
'dashboard/heatmap' routes in the router configuration are missing the required
validator and sanitizer method chains. Add ->validator() and ->sanitizer()
method calls to each route definition, chaining them after the existing
->permission() method. These methods are mandatory for all REST endpoints in the
codebase to ensure proper input validation and sanitization of request data.

Source: Coding guidelines

Comment on lines +64 to +82
$data = [
'user' => $this->user_block(),
'range' => $days,
'kpis' => $this->kpis(),
'projects_status' => $this->projects_status(),
'performance' => $this->performance( $days ),
'task_distribution' => $this->task_distribution(),
'upcoming' => $this->upcoming_tasks(),
'overdue_list' => $this->overdue_tasks(),
'calendar' => $this->calendar_month(),
'active_projects' => $this->active_projects(),
'recent_activity' => $this->recent_activity(),
'milestones' => $this->upcoming_milestones(),
'team' => ( $this->is_admin || $this->is_manager ) ? $this->team_status() : [],
'generated_at' => current_time( 'mysql' ),
];

return rest_ensure_response( [ 'data' => $data ] );
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use Fractal transformers for dashboard responses instead of raw arrays.

The controller is returning raw associative arrays directly; this bypasses the project’s required Fractal serialization contract for src/** API output.

As per coding guidelines, “Use Fractal transformers for API response serialization.”

Also applies to: 303-303

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Dashboard/Controllers/Dashboard_Controller.php` around lines 64 - 82, The
Dashboard_Controller is returning raw associative arrays directly via
rest_ensure_response instead of using Fractal transformers for serialization.
Replace the raw array construction and response return in this method with
proper Fractal transformer implementation. Create or use an existing Fractal
transformer class to serialize the dashboard data array that includes user,
range, kpis, projects_status, performance, task_distribution, upcoming,
overdue_list, calendar, active_projects, recent_activity, milestones, team, and
generated_at fields, then pass the transformed data through Fractal before
returning the response to ensure compliance with the project's API serialization
standards.

Source: Coding guidelines

$total = (clone $this->task_query())->count();
$completed = (clone $this->task_query())->where( 'status', Task::COMPLETE )->count();
$in_progress = (clone $this->task_query())->where( 'status', Task::INCOMPLETE )->count();
$pending = (clone $this->task_query())->where( 'status', Task::PENDING )->count();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align task-status aggregation with the 0/1 task status contract.

pending is being counted via Task::PENDING, but task status is defined as a 2-state integer model. This can make KPI/distribution data inconsistent with persisted values.

As per coding guidelines, “Task status is an INTEGER (0 or 1), NOT a boolean.”

Also applies to: 382-382

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Dashboard/Controllers/Dashboard_Controller.php` at line 163, The task
status aggregation in the Dashboard_Controller where clause is using the
Task::PENDING constant, but task status is defined as a 2-state integer model
with values 0 or 1. Replace the Task::PENDING constant in the where clause with
the correct integer value (0 or 1) that represents pending status according to
the task status contract, ensuring consistency between the aggregated KPI data
and persisted task values. Apply the same fix to line 382 where this pattern
also occurs.

Source: Coding guidelines

Comment on lines +209 to +212
if ( (int) $p->status === Project::COMPLETE ) {
$completed++;
} elseif ( (int) $p->status === Project::ARCHIVED ) {
$archived++;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove integer casting from project status checks.

Casting project status to (int) can misclassify string statuses and break the on-track/completed/archived counters.

🔧 Proposed fix
-        foreach ( $projects as $p ) {
-            if ( (int) $p->status === Project::COMPLETE ) {
+        foreach ( $projects as $p ) {
+            if ( $p->status === 'complete' ) {
                 $completed++;
-            } elseif ( (int) $p->status === Project::ARCHIVED ) {
+            } elseif ( $p->status === 'archived' ) {
                 $archived++;
             } elseif ( $p->overdue_count > 0 ) {
                 $at_risk++;
             } else {
                 $on_track++;
             }
         }

As per coding guidelines, “Project status is a STRING ('incomplete' | 'complete' | 'archived' | 'favourite'), NOT an enum or integer.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Dashboard/Controllers/Dashboard_Controller.php` around lines 209 - 212,
The integer casting (int) on $p->status is incorrect because project status is a
STRING value, not an integer, and casting will misclassify statuses and break
the counter logic. Remove the (int) casting from both comparisons in the if and
elseif conditions that check against Project::COMPLETE and Project::ARCHIVED
constants, comparing the status directly as a string instead.

Source: Coding guidelines

Comment thread views/assets/src/components/dashboard/DashboardPage.jsx
Comment thread views/assets/src/components/dashboard/parts/StatCard.jsx Outdated
Comment thread views/assets/src/components/dashboard/parts/StatCard.jsx Outdated
Comment thread views/assets/src/tailwind.css Outdated
Comment on lines 514 to +516
[data-radix-popper-content-wrapper] {
z-index: 3000 !important;
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
font-family: 'Mona Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reduce dialog/popper z-index to the project maximum.

Line 515 (3000), Line 551 (2001), and Line 580 (2501) exceed the allowed plugin max z-index and can break expected layering behavior.

Suggested fix
 [data-radix-popper-content-wrapper] {
-  z-index: 3000 !important;
+  z-index: 700 !important;
   font-family: 'Mona Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
 }

 [role="dialog"][data-state] {
-  z-index: 2001 !important;
+  z-index: 700 !important;
   font-family: 'Mona Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 }

 [role="alertdialog"][data-state] {
-  z-index: 2501 !important;
+  z-index: 700 !important;
   font-family: 'Mona Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 }
As per coding guidelines: "Maximum z-index for plugin styles is 700 (WP admin bar is 99999, media modal is 160000)". -->

Also applies to: 550-552, 579-581

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@views/assets/src/tailwind.css` around lines 514 - 516, The z-index values in
the tailwind.css file exceed the project's maximum allowed z-index of 700 for
plugin styles. Update the z-index property in the
[data-radix-popper-content-wrapper] selector from 3000 to 700, and also reduce
the z-index values at the locations around lines 551 and 580 to comply with the
700 maximum limit. Ensure all three z-index declarations (3000, 2001, and 2501)
are replaced with values that do not exceed 700 to prevent breaking expected
layering behavior.

Source: Coding guidelines

@arifulhoque7 arifulhoque7 self-assigned this Jun 26, 2026
PR weDevsOfficial#626 review fixes (safe subset):
- DashboardPage: guard load() with requestSeqRef so stale range responses
  cannot overwrite newer data
- StatCard: render clickable card as <button> for keyboard a11y; color
  'flat' trend neutral instead of positive emerald
- tailwind.css: drop url() from @import for Stylelint import-notation
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