Skip to content

feat(ui): Add system path information#1443

Merged
yohamta0 merged 2 commits into
mainfrom
add-system-info
Dec 4, 2025
Merged

feat(ui): Add system path information#1443
yohamta0 merged 2 commits into
mainfrom
add-system-info

Conversation

@yohamta0

@yohamta0 yohamta0 commented Dec 4, 2025

Copy link
Copy Markdown
Collaborator
image

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Paths display panel in System Status page, showing system filesystem locations (DAGs, logs, config files, etc.) with copy-to-clipboard functionality.
  • UI/UX Improvements

    • Updated System Status controls with more compact button sizing and simplified labels.
  • Changes

    • Modified DAG rename operation to streamline the process.

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

@coderabbitai

coderabbitai Bot commented Dec 4, 2025

Copy link
Copy Markdown

Walkthrough

The PR relocates the ConfigFileUsed field from the Global struct to PathsConfig, updates all code references accordingly, extends frontend templates with path configuration variables, and simplifies the DAG rename operation by removing metadata and history handling.

Changes

Cohort / File(s) Change Summary
Config Structure Relocation
internal/common/config/config.go, internal/common/config/context.go, internal/common/config/context_test.go, internal/common/config/loader.go, internal/common/config/loader_test.go
Moved ConfigFileUsed field from Global struct to PathsConfig struct; updated getter functions and test references to read from new location.
Internal Code References
internal/cmd/context.go, internal/runtime/subcmd.go, internal/runtime/subcmd_test.go, internal/test/command.go, internal/test/helper.go
Updated all code references from cfg.Global.ConfigFileUsed to cfg.Paths.ConfigFileUsed for config file path retrieval.
Frontend API
internal/service/frontend/api/v2/dags.go
Simplified RenameDAG by removing pre/post-rename metadata fetches and DAG run history renaming logic.
Frontend Template/Config Exposure
internal/service/frontend/server.go, internal/service/frontend/templates.go, internal/service/frontend/templates/base.gohtml
Added Paths field to template config; exposed path-related values (dagsDir, logDir, suspendFlagsDir, adminLogsDir, baseConfig, dagRunsDir, queueDir, procDir, serviceRegistryDir, configFileUsed) as template functions and JavaScript config object.
Frontend Type Definitions
ui/src/contexts/ConfigContext.tsx
Added new PathsConfig type with path fields; extended Config type with paths property.
Frontend UI Components
ui/src/features/system-status/components/PathsCard.tsx
New component displaying clickable path entries with copy-to-clipboard functionality and visual feedback.
Frontend Integration
ui/index.html, ui/src/pages/system-status/index.tsx
Extended configuration data structure with paths object; added PathsCard component to System Status page header with minor button styling adjustments.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15–20 minutes

  • Homogeneous pattern: Most changes are repetitive field relocation (same reference update across many files)
  • High file count but low per-file complexity: ~20 files touched, but majority are straightforward field renames
  • Additional attention points:
    • internal/service/frontend/api/v2/dags.go — Verify that removing metadata/history renaming in RenameDAG does not break dependent workflows or leave orphaned history records
    • ui/src/features/system-status/components/PathsCard.tsx — New component; confirm clipboard API fallback and styling are properly handled across browsers
    • Completeness of path exposure in templates and frontend — ensure no gaps in required paths being transmitted to UI

Possibly related PRs

Poem

🐰 A field hops from Global to Paths so neat,
Config paths now dance to a frontend beat,
Paths exposed through templates with flair,
Copies and clipboards float through the air—
History's simpler, refactoring's sweet! 📋✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: refactoring to expose system path information through the UI by moving ConfigFileUsed from Global to PathsConfig and adding new template functions and UI components.
✨ 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 add-system-info

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

🧹 Nitpick comments (2)
ui/src/pages/system-status/index.tsx (1)

7-8: Consider adding accessible label to icon-only Refresh button

The Refresh button is now icon-only, which can be unclear for screen readers and keyboard users. Suggest adding an aria-label (and optional title) while keeping the compact style.

Example diff for Lines 75-86:

-      <Button
-        variant="outline"
-        size="sm"
-        onClick={handleRefresh}
-        disabled={isRefreshing}
-        className="h-7 px-2"
-      >
-        <RefreshCw className={cn(
-          "h-3 w-3",
-          isRefreshing && "animate-spin"
-        )} />
-      </Button>
+      <Button
+        variant="outline"
+        size="sm"
+        onClick={handleRefresh}
+        disabled={isRefreshing}
+        className="h-7 px-2"
+        aria-label="Refresh status"
+        title="Refresh status"
+      >
+        <RefreshCw
+          className={cn("h-3 w-3", isRefreshing && "animate-spin")}
+        />
+      </Button>

