Skip to content

fix(ui): refactor small UI issues#1504

Merged
yohamta0 merged 3 commits into
mainfrom
fix-ui-issues-2
Dec 24, 2025
Merged

fix(ui): refactor small UI issues#1504
yohamta0 merged 3 commits into
mainfrom
fix-ui-issues-2

Conversation

@yohamta0

@yohamta0 yohamta0 commented Dec 24, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added unsaved changes detection with a confirmation prompt when attempting to run a DAG with pending edits.
  • Bug Fixes

    • Fixed log line counting and pagination to correctly display actual rendered lines.
    • Improved text selection visibility in log viewers with enhanced styling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 24, 2025

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Introduces unsaved changes detection and management for DAG editing via a new React context. Integrates warnings in DAG actions and tracks changes in the editor. Additionally refactors log pagination and line numbering in execution logs to handle trailing newlines and ensure consistent line counts across view modes.

Changes

Cohort / File(s) Summary
Unsaved Changes Context Infrastructure
ui/src/contexts/UnsavedChangesContext.tsx
New context providing hasUnsavedChanges state and setter through a hook and provider component for global access across DAG-related components.
Unsaved Changes Integration
ui/src/features/dags/components/common/DAGActions.tsx, ui/src/features/dags/components/dag-editor/DAGSpec.tsx
DAGActions: adds modal confirmation when unsaved changes exist before enqueueing. DAGSpec: tracks changes by comparing current editor value with fetched data and disables save button when no changes exist.
Provider Wrappers
ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx, ui/src/pages/dags/dag/index.tsx
Wraps DAG content and context trees with UnsavedChangesProvider to enable unsaved changes tracking across DAG details and page-level components.
Log Rendering and Line Numbering
ui/src/features/dags/components/dag-execution/ExecutionLog.tsx, ui/src/features/dags/components/dag-execution/StepLog.tsx
Refactors pagination and line numbering to strip trailing newlines, use effectiveTotalLines for consistency across tail/head/page view modes, and adjust UI status text and validation bounds accordingly.
Log Styling
ui/src/styles/global.css
Adds blue-on-white text selection styling for .log-content elements to improve visibility on dark backgrounds.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant DAGEditor as DAG Editor
    participant DAGSpec as DAGSpec Component
    participant Context as UnsavedChanges Context
    participant DAGActions as DAG Actions
    participant Modal as Confirmation Modal
    
    User->>DAGEditor: Edit DAG configuration
    DAGEditor->>DAGSpec: Update value
    DAGSpec->>DAGSpec: Compare with fetched data
    DAGSpec->>Context: setHasUnsavedChanges(true)
    DAGSpec->>DAGEditor: Disable save (changes exist)
    
    User->>DAGActions: Click Enqueue
    DAGActions->>Context: Check hasUnsavedChanges
    alt Unsaved changes exist
        Context-->>DAGActions: true
        DAGActions->>Modal: Open "Unsaved Changes" modal
        Modal-->>User: Warn about unsaved edits
        User->>Modal: Confirm proceed
        Modal->>DAGActions: Continue to Enqueue
    else No unsaved changes
        Context-->>DAGActions: false
        DAGActions->>DAGActions: Open Enqueue modal
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Poem

🐰 With context magic, changes are bound,
Unsaved edits now gently found!
Logs count lines true, and modal warns,
Before the DAG execution turns.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'fix(ui): refactor small UI issues' is vague and overly broad, using generic terms like 'small UI issues' that don't convey meaningful information about the specific changes being made. Provide a more specific title that highlights the main change, such as 'feat(ui): add unsaved changes tracking and improve log pagination' or 'fix(ui): add unsaved changes context and refactor log line handling'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-ui-issues-2

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fb869d and 29b3c8d.

📒 Files selected for processing (8)
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/styles/global.css
🧰 Additional context used
📓 Path-based instructions (2)
ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (ui/CLAUDE.md)

