Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
"version": "1.20.6-pre-38",
"version": "1.20.6-pre-39",
"description": "Supporting common component library",
"type": "module",
"main": "dist/index.js",
Expand Down
12 changes: 12 additions & 0 deletions src/Assets/IconV2/ic-security-fixable.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/Assets/IconV2/ic-security-not-fixable.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/Assets/IconV2/ic-security-vulnerability.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/Common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ export const URLS = {
COST_CONFIGURATIONS: `${COST_VISIBILITY_ROOT}/configurations`,
// SECURITY CENTER
SECURITY_CENTER: SECURITY_CENTER_ROOT,
SECURITY_CENTER_OVERVIEW: `${SECURITY_CENTER_ROOT}/overview`,
SECURITY_CENTER_SCANS: `${SECURITY_CENTER_ROOT}/scans`,
SECURITY_CENTER_POLICIES: `${SECURITY_CENTER_ROOT}/policies`,
// AUTOMATION AND ENABLEMENT
AUTOMATION_AND_ENABLEMENT: AUTOMATION_AND_ENABLEMENT_ROOT,
AUTOMATION_AND_ENABLEMENT_JOB: `${AUTOMATION_AND_ENABLEMENT_ROOT}/job`,
Expand Down

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion src/Pages-Devtron-2.0/InfrastructureManagement/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './Overview'
export * from './Shared'

This file was deleted.

1 change: 0 additions & 1 deletion src/Pages-Devtron-2.0/SecurityCenter/Overview/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ComponentSizeType, URLS } from 'src'

import { Button, ButtonComponentType, ButtonVariantType, Icon } from '@Shared/Components'

export const SecurityCenterIcon = () => (
<Button
dataTestId="redirect-to-overview-btn"
component={ButtonComponentType.link}
size={ComponentSizeType.xs}
icon={<Icon name="ic-shield-check" color={null} />}
variant={ButtonVariantType.borderLess}
linkProps={{
to: URLS.SECURITY_CENTER_OVERVIEW,
}}
ariaLabel="Security Center"
showAriaLabelInTippy
/>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getSecurityCenterBreadcrumb } from './utils'
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SecurityCenterIcon } from './SecurityCenterIcon'

export const getSecurityCenterBreadcrumb = () => ({
'security-center': {
component: <SecurityCenterIcon />,
linked: true,
},
})
1 change: 1 addition & 0 deletions src/Pages-Devtron-2.0/SecurityCenter/Shared/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SecurityCenterIcon'
2 changes: 1 addition & 1 deletion src/Pages-Devtron-2.0/SecurityCenter/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './Overview'
export * from './Shared'
1 change: 1 addition & 0 deletions src/Pages-Devtron-2.0/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './ApplicationManagement'
export * from './CostVisibility'
export * from './DataProtectionManagement'
export * from './InfrastructureManagement'
export * from './SecurityCenter'
49 changes: 41 additions & 8 deletions src/Shared/Components/Charts/Chart.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { noop, useDebounce } from '@Common/Helper'
import { DEVTRON_BASE_MAIN_ID } from '@Shared/constants'
import { useTheme } from '@Shared/Providers'

