@bundle-stats/ui 3.4.0-alpha.3 → 3.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app/app.js +3 -1
- package/lib/app/header/header.js +2 -1
- package/lib/components/budget-info/budget-info.js +11 -17
- package/lib/components/budget-info/budget-info.stories.js +27 -12
- package/lib/components/budget-insights/budget-insights.js +37 -75
- package/lib/components/budget-insights/budget-insights.module.css +10 -2
- package/lib/components/budget-insights/budget-insights.stories.js +124 -63
- package/lib/components/bundle-assets/bundle-assets.js +2 -1
- package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.js +3 -4
- package/lib/components/bundle-modules/bundle-modules.js +1 -1
- package/lib/components/summary/summary.js +6 -12
- package/lib/components/summary/summary.module.css +1 -45
- package/lib/components/summary/summary.stories.js +41 -13
- package/lib/components/summary-item/summary-item.js +14 -22
- package/lib/components/summary-item/summary-item.module.css +25 -7
- package/lib/components/summary-item/summary-item.stories.js +20 -6
- package/lib/ui/hover-card/hover-card.js +7 -1
- package/lib-esm/app/app.js +3 -1
- package/lib-esm/app/header/header.js +2 -1
- package/lib-esm/components/budget-info/budget-info.js +11 -12
- package/lib-esm/components/budget-info/budget-info.stories.js +27 -12
- package/lib-esm/components/budget-insights/budget-insights.js +35 -71
- package/lib-esm/components/budget-insights/budget-insights.module.css +10 -2
- package/lib-esm/components/budget-insights/budget-insights.stories.js +115 -55
- package/lib-esm/components/bundle-assets/bundle-assets.js +2 -1
- package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.js +3 -4
- package/lib-esm/components/bundle-modules/bundle-modules.js +1 -1
- package/lib-esm/components/summary/summary.js +6 -11
- package/lib-esm/components/summary/summary.module.css +1 -45
- package/lib-esm/components/summary/summary.stories.js +41 -13
- package/lib-esm/components/summary-item/summary-item.js +11 -20
- package/lib-esm/components/summary-item/summary-item.module.css +25 -7
- package/lib-esm/components/summary-item/summary-item.stories.js +20 -6
- package/lib-esm/ui/hover-card/hover-card.js +7 -1
- package/package.json +25 -25
- package/src/app/app.jsx +2 -2
- package/src/app/header/header.jsx +1 -1
- package/src/components/budget-info/budget-info.jsx +12 -22
- package/src/components/budget-insights/budget-insights.jsx +49 -82
- package/src/components/budget-insights/budget-insights.module.css +10 -2
- package/src/components/bundle-assets/bundle-assets.jsx +1 -1
- package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.jsx +3 -3
- package/src/components/bundle-modules/bundle-modules.jsx +1 -1
- package/src/components/summary/summary.jsx +13 -17
- package/src/components/summary/summary.module.css +1 -45
- package/src/components/summary-item/summary-item.jsx +11 -17
- package/src/components/summary-item/summary-item.module.css +25 -7
- package/src/ui/hover-card/hover-card.jsx +5 -0
|
@@ -17,8 +17,6 @@ var _utils = require("@bundle-stats/utils");
|
|
|
17
17
|
|
|
18
18
|
var _constants = require("../../constants");
|
|
19
19
|
|
|
20
|
-
var _icon = require("../../ui/icon");
|
|
21
|
-
|
|
22
20
|
var _box = require("../../layout/box");
|
|
23
21
|
|
|
24
22
|
var _flexStack = require("../../layout/flex-stack");
|
|
@@ -73,23 +71,19 @@ var Summary = function Summary(_ref) {
|
|
|
73
71
|
metricId = _ref5[0],
|
|
74
72
|
metricOptions = _ref5[1];
|
|
75
73
|
|
|
76
|
-
return /*#__PURE__*/_react["default"].createElement(
|
|
74
|
+
return /*#__PURE__*/_react["default"].createElement(_summaryItem.SummaryItem, _extends({
|
|
77
75
|
key: metricId,
|
|
78
|
-
className: _summaryModule["default"].item
|
|
79
|
-
|
|
76
|
+
className: _summaryModule["default"].item,
|
|
77
|
+
as: SummaryItemCustomLink
|
|
78
|
+
}, metricOptions.link, {
|
|
80
79
|
size: size,
|
|
81
80
|
id: metricId,
|
|
82
81
|
data: (0, _get2["default"])(data, metricId),
|
|
83
|
-
budget: (0, _get2["default"])(budgets, getSourceMetricId(metricId)),
|
|
82
|
+
budget: (0, _get2["default"])(budgets, ['data', getSourceMetricId(metricId)]),
|
|
84
83
|
loading: loading,
|
|
85
84
|
showMetricDescription: true,
|
|
86
85
|
showDelta: showSummaryItemDelta && metricOptions.showDelta !== false
|
|
87
|
-
})
|
|
88
|
-
className: _summaryModule["default"].readMore
|
|
89
|
-
}), /*#__PURE__*/_react["default"].createElement(_icon.Icon, {
|
|
90
|
-
className: _summaryModule["default"].readMoreIcon,
|
|
91
|
-
glyph: _icon.Icon.ICONS.ARROW_RIGHT_CIRLCE
|
|
92
|
-
})));
|
|
86
|
+
}));
|
|
93
87
|
})));
|
|
94
88
|
};
|
|
95
89
|
|
|
@@ -6,49 +6,5 @@
|
|
|
6
6
|
.item {
|
|
7
7
|
padding: var(--space-small);
|
|
8
8
|
flex: 1 0 25%; /* force equal sizes */
|
|
9
|
-
|
|
10
|
-
z-index: 1;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.item::before {
|
|
14
|
-
content: '';
|
|
15
|
-
display: block;
|
|
16
|
-
width: 1px;
|
|
17
|
-
position: absolute;
|
|
18
|
-
left: -1px;
|
|
19
|
-
top: var(--space-small);
|
|
20
|
-
bottom: var(--space-small);
|
|
21
|
-
background: var(--color-outline);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.readMore {
|
|
25
|
-
display: block;
|
|
26
|
-
position: absolute;
|
|
27
|
-
right: 0;
|
|
28
|
-
bottom: 0;
|
|
29
|
-
padding: var(--space-small);
|
|
30
|
-
color: var(--color-text-ultra-light);
|
|
31
|
-
transition: var(--transition-out);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.readMore:hover,
|
|
35
|
-
.readMore:focus {
|
|
36
|
-
color: var(--color-primary);
|
|
37
|
-
transition: var(--transition-in);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.readMoreIcon {
|
|
41
|
-
display: block;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** hover state */
|
|
45
|
-
.readMore {
|
|
46
|
-
opacity: 0;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.item:hover .readMore,
|
|
50
|
-
.item:active .readMore,
|
|
51
|
-
.item:focus .readMore {
|
|
52
|
-
opacity: 1;
|
|
53
|
-
transition: var(--transition-in);
|
|
9
|
+
text-decoration: none;
|
|
54
10
|
}
|
|
@@ -45,26 +45,54 @@ stories.add('budgets', function () {
|
|
|
45
45
|
return /*#__PURE__*/_react["default"].createElement(_.Summary, {
|
|
46
46
|
data: MULTIPLE_JOBS[0].summary,
|
|
47
47
|
budgets: {
|
|
48
|
-
|
|
48
|
+
data: {
|
|
49
49
|
totalSizeByTypeALL: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
type: 'ERROR',
|
|
51
|
+
message: {
|
|
52
|
+
text: 'Metric is over the budget',
|
|
53
|
+
md: 'Metric is over the budget'
|
|
54
|
+
},
|
|
55
|
+
data: {
|
|
56
|
+
currentValue: MULTIPLE_JOBS[0].summary.webpack.totalSizeByTypeALL.current,
|
|
57
|
+
budgetValue: 1024 * 1024,
|
|
58
|
+
failed: false
|
|
59
|
+
}
|
|
53
60
|
},
|
|
54
61
|
totalInitialSizeJS: {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
type: 'WARNING',
|
|
63
|
+
message: {
|
|
64
|
+
text: 'Metric is over the budget',
|
|
65
|
+
md: 'Metric is over the budget'
|
|
66
|
+
},
|
|
67
|
+
data: {
|
|
68
|
+
currentValue: MULTIPLE_JOBS[0].summary.webpack.totalInitialSizeJS.current,
|
|
69
|
+
budgetValue: 512 * 1024,
|
|
70
|
+
failed: true
|
|
71
|
+
}
|
|
58
72
|
},
|
|
59
73
|
totalInitialSizeCSS: {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
74
|
+
type: 'SUCCESS',
|
|
75
|
+
message: {
|
|
76
|
+
text: 'Metric is under the budget',
|
|
77
|
+
md: 'Metric is under the budget'
|
|
78
|
+
},
|
|
79
|
+
data: {
|
|
80
|
+
currentValue: MULTIPLE_JOBS[0].summary.webpack.totalInitialSizeCSS.current,
|
|
81
|
+
budgetValue: 50 * 1024,
|
|
82
|
+
failed: false
|
|
83
|
+
}
|
|
63
84
|
},
|
|
64
85
|
chunkCount: {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
type: 'SUCCESS',
|
|
87
|
+
message: {
|
|
88
|
+
text: 'Metric is under the budget',
|
|
89
|
+
md: 'Metric is under the budget'
|
|
90
|
+
},
|
|
91
|
+
data: {
|
|
92
|
+
currentValue: MULTIPLE_JOBS[0].summary.webpack.chunkCount.current,
|
|
93
|
+
budgetValue: 50,
|
|
94
|
+
failed: false
|
|
95
|
+
}
|
|
68
96
|
}
|
|
69
97
|
}
|
|
70
98
|
}
|
|
@@ -15,14 +15,12 @@ var _utils = require("@bundle-stats/utils");
|
|
|
15
15
|
|
|
16
16
|
var _hoverCard = require("../../ui/hover-card");
|
|
17
17
|
|
|
18
|
-
var _icon = require("../../ui/icon");
|
|
19
|
-
|
|
20
18
|
var _skeleton = require("../../ui/skeleton");
|
|
21
19
|
|
|
22
|
-
var _stack = require("../../layout/stack");
|
|
23
|
-
|
|
24
20
|
var _flexStack = require("../../layout/flex-stack");
|
|
25
21
|
|
|
22
|
+
var _stack = require("../../layout/stack");
|
|
23
|
+
|
|
26
24
|
var _metric = require("../metric");
|
|
27
25
|
|
|
28
26
|
var _delta = require("../delta");
|
|
@@ -46,8 +44,11 @@ var MetricInfo = function MetricInfo(_ref) {
|
|
|
46
44
|
url = _ref.url;
|
|
47
45
|
return /*#__PURE__*/_react["default"].createElement(_stack.Stack, {
|
|
48
46
|
space: "xxxsmall"
|
|
49
|
-
}, /*#__PURE__*/_react["default"].createElement("p", null, description), url && /*#__PURE__*/_react["default"].createElement("p", null, /*#__PURE__*/_react["default"].createElement("
|
|
50
|
-
|
|
47
|
+
}, /*#__PURE__*/_react["default"].createElement("p", null, description), url && /*#__PURE__*/_react["default"].createElement("p", null, /*#__PURE__*/_react["default"].createElement("button", {
|
|
48
|
+
type: "button",
|
|
49
|
+
onClick: function onClick() {
|
|
50
|
+
return window.open(url);
|
|
51
|
+
},
|
|
51
52
|
className: _summaryItemModule["default"].readMoreLink
|
|
52
53
|
}, "Read more")));
|
|
53
54
|
};
|
|
@@ -84,23 +85,17 @@ var SummaryItem = function SummaryItem(_ref2) {
|
|
|
84
85
|
var showMetricDescriptionTooltip = showMetricDescription && (metric === null || metric === void 0 ? void 0 : metric.description);
|
|
85
86
|
var rootClassName = (0, _classnames["default"])(_summaryItemModule["default"].root, className, _summaryItemModule["default"][size], showDelta && _summaryItemModule["default"].showDelta);
|
|
86
87
|
return /*#__PURE__*/_react["default"].createElement(_stack.Stack, _extends({
|
|
87
|
-
space: "
|
|
88
|
+
space: "xxsmall",
|
|
88
89
|
as: Component,
|
|
89
90
|
className: rootClassName
|
|
90
91
|
}, props), /*#__PURE__*/_react["default"].createElement(_flexStack.FlexStack, {
|
|
91
|
-
as: "h3",
|
|
92
92
|
space: "xxxsmall",
|
|
93
|
+
as: "h3",
|
|
93
94
|
className: _summaryItemModule["default"].title
|
|
94
|
-
}, /*#__PURE__*/_react["default"].createElement(
|
|
95
|
-
|
|
96
|
-
}, metric.label
|
|
97
|
-
className: _summaryItemModule["default"].icon,
|
|
98
|
-
label: /*#__PURE__*/_react["default"].createElement(_icon.Icon, {
|
|
99
|
-
glyph: "help"
|
|
100
|
-
})
|
|
101
|
-
}, /*#__PURE__*/_react["default"].createElement(MetricInfo, metric)), budget && /*#__PURE__*/_react["default"].createElement(_budgetInfo.BudgetInfo, {
|
|
95
|
+
}, showMetricDescriptionTooltip ? /*#__PURE__*/_react["default"].createElement(_hoverCard.HoverCard, {
|
|
96
|
+
label: metric.label
|
|
97
|
+
}, /*#__PURE__*/_react["default"].createElement(MetricInfo, metric)) : metric.label, budget && /*#__PURE__*/_react["default"].createElement(_budgetInfo.BudgetInfo, {
|
|
102
98
|
className: _summaryItemModule["default"].budgetInfo,
|
|
103
|
-
metricId: id,
|
|
104
99
|
budgetInsight: budget
|
|
105
100
|
})), !loading ? /*#__PURE__*/_react["default"].createElement(_stack.Stack, null, /*#__PURE__*/_react["default"].createElement(_metric.Metric, {
|
|
106
101
|
className: _summaryItemModule["default"].currentMetric,
|
|
@@ -161,9 +156,6 @@ SummaryItem.propTypes = {
|
|
|
161
156
|
showDelta: _propTypes["default"].bool,
|
|
162
157
|
|
|
163
158
|
/** Budget insight data */
|
|
164
|
-
budget: _propTypes["default"].
|
|
165
|
-
|
|
166
|
-
budgetValue: _propTypes["default"].number,
|
|
167
|
-
failed: _propTypes["default"].bool
|
|
168
|
-
})
|
|
159
|
+
budget: _propTypes["default"].object // eslint-disable-line react/forbid-prop-types
|
|
160
|
+
|
|
169
161
|
};
|
|
@@ -8,17 +8,11 @@
|
|
|
8
8
|
color: var(--color-text-ultra-light);
|
|
9
9
|
font-weight: bold;
|
|
10
10
|
font-size: var(--size-xsmall);
|
|
11
|
-
line-height:
|
|
11
|
+
line-height: 1;
|
|
12
12
|
text-transform: uppercase;
|
|
13
13
|
white-space: nowrap;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.budgetInfo {
|
|
17
|
-
position: absolute;
|
|
18
|
-
right: 0;
|
|
19
|
-
top: 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
16
|
.currentMetric {
|
|
23
17
|
display: block;
|
|
24
18
|
color: var(--color-heading);
|
|
@@ -39,6 +33,30 @@
|
|
|
39
33
|
line-height: var(--space-small);
|
|
40
34
|
}
|
|
41
35
|
|
|
36
|
+
.readMoreLink {
|
|
37
|
+
appearance: none;
|
|
38
|
+
background: none;
|
|
39
|
+
margin: 0;
|
|
40
|
+
border: 0;
|
|
41
|
+
padding: 0;
|
|
42
|
+
color: var(--color-primary);
|
|
43
|
+
text-decoration: underline;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.readMoreLink:hover,
|
|
48
|
+
.readMoreLink:active,
|
|
49
|
+
.readMoreLink:focus {
|
|
50
|
+
color: var(--color-primary-dark);
|
|
51
|
+
text-decoration: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Hover state */
|
|
55
|
+
.root:hover .title {
|
|
56
|
+
color: var(--color-text-light);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
42
60
|
/* Loading state */
|
|
43
61
|
.loading.currentMetric {
|
|
44
62
|
width: 8em;
|
|
@@ -58,9 +58,16 @@ exports.BudgetError = BudgetError;
|
|
|
58
58
|
BudgetError.args = {
|
|
59
59
|
showMetricDescription: true,
|
|
60
60
|
budget: {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
type: 'ERROR',
|
|
62
|
+
message: {
|
|
63
|
+
text: 'Metric is over the budget',
|
|
64
|
+
md: 'Metric is over the budget'
|
|
65
|
+
},
|
|
66
|
+
data: {
|
|
67
|
+
currentValue: 120 * 1000,
|
|
68
|
+
budgetValue: 100 * 1000,
|
|
69
|
+
failed: true
|
|
70
|
+
}
|
|
64
71
|
}
|
|
65
72
|
};
|
|
66
73
|
var BudgetSuccess = Template.bind();
|
|
@@ -68,9 +75,16 @@ exports.BudgetSuccess = BudgetSuccess;
|
|
|
68
75
|
BudgetSuccess.args = {
|
|
69
76
|
showMetricDescription: true,
|
|
70
77
|
budget: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
type: 'SUCCESS',
|
|
79
|
+
message: {
|
|
80
|
+
text: 'Metric is under the budget',
|
|
81
|
+
md: 'Metric is under the budget'
|
|
82
|
+
},
|
|
83
|
+
data: {
|
|
84
|
+
currentValue: 120 * 1000,
|
|
85
|
+
budgetValue: 120 * 1024,
|
|
86
|
+
failed: false
|
|
87
|
+
}
|
|
74
88
|
}
|
|
75
89
|
};
|
|
76
90
|
var Loading = Template.bind();
|
|
@@ -53,6 +53,11 @@ var HoverCard = function HoverCard(props) {
|
|
|
53
53
|
}); // Fallback to span if no href
|
|
54
54
|
|
|
55
55
|
var Component = resolveComponent(as, href);
|
|
56
|
+
|
|
57
|
+
var handleOnClick = function handleOnClick(event) {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
};
|
|
60
|
+
|
|
56
61
|
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
57
62
|
className: (0, _classnames["default"])(_hoverCardModule["default"].root, className)
|
|
58
63
|
}, /*#__PURE__*/_react["default"].createElement(_hovercard.HovercardAnchor, {
|
|
@@ -65,7 +70,8 @@ var HoverCard = function HoverCard(props) {
|
|
|
65
70
|
className: (0, _classnames["default"])(_hoverCardModule["default"].hoverCard, hoverCardClassName),
|
|
66
71
|
style: {
|
|
67
72
|
zIndex: 10000
|
|
68
|
-
}
|
|
73
|
+
},
|
|
74
|
+
onClick: handleOnClick
|
|
69
75
|
}), /*#__PURE__*/_react["default"].createElement(_hovercard.HovercardArrow, {
|
|
70
76
|
size: 24
|
|
71
77
|
}), typeof children === 'function' ? children({
|
package/lib-esm/app/app.js
CHANGED
|
@@ -54,6 +54,7 @@ const Layout = _ref => {
|
|
|
54
54
|
|
|
55
55
|
Layout.propTypes = {
|
|
56
56
|
jobs: PropTypes.arrayOf(PropTypes.object),
|
|
57
|
+
// eslint-disable-line react/forbid-prop-types
|
|
57
58
|
version: PropTypes.string
|
|
58
59
|
};
|
|
59
60
|
Layout.defaultProps = {
|
|
@@ -78,7 +79,8 @@ const JobsProvider = _ref2 => {
|
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
JobsProvider.propTypes = {
|
|
81
|
-
jobs: PropTypes.arrayOf(PropTypes.object).isRequired
|
|
82
|
+
jobs: PropTypes.arrayOf(PropTypes.object).isRequired // eslint-disable-line react/forbid-prop-types
|
|
83
|
+
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
const OverviewContent = () => {
|
|
@@ -21,7 +21,8 @@ export const Header = _ref => {
|
|
|
21
21
|
};
|
|
22
22
|
Header.propTypes = {
|
|
23
23
|
className: PropTypes.string,
|
|
24
|
-
jobs: PropTypes.arrayOf(PropTypes.object)
|
|
24
|
+
jobs: PropTypes.arrayOf(PropTypes.object) // eslint-disable-line react/forbid-prop-types
|
|
25
|
+
|
|
25
26
|
};
|
|
26
27
|
Header.defaultProps = {
|
|
27
28
|
className: '',
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { InsightType } from '@bundle-stats/utils';
|
|
5
|
-
import * as budgetsInsightsTransformer from '@bundle-stats/utils/lib-esm/transformers/budgets-insights';
|
|
6
5
|
import { Icon } from '../../ui/icon';
|
|
7
6
|
import { Tooltip } from '../../ui/tooltip';
|
|
8
7
|
import css from './budget-info.module.css';
|
|
@@ -23,21 +22,16 @@ const INSIGHT_TYPE_MAP = {
|
|
|
23
22
|
export const BudgetInfo = _ref => {
|
|
24
23
|
let {
|
|
25
24
|
className = '',
|
|
26
|
-
metricId,
|
|
27
25
|
budgetInsight
|
|
28
26
|
} = _ref;
|
|
29
|
-
const budgetInsightInfo = budgetsInsightsTransformer.getInfo(metricId, budgetInsight);
|
|
30
27
|
const {
|
|
31
28
|
className: insightTypeClassName,
|
|
32
29
|
glyph
|
|
33
|
-
} = INSIGHT_TYPE_MAP[
|
|
30
|
+
} = INSIGHT_TYPE_MAP[budgetInsight.type];
|
|
34
31
|
const rootClassName = cx(css.root, insightTypeClassName, className);
|
|
35
|
-
const {
|
|
36
|
-
data: messageData
|
|
37
|
-
} = budgetInsightInfo.message;
|
|
38
32
|
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
39
33
|
className: rootClassName,
|
|
40
|
-
title:
|
|
34
|
+
title: budgetInsight.message.text
|
|
41
35
|
}, /*#__PURE__*/React.createElement(Icon, {
|
|
42
36
|
className: css.icon,
|
|
43
37
|
glyph: glyph,
|
|
@@ -45,11 +39,16 @@ export const BudgetInfo = _ref => {
|
|
|
45
39
|
}));
|
|
46
40
|
};
|
|
47
41
|
BudgetInfo.propTypes = {
|
|
48
|
-
metricId: PropTypes.string.isRequired,
|
|
49
42
|
budgetInsight: PropTypes.shape({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
type: PropTypes.string,
|
|
44
|
+
message: PropTypes.shape({
|
|
45
|
+
text: PropTypes.string
|
|
46
|
+
}),
|
|
47
|
+
data: PropTypes.shape({
|
|
48
|
+
currentValue: PropTypes.number,
|
|
49
|
+
budgetValue: PropTypes.number,
|
|
50
|
+
failed: PropTypes.bool
|
|
51
|
+
})
|
|
53
52
|
}).isRequired,
|
|
54
53
|
className: PropTypes.string
|
|
55
54
|
};
|
|
@@ -5,26 +5,41 @@ import { BudgetInfo } from '.';
|
|
|
5
5
|
const stories = storiesOf('Components/BudgetInfo', module);
|
|
6
6
|
stories.addDecorator(getWrapperDecorator());
|
|
7
7
|
stories.add('default', () => /*#__PURE__*/React.createElement(BudgetInfo, {
|
|
8
|
-
metricId: "webpack.assetCount",
|
|
9
8
|
budgetInsight: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
type: 'SUCCESS',
|
|
10
|
+
message: {
|
|
11
|
+
text: 'Metric is under the budget'
|
|
12
|
+
},
|
|
13
|
+
data: {
|
|
14
|
+
budgetValue: 300,
|
|
15
|
+
currentValue: 250,
|
|
16
|
+
failed: false
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
}));
|
|
15
20
|
stories.add('error', () => /*#__PURE__*/React.createElement(BudgetInfo, {
|
|
16
|
-
metricId: "webpack.assetCount",
|
|
17
21
|
budgetInsight: {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
type: 'ERROR',
|
|
23
|
+
message: {
|
|
24
|
+
text: 'Metric is over the budget'
|
|
25
|
+
},
|
|
26
|
+
data: {
|
|
27
|
+
budgetValue: 300,
|
|
28
|
+
currentValue: 250,
|
|
29
|
+
failed: false
|
|
30
|
+
}
|
|
21
31
|
}
|
|
22
32
|
}));
|
|
23
33
|
stories.add('warning', () => /*#__PURE__*/React.createElement(BudgetInfo, {
|
|
24
|
-
metricId: "webpack.assetCount",
|
|
25
34
|
budgetInsight: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
type: 'WARNING',
|
|
36
|
+
message: {
|
|
37
|
+
text: 'Metric is equal the budget'
|
|
38
|
+
},
|
|
39
|
+
data: {
|
|
40
|
+
budgetValue: 300,
|
|
41
|
+
currentValue: 250,
|
|
42
|
+
failed: false
|
|
43
|
+
}
|
|
29
44
|
}
|
|
30
45
|
}));
|
|
@@ -4,7 +4,6 @@ import React, { useMemo, useState } from 'react';
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { METRIC_COMPONENT_LINKS } from '@bundle-stats/utils';
|
|
7
|
-
import * as budgetsInsightsTransformer from '@bundle-stats/utils/lib-esm/transformers/budgets-insights';
|
|
8
7
|
import { Box } from '../../layout/box';
|
|
9
8
|
import { Stack } from '../../layout/stack';
|
|
10
9
|
import { FlexStack } from '../../layout/flex-stack';
|
|
@@ -17,47 +16,60 @@ const Budget = props => {
|
|
|
17
16
|
const {
|
|
18
17
|
className,
|
|
19
18
|
metricId,
|
|
20
|
-
|
|
19
|
+
budget,
|
|
21
20
|
CustomLink
|
|
22
21
|
} = props;
|
|
23
22
|
const componentLinkOptions = METRIC_COMPONENT_LINKS.get(metricId);
|
|
24
|
-
const budgetInsightInfo = budgetsInsightsTransformer.getInfo(metricId, budgetInsight);
|
|
25
|
-
const {
|
|
26
|
-
data: messageData
|
|
27
|
-
} = budgetInsightInfo.message;
|
|
28
23
|
return /*#__PURE__*/React.createElement(CustomLink, _extends({
|
|
29
|
-
className: cx(css.budget, className)
|
|
30
|
-
}, componentLinkOptions == null ? void 0 : componentLinkOptions.link),
|
|
24
|
+
className: cx(css.budget, className, budget.type === 'SUCCESS' && css.budgetSuccess)
|
|
25
|
+
}, componentLinkOptions == null ? void 0 : componentLinkOptions.link), budget.message.text);
|
|
31
26
|
};
|
|
32
27
|
|
|
33
28
|
Budget.propTypes = {
|
|
34
29
|
className: PropTypes.string,
|
|
35
30
|
metricId: PropTypes.string.isRequired,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
budget: PropTypes.shape({
|
|
32
|
+
type: PropTypes.string,
|
|
33
|
+
message: PropTypes.shape({
|
|
34
|
+
text: PropTypes.string
|
|
35
|
+
}),
|
|
36
|
+
data: PropTypes.shape({
|
|
37
|
+
currentValue: PropTypes.number.isRequired,
|
|
38
|
+
budgetValue: PropTypes.number.isRequired,
|
|
39
|
+
failed: PropTypes.bool.isRequired
|
|
40
|
+
})
|
|
40
41
|
}).isRequired,
|
|
41
42
|
CustomLink: PropTypes.elementType.isRequired
|
|
42
43
|
};
|
|
43
44
|
Budget.defaultProps = {
|
|
44
45
|
className: ''
|
|
45
46
|
};
|
|
46
|
-
|
|
47
|
-
const
|
|
47
|
+
const BUDGET_ALERT_KIND = new Map([['ERROR', 'danger'], ['WARNING', 'warning'], ['SUCCESS', 'success']]);
|
|
48
|
+
const BUDGET_ICON = new Map([['ERROR', Icon.ICONS.ALERT_CIRCLE], ['WARNING', Icon.ICONS.WARNING], ['SUCCESS', Icon.ICONS.CHECK_CIRCLE]]);
|
|
49
|
+
export const BudgetInsights = props => {
|
|
48
50
|
const {
|
|
49
51
|
className,
|
|
50
|
-
kind,
|
|
51
52
|
source,
|
|
52
53
|
budgets,
|
|
53
54
|
CustomLink
|
|
54
55
|
} = props;
|
|
55
56
|
const [showBudgets, setShowBudgets] = useState(false);
|
|
56
|
-
const
|
|
57
|
+
const iconGlyph = BUDGET_ICON.get(budgets.type);
|
|
58
|
+
const alertKind = BUDGET_ALERT_KIND.get(budgets.type);
|
|
59
|
+
const rootClassName = cx(css.group, className, css[`group-${alertKind}`]);
|
|
60
|
+
const budgetItems = useMemo(() => {
|
|
61
|
+
const items = Object.entries(budgets.data); // When there are errors/warnings, sort budget items first
|
|
62
|
+
|
|
63
|
+
if (['ERROR', 'WARNING'].includes(budgets.type)) {
|
|
64
|
+
items.sort(a => a[1].type === budgets.type ? -1 : 1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return items;
|
|
68
|
+
}, [budgets]);
|
|
57
69
|
return /*#__PURE__*/React.createElement(Alert, {
|
|
58
|
-
kind:
|
|
70
|
+
kind: alertKind,
|
|
59
71
|
padding: "none",
|
|
60
|
-
className:
|
|
72
|
+
className: rootClassName
|
|
61
73
|
}, /*#__PURE__*/React.createElement(Box, {
|
|
62
74
|
padding: ['xsmall', 'small'],
|
|
63
75
|
className: css.groupHeader,
|
|
@@ -67,74 +79,26 @@ const BudgetsGroup = props => {
|
|
|
67
79
|
}, /*#__PURE__*/React.createElement(FlexStack, {
|
|
68
80
|
space: "xxsmall",
|
|
69
81
|
className: css.groupTitle
|
|
70
|
-
}, /*#__PURE__*/React.createElement(Icon, {
|
|
82
|
+
}, iconGlyph && /*#__PURE__*/React.createElement(Icon, {
|
|
71
83
|
className: css.groupIcon,
|
|
72
|
-
glyph:
|
|
73
|
-
}), /*#__PURE__*/React.createElement("span", null,
|
|
84
|
+
glyph: iconGlyph
|
|
85
|
+
}), /*#__PURE__*/React.createElement("span", null, budgets.message.text), /*#__PURE__*/React.createElement("span", {
|
|
74
86
|
className: css.groupTitleToggle
|
|
75
87
|
}, showBudgets ? 'hide' : 'show', " all"))), showBudgets && /*#__PURE__*/React.createElement(Box, {
|
|
76
88
|
padding: ['xsmall', 'small'],
|
|
77
89
|
className: css.groupContent
|
|
78
90
|
}, /*#__PURE__*/React.createElement(Stack, {
|
|
79
91
|
space: "none"
|
|
80
|
-
},
|
|
92
|
+
}, budgetItems.map(_ref => {
|
|
81
93
|
let [key, budget] = _ref;
|
|
82
94
|
return /*#__PURE__*/React.createElement(Budget, {
|
|
83
95
|
key: key,
|
|
84
96
|
metricId: `${source}.${key}`,
|
|
85
|
-
|
|
97
|
+
budget: budget,
|
|
86
98
|
CustomLink: CustomLink
|
|
87
99
|
});
|
|
88
100
|
}))));
|
|
89
101
|
};
|
|
90
|
-
|
|
91
|
-
BudgetsGroup.propTypes = {
|
|
92
|
-
className: PropTypes.string,
|
|
93
|
-
kind: PropTypes.oneOf(['success', 'danger']).isRequired,
|
|
94
|
-
source: PropTypes.string.isRequired,
|
|
95
|
-
budgets: PropTypes.object.isRequired,
|
|
96
|
-
// eslint-disable-line react/forbid-prop-types
|
|
97
|
-
CustomLink: PropTypes.elementType.isRequired
|
|
98
|
-
};
|
|
99
|
-
BudgetsGroup.defaultProps = {
|
|
100
|
-
className: ''
|
|
101
|
-
};
|
|
102
|
-
export const BudgetInsights = props => {
|
|
103
|
-
const {
|
|
104
|
-
className,
|
|
105
|
-
source,
|
|
106
|
-
budgets,
|
|
107
|
-
CustomLink
|
|
108
|
-
} = props;
|
|
109
|
-
const [failedBudgets, passedBudgets] = useMemo(() => {
|
|
110
|
-
const passed = [];
|
|
111
|
-
const failed = [];
|
|
112
|
-
Object.entries(budgets).forEach(_ref2 => {
|
|
113
|
-
let [key, budget] = _ref2;
|
|
114
|
-
|
|
115
|
-
if (budget.failed) {
|
|
116
|
-
failed.push([key, budget]);
|
|
117
|
-
} else {
|
|
118
|
-
passed.push([key, budget]);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
return [failed, passed];
|
|
122
|
-
}, [budgets]);
|
|
123
|
-
return /*#__PURE__*/React.createElement(Stack, {
|
|
124
|
-
className: className,
|
|
125
|
-
space: "xsmall"
|
|
126
|
-
}, failedBudgets.length > 0 && /*#__PURE__*/React.createElement(BudgetsGroup, {
|
|
127
|
-
kind: "danger",
|
|
128
|
-
source: source,
|
|
129
|
-
budgets: failedBudgets,
|
|
130
|
-
CustomLink: CustomLink
|
|
131
|
-
}), passedBudgets.length > 0 && /*#__PURE__*/React.createElement(BudgetsGroup, {
|
|
132
|
-
kind: "success",
|
|
133
|
-
source: source,
|
|
134
|
-
budgets: passedBudgets,
|
|
135
|
-
CustomLink: CustomLink
|
|
136
|
-
}));
|
|
137
|
-
};
|
|
138
102
|
BudgetInsights.propTypes = {
|
|
139
103
|
className: PropTypes.string,
|
|
140
104
|
source: PropTypes.string.isRequired,
|
|
@@ -20,11 +20,15 @@
|
|
|
20
20
|
margin: 0 0 0 auto !important;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
.danger .groupIcon {
|
|
23
|
+
.group-danger .groupIcon {
|
|
24
24
|
color: var(--color-danger);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
.
|
|
27
|
+
.group-warning .groupIcon {
|
|
28
|
+
color: var(--color-warning);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.group-success .groupIcon {
|
|
28
32
|
color: var(--color-success);
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -39,6 +43,10 @@
|
|
|
39
43
|
text-decoration: none;
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
.budgetSuccess {
|
|
47
|
+
color: var(--color-text-light);
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
.budgetLabel,
|
|
43
51
|
.budgetValue {
|
|
44
52
|
color: var(--color-text-dark);
|