fix: project list job stats not showing + uniform card height + clickable links#77
fix: project list job stats not showing + uniform card height + clickable links#77wicky-zipstack wants to merge 1 commit intomainfrom
Conversation
…able links
- Fix apps.is_installed("job_scheduler") returning False — use
apps.get_app_config() instead (checks by label, not module path)
- Add min-height to "No jobs" section for uniform card height
- Make Scheduled/In Progress/Failed clickable — navigate to
Jobs list or Run History page
|
| Filename | Overview |
|---|---|
| backend/backend/application/context/base_context.py | Replaces apps.is_installed (matched by module path) with apps.get_app_config in a try/except (matched by label), correctly fixing the always-false check; minor: result is recomputed on every request rather than cached at module level. |
| frontend/src/base/components/project-list/ProjectListCard.css | Adds min-height: 38px + flex centering to .project-list-card-no-jobs for uniform card height, and introduces .project-list-card-job-link with cursor pointer and hover opacity — clean, additive changes with no issues. |
| frontend/src/base/components/project-list/ProjectListCard.jsx | Adds onClick handlers with e.stopPropagation() to job-stat Typography elements; navigates to global /project/job/list and /project/job/history routes without a project-specific filter, which may confuse users expecting project-scoped results. |
Sequence Diagram
sequenceDiagram
participant Browser
participant ProjectListCard
participant Django as Django Backend
participant AppRegistry as Django App Registry
Browser->>Django: GET /api/projects/list
Django->>AppRegistry: get_app_config("job_scheduler")
AppRegistry-->>Django: AppConfig (or LookupError)
Note over Django: _scheduler_installed = True/False
Django->>Django: Annotate queryset with job counts (if installed)
Django-->>Browser: Project list + job stats
Browser->>ProjectListCard: Render cards with job stats
Note over ProjectListCard: Show stats if any > 0, else "No jobs scheduled yet"
ProjectListCard->>Browser: User clicks "Scheduled"
Browser->>Browser: e.stopPropagation()
Browser->>Browser: navigate("/project/job/list")
ProjectListCard->>Browser: User clicks "In Progress" or "Failed"
Browser->>Browser: e.stopPropagation()
Browser->>Browser: navigate("/project/job/history")
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
backend/backend/application/context/base_context.py:184-189
**Scheduler check recomputed on every request**
`apps.get_app_config("job_scheduler")` is called inside the request handler on every project-list fetch. Since the Django app registry is fixed at startup, this result never changes at runtime. Consider hoisting the check to module level (or caching it as a module-level constant) to avoid the repeated try/except overhead on every request.
```python
# module level, outside the class/method
from django.apps import apps as _django_apps
try:
_django_apps.get_app_config("job_scheduler")
_SCHEDULER_INSTALLED = True
except LookupError:
_SCHEDULER_INSTALLED = False
```
Then replace the inline block with just:
```python
if _SCHEDULER_INSTALLED and hasattr(ProjectDetails, "user_tasks"):
```
### Issue 2 of 2
frontend/src/base/components/project-list/ProjectListCard.jsx:226-255
**Job link navigation missing project context**
Clicking any of the three job-stat links navigates to the global `/project/job/list` or `/project/job/history` route without carrying the current project's ID. A user clicking "3 Scheduled" on a specific project card will land on the full global jobs list with no filter applied, which can be disorienting. Other call sites (e.g. `no-code-model.jsx`) pass a `task=` or params query string; at minimum passing a project filter would make these links meaningfully project-scoped.
This matches the existing `NavigationTabs` behaviour, so it may be intentional, but it is worth confirming whether the Jobs/Run History pages support a project filter query param.
Reviews (1): Last reviewed commit: "fix: project list job stats not showing ..." | Re-trigger Greptile
| from django.apps import apps | ||
| if apps.is_installed("job_scheduler") and hasattr(ProjectDetails, "user_tasks"): | ||
| try: | ||
| apps.get_app_config("job_scheduler") | ||
| _scheduler_installed = True | ||
| except LookupError: | ||
| _scheduler_installed = False |
There was a problem hiding this comment.
Scheduler check recomputed on every request
apps.get_app_config("job_scheduler") is called inside the request handler on every project-list fetch. Since the Django app registry is fixed at startup, this result never changes at runtime. Consider hoisting the check to module level (or caching it as a module-level constant) to avoid the repeated try/except overhead on every request.
# module level, outside the class/method
from django.apps import apps as _django_apps
try:
_django_apps.get_app_config("job_scheduler")
_SCHEDULER_INSTALLED = True
except LookupError:
_SCHEDULER_INSTALLED = FalseThen replace the inline block with just:
if _SCHEDULER_INSTALLED and hasattr(ProjectDetails, "user_tasks"):Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/backend/application/context/base_context.py
Line: 184-189
Comment:
**Scheduler check recomputed on every request**
`apps.get_app_config("job_scheduler")` is called inside the request handler on every project-list fetch. Since the Django app registry is fixed at startup, this result never changes at runtime. Consider hoisting the check to module level (or caching it as a module-level constant) to avoid the repeated try/except overhead on every request.
```python
# module level, outside the class/method
from django.apps import apps as _django_apps
try:
_django_apps.get_app_config("job_scheduler")
_SCHEDULER_INSTALLED = True
except LookupError:
_SCHEDULER_INSTALLED = False
```
Then replace the inline block with just:
```python
if _SCHEDULER_INSTALLED and hasattr(ProjectDetails, "user_tasks"):
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Acknowledged — apps.get_app_config() is a dict lookup internally (O(1), nanosecond overhead). Caching at module level would save the try/except but the gain is negligible for a page-load endpoint. Can optimize in a follow-up if profiling shows it matters.
| <Typography.Text | ||
| className="project-list-card-job-link" | ||
| onClick={(e) => { | ||
| e.stopPropagation(); | ||
| navigate("/project/job/list"); | ||
| }} | ||
| > | ||
| <ExclamationCircleFilled className="project-list-card-status-icon warning" /> | ||
| {details?.total_scheduled_jobs} Scheduled | ||
| </Typography.Text> | ||
| <Typography.Text> | ||
| <Typography.Text | ||
| className="project-list-card-job-link" | ||
| onClick={(e) => { | ||
| e.stopPropagation(); | ||
| navigate("/project/job/history"); | ||
| }} | ||
| > | ||
| <InfoCircleFilled className="project-list-card-status-icon info" /> | ||
| {details?.total_active_jobs} In Progress | ||
| </Typography.Text> | ||
| <Typography.Text> | ||
| <Typography.Text | ||
| className="project-list-card-job-link" | ||
| onClick={(e) => { | ||
| e.stopPropagation(); | ||
| navigate("/project/job/history"); | ||
| }} | ||
| > | ||
| <CheckCircleFilled className="project-list-card-status-icon failed" /> | ||
| {details?.total_failed_job} Failed | ||
| </Typography.Text> |
There was a problem hiding this comment.
Job link navigation missing project context
Clicking any of the three job-stat links navigates to the global /project/job/list or /project/job/history route without carrying the current project's ID. A user clicking "3 Scheduled" on a specific project card will land on the full global jobs list with no filter applied, which can be disorienting. Other call sites (e.g. no-code-model.jsx) pass a task= or params query string; at minimum passing a project filter would make these links meaningfully project-scoped.
This matches the existing NavigationTabs behaviour, so it may be intentional, but it is worth confirming whether the Jobs/Run History pages support a project filter query param.
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/base/components/project-list/ProjectListCard.jsx
Line: 226-255
Comment:
**Job link navigation missing project context**
Clicking any of the three job-stat links navigates to the global `/project/job/list` or `/project/job/history` route without carrying the current project's ID. A user clicking "3 Scheduled" on a specific project card will land on the full global jobs list with no filter applied, which can be disorienting. Other call sites (e.g. `no-code-model.jsx`) pass a `task=` or params query string; at minimum passing a project filter would make these links meaningfully project-scoped.
This matches the existing `NavigationTabs` behaviour, so it may be intentional, but it is worth confirming whether the Jobs/Run History pages support a project filter query param.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Valid point — currently navigates to the global Jobs/Run History pages, consistent with how the sidebar navigation works (same routes, no project filter). Filtering by project would need a query param (?project=<id>) which the Jobs page doesn't support yet. Will address when project-scoped filtering is added to the Jobs page.
What
Why
apps.is_installed("job_scheduler")was returningFalsebecause it checks by app module path, not label. The scheduler app is registered asbackend.core.schedulerwith labeljob_scheduler, butis_installed()only matches by module path. The job count annotations were never running.How
base_context.py): Replacedapps.is_installed("job_scheduler")withapps.get_app_config("job_scheduler")wrapped in try/except —get_app_configresolves by label correctly.ProjectListCard.css): Addedmin-height: 38pxto.project-list-card-no-jobswithdisplay: flex; align-items: centerfor uniform height.ProjectListCard.jsx): AddedonClickhandlers withe.stopPropagation()— Scheduled navigates to/project/job/list, In Progress and Failed navigate to/project/job/history. Added cursor pointer + hover opacity via.project-list-card-job-linkclass.Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
stopPropagationso the card click still works. CSS adds min-height which only affects empty-state cards.Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
Dependencies Versions
Notes on Testing
Screenshots
Checklist