import { drawReferenceLine, htmlLegendPlugin } from './plugins'
import { drawCenterText, drawReferenceLine, htmlLegendPlugin } from './plugins'
import { ChartProps, GetDefaultOptionsParams, TypeAndDatasetsType } from './types'
import {
buildChartTooltipFromContext,
Expand Down Expand Up @@ -89,7 +89,7 @@ ChartJSTooltip.positioners.barElementCenterPositioner = (items, eventPosition) =

/**
* A versatile Chart component that renders different types of charts using Chart.js.
* Supports area charts, pie charts, stacked bar charts (vertical/horizontal), and line charts.
* Supports area charts, pie charts, semi-pie charts, stacked bar charts (vertical/horizontal), and line charts.
*
* The component automatically adapts to theme changes and provides consistent styling
* across all chart types. Colors are provided by the user through the CHART_COLORS constant
Expand Down Expand Up @@ -117,7 +117,24 @@ ChartJSTooltip.positioners.barElementCenterPositioner = (items, eventPosition) =
* datasets={{
* datasetName: 'Adoption Rate (%)',
* yAxisValues: [45.2, 28.7, 35.4],
* backgroundColor: ['SkyBlue300', 'AquaTeal400', 'LavenderPurple300']
* colors: ['SkyBlue300', 'AquaTeal400', 'LavenderPurple300']
* }}
* />
*
* [Semi-Pie Chart Example with Center Text]
* <Chart
* id="performance-metrics"
* type="semiPie"
* xAxisLabels={['Good', 'Average', 'Poor']}
* datasets={{
* datasetName: 'Performance Score (%)',
* yAxisValues: [65, 25, 10],
* colors: ['LimeGreen500', 'GoldenYellow400', 'CoralRed400']
* }}
* centerText={{
* text: '85%',
* fontSize: 24,
* fontWeight: '600'
* }}
* />
*
Expand Down Expand Up @@ -154,9 +171,9 @@ ChartJSTooltip.positioners.barElementCenterPositioner = (items, eventPosition) =
* ```
*
* @param id - Unique identifier for the chart canvas element
* @param type - Chart type: 'area', 'pie', 'stackedBar', 'stackedBarHorizontal', or 'line'
* @param xAxisLabels - Array of labels for the x-axis (or categories for pie charts)
* @param datasets - Chart data: array of datasets for most charts, single dataset object for pie charts
* @param type - Chart type: 'area', 'pie', 'semiPie', 'stackedBar', 'stackedBarHorizontal', or 'line'
* @param xAxisLabels - Array of labels for the x-axis (or categories for pie/semi-pie charts)
* @param datasets - Chart data: array of datasets for most charts, single dataset object for pie/semi-pie charts
*
* @performance
* **Memoization Recommendations:**
Expand All @@ -182,7 +199,9 @@ ChartJSTooltip.positioners.barElementCenterPositioner = (items, eventPosition) =
* @notes
* - Chart automatically re-renders when theme changes (light/dark mode)
* - Line charts are rendered as non-stacked and non-filled by default
* - Pie charts expect a single dataset object instead of an array
* - Pie and semi-pie charts expect a single dataset object instead of an array
* - Semi-pie charts render as half-circles, ideal for gauges or progress indicators
* - Center text can be added to pie and semi-pie charts using the centerText prop
* - Colors should reference CHART_COLORS tokens for consistency
* - Component destroys and recreates Chart.js instance on prop changes for optimal performance
*/
Expand All @@ -200,6 +219,7 @@ const Chart = (props: ChartProps) => {
xScaleTitle,
yAxisMax,
yScaleTitle,
centerText,
} = props
const { getTooltipContent, placement } = tooltipConfig || { placement: 'top' }

Expand Down Expand Up @@ -277,14 +297,27 @@ const Chart = (props: ChartProps) => {
},
plugins: [
...(referenceLines ?? []).map((rl, idx) => drawReferenceLine(rl, `reference-line-${idx}`, appTheme)),
...(centerText && (type === 'pie' || type === 'semiPie') ? [drawCenterText(centerText, appTheme)] : []),
...(!hideAxis ? [htmlLegendPlugin(id, legendRef, type)] : []),
],
})

return () => {
chartRef.current.destroy()
}
}, [type, datasets, labels, appTheme, hideAxis, referenceLines, xAxisMax, xScaleTitle, yAxisMax, yScaleTitle])
}, [
type,
datasets,
labels,
appTheme,
hideAxis,
referenceLines,
xAxisMax,
xScaleTitle,
yAxisMax,
yScaleTitle,
centerText,
])