ui/**/*.{ts,tsx,jsx,js}: Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations
Support both light and dark modes for all UI components using Tailwind CSS class pairs like dark:bg-slate-700
NEVER use full-page loading overlays or LoadingIndicator components that hide content - show stale data while fetching updates instead
Use compact modal design with small headers, minimal padding (p-2 or p-3), tight spacing, and support keyboard navigation (arrows, enter, escape)
Use small heights for form elements: select boxes h-7 or smaller, buttons h-7 or h-8, inputs with compact padding (py-0.5 or py-1)
Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text with whitespace-normal break-words
Use consistent metadata styling with bg-slate-200 dark:bg-slate-700 backgrounds and maintain text hierarchy with primary/secondary/muted text colors
Use flexbox-first layouts with min-h-0 and overflow-hidden to prevent layout breaks, account for fixed elements when setting heights
Maintain keyboard navigation support in all interactive components with appropriate focus indicators and ARIA labels

Files:

  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
ui/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

ui/**/*.{ts,tsx}: The React + TypeScript frontend resides in ui/, with production bundles copied to internal/service/frontend/assets by make ui
UI code follows ESLint + Prettier (2-space indent) and Tailwind utilities; name React components in PascalCase (JobList.tsx) and hooks with use* (useJobs.ts)

Files:

  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text with `whitespace-normal break-words`

Applied to files:

  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use consistent metadata styling with `bg-slate-200 dark:bg-slate-700` backgrounds and maintain text hierarchy with primary/secondary/muted text colors

Applied to files:

  • ui/src/styles/global.css
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations

Applied to files:

  • ui/src/features/dags/components/common/DAGActions.tsx
🧬 Code graph analysis (3)
ui/src/features/dags/components/dag-editor/DAGSpec.tsx (1)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • useUnsavedChanges (10-17)
ui/src/features/dags/components/common/DAGActions.tsx (1)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • useUnsavedChanges (10-17)
ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx (3)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • UnsavedChangesProvider (19-31)
ui/src/features/dags/contexts/DAGContext.ts (1)
  • DAGContext (3-9)
