Skip to content

R 21 asset views#1972

Open
jsers wants to merge 4 commits intoprefrom
r-21-asset-views
Open

R 21 asset views#1972
jsers wants to merge 4 commits intoprefrom
r-21-asset-views

Conversation

@jsers
Copy link
Collaborator

@jsers jsers commented Dec 10, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Honeycomb chart visualization component for displaying data in a hexagonal grid layout with interactive tooltips.
    • Dashboard notes field—add notes to dashboards throughout creation, editing, and import workflows.
    • Metric prefix ignore feature to customize metric classification during dashboard setup.
    • Enhanced Doris datasource support with event detail rendering and recording rule query builder.
  • Dependencies

    • Added react-hexgrid library for hexagon grid rendering.

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

Tip

For best results, initiate chat on the files or code changes.

@guguji5, I'm here to help! How can I assist you with this PR? Here are some things I can do:

  • Review the code: Use @coderabbitai review to trigger a review
  • Answer questions: Ask me about specific files, functions, or changes in this PR
  • Generate artifacts: I can generate unit tests, sequence diagrams, or docstrings
  • Analyze the codebase: I can gather stats, create diagrams, or explore specific parts of the code
  • Manage the review: Pause, resume, or resolve review comments

Please let me know what you'd like me to do!

@guguji5
Copy link
Contributor

guguji5 commented Feb 26, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@n9e n9e deleted a comment from coderabbitai bot Feb 26, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

Multiple feature additions and enhancements: introduces HoneycombChart component with hexagonal grid rendering, adds dashboard note field across create/edit/list workflows, extends monitor metric views with prefix filtering, and expands Doris plugin with event detail and recording rule query handling. Includes new utility functions for hex calculations and localization strings.

Changes

Cohort / File(s) Summary
HoneycombChart Component
package.json, src/components/HoneycombChart/index.tsx, src/components/HoneycombChart/utils/calculateHexCoordinates.ts, src/components/HoneycombChart/utils/getRoundedHexagonPath.ts
New React component rendering data-driven hexagonal grids with hover tooltips, interactive text overlays, and configurable layout via utility functions for hex coordinate calculation and rounded path generation. Adds react-hexgrid dependency.
Dashboard Note Field Feature
src/pages/dashboard/types.ts, src/pages/dashboard/Detail/Detail.tsx, src/pages/dashboard/Detail/Title.tsx, src/pages/dashboard/List/FormModal.tsx, src/pages/dashboard/List/Import/index.tsx, src/pages/dashboard/List/ImportGrafanaURLFormModal.tsx, src/pages/dashboard/List/constants.ts, src/pages/dashboard/List/index.tsx, src/pages/dashboard/List/style.less, src/pages/dashboard/List/utils.ts, src/services/dashboardV2.ts, src/store/dashboardInterface/index.ts, src/pages/builtInComponents/Dashboards/index.tsx
Propagates optional note field through dashboard creation, editing, importing, and list display; includes form fields with textarea inputs, table column additions, export support, and type/service updates across dashboard management.
Monitor Metric Prefix Filtering
src/pages/monitor/object/locale/en_US.ts, src/pages/monitor/object/locale/zh_CN.ts, src/pages/monitor/object/locale/zh_HK.ts, src/pages/monitor/object/metricViews/Form.tsx, src/pages/monitor/object/metricViews/Metrics/index.tsx, src/pages/monitor/object/types.ts
Adds prefix-based metric filtering with ignorePrefix field; includes localization strings in three languages, form item with tooltip display, filtering logic in metric rendering, and type definition for IMatch interface.
Doris Plugin Event Details
src/pages/event/DetailNG/eventDetailByCate.tsx, src/plugins/doris/Event/index.tsx, src/plugins/doris/index.tsx
Introduces Doris event detail handler rendering SQL queries and trigger expressions with localized labels; integrates via datasource category handler and exports from Doris plugin index.
Doris Recording Rule Queries
src/plugins/doris/RecordingRules/Queries/index.tsx, src/plugins/doris/index.tsx
New query builder component for Doris recording rules with SQL input (MySQL mode), document link drawer, advanced settings, and live GraphPreview; exported via Doris plugin index.
Doris AlertRule Refactoring
src/plugins/doris/AlertRule/GraphPreview.tsx, src/plugins/doris/AlertRule/index.tsx
Removes keys prop from GraphPreview component signature and invocation, adding explicit type annotation for remaining props (cate, datasourceValue, sql, database).
Demo Page Updates
src/pages/demo/data.js, src/pages/demo/index.tsx
Removes large demo data fixtures (data01, data02 with ~1374 lines) and replaces minimal placeholder with HoneycombChart implementation using generated sample data with hex coordinate calculations.
Monitor Metric View Styling
src/pages/monitor/object/metricViews/LabelsValues.tsx
Minor CSS class update: changes inline marginBottom style to mb-2 utility class for "No Data" message styling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Poem