return (
<div
Expand Down
1 change: 1 addition & 0 deletions src/Shared/Components/Charts/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { default as Chart } from './Chart.component'
export { CHART_COLORS } from './constants'
export type {
CenterTextConfig,
ChartColorKey,
ChartProps,
ChartType,
Expand Down
24 changes: 22 additions & 2 deletions src/Shared/Components/Charts/plugins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { LegendItem, Plugin } from 'chart.js'
import { Tooltip } from '@Common/Tooltip'
import { AppThemeType } from '@Shared/Providers'

import { CHART_COLORS } from './constants'
import { ChartType, HTMLLegendProps, ReferenceLineConfigType } from './types'
import { CHART_AXIS_LABELS_COLOR, CHART_COLORS } from './constants'
import { CenterTextConfig, ChartType, HTMLLegendProps, ReferenceLineConfigType } from './types'

export const drawReferenceLine = (config: ReferenceLineConfigType, id: string, appTheme: AppThemeType): Plugin => ({
id,
Expand Down Expand Up @@ -76,3 +76,23 @@ export const htmlLegendPlugin = (id: string, ref: RefObject<HTMLDivElement>, typ
)
},
})

export const drawCenterText = (config: CenterTextConfig, appTheme: AppThemeType): Plugin => ({
id: 'centerText',
afterDraw: (chart) => {
const { ctx, chartArea } = chart
if (!config?.text) {
return
}

const centerX = (chartArea.left + chartArea.right) / 2

ctx.save()
ctx.font = `${config.fontWeight || '600'} ${config.fontSize || 16}px ${config.fontFamily || "'IBM Plex Sans', 'Open Sans', 'Roboto'"}`
ctx.fillStyle = config.color || CHART_AXIS_LABELS_COLOR[appTheme]
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillText(config.text, centerX, chartArea.bottom - 20)
ctx.restore()
},
})
25 changes: 19 additions & 6 deletions src/Shared/Components/Charts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TooltipProps } from '@Common/Tooltip'
import { AppThemeType } from '@Shared/Providers'
import { Never } from '@Shared/types'

export type ChartType = 'area' | 'pie' | 'stackedBar' | 'stackedBarHorizontal' | 'line'
export type ChartType = 'area' | 'pie' | 'semiPie' | 'stackedBar' | 'stackedBarHorizontal' | 'line'

export type ColorTokensType =
| 'DeepPlum'
Expand All @@ -24,7 +24,7 @@ export type VariantsType = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 |

export type ChartColorKey = `${ColorTokensType}${VariantsType}`

export type ChartTypeWithoutPie = Exclude<ChartType, 'pie'>
export type ChartTypeWithoutPie = Exclude<ChartType, 'pie' | 'semiPie'>

interface BaseSimpleDataset {
datasetName: string
Expand All @@ -51,6 +51,14 @@ export interface ReferenceLineConfigType {
value: number
}

export interface CenterTextConfig {
text: string
fontSize?: number
fontWeight?: string | number
color?: string
fontFamily?: string
}

type XYAxisMax = {
xAxisMax?: number
yAxisMax?: number
Expand All @@ -69,31 +77,36 @@ type ScaleTickFormatCallbacks = Partial<{

export type TypeAndDatasetsType =
| ({
type: 'pie'
type: 'pie' | 'semiPie'
/**
* Needs to be memoized
*/
datasets: SimpleDatasetForPie
onChartClick?: OnChartClickHandler
/** Configuration for center text (only for doughnut/pie charts) */
centerText?: CenterTextConfig
} & Never<XYAxisMax> &
Never<ScaleTickFormatCallbacks>)
| ({
type: 'line'
datasets: SimpleDatasetForLineAndArea[]
onChartClick?: never
centerText?: never
} & XYAxisMax &
ScaleTickFormatCallbacks)
| ({
type: 'area'
datasets: SimpleDatasetForLineAndArea
/* onChartClick is not applicable for area charts */
onChartClick?: never
centerText?: never
} & XYAxisMax &
ScaleTickFormatCallbacks)
| ({
type: Exclude<ChartType, 'pie' | 'line' | 'area'>
type: Exclude<ChartType, 'pie' | 'semiPie' | 'line' | 'area'>
datasets: SimpleDataset[]
onChartClick?: OnChartClickHandler
centerText?: never
} & XYAxisMax &
ScaleTickFormatCallbacks)

Expand Down Expand Up @@ -127,15 +140,15 @@ export type TransformDatasetProps = {
appTheme: AppThemeType
} & (
| {
type: 'pie'
type: 'pie' | 'semiPie'
dataset: SimpleDatasetForPie
}
| {
type: 'line' | 'area'
dataset: SimpleDatasetForLineAndArea
}
| {
type: Exclude<ChartType, 'pie' | 'line' | 'area'>
type: Exclude<ChartType, 'pie' | 'semiPie' | 'line' | 'area'>
dataset: SimpleDataset
}
)
Expand Down
Loading