ui/src/features/dags/contexts/RootDAGRunContext.ts (1)
  • RootDAGRunContext (9-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
ui/src/styles/global.css (1)

459-470: LGTM! Good UX improvement for log text selection.

The selection styling ensures visible text selection on dark backgrounds. The Mozilla-prefixed selector provides broader browser compatibility.

ui/src/features/dags/components/dag-editor/DAGSpec.tsx (2)

128-143: LGTM! Clean implementation of unsaved changes tracking.

The change detection logic correctly compares editor state against fetched data, and the cleanup effect properly resets state on unmount to prevent stale context values.


394-402: LGTM! Save button correctly reflects unsaved state.

Disabling the save button when there are no changes provides clear visual feedback to users.

ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx (1)

180-242: LGTM! Proper provider integration.

The UnsavedChangesProvider correctly wraps the panel content, enabling descendant components (like DAGSpec) to track and report unsaved changes.

ui/src/features/dags/components/common/DAGActions.tsx (2)

111-117: LGTM! Good UX for unsaved changes warning.

The conditional flow correctly intercepts the enqueue action when unsaved changes exist, preventing users from accidentally running outdated DAG configurations.


547-571: LGTM! Clear and informative warning modal.

The modal content clearly explains that the DAG will run with the last saved version, and the "Run Anyway" button text sets appropriate expectations.

ui/src/pages/dags/dag/index.tsx (1)

195-242: LGTM! Consistent provider integration with DAGDetailsPanel.

The UnsavedChangesProvider placement mirrors the pattern in DAGDetailsPanel.tsx, ensuring consistent unsaved changes tracking across both the full page and modal panel views.

ui/src/contexts/UnsavedChangesContext.tsx (2)

10-17: LGTM! Safe fallback pattern for context usage.

Returning a default object when used outside the provider prevents runtime errors and allows components to be used in different contexts without crashing. The no-op setter is appropriate for the fallback case.


19-31: LGTM! Clean provider implementation.

The useCallback wrapper ensures a stable setter reference, preventing unnecessary re-renders in consuming components.

ui/src/features/dags/components/dag-execution/StepLog.tsx (2)

286-293: LGTM! Smart handling of trailing newline inconsistency.

The logic correctly handles the common edge case where split('\n') produces a trailing empty string, and the effectiveTotalLines calculation accommodates potential API inconsistencies in counting trailing newlines.


463-476: LGTM! Improved log content styling and selection.

The log-content class enables the custom text selection styling from global.css, and select-text cursor-text on line content improves copy-paste UX.

ui/src/features/dags/components/dag-execution/ExecutionLog.tsx (2)

277-284: LGTM! Consistent trailing newline handling with StepLog.

The logic correctly mirrors StepLog.tsx, ensuring consistent line counting behavior across both log components.


455-468: LGTM! Improved log content styling and selection.

The log-content class and select-text cursor-text styling match the StepLog.tsx implementation for a consistent user experience.


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 and usage tips.

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/src/features/dags/components/dag-execution/ExecutionLog.tsx (1)

378-400: Inconsistency: Page navigation condition uses totalLines instead of effectiveTotalLines.

This differs from StepLog.tsx (line 386) which uses effectiveTotalLines for the same condition. For consistency, consider updating this line:

🔎 Suggested fix
         {/* Page navigation controls */}
-        {viewMode === 'page' && totalLines > 0 && (
+        {viewMode === 'page' && effectiveTotalLines > 0 && (
           <div className="flex items-center gap-2 mt-2">
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fb869d and 29b3c8d.

📒 Files selected for processing (8)
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/styles/global.css
🧰 Additional context used
📓 Path-based instructions (2)
ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (ui/CLAUDE.md)

ui/**/*.{ts,tsx,jsx,js}: Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations
Support both light and dark modes for all UI components using Tailwind CSS class pairs like dark:bg-slate-700
NEVER use full-page loading overlays or LoadingIndicator components that hide content - show stale data while fetching updates instead
Use compact modal design with small headers, minimal padding (p-2 or p-3), tight spacing, and support keyboard navigation (arrows, enter, escape)
Use small heights for form elements: select boxes h-7 or smaller, buttons h-7 or h-8, inputs with compact padding (py-0.5 or py-1)
Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text with whitespace-normal break-words
Use consistent metadata styling with bg-slate-200 dark:bg-slate-700 backgrounds and maintain text hierarchy with primary/secondary/muted text colors
Use flexbox-first layouts with min-h-0 and overflow-hidden to prevent layout breaks, account for fixed elements when setting heights
Maintain keyboard navigation support in all interactive components with appropriate focus indicators and ARIA labels

Files:

  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
ui/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

ui/**/*.{ts,tsx}: The React + TypeScript frontend resides in ui/, with production bundles copied to internal/service/frontend/assets by make ui
UI code follows ESLint + Prettier (2-space indent) and Tailwind utilities; name React components in PascalCase (JobList.tsx) and hooks with use* (useJobs.ts)

Files:

  • ui/src/features/dags/components/dag-editor/DAGSpec.tsx
  • ui/src/contexts/UnsavedChangesContext.tsx
  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
  • ui/src/features/dags/components/common/DAGActions.tsx
  • ui/src/pages/dags/dag/index.tsx
  • ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text with `whitespace-normal break-words`

Applied to files:

  • ui/src/features/dags/components/dag-execution/ExecutionLog.tsx
  • ui/src/features/dags/components/dag-execution/StepLog.tsx
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use consistent metadata styling with `bg-slate-200 dark:bg-slate-700` backgrounds and maintain text hierarchy with primary/secondary/muted text colors

Applied to files:

  • ui/src/styles/global.css
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations

Applied to files:

  • ui/src/features/dags/components/common/DAGActions.tsx
🧬 Code graph analysis (3)
ui/src/features/dags/components/dag-editor/DAGSpec.tsx (1)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • useUnsavedChanges (10-17)
ui/src/features/dags/components/common/DAGActions.tsx (1)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • useUnsavedChanges (10-17)
ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx (3)
ui/src/contexts/UnsavedChangesContext.tsx (1)
  • UnsavedChangesProvider (19-31)
ui/src/features/dags/contexts/DAGContext.ts (1)
  • DAGContext (3-9)
ui/src/features/dags/contexts/RootDAGRunContext.ts (1)
  • RootDAGRunContext (9-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
ui/src/styles/global.css (1)

459-470: LGTM! Good UX improvement for log text selection.

The selection styling ensures visible text selection on dark backgrounds. The Mozilla-prefixed selector provides broader browser compatibility.

ui/src/features/dags/components/dag-editor/DAGSpec.tsx (2)

128-143: LGTM! Clean implementation of unsaved changes tracking.

The change detection logic correctly compares editor state against fetched data, and the cleanup effect properly resets state on unmount to prevent stale context values.


394-402: LGTM! Save button correctly reflects unsaved state.

Disabling the save button when there are no changes provides clear visual feedback to users.

ui/src/features/dags/components/dag-details/DAGDetailsPanel.tsx (1)

180-242: LGTM! Proper provider integration.

The UnsavedChangesProvider correctly wraps the panel content, enabling descendant components (like DAGSpec) to track and report unsaved changes.

ui/src/features/dags/components/common/DAGActions.tsx (2)

111-117: LGTM! Good UX for unsaved changes warning.

The conditional flow correctly intercepts the enqueue action when unsaved changes exist, preventing users from accidentally running outdated DAG configurations.


547-571: LGTM! Clear and informative warning modal.

The modal content clearly explains that the DAG will run with the last saved version, and the "Run Anyway" button text sets appropriate expectations.

ui/src/pages/dags/dag/index.tsx (1)

195-242: LGTM! Consistent provider integration with DAGDetailsPanel.

The UnsavedChangesProvider placement mirrors the pattern in DAGDetailsPanel.tsx, ensuring consistent unsaved changes tracking across both the full page and modal panel views.

ui/src/contexts/UnsavedChangesContext.tsx (2)

10-17: LGTM! Safe fallback pattern for context usage.

Returning a default object when used outside the provider prevents runtime errors and allows components to be used in different contexts without crashing. The no-op setter is appropriate for the fallback case.


19-31: LGTM! Clean provider implementation.

The useCallback wrapper ensures a stable setter reference, preventing unnecessary re-renders in consuming components.

ui/src/features/dags/components/dag-execution/StepLog.tsx (2)

286-293: LGTM! Smart handling of trailing newline inconsistency.

The logic correctly handles the common edge case where split('\n') produces a trailing empty string, and the effectiveTotalLines calculation accommodates potential API inconsistencies in counting trailing newlines.


463-476: LGTM! Improved log content styling and selection.

The log-content class enables the custom text selection styling from global.css, and select-text cursor-text on line content improves copy-paste UX.

ui/src/features/dags/components/dag-execution/ExecutionLog.tsx (2)

277-284: LGTM! Consistent trailing newline handling with StepLog.

The logic correctly mirrors StepLog.tsx, ensuring consistent line counting behavior across both log components.


455-468: LGTM! Improved log content styling and selection.

The log-content class and select-text cursor-text styling match the StepLog.tsx implementation for a consistent user experience.

@yohamta0 yohamta0 merged commit 64f1884 into main Dec 24, 2025
2 checks passed
@yohamta0 yohamta0 deleted the fix-ui-issues-2 branch December 24, 2025 12:13
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