Skip to content

feat: Quick Deploy button in model tab with scope selection and Run History integration#62

Merged
abhizipstack merged 14 commits intomainfrom
feat/quick-deploy-button-in-model-tab
Apr 16, 2026
Merged

feat: Quick Deploy button in model tab with scope selection and Run History integration#62
abhizipstack merged 14 commits intomainfrom
feat/quick-deploy-button-in-model-tab

Conversation

@abhizipstack
Copy link
Copy Markdown
Contributor

@abhizipstack abhizipstack commented Apr 16, 2026

What

Model Tab — Quick Deploy

  • Primary Quick Deploy button added to the model tab action row (next to Clear / Download CSV / Reveal Sequence), with a dropdown chevron that shows recent runs.
  • Click → fetches candidate jobs for this model → modal flow:
    • 0 candidates → "No Deployment Job Found" with a CTA linking to the Scheduler page.
    • 1 candidate → confirm modal showing job + environment.
    • 2+ candidates → job picker radio group above.
  • Modal shows two scope cards (Run this model only / Run full job) — visual selection, does NOT auto-trigger.
  • "I understand…" confirmation checkbox (gated on scope selection) — dynamic text reflects the chosen scope, job name, environment, and model count.
  • Run button in the footer ("Run model" / "Run full job") — disabled until job selected + scope selected + checkbox ticked.
  • Success/error toast with job + env summary; explorer refresh after dispatch.
  • Dropdown chevron opens a recent-runs popup (last 5 runs for this model, mixed scheduled + manual) with theme-aware styling, relative timestamps, and a "View full Run History →" link.

Run History — Trigger + Scope taxonomy

  • Replaced the single "Source" column with two columns: Trigger (Manual / Scheduled) and Scope (Full job / Single model with model names).
  • Two composable filters (Trigger + Scope) replace the old Source filter. Both work with Status.
  • Back-compat: old rows with kwargs.source === "quick_deploy" render correctly as Manual + Single model.
  • Expanded error row anchored to parent row: red left-border stripe runs through both, transparent row border in between, collapse by default.

Jobs List

  • Run icon tooltip updated to "Deploy Job" for naming consistency.

Backend

  • trigger_scheduled_run gains models_override: list and trigger: str kwargs. When models_override is set, scopes the DAG run to those models via execute_visitran_run_command(current_models=...). Records trigger ("manual" / "scheduled") and scope ("model" / "job") on TaskRunHistory.kwargs for every run (including retries).
  • trigger_task_once refactored into shared _dispatch_task_run helper (Celery-first with sync fallback) used by both the existing full-job trigger and the new single-model trigger.
  • New endpoints:
    • POST /jobs/trigger-periodic-task/<task_id>/model/<model_name> — validates the model is enabled on the job, dispatches a scoped run.
    • GET /jobs/quick-deploy/candidates/<model_name> — returns jobs in the project that include the model with enabled_model_count.
    • GET /jobs/quick-deploy/recent-runs/<model_name>?limit=5 — returns recent runs for any job that includes this model, with trigger/scope/models_override and back-compat.

Why

Users had no way to deploy a model from the model tab — they had to navigate to the Jobs List and trigger the whole job. This feature lets users deploy the current model (or the full job) with a clear scope-selection and confirmation flow, directly from where they're editing.

The Run History taxonomy was conflating trigger type (manual vs scheduled) with scope (model vs job), making it impossible to filter "show me only the runs I manually kicked off" or "only single-model deploys".

How

  • Frontend (no-code-model.jsx): useJobService hooks for listDeployCandidates, runTaskForModel, runTask, listRecentRunsForModel. Modal state machine with step (loading/empty/confirm/pick), selectedScope (model/job), and confirmed (checkbox). Space.Compact with Dropdown for the recent-runs popup. All using antd theme tokens.
  • Frontend (Runhistory.jsx): getRunTriggerScope helper with back-compat for legacy kwargs.source. CSS .runhistory-row-expanded + .ant-table-expanded-row overrides to bind parent-child rows visually. onRow injects red box-shadow on expanded parents.
  • Backend (celery_tasks.py): trigger_scheduled_run computes scope from models_override, passes trigger through to TaskRunHistory.kwargs and the retry path.
  • Backend (views.py): _dispatch_task_run centralizes Celery dispatch + sync fallback; list_deploy_candidates filters model_configs by model name; list_recent_runs_for_model queries across all jobs containing the model.

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)

