Conversation
feat: add note field
feat: support ignoring metric prefixes in quick view
|
Tip For best results, initiate chat on the files or code changes.
Please let me know what you'd like me to do! |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughMultiple 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~28 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
identandnoteas 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 unusedkeysvariable.Line 131 retrieves
keysfrom the form, but it's no longer passed toGraphPreviewafter 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 forvalparameter.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
isActivedirectly 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.
lodashis 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 (#fffbackground,rgba(0, 0, 0, 0.85)text) are hardcoded for light theme. Given thatCommonStateContextprovidesdarkModeelsewhere in the codebase (as seen in the Doris plugin), consider accepting adarkModeprop 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-widthalone 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 preservenoteon partial local updates.If a future caller passes
updateDatawithoutnote, 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
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (32)
package.jsonsrc/components/HoneycombChart/index.tsxsrc/components/HoneycombChart/utils/calculateHexCoordinates.tssrc/components/HoneycombChart/utils/getRoundedHexagonPath.tssrc/pages/builtInComponents/Dashboards/index.tsxsrc/pages/dashboard/Detail/Detail.tsxsrc/pages/dashboard/Detail/Title.tsxsrc/pages/dashboard/List/FormModal.tsxsrc/pages/dashboard/List/Import/index.tsxsrc/pages/dashboard/List/ImportGrafanaURLFormModal.tsxsrc/pages/dashboard/List/constants.tssrc/pages/dashboard/List/index.tsxsrc/pages/dashboard/List/style.lesssrc/pages/dashboard/List/utils.tssrc/pages/dashboard/types.tssrc/pages/demo/data.jssrc/pages/demo/index.tsxsrc/pages/event/DetailNG/eventDetailByCate.tsxsrc/pages/monitor/object/locale/en_US.tssrc/pages/monitor/object/locale/zh_CN.tssrc/pages/monitor/object/locale/zh_HK.tssrc/pages/monitor/object/metricViews/Form.tsxsrc/pages/monitor/object/metricViews/LabelsValues.tsxsrc/pages/monitor/object/metricViews/Metrics/index.tsxsrc/pages/monitor/object/types.tssrc/plugins/doris/AlertRule/GraphPreview.tsxsrc/plugins/doris/AlertRule/index.tsxsrc/plugins/doris/Event/index.tsxsrc/plugins/doris/RecordingRules/Queries/index.tsxsrc/plugins/doris/index.tsxsrc/services/dashboardV2.tssrc/store/dashboardInterface/index.ts
💤 Files with no reviewable changes (1)
- src/pages/demo/data.js
| // 容器宽高比 | ||
| const aspectRatio = containerWidth / containerHeight; |
There was a problem hiding this comment.
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.
| 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) { |
There was a problem hiding this comment.
🧩 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 -200Repository: 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.
| const triggers = _.get(val, 'triggers', []); | ||
| const trigger = _.get(triggers, '[0]'); | ||
| return `${trigger?.exp} ${i18next.t('AlertCurEvents:detail.trigger')} ${i18next.t(`common:severity.${trigger?.severity}`)}`; |
There was a problem hiding this comment.
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.
| 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.
| 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']); |
There was a problem hiding this comment.
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.
| 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.
Summary by CodeRabbit
Release Notes
New Features
Dependencies