@@ -2,7 +2,6 @@ import React, { useMemo, useState } from 'react';
2
2
import PropTypes from 'prop-types' ;
3
3
import cx from 'classnames' ;
4
4
import { METRIC_COMPONENT_LINKS } from '@bundle-stats/utils' ;
5
- import * as budgetsInsightsTransformer from '@bundle-stats/utils/lib-esm/transformers/budgets-insights' ;
6
5
7
6
import { Box } from '../../layout/box' ;
8
7
import { Stack } from '../../layout/stack' ;
@@ -13,30 +12,28 @@ import { ComponentLink } from '../component-link';
13
12
import css from './budget-insights.module.css' ;
14
13
15
14
const Budget = ( props ) => {
16
- const { className, metricId, budgetInsight , CustomLink } = props ;
15
+ const { className, metricId, budget , CustomLink } = props ;
17
16
const componentLinkOptions = METRIC_COMPONENT_LINKS . get ( metricId ) ;
18
- const budgetInsightInfo = budgetsInsightsTransformer . getInfo ( metricId , budgetInsight ) ;
19
- const { data : messageData } = budgetInsightInfo . message ;
20
17
21
18
return (
22
19
< CustomLink className = { cx ( css . budget , className ) } { ...componentLinkOptions ?. link } >
23
- < strong > { messageData . metricLabel } </ strong >
24
- { ` value (` }
25
- < strong > { messageData . currentValue } </ strong >
26
- { `) is ${ messageData . diffLabel } ` }
27
- < strong > { messageData . budgetValue } </ strong >
28
- { ` budget ` }
20
+ { budget . message . text }
29
21
</ CustomLink >
30
22
) ;
31
23
} ;
32
24
33
25
Budget . propTypes = {
34
26
className : PropTypes . string ,
35
27
metricId : PropTypes . string . isRequired ,
36
- budgetInsight : PropTypes . shape ( {
37
- currentValue : PropTypes . number . isRequired ,
38
- budgetValue : PropTypes . number . isRequired ,
39
- failed : PropTypes . bool . isRequired ,
28
+ budget : PropTypes . shape ( {
29
+ message : PropTypes . shape ( {
30
+ text : PropTypes . string ,
31
+ } ) ,
32
+ data : PropTypes . shape ( {
33
+ currentValue : PropTypes . number . isRequired ,
34
+ budgetValue : PropTypes . number . isRequired ,
35
+ failed : PropTypes . bool . isRequired ,
36
+ } ) ,
40
37
} ) . isRequired ,
41
38
CustomLink : PropTypes . elementType . isRequired ,
42
39
} ;
@@ -103,44 +100,57 @@ BudgetsGroup.defaultProps = {
103
100
className : '' ,
104
101
} ;
105
102
106
- export const BudgetInsights = ( props ) => {
107
- const { className, source, budgets, CustomLink } = props ;
103
+ const BUDGET_ALERT_KIND = new Map ( [
104
+ [ 'ERROR' , 'danger' ] ,
105
+ [ 'WARNING' , 'warning' ] ,
106
+ [ 'SUCCESS' , 'success' ] ,
107
+ ] ) ;
108
108
109
- const [ failedBudgets , passedBudgets ] = useMemo ( ( ) => {
110
- const passed = [ ] ;
111
- const failed = [ ] ;
109
+ const BUDGET_ICON = new Map ( [
110
+ [ 'ERROR' , Icon . ICONS . ALERT_CIRCLE ] ,
111
+ [ 'WARNING' , Icon . ICONS . WARNING ] ,
112
+ [ 'SUCCESS' , Icon . ICONS . CHECK_CIRCLE ] ,
113
+ ] ) ;
112
114
113
- Object . entries ( budgets ) . forEach ( ( [ key , budget ] ) => {
114
- if ( budget . failed ) {
115
- failed . push ( [ key , budget ] ) ;
116
- } else {
117
- passed . push ( [ key , budget ] ) ;
118
- }
119
- } ) ;
115
+ export const BudgetInsights = ( props ) => {
116
+ const { className, source, budgets, CustomLink } = props ;
117
+ const [ showBudgets , setShowBudgets ] = useState ( false ) ;
120
118
121
- return [ failed , passed ] ;
122
- } , [ budgets ] ) ;
119
+ const iconGlyph = BUDGET_ICON . get ( budgets . type ) ;
120
+ const alertKind = BUDGET_ALERT_KIND . get ( budgets . type ) ;
121
+ const rootClassName = cx ( css . group , className , css [ `group-${ alertKind } ` ] ) ;
123
122
124
123
return (
125
- < Stack className = { className } space = "xsmall" >
126
- { failedBudgets . length > 0 && (
127
- < BudgetsGroup
128
- kind = "danger"
129
- source = { source }
130
- budgets = { failedBudgets }
131
- CustomLink = { CustomLink }
132
- />
133
- ) }
124
+ < Alert kind = { alertKind } padding = "none" className = { rootClassName } >
125
+ < Box
126
+ padding = { [ 'xsmall' , 'small' ] }
127
+ className = { css . groupHeader }
128
+ as = "button"
129
+ type = "button"
130
+ onClick = { ( ) => setShowBudgets ( ! showBudgets ) }
131
+ >
132
+ < FlexStack space = "xxsmall" className = { css . groupTitle } >
133
+ { iconGlyph && < Icon className = { css . groupIcon } glyph = { iconGlyph } /> }
134
+ < span > { budgets . message . text } </ span >
135
+ < span className = { css . groupTitleToggle } > { showBudgets ? 'hide' : 'show' } all</ span >
136
+ </ FlexStack >
137
+ </ Box >
134
138
135
- { passedBudgets . length > 0 && (
136
- < BudgetsGroup
137
- kind = "success"
138
- source = { source }
139
- budgets = { passedBudgets }
140
- CustomLink = { CustomLink }
141
- />
139
+ { showBudgets && (
140
+ < Box padding = { [ 'xsmall' , 'small' ] } className = { css . groupContent } >
141
+ < Stack space = "none" >
142
+ { Object . entries ( budgets . data ) . map ( ( [ key , budget ] ) => (
143
+ < Budget
144
+ key = { key }
145
+ metricId = { `${ source } .${ key } ` }
146
+ budget = { budget }
147
+ CustomLink = { CustomLink }
148
+ />
149
+ ) ) }
150
+ </ Stack >
151
+ </ Box >
142
152
) }
143
- </ Stack >
153
+ </ Alert >
144
154
) ;
145
155
} ;
146
156
0 commit comments