Low risk:

  • Backend endpoints are additive — new URL routes alongside existing ones. trigger_task_once is refactored to use _dispatch_task_run but its external behavior is identical (same request/response shape).
  • trigger_scheduled_run gains optional kwargs with defaults that preserve existing Celery beat behavior (trigger="scheduled", models_override=None).
  • TaskRunHistory.kwargs now includes trigger and scope on every new run. Old rows lack these; the frontend falls back to legacy kwargs.source handling or defaults ("scheduled" / "job"). No migration needed.
  • Run History expand behavior widens from FAILURE-only to all completed runs. The FAILURE path is preserved (error_message Alert, scrollable pre). SUCCESS rows that were not expandable now are — no known consumer relies on them being non-expandable.
  • Jobs List tooltip text changes from "run" to "Deploy Job" — cosmetic only.

Database Migrations

None. trigger, scope, and models_override live in the existing TaskRunHistory.kwargs JSONField.

Env Config

None.

Relevant Docs

None.

Related Issues or PRs

Dependencies Versions

No changes.

Notes on Testing

Tested locally (host-mode: Django runserver + Celery worker/beat + React dev server, Postgres + Redis via Docker):

  1. Quick Deploy — 0 candidates: opened a model with no scheduled job → "No Deployment Job Found" modal → "Go to Scheduler" navigated correctly.
  2. Quick Deploy — 1 candidate: opened model included in one job → confirm modal showed job + env → selected scope "Run this model only" → ticked checkbox → "Run model" button enabled → clicked → toast "Deploy Triggered" appeared, setRefreshModels called.
  3. Quick Deploy — scope "Run full job": selected "Run full job" card → checkbox text updated to show all N models → button label flipped to "Run full job" → dispatched via runTask.
  4. Recent-runs popup: clicked chevron → popup showed last 5 runs with Manual/Scheduled tag, scope tag, relative time, job name + env → "View full Run History →" navigated correctly.
  5. Run History — Trigger/Scope columns: verified Manual + Single model for quick-deploy runs, Scheduled + Full job for cron runs. Filters compose correctly.
  6. Run History — error anchor: expanded FAILURE row → red stripe from parent through expanded panel, transparent border between. Collapsed by default on data load. Dark mode verified.
  7. Back-compat: old kwargs.source="quick_deploy" rows rendered as Manual + Single model.

Screenshots

Screenshot 2026-04-16 at 2 41 25 PM Screenshot 2026-04-16 at 2 43 53 PM Screenshot 2026-04-16 at 2 44 13 PM

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

@abhizipstack abhizipstack requested review from a team as code owners April 16, 2026 03:20
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 16, 2026

Greptile Summary

This PR adds a Quick Deploy button to the model tab (scope selection, confirmation checkbox, recent-runs popup) and splits Run History's single "Source" column into composable Trigger + Scope filters, backed by three new Django endpoints and extended trigger_scheduled_run kwargs. Prior reviewer feedback on null environment, stale cache, missing DB filter, and enabled_model_count null safety has all been addressed in follow-up commits.

Confidence Score: 5/5

Safe to merge; all prior P1 issues resolved, remaining findings are P2 edge cases

All previous reviewer concerns (null env, stale cache, missing DB filter, enabled_model_count null safety) have been addressed. Remaining findings are P2: an AttributeError on non-dict truthy cfg values (unlikely in practice, same class as the already-fixed null case) and a benign double-fetch race in the dropdown guard. Backend endpoints are additive, Celery kwargs are backward-compatible, and the Run History taxonomy is cleanly back-compat.

backend/backend/core/scheduler/views.py — cfg.get() guards in list_deploy_candidates and trigger_task_once_for_model should use isinstance(cfg, dict) for consistency with the enabled_model_count fix

Important Files Changed