Also applies to: 57-87

ui/src/features/system-status/components/PathsCard.tsx (1)

7-52: Solid Paths UI; consider small a11y improvements for dialog and copy button

The overall structure (PathItem, PathsDialog, PathsCard) is clear and matches the new paths config. A few tweaks would improve accessibility and keyboard use without changing behavior:

  1. Make the dialog a proper ARIA dialog and support Escape key to close
    Add dialog roles/labels and an Escape handler:
 function PathsDialog({ open, onClose }: { open: boolean; onClose: () => void }) {
   const config = useConfig();
   const paths: PathsConfig = config.paths;
+
+  React.useEffect(() => {
+    if (!open) return;
+    const handleKeyDown = (event: KeyboardEvent) => {
+      if (event.key === 'Escape') {
+        onClose();
+      }
+    };
+    window.addEventListener('keydown', handleKeyDown);
+    return () => window.removeEventListener('keydown', handleKeyDown);
+  }, [open, onClose]);
@@
-  return (
-    <div className="fixed inset-0 z-50 flex items-center justify-center">
+  return (
+    <div
+      className="fixed inset-0 z-50 flex items-center justify-center"
+      role="dialog"
+      aria-modal="true"
+      aria-labelledby="paths-dialog-title"
+    >
@@
-            <span className="text-xs font-medium">System Paths</span>
+            <span id="paths-dialog-title" className="text-xs font-medium">
+              System Paths
+            </span>
  1. Ensure the copy button is visible when focused and labeled for screen readers
    Right now it appears only on hover; keyboard focus still leaves it invisible.
-      <button
-        onClick={handleCopy}
-        className={cn(
-          'p-0.5 rounded transition-all shrink-0',
-          'opacity-0 group-hover:opacity-100',
-          'hover:bg-slate-200 dark:hover:bg-slate-700',
-          copied && 'opacity-100 text-green-500'
-        )}
-        title="Copy path"
-      >
+      <button
+        type="button"
+        onClick={handleCopy}
+        aria-label="Copy path"
+        className={cn(
+          'p-0.5 rounded transition-all shrink-0',
+          'opacity-0 group-hover:opacity-100 focus-visible:opacity-100',
+          'hover:bg-slate-200 dark:hover:bg-slate-700',
+          copied && 'opacity-100 text-green-500'
+        )}
+        title="Copy path"
+      >

These changes keep the compact design while better matching the keyboard navigation and a11y guidelines.

Also applies to: 53-107, 109-126

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e076056 and f086f36.

📒 Files selected for processing (18)
  • internal/cmd/context.go (1 hunks)
  • internal/common/config/config.go (1 hunks)
  • internal/common/config/context.go (1 hunks)
  • internal/common/config/context_test.go (1 hunks)
  • internal/common/config/loader.go (1 hunks)
  • internal/common/config/loader_test.go (3 hunks)
  • internal/runtime/subcmd.go (1 hunks)
  • internal/runtime/subcmd_test.go (9 hunks)
  • internal/service/frontend/api/v2/dags.go (0 hunks)
  • internal/service/frontend/server.go (1 hunks)
  • internal/service/frontend/templates.go (2 hunks)
  • internal/service/frontend/templates/base.gohtml (1 hunks)
  • internal/test/command.go (2 hunks)
  • internal/test/helper.go (1 hunks)
  • ui/index.html (1 hunks)
  • ui/src/contexts/ConfigContext.tsx (2 hunks)
  • ui/src/features/system-status/components/PathsCard.tsx (1 hunks)
  • ui/src/pages/system-status/index.tsx (3 hunks)
💤 Files with no reviewable changes (1)
  • internal/service/frontend/api/v2/dags.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Backend entrypoint in cmd/ orchestrates the scheduler and CLI; runtime, persistence, and service layers sit under internal/* (for example internal/runtime, internal/persistence)
Keep Go files gofmt/goimports clean; use tabs, PascalCase for exported symbols (SchedulerClient), lowerCamelCase for locals, and Err... names for package-level errors
Repository linting relies on golangci-lint; prefer idiomatic Go patterns, minimal global state, and structured logging helpers in internal/common

Files:

  • internal/common/config/config.go
  • internal/test/helper.go
  • internal/common/config/context.go
  • internal/test/command.go
  • internal/service/frontend/server.go
  • internal/common/config/loader_test.go
  • internal/runtime/subcmd.go
  • internal/cmd/context.go
  • internal/common/config/loader.go
  • internal/service/frontend/templates.go
  • internal/common/config/context_test.go
  • internal/runtime/subcmd_test.go
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/system-status/components/PathsCard.tsx
  • ui/src/contexts/ConfigContext.tsx
  • ui/src/pages/system-status/index.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/system-status/components/PathsCard.tsx
  • ui/src/contexts/ConfigContext.tsx
  • ui/src/pages/system-status/index.tsx
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: Co-locate Go tests as *_test.go; favour table-driven cases and cover failure paths
Use stretchr/testify/require and shared fixtures from internal/test instead of duplicating mocks

Files:

  • internal/common/config/loader_test.go
  • internal/common/config/context_test.go
  • internal/runtime/subcmd_test.go
🧠 Learnings (4)
📚 Learning: 2025-12-04T10:34:01.023Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.023Z
Learning: Applies to ui/~/.config/dagu/config.yaml : Dagu configuration file supports environment variables with DAGU_* prefix, per-DAG overrides, and command-line arguments

Applied to files:

  • internal/test/helper.go
  • ui/index.html
  • internal/runtime/subcmd_test.go
📚 Learning: 2025-12-04T10:34:01.023Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.023Z
Learning: Applies to ui/**/*.{yaml,yml} : Dagu YAML configurations should support minimal setup with sensible defaults and support for environment variable expansion and command substitution

Applied to files:

  • ui/index.html
📚 Learning: 2025-12-04T10:34:17.051Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T10:34:17.051Z
Learning: Applies to **/*_test.go : Co-locate Go tests as `*_test.go`; favour table-driven cases and cover failure paths

Applied to files:

  • internal/common/config/loader_test.go
  • internal/common/config/context_test.go
📚 Learning: 2025-12-04T10:34:17.051Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T10:34:17.051Z
Learning: Applies to **/*_test.go : Use `stretchr/testify/require` and shared fixtures from `internal/test` instead of duplicating mocks

Applied to files:

  • internal/common/config/loader_test.go
  • internal/common/config/context_test.go
🧬 Code graph analysis (14)
internal/common/config/config.go (1)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
ui/src/features/system-status/components/PathsCard.tsx (3)
ui/src/lib/utils.ts (1)
  • cn (4-6)
ui/src/contexts/ConfigContext.tsx (2)
  • useConfig (35-37)
  • PathsConfig (3-14)
ui/src/components/ui/button.tsx (1)
  • Button (59-59)
internal/test/helper.go (2)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
ui/src/contexts/ConfigContext.tsx (1)
internal/common/config/config.go (1)
  • PathsConfig (144-157)
internal/common/config/context.go (1)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/test/command.go (2)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/service/frontend/server.go (1)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/loader_test.go (2)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/runtime/subcmd.go (2)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/cmd/context.go (4)
internal/common/config/config.go (1)
  • Config (9-36)
internal/common/logger/tag/tag.go (1)
  • Config (354-356)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/common/config/loader.go (2)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/service/frontend/templates.go (4)
internal/common/config/path.go (1)
  • Paths (13-30)
internal/common/config/config.go (1)
  • PathsConfig (144-157)
ui/src/contexts/ConfigContext.tsx (1)
  • PathsConfig (3-14)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
ui/src/pages/system-status/index.tsx (2)
ui/src/components/ui/button.tsx (1)
  • Button (59-59)
ui/src/lib/utils.ts (1)
  • cn (4-6)
internal/runtime/subcmd_test.go (3)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/common/config/config.go (1)
  • Global (38-66)
internal/common/config/env.go (2)
  • BaseEnv (9-11)
  • NewBaseEnv (15-17)
⏰ 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). (2)
  • GitHub Check: Build
  • GitHub Check: Test on ubuntu-latest
🔇 Additional comments (16)
internal/common/config/config.go (1)

156-156: LGTM! Logical placement for config file path.

Moving ConfigFileUsed to PathsConfig improves code organization by grouping all path-related configuration together. The field is well-documented and maintains consistent visibility.

internal/common/config/loader_test.go (1)

132-133: LGTM! Test updates align with the refactoring.

All test assertions and setup code correctly updated to reference cfg.Paths.ConfigFileUsed instead of cfg.Global.ConfigFileUsed. Test coverage for configuration file path tracking is maintained.

Also applies to: 714-714, 734-734

internal/service/frontend/server.go (1)

65-65: LGTM! Clean extension of frontend configuration.

Adding Paths to funcsConfig provides the frontend with access to path configuration, enabling the UI to display system path information. The change is consistent with how other config sections are passed to the frontend.

internal/common/config/context.go (1)

28-28: LGTM! Accessor function correctly updated.

The ConfigFileUsed function now returns the value from the new location (cfg.Paths.ConfigFileUsed) while maintaining the same API signature. This abstraction shields callers from the internal refactoring.

internal/cmd/context.go (1)

151-151: LGTM! Logging statement correctly updated.

The debug log now references cfg.Paths.ConfigFileUsed instead of the old location. The structured logging output remains unchanged for consumers.

internal/common/config/loader.go (1)

116-116: LGTM! Config loader correctly updated.

The assignment of ConfigFileUsed now targets the new location (cfg.Paths.ConfigFileUsed). This is the source where the configuration file path is initially captured from Viper during config loading.

internal/service/frontend/templates/base.gohtml (1)

26-37: LGTM! Comprehensive path information exposed to UI.

The new paths object in the JavaScript config provides the frontend with access to all system path configurations, including the relocated configFileUsed. This aligns with the PR's goal to add system path information and enables features like the PathsCard component mentioned in the AI summary.

internal/test/helper.go (1)

166-166: LGTM! Test helper correctly updated.

The test setup now assigns the config file path to the new location (cfg.Paths.ConfigFileUsed), ensuring test fixtures match the production configuration structure.

internal/runtime/subcmd.go (1)

24-30: ConfigFileUsed correctly sourced from PathsConfig in SubCmdBuilder

Using cfg.Paths.ConfigFileUsed for configFile keeps subcommands aligned with the new config shape while preserving existing behavior wherever b.configFile != "" is checked. Looks good.

internal/test/command.go (1)

79-98: withConfigFlag correctly updated to use Paths.ConfigFileUsed

The helper now reads cfg.Paths.ConfigFileUsed, preserving existing semantics for detecting existing config flags and inserting before -- passthrough. This keeps tests in sync with the new config layout.

internal/common/config/context_test.go (1)

54-63: TestConfigFileUsed aligned with PathsConfig

Initializing Config.Paths.ConfigFileUsed in TestConfigFileUsed now matches the production accessor, so the test remains meaningful after the field move.

ui/index.html (1)

39-50: paths defaults match frontend PathsConfig

The new paths object provides sensible defaults and matches the PathsConfig keys used in the TS context/components, which should keep the dev index bootstrap consistent.

ui/src/contexts/ConfigContext.tsx (1)

3-14: Typed PathsConfig integration into Config looks consistent

Defining PathsConfig and threading it through Config.paths cleanly models the new path data exposed from the backend and matches usage in PathsCard and index.html.

Also applies to: 16-31

internal/runtime/subcmd_test.go (1)

19-27: Tests correctly updated to use PathsConfig for Executable and ConfigFileUsed

The subcommand tests now initialize config.Config via PathsConfig.Executable and PathsConfig.ConfigFileUsed, and the “without config” cases rely on empty/absent values. This keeps all --config expectations in sync with the refactored runtime builder.

Also applies to: 35-40, 124-129, 140-145, 233-237, 279-283, 332-336, 399-403, 510-514

internal/service/frontend/templates.go (2)

62-62: LGTM! Path configuration field added correctly.

The addition of the Paths field to funcsConfig aligns with the relocation of path-related configuration. The type matches config.PathsConfig and the AI summary confirms proper initialization in server.go.


107-136: Template functions correctly expose path configuration.

All 10 new functions match the fields in config.PathsConfig and follow a consistent naming pattern. The implementation is straightforward and correct.

Security note: These functions expose filesystem paths to templates. Verify that the templates rendering this data are only accessible to authorized administrators, as path disclosure could aid reconnaissance in a security context.

@yohamta0 yohamta0 merged commit c79f7c5 into main Dec 4, 2025
6 checks passed
@yohamta0 yohamta0 deleted the add-system-info branch December 4, 2025 12:06
@codecov

codecov Bot commented Dec 4, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.94%. Comparing base (e75d14f) to head (f086f36).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1443   +/-   ##
=======================================
  Coverage   59.94%   59.94%           
=======================================
  Files         187      187           
  Lines       21022    21022           
=======================================
  Hits        12602    12602           
  Misses       7106     7106           
  Partials     1314     1314           
Files with missing lines Coverage Δ
internal/cmd/context.go 70.74% <100.00%> (ø)
internal/common/config/config.go 100.00% <ø> (ø)
internal/common/config/context.go 86.66% <100.00%> (ø)
internal/common/config/loader.go 91.86% <100.00%> (ø)
internal/runtime/subcmd.go 78.47% <100.00%> (ø)

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f622796...f086f36. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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