🐰 Hop-hop, a honeycomb grid takes flight,
Each hex aglow with color bright,
Dashboard notes now saved with care,
And Doris queries float through air!
A rabbit's work is never done,
But oh, what changes we've spun!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'R 21 asset views' is vague and does not clearly convey the main changes in this PR, which include adding a HoneycombChart component, dashboard note fields, Doris plugin support, and monitor metric prefix features. Provide a more descriptive title that specifically summarizes the primary change, such as 'Add HoneycombChart component and dashboard note field' or similar that reflects the main objectives.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch r-21-asset-views

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (9)
src/services/dashboardV2.ts (1)

115-116: Consider updating the comment to reflect the expanded payload.

The comment on line 115 states "只能更新 name 和 tags" (can only update name and tags), but the payload now includes ident and note as well. The comment should be updated for accuracy.

📝 Suggested comment update
-// 更新仪表盘 - 只能更新 name 和 tags
+// 更新仪表盘 - 更新 name, ident, tags, note
 export const updateDashboard = function (id: string | number, data: { name: string; ident?: string; tags: string; note?: string }) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/dashboardV2.ts` around lines 115 - 116, Update the outdated
comment above the updateDashboard function: change "只能更新 name 和 tags" to
accurately list all updatable fields (name, tags, ident, note) so it matches the
payload signature of updateDashboard(id: string | number, data: { name: string;
ident?: string; tags: string; note?: string }); ensure the comment is concise
and in Chinese to match existing style.
src/plugins/doris/AlertRule/index.tsx (1)

127-136: Remove unused keys variable.

Line 131 retrieves keys from the form, but it's no longer passed to GraphPreview after the signature change. This unused variable should be removed.

🧹 Proposed fix to remove unused variable
                     {({ getFieldValue }) => {
                       const cate = getFieldValue('cate');
                       const sql = getFieldValue(['rule_config', 'queries', field.name, 'sql']);
-                      const keys = getFieldValue(['rule_config', 'queries', field.name, 'keys']);
                       const database = getFieldValue(['rule_config', 'queries', field.name, 'database']);

                       return <GraphPreview cate={cate} datasourceValue={datasourceId} sql={sql} database={database} />;
                     }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/doris/AlertRule/index.tsx` around lines 127 - 136, The Form.Item
render function currently reads an unused variable keys via
getFieldValue(['rule_config', 'queries', field.name, 'keys']) but never passes
it to GraphPreview; remove the keys retrieval line to eliminate the unused
variable. Update the anonymous render callback inside Form.Item (the function
that calls getFieldValue) to stop declaring keys and leave all other
getFieldValue calls (cate, sql, database) and the GraphPreview props unchanged.
src/plugins/doris/Event/index.tsx (1)

10-10: Consider adding type annotation for val parameter.