Filename Overview
backend/backend/core/scheduler/views.py Adds _dispatch_task_run helper + three new endpoints; non-dict truthy cfg values are not guarded in list_deploy_candidates and trigger_task_once_for_model (AttributeError risk)
backend/backend/core/scheduler/celery_tasks.py Adds models_override/trigger kwargs with safe defaults; retry path correctly propagates both; scope is recomputed at entry so no extra kwarg needed
backend/backend/core/scheduler/urls.py Additive URL registration for three new endpoints; correct path patterns and names
frontend/src/ide/editor/no-code-model/no-code-model.jsx Adds Quick Deploy modal flow, recent-runs popup, log-level filter, and socket cleanup fix; dedup guard in fetchRecentRuns allows duplicate in-flight requests
frontend/src/ide/run-history/Runhistory.jsx Replaces Source column with Trigger + Scope, adds two composable filters, moves getRunTriggerScope to module scope; auto-expand correctly keyed to backUpData
frontend/src/ide/run-history/RunHistory.css CSS overrides to visually bind expanded error rows to their parent; clean and non-breaking
frontend/src/ide/scheduler/JobListTable.jsx Tooltip text updated from 'run' to 'Deploy Job'; cosmetic-only change
frontend/src/ide/scheduler/service.js Three new service methods (runTaskForModel, listDeployCandidates, listRecentRunsForModel) with correct encodeURIComponent usage

Sequence Diagram

sequenceDiagram
    participant U as User (model tab)
    participant FE as no-code-model.jsx
    participant SVC as service.js
    participant BE as views.py
    participant CL as Celery
    participant DB as TaskRunHistory

    U->>FE: Click Quick Deploy
    FE->>SVC: listDeployCandidates(projectId, modelName)
    SVC->>BE: GET /jobs/quick-deploy/candidates/{model}
    BE-->>FE: candidates[]

    alt 0 candidates
        FE-->>U: No Deployment Job Found modal
    else 1 candidate
        FE-->>U: confirm modal (job + env)
    else 2+ candidates
        FE-->>U: job picker radio + confirm modal
    end

    U->>FE: Select scope + tick checkbox + Run
    alt scope = model
        FE->>SVC: runTaskForModel(projectId, taskId, modelName)
        SVC->>BE: POST /jobs/trigger-periodic-task/{id}/model/{model}
    else scope = job
        FE->>SVC: runTask(projectId, taskId)
        SVC->>BE: POST /jobs/trigger-periodic-task/{id}
    end

    BE->>BE: _dispatch_task_run(task, userId, models_override?)
    BE->>CL: apply_async(trigger=manual, models_override?)
    CL->>DB: TaskRunHistory.create(trigger, scope, models_override)
    BE-->>FE: success
    FE-->>U: toast + refresh

    U->>FE: Click chevron dropdown
    FE->>SVC: listRecentRunsForModel(projectId, modelName, 5)
    SVC->>BE: GET /jobs/quick-deploy/recent-runs/{model}
    BE-->>FE: runs[] with trigger/scope back-compat
    FE-->>U: Recent runs popup
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: backend/backend/core/scheduler/views.py
Line: 775-776

Comment:
**Non-dict truthy config causes `AttributeError`**

`not cfg` short-circuits for `None` and `{}`, but for any other truthy non-dict value (e.g. a JSON boolean `true` stored as `model_configs["my_model"] = True`), `not cfg` is `False` and `cfg.get("enabled", True)` raises `AttributeError`. The previous null-safety fix already established the right pattern — `isinstance(m_cfg, dict)` is used in `enabled_model_count` on line 780 but not here.

The same gap exists in `trigger_task_once_for_model` (line 696).

```suggestion
        if not isinstance(cfg, dict) or not cfg.get("enabled", True):
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: backend/backend/core/scheduler/views.py
Line: 695-696

Comment:
**Non-dict truthy config causes `AttributeError`**

Same issue as in `list_deploy_candidates` line 776: `not model_cfg` short-circuits for `None`/`{}` but not for other truthy non-dict values. If `model_cfg` is, say, a JSON boolean `True`, `not model_cfg` is `False` and `model_cfg.get("enabled", True)` raises `AttributeError`. The `enabled_model_count` sibling check already uses `isinstance(m_cfg, dict)` as the guard.

```suggestion
    if not isinstance(model_cfg, dict) or not model_cfg.get("enabled", True):
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: frontend/src/ide/editor/no-code-model/no-code-model.jsx
Line: 1678

Comment:
**Dedup guard doesn't cover in-flight fetches**

The early-return only fires when `!loading`. If the user opens the chevron dropdown while a fetch is already in progress (`loading === true`), the condition evaluates to `false` and a second concurrent request is dispatched. The two responses will race to set state; the final value is correct but the extra request is wasteful.

```suggestion
    if (recentRunsState.loading || recentRunsState.fetchedFor === name) return;
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (4): Last reviewed commit: "fix: address reviewer feedback — null co..." | Re-trigger Greptile

Comment thread backend/backend/core/scheduler/views.py Outdated
Comment thread frontend/src/ide/editor/no-code-model/no-code-model.jsx
Comment thread frontend/src/ide/run-history/Runhistory.jsx
Comment thread backend/backend/core/scheduler/views.py
Comment thread backend/backend/core/scheduler/views.py
@wicky-zipstack
Copy link
Copy Markdown
Contributor

wicky-zipstack commented Apr 16, 2026

Changes requested (small, mostly polish):

  1. Dedupe formatRelativeTime (no-code-model.jsx) → use shared getRelativeTime.
  2. Keep auto-expand on FAILURE in Run History — current behaviour is a regression.
  3. Gate the red boxShadow on record.status === "FAILURE", or colour-match by status.
  4. (Coordinate with feat: Deploy, Jobs & Run History UX improvements #61) Pull getRunTriggerScope/getRunInsights into one shared util.

Comment thread backend/backend/core/scheduler/views.py
Comment thread frontend/src/ide/run-history/Runhistory.jsx
Comment thread frontend/src/ide/editor/no-code-model/no-code-model.jsx Outdated
Comment thread frontend/src/ide/run-history/Runhistory.jsx
Copy link
Copy Markdown
Contributor

@wicky-zipstack wicky-zipstack left a comment

Choose a reason for hiding this comment

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

@abhizipstack One small leftover (non-blocking, can ship): the inline boxShadow: inset 3px 0 0 0 ${token.colorError} on onRow is still applied to any expanded row regardless of status. Auto-expand is now FAILURE-only so it's fine in practice, but if a user manually expands a SUCCESS/RETRY row they'll get a misleading red bar. Worth a follow-up to gate on record.status === "FAILURE" or color-match by status.

abhizipstack and others added 13 commits April 16, 2026 17:09
Quick Deploy runs the current model through the same pipeline as the
scheduler's "Run Now" — reusing an existing enabled job's environment,
model_configs (materialization, incremental, watermark), retries, Slack
notifications, and TaskRunHistory — but scopes the DAG run to just the
current model.

Backend
- trigger_scheduled_run accepts an optional models_override list. When
  provided it's passed to execute_visitran_run_command as current_models
  so only those models execute. Recorded in TaskRunHistory.kwargs with
  source="quick_deploy" so ad-hoc runs are distinguishable from
  scheduled ones. Models_override is threaded through the retry path.
- New endpoint POST /jobs/trigger-periodic-task/<task>/model/<model>
  dispatches a single-model run; validates the model is present and
  enabled on the job before running.
- New endpoint GET /jobs/quick-deploy/candidates/<model> returns the
  jobs in the project that include the model with enabled=true.
- trigger_task_once and the new single-model variant share a
  _dispatch_task_run helper (Celery-first with sync fallback).

Frontend
- Primary "Quick Deploy" button in the model tab action row.
- Click → fetches candidates:
    - 0  → modal explains no job covers this model and links to the
           scheduler page to create one.
    - 1  → confirm modal shows job + environment before running.
    - 2+ → picker modal with a radio list of qualifying jobs.
- On success: success notification with job + environment summary,
  triggers explorer refresh so the status badge reflects the new run.
- On failure: existing error notification path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Run History now shows a Source column with a blue "Quick Deploy" tag
  and the overridden model name(s) for ad-hoc runs; scheduled runs show
  a muted "Scheduled" label. Reads the markers already written into
  TaskRunHistory.kwargs ("source" + "models_override").
- list_deploy_candidates was returning environment_name="" because it
  read task.environment.name; the field on EnvironmentModels is
  environment_name. Fixed to prefer environment_name with a fallback
  to name for defensive cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the Quick Deploy control into a Space.Compact pair: the primary
button still opens the deploy flow; the adjacent chevron opens a small
popup listing recent runs for the current model, mixing scheduled and
quick-deploy runs. A "View full Run History" link-button at the bottom
navigates to /project/job/history.

Backend
- GET /jobs/quick-deploy/recent-runs/<model>?limit=5 returns the most
  recent TaskRunHistory entries where the job's model_configs includes
  the model. Each row exposes status, start_time, environment_name,
  task_name, error_message, and source (derived from
  kwargs.source, defaulting to "scheduled").

Frontend
- useJobService gets listRecentRunsForModel(projId, modelName, limit).
- Dropdown fetches on open (once per model name — cached within
  component state). Panel shows colored status tag, a Quick Deploy /
  Scheduled source tag, job name, environment, and a relative time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hardcoded #fff / #555 / #888 / #f0f0f0 rendered illegibly on dark
themes. Swap to antd theme tokens so the panel follows the active
theme: colorBgElevated for the backdrop, colorTextSecondary for muted
headers/empty states, colorBorderSecondary for the row separators,
boxShadowSecondary + borderRadiusLG for the elevated card feel.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Run History now has a third filter next to Job and Status that narrows
rows by kwargs.source ("quick_deploy" vs scheduled, where scheduled is
defined as everything lacking the quick_deploy marker). The filter is
client-side on the currently loaded page; it plays with the Status
filter (both apply). Switching jobs resets the Source filter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original "Source" marker conflated two orthogonal dimensions:
whether a run was triggered manually or by cron, and whether it ran the
full job or a single model. Manual job triggers ("Run Now") were
indistinguishable from cron runs because both lacked the
source="quick_deploy" marker, which was wrong.

Backend
- trigger_scheduled_run gains trigger: str = "scheduled" and derives
  scope ("model" if models_override else "job"). Both are recorded on
  TaskRunHistory.kwargs on every run (including retries).
- _dispatch_task_run (used by both trigger_task_once and the new
  single-model variant) always sends trigger="manual"; the Celery beat
  path keeps the "scheduled" default, so manual job deploys are now
  correctly distinguished from cron-driven runs.
- list_recent_runs_for_model returns trigger + scope, with back-compat
  fallback for legacy rows that only carried kwargs.source.
- kwargs.source is no longer written.

Frontend
- Run History: replaced the Source column with Trigger (Manual /
  Scheduled) and Scope (Full job / Single model, with the targeted
  model names). The Source filter is now two filters — Trigger and
  Scope — each composable with Status and with each other. A shared
  helper derives trigger/scope with legacy-row back-compat.
- Recent-runs popup on the model tab shows both tags.
- Button labels updated to match the new taxonomy: model tab's
  "Quick Deploy" → "Deploy Model"; jobs list tooltip "run" →
  "Deploy Job". Success toast and modal heading updated accordingly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keeps "Quick Deploy" as the toolbar button but lets users pick scope at
the point of confirmation, directly in the model tab — so they no
longer need to bounce to the Jobs List to run the full pipeline that
includes the model they are editing.

- Modal's confirm step now shows two side-by-side cards:
    ▸ "Run this model only" — uses runTaskForModel (existing)
    ▸ "Run full job" — uses runTask (existing); shows the enabled
      model count so users see the blast radius before committing.
- If multiple candidate jobs include the model, the job picker radio
  group appears above the scope cards so the whole decision happens in
  one modal. Single-candidate case skips the picker.
- Cards act as the primary CTAs; the submit state highlights the
  clicked card's border and dims the other while the dispatch is in
  flight. Footer keeps just a Cancel button.
- Success toast copy differentiates model vs job deploys.

Backend candidate response now includes enabled_model_count derived
from the job's model_configs so the "Run full job" card can show
"Runs all N enabled models".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the auto-triggering scope cards with a single checkbox
("Also run the other models in this job") plus a primary "Run model" /
"Run full job" button in the footer. Picking a job in the radio no
longer fires a deploy — the user now has one clear moment where they
commit, and the button label reflects the current scope so they see
exactly what will run.

- Scope lives on quickDeployModal.runFullJob; starts unchecked
  (model-only) every time the modal opens, and resets when the user
  switches the selected job so scope can't silently carry over.
- Checkbox description swaps text based on state so the blast radius
  is visible before clicking.
- Footer button label: "Run model" → "Run full job" when checkbox is
  ticked, for an unambiguous preview of the action.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Final modal flow, matches the agreed UX:
1. (Multi-candidate) radio picker for the job — selection only,
   doesn't trigger anything.
2. Two scope cards — "Run this model only" / "Run full job" — act
   as visual radios; clicking selects the scope, does not dispatch.
3. Confirmation checkbox ("I understand this will run <scope> against
   environment X") — gated on a scope being picked.
4. Primary footer button "Run model" / "Run full job" — disabled
   until a scope is selected AND the confirmation checkbox is ticked.

Scope is stored in quickDeployModal.selectedScope and resets when the
user flips the candidate radio so stale scope can't carry to a
different job. The button is the only thing that dispatches; clicking
a card never triggers a run.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Expanded error rows previously rendered as a flat danger-red text
block with no visual connection to the failed run above — users
couldn't immediately tell the error belonged to that row.

- Wrap the expanded panel in an error-themed container: a 3px
  colorError left border, colorErrorBg background, and a small header
  ("Error from this run · <start_time>") with a CloseCircleFilled
  icon so the panel clearly extends the row that spawned it.
- Error text itself goes inside an antd Alert (showIcon=false) using a
  <pre> with max-height + scroll so long stack traces don't blow out
  the page; whitespace and line breaks are preserved (previously
  Typography collapsed them).
- All colors go through theme tokens so light/dark both work.
- Dropped the now-redundant .runhistory-error-row padding rule.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Expanded error rows were rendering as a full-width sibling row,
separated from the failed run above by antd's default row border.
Users couldn't tell at a glance which run the error belonged to.

- rowClassName marks expanded parent rows; their bottom border is now
  transparent so visual flow continues down into the expanded panel.
- The parent row gets an inset 3px red box-shadow on its left edge
  (via onRow, theme-token-driven) that lines up with the panel's own
  red left border — the red stripe now runs top-to-bottom through
  both parts, reading as one grouped item.
- .ant-table-expanded-row <td> is neutralized (no top border, no
  padding, transparent background incl. hover) so only the inner
  styled panel shows; no antd chrome separates parent from child.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Failed runs were auto-expanded whenever the data loaded, which made
error panels land in the user's face every visit. Reset
expandedRowKeys on data change so rows start collapsed; users click
the expander to see the stack trace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
P1: list_deploy_candidates crashed with AttributeError when a task had
    no environment. Guard with `if env else ""` (same pattern used in
    list_recent_runs_for_model).

P2: list_deploy_candidates loaded all project tasks and filtered in
    Python. Added model_configs__has_key=model_name to the queryset so
    the DB does the heavy lifting.

P2: Recent-runs popup showed stale data after a Quick Deploy because
    fetchedFor wasn't cleared. Now reset to null after successful
    dispatch so the next dropdown open refetches.

P2: getRunTriggerScope was defined inside the Runhistory component,
    triggering react-hooks/exhaustive-deps warnings and unnecessary
    re-creation. Moved to module scope — it has no dependency on
    component state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@tahierhussain tahierhussain left a comment

Choose a reason for hiding this comment

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

LGTM

P1: enabled_model_count crashed with AttributeError when a model in
    model_configs had a null/non-dict value. Added isinstance(m_cfg,
    dict) guard before calling .get().

P2: FAILURE rows no longer auto-expanded after the earlier "collapse
    by default" change. Restored auto-expand for FAILURE rows only,
    keyed on backUpData (fresh loads) so filter changes don't reset
    user-expanded rows.

P2: Replaced the local formatRelativeTime in no-code-model.jsx with
    the shared getRelativeTime from common/helpers.js which already
    handles both past and future dates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@abhizipstack abhizipstack force-pushed the feat/quick-deploy-button-in-model-tab branch from de97852 to 289eec0 Compare April 16, 2026 11:41
@abhizipstack abhizipstack merged commit 6420853 into main Apr 16, 2026
8 checks passed
@abhizipstack abhizipstack deleted the feat/quick-deploy-button-in-model-tab branch April 16, 2026 11:47
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.

4 participants