The render(val) function parameter lacks type information. Adding a type annotation would improve code maintainability and catch potential issues at compile time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/doris/Event/index.tsx` at line 10, The render(val) parameter in
src/plugins/doris/Event/index.tsx is untyped; update the function signature for
render to include an explicit type for val (e.g., val: React.ReactNode if it
receives UI content, val: string if it’s text, or val: unknown and then
narrow/cast inside) to surface type errors and improve maintainability; modify
the render method declaration (render) accordingly and adjust any internal
usage/returns to match the chosen type (or add local type guards) so the
TypeScript compiler can validate correctness.
src/components/HoneycombChart/index.tsx (3)

79-145: Consider simplifying the IIFE pattern inside the map.

The immediately-invoked function expression (lines 81-144) adds indirection. You could compute isActive directly and use a fragment without the IIFE wrapper.

Proposed simplification
           {data.map((hex, i) => (
-            <Hexagon key={i} q={hex.q} r={hex.r} s={hex.s} cellStyle={{ fill: 'none' }}>
-              {(() => {
-                const isActive = hoveredIndex === i;
-                return (
-                  <>
-                    <path
-                      d={roundedPath}
-                      fill={hex.color}
-                      style={{
-                        cursor: 'pointer',
-                        transition: 'fill 120ms ease, filter 120ms ease',
-                        filter: isActive ? 'brightness(0.9)' : 'none',
-                      }}
+            <Hexagon key={i} q={hex.q} r={hex.r} s={hex.s} cellStyle={{ fill: 'none' }}>
+              <>
+                <path
+                  d={roundedPath}
+                  fill={hex.color}
+                  style={{
+                    cursor: 'pointer',
+                    transition: 'fill 120ms ease, filter 120ms ease',
+                    filter: hoveredIndex === i ? 'brightness(0.9)' : 'none',
+                  }}
                   ...
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HoneycombChart/index.tsx` around lines 79 - 145, Inside the
data.map rendering for Hexagon (the block using hoveredIndex and
handleHexMouseEnter/Move/Leave), remove the unnecessary immediately-invoked
function expression and compute isActive directly in the map callback (e.g.,
const isActive = hoveredIndex === i) then return the fragment JSX directly; keep
the existing props (q, r, s, cellStyle) and event handlers (handleHexMouseEnter,
handleHexMouseMove, handleHexMouseLeave) and preserve the roundedPath,
foreignObject and text layout – this simplifies the code by eliminating the IIFE
wrapper while keeping behavior intact.

2-2: Remove unused import.

lodash is imported but never used in this file.

Proposed fix
 import React, { useState, useCallback } from 'react';
-import _ from 'lodash';
 import { HexGrid, Layout, Hexagon } from 'react-hexgrid';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HoneycombChart/index.tsx` at line 2, The import of lodash
(import _ from 'lodash') in the HoneycombChart component is unused; remove the
unused import statement (the '_' binding) from
src/components/HoneycombChart/index.tsx so there are no unused symbols and
linting/unused-import warnings are resolved.

113-139: Hardcoded colors may not work well in dark mode.

The text colors (#2c2c2c, #4a4a4a) and tooltip styles (#fff background, rgba(0, 0, 0, 0.85) text) are hardcoded for light theme. Given that CommonStateContext provides darkMode elsewhere in the codebase (as seen in the Doris plugin), consider accepting a darkMode prop or using CSS variables for theme compatibility.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HoneycombChart/index.tsx` around lines 113 - 139, The text
color and tooltip styles inside the HoneycombChart component are hardcoded
(e.g., the divs rendering {hex.title} and {hex.subtitle} use '#2c2c2c' and
'#4a4a4a'), which breaks in dark mode; update the component (HoneycombChart) to
derive colors from theme instead of hardcoded values by either reading darkMode
from CommonStateContext or accepting a darkMode prop, then replace the literal
color strings used with conditional values or CSS variables (e.g., choose
light/dark foreground and muted colors based on hexSize/hex.title/hex.subtitle
rendering) and ensure any tooltip background/text colors are also switched to
theme-aware values so text remains readable in both modes.
src/pages/demo/index.tsx (1)

16-29: Consider using a proper type for generated data.

Using any[] weakens type safety. Define an interface for the data items to improve maintainability.

Proposed improvement
+interface HexData {
+  color: string;
+  title: string;
+  subtitle: string;
+  tooltip: string;
+}
+
 const dataGenerator = () => {
   const count = 100;
   const colors = ['#FFB6C1', '#87CEFA', '#90EE90', '#FFD700', '#FFA500', '#DA70D6'];
-  const data: any[] = [];
+  const data: HexData[] = [];
   for (let i = 0; i < count; i++) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/demo/index.tsx` around lines 16 - 29, The dataGenerator function
currently types its array as any[] which loses type safety; define a specific
interface (e.g., HexagonData or DemoItem) describing properties color: string,
title: string, subtitle: string, tooltip: string and then change the data
variable and the function return type to use that interface (for example: const
data: HexagonData[] and function dataGenerator(): HexagonData[]), updating any
callers if necessary.
src/pages/dashboard/List/style.less (1)

14-16: Consider adding overflow handling for note cells.

max-width alone may not prevent long note text from visually overflowing in table cells.

💡 Proposed CSS hardening
   .note-column {
     max-width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/dashboard/List/style.less` around lines 14 - 16, The .note-column
rule only sets max-width and can still allow long text to overflow; update the
.note-column selector to add overflow handling (e.g., overflow: hidden,
text-overflow: ellipsis and white-space: nowrap) so long note text is truncated
visually, and optionally add a tooltip via title attribute where the full note
is needed; target the .note-column CSS rule in
src/pages/dashboard/List/style.less to apply these properties.
src/pages/dashboard/Detail/Detail.tsx (1)

213-219: Defensively preserve note on partial local updates.

If a future caller passes updateData without note, local state can drop it before manual save.

🛡️ Suggested defensive merge
       setDashboard({
         ...dashboard,
         name: updateData.name,
         ident: updateData.ident,
         tags: updateData.tags,
-        note: updateData.note,
+        note: updateData.note ?? dashboard.note,
         configs,
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/dashboard/Detail/Detail.tsx` around lines 213 - 219, When merging
partial updates into local state in setDashboard({...dashboard, name:
updateData.name, ident: updateData.ident, tags: updateData.tags, note:
updateData.note, configs}), ensure you defensively preserve the existing
dashboard.note when updateData.note is missing; change the merge to set note
using a conditional/nullish-coalescing expression (e.g., note: updateData.note
?? dashboard.note) so partial updates do not erase the stored note while still
allowing intentional clears.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/HoneycombChart/utils/calculateHexCoordinates.ts`:
- Around line 47-48: Guard against division by zero when computing aspectRatio
by checking containerHeight before dividing: in calculateHexCoordinates (the
code that defines const aspectRatio = containerWidth / containerHeight) detect
if containerHeight is 0 (or falsy) and either return early with a safe default
layout or assign a sensible fallback (e.g., aspectRatio = 1) instead of
performing the division; update any downstream calculations that rely on
aspectRatio accordingly and ensure you reference the existing variables
containerHeight and containerWidth when applying the guard.

In `@src/pages/monitor/object/metricViews/Metrics/index.tsx`:
- Around line 56-60: renderMetricList is misclassifying metrics because
filtering uses `${ignorePrefix}${metricTabKey}_` while metricPrefixes and
normalization remove ignorePrefix non-conditionally using replace(); fix by
consistently normalizing metric names only when the metric actually starts with
ignorePrefix (use startsWith) and by using startsWith for prefix checks rather
than indexOf/replace. Concretely: in renderMetricList and in the metricPrefixes
extraction (the code that currently calls replace on metric names), change the
normalization to: if (ignorePrefix && metric.startsWith(ignorePrefix))
normalized = metric.slice(ignorePrefix.length) else normalized = metric; then
use normalized.startsWith(`${metricTabKey}_`) (or check metricTabKey === 'all')
for filtering and build metricPrefixes from these normalized names so both
places use the same logic and you no longer use String.replace for prefix
removal.

In `@src/plugins/doris/Event/index.tsx`:
- Around line 29-31: The current code uses the unconventional _.get(triggers,
'[0]') and can render "undefined undefined undefined" when no trigger exists;
replace the _.get accessor with a direct safe read (const trigger = triggers &&
triggers[0]) or use _.head(triggers), then guard the return: if (!trigger)
return a sensible fallback (e.g. empty string or a localized "no trigger"
message) and otherwise build the template using safe fields like trigger.exp ||
'' and trigger.severity || 'unknown' with i18next translations; update the code
around the triggers/trigger variables and the return expression to implement
this guard and simplified accessor.

In `@src/plugins/doris/RecordingRules/Queries/index.tsx`:
- Around line 24-31: The component function is named `index` which breaks React
hook naming rules; rename the exported function to `Index` (update the default
export accordingly) so hooks like `useTranslation` and `useContext` are called
from a PascalCase component; also resolve the `path` shadowing by renaming the
local `path` variable (e.g., `configPath` or `localPath`) so it doesn't shadow
the `path` prop referenced from `props`, and remove or use the unused `disabled`
variable (declared near `datasourceValue`, `field`, `prefixPath`) to eliminate
the dead variable.

---

Nitpick comments:
In `@src/components/HoneycombChart/index.tsx`:
- Around line 79-145: Inside the data.map rendering for Hexagon (the block using
hoveredIndex and handleHexMouseEnter/Move/Leave), remove the unnecessary
immediately-invoked function expression and compute isActive directly in the map
callback (e.g., const isActive = hoveredIndex === i) then return the fragment
JSX directly; keep the existing props (q, r, s, cellStyle) and event handlers
(handleHexMouseEnter, handleHexMouseMove, handleHexMouseLeave) and preserve the
roundedPath, foreignObject and text layout – this simplifies the code by
eliminating the IIFE wrapper while keeping behavior intact.
- Line 2: The import of lodash (import _ from 'lodash') in the HoneycombChart
component is unused; remove the unused import statement (the '_' binding) from
src/components/HoneycombChart/index.tsx so there are no unused symbols and
linting/unused-import warnings are resolved.
- Around line 113-139: The text color and tooltip styles inside the
HoneycombChart component are hardcoded (e.g., the divs rendering {hex.title} and
{hex.subtitle} use '#2c2c2c' and '#4a4a4a'), which breaks in dark mode; update
the component (HoneycombChart) to derive colors from theme instead of hardcoded
values by either reading darkMode from CommonStateContext or accepting a
darkMode prop, then replace the literal color strings used with conditional
values or CSS variables (e.g., choose light/dark foreground and muted colors
based on hexSize/hex.title/hex.subtitle rendering) and ensure any tooltip
background/text colors are also switched to theme-aware values so text remains
readable in both modes.

In `@src/pages/dashboard/Detail/Detail.tsx`:
- Around line 213-219: When merging partial updates into local state in
setDashboard({...dashboard, name: updateData.name, ident: updateData.ident,
tags: updateData.tags, note: updateData.note, configs}), ensure you defensively
preserve the existing dashboard.note when updateData.note is missing; change the
merge to set note using a conditional/nullish-coalescing expression (e.g., note:
updateData.note ?? dashboard.note) so partial updates do not erase the stored
note while still allowing intentional clears.

In `@src/pages/dashboard/List/style.less`:
- Around line 14-16: The .note-column rule only sets max-width and can still
allow long text to overflow; update the .note-column selector to add overflow
handling (e.g., overflow: hidden, text-overflow: ellipsis and white-space:
nowrap) so long note text is truncated visually, and optionally add a tooltip
via title attribute where the full note is needed; target the .note-column CSS
rule in src/pages/dashboard/List/style.less to apply these properties.

In `@src/pages/demo/index.tsx`:
- Around line 16-29: The dataGenerator function currently types its array as
any[] which loses type safety; define a specific interface (e.g., HexagonData or
DemoItem) describing properties color: string, title: string, subtitle: string,
tooltip: string and then change the data variable and the function return type
to use that interface (for example: const data: HexagonData[] and function
dataGenerator(): HexagonData[]), updating any callers if necessary.

In `@src/plugins/doris/AlertRule/index.tsx`:
- Around line 127-136: The Form.Item render function currently reads an unused
variable keys via getFieldValue(['rule_config', 'queries', field.name, 'keys'])
but never passes it to GraphPreview; remove the keys retrieval line to eliminate
the unused variable. Update the anonymous render callback inside Form.Item (the
function that calls getFieldValue) to stop declaring keys and leave all other
getFieldValue calls (cate, sql, database) and the GraphPreview props unchanged.

In `@src/plugins/doris/Event/index.tsx`:
- Line 10: The render(val) parameter in src/plugins/doris/Event/index.tsx is
untyped; update the function signature for render to include an explicit type
for val (e.g., val: React.ReactNode if it receives UI content, val: string if
it’s text, or val: unknown and then narrow/cast inside) to surface type errors
and improve maintainability; modify the render method declaration (render)
accordingly and adjust any internal usage/returns to match the chosen type (or
add local type guards) so the TypeScript compiler can validate correctness.

In `@src/services/dashboardV2.ts`:
- Around line 115-116: Update the outdated comment above the updateDashboard
function: change "只能更新 name 和 tags" to accurately list all updatable fields
(name, tags, ident, note) so it matches the payload signature of
updateDashboard(id: string | number, data: { name: string; ident?: string; tags:
string; note?: string }); ensure the comment is concise and in Chinese to match
existing style.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12b6437 and 9c8a96b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (32)
  • package.json
  • src/components/HoneycombChart/index.tsx
  • src/components/HoneycombChart/utils/calculateHexCoordinates.ts
  • src/components/HoneycombChart/utils/getRoundedHexagonPath.ts
  • src/pages/builtInComponents/Dashboards/index.tsx
  • src/pages/dashboard/Detail/Detail.tsx
  • src/pages/dashboard/Detail/Title.tsx
  • src/pages/dashboard/List/FormModal.tsx
  • src/pages/dashboard/List/Import/index.tsx
  • src/pages/dashboard/List/ImportGrafanaURLFormModal.tsx
  • src/pages/dashboard/List/constants.ts
  • src/pages/dashboard/List/index.tsx
  • src/pages/dashboard/List/style.less
  • src/pages/dashboard/List/utils.ts
  • src/pages/dashboard/types.ts
  • src/pages/demo/data.js
  • src/pages/demo/index.tsx
  • src/pages/event/DetailNG/eventDetailByCate.tsx
  • src/pages/monitor/object/locale/en_US.ts
  • src/pages/monitor/object/locale/zh_CN.ts
  • src/pages/monitor/object/locale/zh_HK.ts
  • src/pages/monitor/object/metricViews/Form.tsx
  • src/pages/monitor/object/metricViews/LabelsValues.tsx
  • src/pages/monitor/object/metricViews/Metrics/index.tsx
  • src/pages/monitor/object/types.ts
  • src/plugins/doris/AlertRule/GraphPreview.tsx
  • src/plugins/doris/AlertRule/index.tsx
  • src/plugins/doris/Event/index.tsx
  • src/plugins/doris/RecordingRules/Queries/index.tsx
  • src/plugins/doris/index.tsx
  • src/services/dashboardV2.ts
  • src/store/dashboardInterface/index.ts
💤 Files with no reviewable changes (1)
  • src/pages/demo/data.js

Comment on lines +47 to +48
// 容器宽高比
const aspectRatio = containerWidth / containerHeight;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against division by zero when containerHeight is 0.

If containerHeight is 0, computing aspectRatio will result in Infinity, which may lead to unexpected behavior in the layout calculations.

Proposed fix
+  if (containerHeight === 0 || containerWidth === 0)
+    return {
+      coordinates: [],
+      hexSize: 10,
+      rows: 0,
+      cols: 0,
+      viewBoxWidth: 0,
+      viewBoxHeight: 0,
+      minX: 0,
+      minY: 0,
+    };
+
   // 容器宽高比
   const aspectRatio = containerWidth / containerHeight;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HoneycombChart/utils/calculateHexCoordinates.ts` around lines
47 - 48, Guard against division by zero when computing aspectRatio by checking
containerHeight before dividing: in calculateHexCoordinates (the code that
defines const aspectRatio = containerWidth / containerHeight) detect if
containerHeight is 0 (or falsy) and either return early with a safe default
layout or assign a sensible fallback (e.g., aspectRatio = 1) instead of
performing the division; update any downstream calculations that rely on
aspectRatio accordingly and ensure you reference the existing variables
containerHeight and containerWidth when applying the guard.

Comment on lines +56 to 60
const renderMetricList = (metrics: any[] = [], metricTabKey: string, ignorePrefix = '') => {
const filtered = _.filter(metrics, (metric) => {
let flag = true;
flag = metricTabKey === 'all' ? true : metric.indexOf(`${metricTabKey}_`) === 0;
flag = metricTabKey === 'all' ? true : metric.indexOf(`${ignorePrefix}${metricTabKey}_`) === 0;
if (flag && search) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd -t f "index.tsx" | grep -i "metricViews/Metrics"

Repository: n9e/fe

Length of output: 104


🏁 Script executed:

cat -n src/pages/monitor/object/metricViews/Metrics/index.tsx | head -200

Repository: n9e/fe

Length of output: 8591


Fix prefix normalization to avoid dropping/misclassifying metrics in tabs.

Line 59 filters metrics against ${ignorePrefix}${metricTabKey}_, but when extracting metricPrefixes (lines 107–115), the ignorePrefix is removed first. This creates a mismatch: metrics starting with just ${metricTabKey}_ (after prefix removal) won't match the full prefix check, causing them to be excluded from their correct tab.

Additionally, line 110 uses replace() which removes the first occurrence of ignorePrefix from anywhere in the metric name, not just the prefix. For example, "my_node_cpu".replace("node_", "") produces "my_cpu" instead of leaving it unchanged.

💡 Suggested fix
+  const stripIgnorePrefix = (metric: string, ignorePrefix?: string) => {
+    if (!ignorePrefix) return metric;
+    return metric.startsWith(ignorePrefix) ? metric.slice(ignorePrefix.length) : metric;
+  };
+
   const renderMetricList = (metrics: any[] = [], metricTabKey: string, ignorePrefix = '') => {
     const filtered = _.filter(metrics, (metric) => {
       let flag = true;
-      flag = metricTabKey === 'all' ? true : metric.indexOf(`${ignorePrefix}${metricTabKey}_`) === 0;
+      if (metricTabKey !== 'all') {
+        const normalized = stripIgnorePrefix(metric, ignorePrefix);
+        flag = normalized.indexOf(`${metricTabKey}_`) === 0;
+      }
       if (flag && search) {
         try {
           const reg = new RegExp(search, 'gi');
@@
             _.map(_metrics, (m) => {
-              let name = m;
-              if (match.ignorePrefix) {
-                name = m.replace(match.ignorePrefix, '');
-              }
+              const name = stripIgnorePrefix(m, match.ignorePrefix);
               return _.get(_.split(name, '_'), '[0]');
             }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/monitor/object/metricViews/Metrics/index.tsx` around lines 56 - 60,
renderMetricList is misclassifying metrics because filtering uses
`${ignorePrefix}${metricTabKey}_` while metricPrefixes and normalization remove
ignorePrefix non-conditionally using replace(); fix by consistently normalizing
metric names only when the metric actually starts with ignorePrefix (use
startsWith) and by using startsWith for prefix checks rather than
indexOf/replace. Concretely: in renderMetricList and in the metricPrefixes
extraction (the code that currently calls replace on metric names), change the
normalization to: if (ignorePrefix && metric.startsWith(ignorePrefix))
normalized = metric.slice(ignorePrefix.length) else normalized = metric; then
use normalized.startsWith(`${metricTabKey}_`) (or check metricTabKey === 'all')
for filtering and build metricPrefixes from these normalized names so both
places use the same logic and you no longer use String.replace for prefix
removal.

Comment on lines +29 to +31
const triggers = _.get(val, 'triggers', []);
const trigger = _.get(triggers, '[0]');
return `${trigger?.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger?.severity}`)}`;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Simplify the lodash accessor and handle missing trigger gracefully.

The _.get(triggers, '[0]') syntax works but is unconventional. More importantly, if triggers is empty, trigger will be undefined, and the template literal on line 31 will produce output like undefined undefined undefined when the trigger data is missing.

🛡️ Proposed fix with guard and simplified accessor
       render(val) {
         const triggers = _.get(val, 'triggers', []);
-        const trigger = _.get(triggers, '[0]');
-        return `${trigger?.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger?.severity}`)}`;
+        const trigger = _.head(triggers);
+        if (!trigger) {
+          return '-';
+        }
+        return `${trigger.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger.severity}`)}`;
       },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const triggers = _.get(val, 'triggers', []);
const trigger = _.get(triggers, '[0]');
return `${trigger?.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger?.severity}`)}`;
const triggers = _.get(val, 'triggers', []);
const trigger = _.head(triggers);
if (!trigger) {
return '-';
}
return `${trigger.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger.severity}`)}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/doris/Event/index.tsx` around lines 29 - 31, The current code
uses the unconventional _.get(triggers, '[0]') and can render "undefined
undefined undefined" when no trigger exists; replace the _.get accessor with a
direct safe read (const trigger = triggers && triggers[0]) or use
_.head(triggers), then guard the return: if (!trigger) return a sensible
fallback (e.g. empty string or a localized "no trigger" message) and otherwise
build the template using safe fields like trigger.exp || '' and trigger.severity
|| 'unknown' with i18next translations; update the code around the
triggers/trigger variables and the return expression to implement this guard and
simplified accessor.

Comment on lines +24 to +31
export default function index(props: IProps) {
const { t, i18n } = useTranslation(NAME_SPACE);
const { darkMode } = useContext(CommonStateContext);
const { datasourceValue, field, prefixPath } = props;
const disabled = false;
const cate = DatasourceCateEnum.mysql;
const path = [field.name, 'config'];
const query = Form.useWatch([...prefixPath, 'config']);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Rename component to Index (PascalCase) to fix hook linting errors.

The function name index (lowercase) violates React naming conventions, which is why Biome reports hooks being called from a non-component. React components must use PascalCase names.

Additionally, path from props (line 21) is shadowed by the local path variable on line 30, and disabled is declared but never used in a meaningful way.

Proposed fix
-export default function index(props: IProps) {
+export default function Index(props: IProps) {
   const { t, i18n } = useTranslation(NAME_SPACE);
   const { darkMode } = useContext(CommonStateContext);
-  const { datasourceValue, field, prefixPath } = props;
-  const disabled = false;
+  const { datasourceValue, field, prefixPath, path: _path } = props;
   const cate = DatasourceCateEnum.mysql;
   const path = [field.name, 'config'];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default function index(props: IProps) {
const { t, i18n } = useTranslation(NAME_SPACE);
const { darkMode } = useContext(CommonStateContext);
const { datasourceValue, field, prefixPath } = props;
const disabled = false;
const cate = DatasourceCateEnum.mysql;
const path = [field.name, 'config'];
const query = Form.useWatch([...prefixPath, 'config']);
export default function Index(props: IProps) {
const { t, i18n } = useTranslation(NAME_SPACE);
const { darkMode } = useContext(CommonStateContext);
const { datasourceValue, field, prefixPath, path: _path } = props;
const cate = DatasourceCateEnum.mysql;
const path = [field.name, 'config'];
const query = Form.useWatch([...prefixPath, 'config']);
🧰 Tools
🪛 Biome (2.4.4)

[error] 25-25: This hook is being called from within a function or method that is not a hook or component.

(lint/correctness/useHookAtTopLevel)


[error] 26-26: This hook is being called from within a function or method that is not a hook or component.

(lint/correctness/useHookAtTopLevel)


[error] 31-31: This hook is being called from within a function or method that is not a hook or component.

(lint/correctness/useHookAtTopLevel)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/doris/RecordingRules/Queries/index.tsx` around lines 24 - 31, The
component function is named `index` which breaks React hook naming rules; rename
the exported function to `Index` (update the default export accordingly) so
hooks like `useTranslation` and `useContext` are called from a PascalCase
component; also resolve the `path` shadowing by renaming the local `path`
variable (e.g., `configPath` or `localPath`) so it doesn't shadow the `path`
prop referenced from `props`, and remove or use the unused `disabled` variable
(declared near `datasourceValue`, `field`, `prefixPath`) to eliminate the dead
variable.

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.

2 participants