@bundle-stats/ui 3.3.0-alpha.1 → 3.3.1-beta.12

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.
Files changed (240) hide show
  1. package/CHANGELOG.md +65 -13
  2. package/lib/app/app.js +126 -104
  3. package/lib/app/app.module.css +11 -4
  4. package/lib/app/app.stories.js +1 -22
  5. package/lib/app/header/header.js +3 -11
  6. package/lib/assets/icons.svg +0 -8
  7. package/lib/components/asset-info/asset-info.module.css +1 -0
  8. package/lib/components/bundle-assets/bundle-assets.js +105 -52
  9. package/lib/components/bundle-assets/bundle-assets.module.css +24 -26
  10. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.js +16 -42
  11. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  12. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +1 -20
  13. package/lib/components/bundle-modules/bundle-modules.js +68 -68
  14. package/lib/components/bundle-modules/bundle-modules.module.css +11 -2
  15. package/lib/components/bundle-modules/bundle-modules.utils.js +14 -10
  16. package/lib/components/bundle-modules/index.js +4 -4
  17. package/lib/components/bundle-packages/bundle-packages.js +100 -44
  18. package/lib/components/bundle-packages/bundle-packages.module.css +17 -21
  19. package/lib/components/delta/delta.module.css +1 -0
  20. package/lib/components/index.js +0 -8
  21. package/lib/components/job-header/job-header.js +3 -1
  22. package/lib/components/job-header/job-header.module.css +6 -8
  23. package/lib/components/jobs-header/jobs-header.module.css +5 -0
  24. package/lib/components/metrics-table/metrics-table.js +72 -59
  25. package/lib/components/metrics-table/metrics-table.module.css +18 -7
  26. package/lib/components/metrics-table-search/metrics-table-search.module.css +5 -4
  27. package/lib/components/metrics-table-title/metrics-table-title.js +9 -7
  28. package/lib/components/metrics-table-title/metrics-table-title.module.css +2 -0
  29. package/lib/components/module-info/module-info.js +2 -2
  30. package/lib/components/module-info/module-info.module.css +1 -0
  31. package/lib/components/summary/summary.js +7 -12
  32. package/lib/components/summary/summary.module.css +1 -1
  33. package/lib/components/summary/summary.stories.js +0 -29
  34. package/lib/components/summary-item/summary-item.js +18 -38
  35. package/lib/components/summary-item/summary-item.module.css +1 -34
  36. package/lib/components/summary-item/summary-item.stories.js +53 -51
  37. package/lib/components/total-size-type-title/total-size-type-title.js +7 -3
  38. package/lib/constants.js +4 -4
  39. package/lib/css/default.css +14 -3
  40. package/lib/css/variables.css +17 -17
  41. package/lib/hooks/search-params.js +31 -31
  42. package/lib/layout/box/box.module.css +9 -0
  43. package/lib/layout/footer/footer.module.css +1 -1
  44. package/lib/layout/index.js +8 -0
  45. package/lib/layout/separator.js +48 -0
  46. package/lib/layout/separator.module.css +5 -0
  47. package/lib/ui/alert/alert.js +3 -13
  48. package/lib/ui/dropdown/dropdown.js +21 -26
  49. package/lib/ui/dropdown/dropdown.module.css +11 -12
  50. package/lib/ui/dropdown/dropdown.stories.js +2 -9
  51. package/lib/ui/empty-set/empty-set.js +5 -4
  52. package/lib/ui/empty-set/empty-set.module.css +2 -2
  53. package/lib/ui/filters/filters.container.js +1 -1
  54. package/lib/ui/filters/filters.js +22 -7
  55. package/lib/ui/filters/filters.module.css +3 -3
  56. package/lib/ui/horizontal-bar-chart/horizontal-bar-chart.js +1 -1
  57. package/lib/ui/hover-card/hover-card.js +102 -0
  58. package/lib/ui/hover-card/hover-card.module.css +29 -0
  59. package/lib/ui/hover-card/hover-card.stories.js +56 -0
  60. package/lib/{components/budget-info → ui/hover-card}/index.js +4 -4
  61. package/lib/ui/icon/icon.js +6 -8
  62. package/lib/ui/icon/icon.module.css +1 -0
  63. package/lib/ui/index.js +8 -8
  64. package/lib/ui/table/table.js +5 -74
  65. package/lib/ui/table/table.module.css +41 -25
  66. package/lib/ui/table/table.stories.js +1 -1
  67. package/lib/ui/{popover → tag}/index.js +4 -4
  68. package/lib/ui/tag/tag.js +72 -0
  69. package/lib/ui/tag/tag.module.css +55 -0
  70. package/lib/ui/tag/tag.stories.js +38 -0
  71. package/lib/ui/tooltip/tooltip.js +10 -9
  72. package/lib/ui/tooltip/tooltip.module.css +2 -1
  73. package/lib-esm/app/app.js +121 -103
  74. package/lib-esm/app/app.module.css +11 -4
  75. package/lib-esm/app/app.stories.js +1 -22
  76. package/lib-esm/app/header/header.js +3 -10
  77. package/lib-esm/assets/icons.svg +0 -8
  78. package/lib-esm/components/asset-info/asset-info.module.css +1 -0
  79. package/lib-esm/components/bundle-assets/bundle-assets.js +98 -56
  80. package/lib-esm/components/bundle-assets/bundle-assets.module.css +24 -26
  81. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.js +13 -26
  82. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  83. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +0 -18
  84. package/lib-esm/components/bundle-modules/bundle-modules.js +50 -51
  85. package/lib-esm/components/bundle-modules/bundle-modules.module.css +11 -2
  86. package/lib-esm/components/bundle-modules/bundle-modules.utils.js +14 -6
  87. package/lib-esm/components/bundle-modules/index.js +5 -3
  88. package/lib-esm/components/bundle-packages/bundle-packages.js +88 -41
  89. package/lib-esm/components/bundle-packages/bundle-packages.module.css +17 -21
  90. package/lib-esm/components/delta/delta.module.css +1 -0
  91. package/lib-esm/components/index.js +0 -1
  92. package/lib-esm/components/job-header/job-header.js +2 -1
  93. package/lib-esm/components/job-header/job-header.module.css +6 -8
  94. package/lib-esm/components/jobs-header/jobs-header.module.css +5 -0
  95. package/lib-esm/components/metrics-table/metrics-table.js +61 -53
  96. package/lib-esm/components/metrics-table/metrics-table.module.css +18 -7
  97. package/lib-esm/components/metrics-table-search/metrics-table-search.module.css +5 -4
  98. package/lib-esm/components/metrics-table-title/metrics-table-title.js +8 -7
  99. package/lib-esm/components/metrics-table-title/metrics-table-title.module.css +2 -0
  100. package/lib-esm/components/module-info/module-info.js +2 -2
  101. package/lib-esm/components/module-info/module-info.module.css +1 -0
  102. package/lib-esm/components/summary/summary.js +7 -11
  103. package/lib-esm/components/summary/summary.module.css +1 -1
  104. package/lib-esm/components/summary/summary.stories.js +0 -27
  105. package/lib-esm/components/summary-item/summary-item.js +16 -36
  106. package/lib-esm/components/summary-item/summary-item.module.css +1 -34
  107. package/lib-esm/components/summary-item/summary-item.stories.js +38 -50
  108. package/lib-esm/components/total-size-type-title/total-size-type-title.js +6 -3
  109. package/lib-esm/constants.js +4 -4
  110. package/lib-esm/css/default.css +14 -3
  111. package/lib-esm/css/variables.css +17 -17
  112. package/lib-esm/hooks/search-params.js +27 -28
  113. package/lib-esm/layout/box/box.module.css +9 -0
  114. package/lib-esm/layout/footer/footer.module.css +1 -1
  115. package/lib-esm/layout/index.js +1 -0
  116. package/lib-esm/layout/separator.js +28 -0
  117. package/lib-esm/layout/separator.module.css +5 -0
  118. package/lib-esm/ui/alert/alert.js +3 -6
  119. package/lib-esm/ui/dropdown/dropdown.js +20 -25
  120. package/lib-esm/ui/dropdown/dropdown.module.css +11 -12
  121. package/lib-esm/ui/dropdown/dropdown.stories.js +2 -7
  122. package/lib-esm/ui/empty-set/empty-set.js +4 -4
  123. package/lib-esm/ui/empty-set/empty-set.module.css +2 -2
  124. package/lib-esm/ui/filters/filters.js +20 -5
  125. package/lib-esm/ui/filters/filters.module.css +3 -3
  126. package/lib-esm/ui/hover-card/hover-card.js +83 -0
  127. package/lib-esm/ui/hover-card/hover-card.module.css +29 -0
  128. package/lib-esm/ui/hover-card/hover-card.stories.js +35 -0
  129. package/lib-esm/ui/hover-card/index.js +1 -0
  130. package/lib-esm/ui/icon/icon.js +3 -5
  131. package/lib-esm/ui/icon/icon.module.css +1 -0
  132. package/lib-esm/ui/index.js +1 -1
  133. package/lib-esm/ui/table/table.js +5 -65
  134. package/lib-esm/ui/table/table.module.css +41 -25
  135. package/lib-esm/ui/table/table.stories.js +1 -1
  136. package/lib-esm/ui/tag/index.js +1 -0
  137. package/lib-esm/ui/tag/tag.js +45 -0
  138. package/lib-esm/ui/tag/tag.module.css +55 -0
  139. package/lib-esm/ui/tag/tag.stories.js +23 -0
  140. package/lib-esm/ui/tooltip/tooltip.js +10 -9
  141. package/lib-esm/ui/tooltip/tooltip.module.css +2 -1
  142. package/package.json +33 -31
  143. package/src/app/app.jsx +136 -146
  144. package/src/app/app.module.css +11 -4
  145. package/src/app/header/header.jsx +1 -11
  146. package/src/assets/icons.svg +0 -8
  147. package/src/components/asset-info/asset-info.module.css +1 -0
  148. package/src/components/bundle-assets/bundle-assets.jsx +85 -31
  149. package/src/components/bundle-assets/bundle-assets.module.css +24 -26
  150. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.jsx +13 -25
  151. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  152. package/src/components/bundle-modules/bundle-modules.jsx +53 -36
  153. package/src/components/bundle-modules/bundle-modules.module.css +11 -2
  154. package/src/components/bundle-modules/bundle-modules.utils.js +16 -4
  155. package/src/components/bundle-modules/index.jsx +3 -0
  156. package/src/components/bundle-packages/bundle-packages.jsx +89 -39
  157. package/src/components/bundle-packages/bundle-packages.module.css +17 -21
  158. package/src/components/delta/delta.module.css +1 -0
  159. package/src/components/index.js +0 -1
  160. package/src/components/job-header/job-header.jsx +2 -1
  161. package/src/components/job-header/job-header.module.css +6 -8
  162. package/src/components/jobs-header/jobs-header.module.css +5 -0
  163. package/src/components/metrics-table/metrics-table.jsx +53 -44
  164. package/src/components/metrics-table/metrics-table.module.css +18 -7
  165. package/src/components/metrics-table-search/metrics-table-search.module.css +5 -4
  166. package/src/components/metrics-table-title/metrics-table-title.jsx +20 -21
  167. package/src/components/metrics-table-title/metrics-table-title.module.css +2 -0
  168. package/src/components/module-info/module-info.jsx +3 -7
  169. package/src/components/module-info/module-info.module.css +1 -0
  170. package/src/components/summary/summary.jsx +7 -8
  171. package/src/components/summary/summary.module.css +1 -1
  172. package/src/components/summary-item/summary-item.jsx +23 -40
  173. package/src/components/summary-item/summary-item.module.css +1 -34
  174. package/src/components/total-size-type-title/total-size-type-title.jsx +6 -9
  175. package/src/constants.js +11 -7
  176. package/src/css/default.css +14 -3
  177. package/src/css/variables.css +17 -17
  178. package/src/hooks/search-params.js +42 -33
  179. package/src/layout/box/box.module.css +9 -0
  180. package/src/layout/footer/footer.module.css +1 -1
  181. package/src/layout/index.js +1 -0
  182. package/src/layout/separator.jsx +25 -0
  183. package/src/layout/separator.module.css +5 -0
  184. package/src/ui/alert/alert.jsx +2 -7
  185. package/src/ui/dropdown/dropdown.jsx +16 -22
  186. package/src/ui/dropdown/dropdown.module.css +11 -12
  187. package/src/ui/empty-set/empty-set.jsx +25 -21
  188. package/src/ui/empty-set/empty-set.module.css +2 -2
  189. package/src/ui/filters/filters.jsx +64 -53
  190. package/src/ui/filters/filters.module.css +3 -3
  191. package/src/ui/hover-card/hover-card.jsx +73 -0
  192. package/src/ui/hover-card/hover-card.module.css +29 -0
  193. package/src/ui/hover-card/index.js +1 -0
  194. package/src/ui/icon/icon.jsx +11 -9
  195. package/src/ui/icon/icon.module.css +1 -0
  196. package/src/ui/index.js +1 -1
  197. package/src/ui/table/table.jsx +5 -52
  198. package/src/ui/table/table.module.css +41 -25
  199. package/src/ui/tag/index.js +1 -0
  200. package/src/ui/tag/tag.jsx +49 -0
  201. package/src/ui/tag/tag.module.css +55 -0
  202. package/src/ui/tooltip/tooltip.jsx +10 -14
  203. package/src/ui/tooltip/tooltip.module.css +2 -1
  204. package/lib/assets/icons/alert-circle.svg +0 -1
  205. package/lib/assets/icons/check-circle.svg +0 -1
  206. package/lib/components/budget-info/budget-info.js +0 -80
  207. package/lib/components/budget-info/budget-info.module.css +0 -40
  208. package/lib/components/budget-info/budget-info.stories.js +0 -44
  209. package/lib/components/budget-insights/budget-insights.js +0 -200
  210. package/lib/components/budget-insights/budget-insights.module.css +0 -53
  211. package/lib/components/budget-insights/budget-insights.stories.js +0 -104
  212. package/lib/components/budget-insights/index.js +0 -18
  213. package/lib/ui/popover/popover.js +0 -92
  214. package/lib/ui/popover/popover.module.css +0 -66
  215. package/lib/ui/popover/popover.stories.js +0 -26
  216. package/lib-esm/assets/icons/alert-circle.svg +0 -1
  217. package/lib-esm/assets/icons/check-circle.svg +0 -1
  218. package/lib-esm/components/budget-info/budget-info.js +0 -58
  219. package/lib-esm/components/budget-info/budget-info.module.css +0 -40
  220. package/lib-esm/components/budget-info/budget-info.stories.js +0 -30
  221. package/lib-esm/components/budget-info/index.js +0 -1
  222. package/lib-esm/components/budget-insights/budget-insights.js +0 -148
  223. package/lib-esm/components/budget-insights/budget-insights.module.css +0 -53
  224. package/lib-esm/components/budget-insights/budget-insights.stories.js +0 -84
  225. package/lib-esm/components/budget-insights/index.js +0 -1
  226. package/lib-esm/ui/popover/index.js +0 -1
  227. package/lib-esm/ui/popover/popover.js +0 -71
  228. package/lib-esm/ui/popover/popover.module.css +0 -66
  229. package/lib-esm/ui/popover/popover.stories.js +0 -14
  230. package/src/assets/icons/alert-circle.svg +0 -1
  231. package/src/assets/icons/check-circle.svg +0 -1
  232. package/src/components/budget-info/budget-info.jsx +0 -65
  233. package/src/components/budget-info/budget-info.module.css +0 -40
  234. package/src/components/budget-info/index.js +0 -1
  235. package/src/components/budget-insights/budget-insights.jsx +0 -157
  236. package/src/components/budget-insights/budget-insights.module.css +0 -53
  237. package/src/components/budget-insights/index.js +0 -1
  238. package/src/ui/popover/index.js +0 -1
  239. package/src/ui/popover/popover.jsx +0 -79
  240. package/src/ui/popover/popover.module.css +0 -66
@@ -3,7 +3,7 @@ import _get from "lodash/get";
3
3
 
4
4
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
5
5
 
6
- import React, { useMemo } from 'react';
6
+ import React, { useCallback, useMemo, useState } from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import cx from 'classnames';
9
9
  import { ASSET_ENTRY_TYPE, ASSET_FILE_TYPE, ASSET_FILTERS, FILE_TYPE_LABELS } from '@bundle-stats/utils';
@@ -12,8 +12,9 @@ import I18N from '../../i18n';
12
12
  import { FlexStack } from '../../layout/flex-stack';
13
13
  import { Icon } from '../../ui/icon';
14
14
  import { FileName } from '../../ui/file-name';
15
- import { Popover } from '../../ui/popover';
15
+ import { HoverCard } from '../../ui/hover-card';
16
16
  import { Tooltip } from '../../ui/tooltip';
17
+ import { Tag } from '../../ui/tag';
17
18
  import { Filters } from '../../ui/filters';
18
19
  import { SortDropdown } from '../../ui/sort-dropdown';
19
20
  import { EmptySet } from '../../ui/empty-set';
@@ -71,58 +72,93 @@ TooltipNotPredictive.propTypes = {
71
72
 
72
73
  };
73
74
 
74
- const getRenderRowHeader = _ref4 => {
75
+ const RowHeader = _ref4 => {
75
76
  let {
77
+ row,
76
78
  labels,
77
- CustomComponentLink,
78
- chunks
79
+ chunks,
80
+ CustomComponentLink
79
81
  } = _ref4;
80
- return item => {
81
- const {
82
- label,
83
- isNotPredictive,
84
- runs,
85
- isChunk,
86
- isEntry,
87
- isInitial
88
- } = item;
89
- return /*#__PURE__*/React.createElement(Popover, {
90
- label: /*#__PURE__*/React.createElement(FileName, {
91
- name: label
92
- }),
93
- icon: /*#__PURE__*/React.createElement("div", {
94
- className: css.assetInfoFlags
95
- }, isNotPredictive && /*#__PURE__*/React.createElement(Tooltip, {
96
- className: css.notPredictive,
97
- title: /*#__PURE__*/React.createElement(TooltipNotPredictive, {
98
- runs: runs
99
- })
100
- }, /*#__PURE__*/React.createElement(Icon, {
101
- className: css.notPredictiveIcon,
102
- glyph: "warning"
103
- })), isChunk && /*#__PURE__*/React.createElement("span", {
104
- title: "Chunk",
105
- className: css.flagChunk
106
- }, "c"), isEntry && /*#__PURE__*/React.createElement("span", {
107
- title: "Entrypoint",
108
- className: css.flagEntry
109
- }, "e"), isInitial && /*#__PURE__*/React.createElement("span", {
110
- title: "Initial",
111
- className: css.flagInitial
112
- }, "i"))
113
- }, /*#__PURE__*/React.createElement(AssetInfo, {
114
- className: css.assetInfo,
115
- item: item,
116
- labels: labels,
117
- chunks: chunks,
118
- CustomComponentLink: CustomComponentLink
119
- }));
120
- };
82
+ const {
83
+ label,
84
+ isNotPredictive,
85
+ runs,
86
+ isChunk,
87
+ isEntry,
88
+ isInitial
89
+ } = row;
90
+ const [showHoverCard, setHoverCard] = useState(false);
91
+ const handleOnMouseEnter = useCallback(() => setHoverCard(true), [showHoverCard]);
92
+ const content = useMemo(() => /*#__PURE__*/React.createElement("span", {
93
+ className: css.assetName
94
+ }, /*#__PURE__*/React.createElement("span", {
95
+ className: css.assetNameTags
96
+ }, isNotPredictive && /*#__PURE__*/React.createElement(Tooltip, {
97
+ className: css.notPredictive,
98
+ title: /*#__PURE__*/React.createElement(TooltipNotPredictive, {
99
+ runs: runs
100
+ })
101
+ }, /*#__PURE__*/React.createElement(Icon, {
102
+ className: css.notPredictiveIcon,
103
+ glyph: "warning"
104
+ })), isChunk && /*#__PURE__*/React.createElement(Tag, {
105
+ className: cx(css.assetNameTag, css.assetNameTagChunk),
106
+ title: "Chunk",
107
+ size: Tag.SIZES.SMALL,
108
+ kind: Tag.KINDS.INFO
109
+ }), isEntry && /*#__PURE__*/React.createElement(Tag, {
110
+ className: cx(css.assetNameTag, css.assetNameTagEntry),
111
+ title: "Entrypoint",
112
+ size: Tag.SIZES.SMALL,
113
+ kind: Tag.KINDS.INFO
114
+ }), isInitial && /*#__PURE__*/React.createElement(Tag, {
115
+ className: cx(css.assetNameTag, css.assetNameTagInitial),
116
+ title: "Initial",
117
+ size: Tag.SIZES.SMALL,
118
+ kind: Tag.KINDS.INFO
119
+ })), /*#__PURE__*/React.createElement(FileName, {
120
+ className: css.assetNameText,
121
+ name: label
122
+ })), [isChunk, isEntry, isInitial, isNotPredictive, runs]);
123
+
124
+ if (!showHoverCard) {
125
+ return /*#__PURE__*/React.createElement("span", {
126
+ onMouseEnter: handleOnMouseEnter
127
+ }, content);
128
+ }
129
+
130
+ return /*#__PURE__*/React.createElement(HoverCard, {
131
+ label: content
132
+ }, /*#__PURE__*/React.createElement(AssetInfo, {
133
+ className: css.assetInfo,
134
+ item: row,
135
+ labels: labels,
136
+ chunks: chunks,
137
+ CustomComponentLink: CustomComponentLink
138
+ }));
121
139
  };
122
140
 
123
- export const BundleAssets = props => {
124
- var _jobs$, _jobs$$meta, _jobs$$meta$webpack;
141
+ RowHeader.propTypes = {
142
+ row: PropTypes.shape({
143
+ label: PropTypes.string,
144
+ isNotPredictive: PropTypes.bool,
145
+ isChunk: PropTypes.bool,
146
+ isInitial: PropTypes.bool,
147
+ isEntry: PropTypes.bool,
148
+ runs: PropTypes.arrayOf(PropTypes.object) // eslint-disable-line react/forbid-prop-types
125
149
 
150
+ }).isRequired,
151
+ chunks: PropTypes.arrayOf(PropTypes.shape({
152
+ id: PropTypes.string,
153
+ name: PropTypes.string
154
+ })),
155
+ labels: PropTypes.arrayOf(PropTypes.string).isRequired,
156
+ CustomComponentLink: PropTypes.elementType.isRequired
157
+ };
158
+ RowHeader.defaultProps = {
159
+ chunks: []
160
+ };
161
+ export const BundleAssets = props => {
126
162
  const {
127
163
  className,
128
164
  jobs,
@@ -146,12 +182,16 @@ export const BundleAssets = props => {
146
182
  handleResetFilters: resetFilters,
147
183
  handleViewAll: resetAllFilters
148
184
  });
149
- const chunks = ((_jobs$ = jobs[0]) == null ? void 0 : (_jobs$$meta = _jobs$.meta) == null ? void 0 : (_jobs$$meta$webpack = _jobs$$meta.webpack) == null ? void 0 : _jobs$$meta$webpack.chunks) || [];
150
- const renderRowHeader = useMemo(() => getRenderRowHeader({
151
- labels: _map(jobs, 'label'),
152
- CustomComponentLink,
153
- chunks
154
- }), [jobs, chunks]);
185
+ const renderRowHeader = useCallback(row => {
186
+ var _jobs$, _jobs$$meta, _jobs$$meta$webpack;
187
+
188
+ return /*#__PURE__*/React.createElement(RowHeader, {
189
+ row: row,
190
+ labels: _map(jobs, 'label'),
191
+ chunks: ((_jobs$ = jobs[0]) == null ? void 0 : (_jobs$$meta = _jobs$.meta) == null ? void 0 : (_jobs$$meta$webpack = _jobs$$meta.webpack) == null ? void 0 : _jobs$$meta$webpack.chunks) || [],
192
+ CustomComponentLink: CustomComponentLink
193
+ });
194
+ }, [jobs, CustomComponentLink]);
155
195
  return /*#__PURE__*/React.createElement("section", {
156
196
  className: cx(css.root, className)
157
197
  }, /*#__PURE__*/React.createElement(Toolbar, {
@@ -161,7 +201,7 @@ export const BundleAssets = props => {
161
201
  actionClassName
162
202
  } = _ref5;
163
203
  return /*#__PURE__*/React.createElement(FlexStack, {
164
- space: "xsmall",
204
+ space: "xxsmall",
165
205
  className: cx(css.dropdown, actionClassName)
166
206
  }, /*#__PURE__*/React.createElement(SortDropdown, _extends({
167
207
  fields: sortFields
@@ -172,7 +212,9 @@ export const BundleAssets = props => {
172
212
  handleResetFilters: resetFilters
173
213
  }));
174
214
  }
175
- }, /*#__PURE__*/React.createElement(FlexStack, null, /*#__PURE__*/React.createElement(MetricsTableSearch, {
215
+ }, /*#__PURE__*/React.createElement(FlexStack, {
216
+ space: "xxsmall"
217
+ }, /*#__PURE__*/React.createElement(MetricsTableSearch, {
176
218
  className: css.toolbarSearch,
177
219
  placeholder: "Search by name",
178
220
  search: search,
@@ -8,6 +8,8 @@
8
8
  margin-right: -1px; /** collapse border */
9
9
  }
10
10
 
11
+ .assetName {}
12
+
11
13
  .notPredictive {
12
14
  margin-right: var(--space-xxsmall);
13
15
  display: inline-block;
@@ -21,50 +23,46 @@
21
23
  vertical-align: top;
22
24
  }
23
25
 
24
- .assetInfoFlags {
25
- display: inline-block;
26
+ .assetNameTags {
27
+ display: inline;
26
28
  margin-right: var(--space-xxxsmall);
27
29
  }
28
30
 
29
- .assetInfoFlags:empty {
31
+ .assetNameTags:empty {
30
32
  display: none;
31
33
  }
32
34
 
33
- .flag {
34
- display: inline-block;
35
- width: var(--space-xsmall);
36
- height: var(--space-xsmall);
37
- font-family: var(--font-family);
38
- font-size: 8px;
39
- font-weight: bold;
40
- background: var(--color-highlight);
41
- color: var(--color-text-light);
42
- line-height: var(--space-xsmall);
43
- text-align: center;
44
- text-transform: uppercase;
35
+ .assetNameTag {
45
36
  vertical-align: middle;
46
37
  }
47
38
 
48
- .flag + .flag {
39
+ .assetNameTag + .assetNameTag {
49
40
  margin-left: 2px;
50
41
  }
51
42
 
52
- .flagEntry {
53
- composes: flag;
43
+ .assetNameTagEntry {
54
44
  background: var(--color-info-light);
55
- color: var(--color-background);
56
45
  }
57
46
 
58
- .flagInitial {
59
- composes: flag;
47
+ .assetNameTagEntry::before {
48
+ content: 'e';
49
+ }
50
+
51
+ .assetNameTagInitial {
60
52
  background: var(--color-info-light);
61
- color: var(--color-background);
62
53
  }
63
54
 
64
- .flagChunk {
65
- composes: flag;
66
- background: var(--color-info);
67
- color: var(--color-background);
55
+ .assetNameTagInitial::before {
56
+ content: 'i';
57
+ }
58
+
59
+ .assetNameTagChunk::before {
60
+ content: 'c';
61
+ }
62
+
63
+ .assetNameText {
64
+ display: inline;
65
+ vertical-align: middle;
68
66
  }
69
67
 
70
68
  /* Tooltip not predictive */
@@ -1,55 +1,42 @@
1
- import _get from "lodash/get";
2
- import React, { useCallback, useMemo } from 'react';
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React from 'react';
3
4
  import PropTypes from 'prop-types';
4
5
  import { getBundleAssetsFileTypeComponentLink } from '@bundle-stats/utils';
5
6
  import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
6
7
  import { ASSETS_SIZES_FILE_TYPE_MAP } from '../../constants';
7
- import { FlexStack } from '../../layout/flex-stack';
8
8
  import { MetricsTable } from '../metrics-table';
9
9
  import { ComponentLink } from '../component-link';
10
- import { BudgetInfo } from '../budget-info';
11
- import css from './bundle-assets-totals-table.module.css';
12
10
  export const BundleAssetsTotalsTable = _ref => {
13
- var _jobs$0$insights, _jobs$0$insights$webp;
14
-
15
11
  let {
16
12
  className,
17
13
  jobs,
18
- customComponentLink: CustomComponentLink
14
+ customComponentLink: CustomComponentLink,
15
+ ...restProps
19
16
  } = _ref;
20
- const items = useMemo(() => webpack.compareBySection.sizes(jobs), [jobs]);
21
- const budgets = (_jobs$0$insights = jobs[0].insights) == null ? void 0 : (_jobs$0$insights$webp = _jobs$0$insights.webpack) == null ? void 0 : _jobs$0$insights$webp.budgets;
22
- const renderRowHeader = useCallback(item => {
17
+ const items = webpack.compareBySection.sizes(jobs);
18
+
19
+ const renderRowHeader = item => {
23
20
  const fileType = ASSETS_SIZES_FILE_TYPE_MAP[item.key];
24
21
  const {
25
22
  section,
26
23
  title,
27
24
  params
28
25
  } = getBundleAssetsFileTypeComponentLink(fileType, item.label);
29
- const [_, ...metricSlugs] = item.key.split('.');
30
- const metricKey = metricSlugs.join('.');
31
-
32
- const budget = _get(budgets, metricKey);
33
-
34
26
  return /*#__PURE__*/React.createElement(CustomComponentLink, {
35
27
  section: section,
36
28
  title: title,
37
29
  params: params
38
- }, /*#__PURE__*/React.createElement(FlexStack, {
39
- space: "xxsmall",
40
- className: css.itemTitleText
41
- }, /*#__PURE__*/React.createElement("span", null, item.label), budget && /*#__PURE__*/React.createElement(BudgetInfo, {
42
- metricId: item.key,
43
- budgetInsight: budget
44
- })));
45
- }, [CustomComponentLink]);
46
- return /*#__PURE__*/React.createElement(MetricsTable, {
30
+ }, item.label);
31
+ };
32
+
33
+ return /*#__PURE__*/React.createElement(MetricsTable, _extends({
47
34
  className: className,
48
35
  runs: jobs,
49
36
  items: items,
50
37
  renderRowHeader: renderRowHeader,
51
38
  showHeaderSum: true
52
- });
39
+ }, restProps));
53
40
  };
54
41
  BundleAssetsTotalsTable.defaultProps = {
55
42
  className: '',
@@ -1,3 +1,3 @@
1
- .itemTitleText {
2
- align-items: center;
1
+ .title {
2
+ color: var(--color-text-light);
3
3
  }
@@ -31,22 +31,4 @@ EmptyBaseline.args = {
31
31
  jobs: createJobs([{
32
32
  webpack: currentStats
33
33
  }, null])
34
- };
35
- export const WithBudgets = Template.bind();
36
- WithBudgets.args = {
37
- jobs: createJobs([{
38
- webpack: currentStats
39
- }, {
40
- webpack: baselineStats
41
- }], {
42
- webpack: {
43
- budgets: [{
44
- metric: 'sizes.totalSizeByTypeJS',
45
- value: 2 * 1024 * 1024
46
- }, {
47
- metric: 'sizes.totalSizeByTypeCSS',
48
- value: 20 * 1024
49
- }]
50
- }
51
- })
52
34
  };
@@ -15,8 +15,9 @@ import { FlexStack } from '../../layout/flex-stack';
15
15
  import { EmptySet } from '../../ui/empty-set';
16
16
  import { FileName } from '../../ui/file-name';
17
17
  import { Filters } from '../../ui/filters';
18
- import { Popover } from '../../ui/popover';
18
+ import { HoverCard } from '../../ui/hover-card';
19
19
  import { SortDropdown } from '../../ui/sort-dropdown';
20
+ import { Tag } from '../../ui/tag';
20
21
  import { Toolbar } from '../../ui/toolbar';
21
22
  import { MetricsTable } from '../metrics-table';
22
23
  import { MetricsTableSearch } from '../metrics-table-search';
@@ -35,35 +36,41 @@ const RowHeader = _ref => {
35
36
 
36
37
  const chunkIds = _map(chunks, 'id');
37
38
 
38
- const [showPopopver, setPopover] = useState(false);
39
- const handleOnMouseEnter = useCallback(() => setPopover(true), [showPopopver]);
40
- const content = /*#__PURE__*/React.createElement(FileName, {
39
+ const [showHoverCard, setHoverCard] = useState(false);
40
+ const handleOnMouseEnter = useCallback(() => setHoverCard(true), [showHoverCard]);
41
+ const content = useMemo(() => /*#__PURE__*/React.createElement("span", {
42
+ className: css.name
43
+ }, row.duplicated && /*#__PURE__*/React.createElement(Tag, {
44
+ className: css.nameTagDuplicated,
45
+ size: "small",
46
+ kind: Tag.KINDS.DANGER
47
+ }), /*#__PURE__*/React.createElement(FileName, {
48
+ className: css.nameText,
41
49
  name: row.label
42
- });
43
- return /*#__PURE__*/React.createElement("div", {
44
- onMouseEnter: handleOnMouseEnter
45
- }, !showPopopver ? content : /*#__PURE__*/React.createElement(Popover, {
46
- ariaLabel: "View module info",
50
+ })), [row]);
51
+
52
+ if (!showHoverCard) {
53
+ return /*#__PURE__*/React.createElement("div", {
54
+ onMouseEnter: handleOnMouseEnter
55
+ }, content);
56
+ }
57
+
58
+ return /*#__PURE__*/React.createElement(HoverCard, {
47
59
  label: content
48
- }, _ref2 => {
49
- let {
50
- popoverToggle
51
- } = _ref2;
52
- return /*#__PURE__*/React.createElement(ModuleInfo, {
53
- className: css.namePopover,
54
- item: row,
55
- chunks: chunks,
56
- chunkIds: chunkIds,
57
- labels: labels,
58
- customComponentLink: CustomComponentLink,
59
- onClick: popoverToggle
60
- });
60
+ }, /*#__PURE__*/React.createElement(ModuleInfo, {
61
+ className: css.namePopover,
62
+ item: row,
63
+ chunks: chunks,
64
+ chunkIds: chunkIds,
65
+ labels: labels,
66
+ customComponentLink: CustomComponentLink
61
67
  }));
62
68
  };
63
69
 
64
70
  RowHeader.propTypes = {
65
71
  row: PropTypes.shape({
66
- label: PropTypes.string
72
+ label: PropTypes.string,
73
+ duplicated: PropTypes.bool
67
74
  }).isRequired,
68
75
  chunks: PropTypes.arrayOf(PropTypes.shape({
69
76
  id: PropTypes.string,
@@ -75,22 +82,7 @@ RowHeader.propTypes = {
75
82
  RowHeader.defaultProps = {
76
83
  chunks: []
77
84
  };
78
-
79
- const getRenderRowHeader = _ref3 => {
80
- let {
81
- labels,
82
- chunks,
83
- CustomComponentLink
84
- } = _ref3;
85
- return row => /*#__PURE__*/React.createElement(RowHeader, {
86
- row: row,
87
- chunks: chunks,
88
- labels: labels,
89
- CustomComponentLink: CustomComponentLink
90
- });
91
- };
92
-
93
- export const BundleModules = _ref4 => {
85
+ export const BundleModules = _ref2 => {
94
86
  let {
95
87
  className,
96
88
  jobs,
@@ -108,14 +100,14 @@ export const BundleModules = _ref4 => {
108
100
  updateSearch,
109
101
  hasActiveFilters,
110
102
  customComponentLink: CustomComponentLink
111
- } = _ref4;
103
+ } = _ref2;
112
104
  const rootClassName = cx(css.root, className);
113
- const labels = useMemo(() => _map(jobs, 'label'), [jobs]);
114
- const renderRowHeader = useMemo(() => getRenderRowHeader({
115
- labels,
116
- chunks,
117
- CustomComponentLink
118
- }), [labels, chunks]);
105
+ const renderRowHeader = useCallback(row => /*#__PURE__*/React.createElement(RowHeader, {
106
+ row: row,
107
+ chunks: chunks,
108
+ labels: _map(jobs, 'label'),
109
+ CustomComponentLink: CustomComponentLink
110
+ }), [jobs, chunks, CustomComponentLink]);
119
111
  const emptyMessage = /*#__PURE__*/React.createElement(EmptySet, {
120
112
  resources: "modules",
121
113
  filtered: totalRowCount !== 0,
@@ -128,6 +120,11 @@ export const BundleModules = _ref4 => {
128
120
  defaultValue: filters.changed,
129
121
  disabled: jobs.length <= 1
130
122
  },
123
+ [MODULE_FILTERS.DUPLICATED]: {
124
+ label: 'Duplicated',
125
+ defaultValue: filters[MODULE_FILTERS.DUPLICATED],
126
+ disabled: jobs.length <= 1
127
+ },
131
128
  [MODULE_SOURCE_TYPE]: {
132
129
  label: 'Source',
133
130
  [MODULE_FILTERS.FIRST_PARTY]: {
@@ -143,11 +140,11 @@ export const BundleModules = _ref4 => {
143
140
  ...(!_isEmpty(chunks) && {
144
141
  [MODULE_CHUNK]: {
145
142
  label: 'Chunk',
146
- ...chunks.reduce((chunkFilters, _ref5) => {
143
+ ...chunks.reduce((chunkFilters, _ref3) => {
147
144
  let {
148
145
  id,
149
146
  name
150
- } = _ref5;
147
+ } = _ref3;
151
148
  return { ...chunkFilters,
152
149
  [id]: {
153
150
  label: name,
@@ -172,10 +169,10 @@ export const BundleModules = _ref4 => {
172
169
  className: rootClassName
173
170
  }, /*#__PURE__*/React.createElement(Toolbar, {
174
171
  className: css.toolbar,
175
- renderActions: _ref6 => {
172
+ renderActions: _ref4 => {
176
173
  let {
177
174
  actionClassName
178
- } = _ref6;
175
+ } = _ref4;
179
176
  return /*#__PURE__*/React.createElement(FlexStack, {
180
177
  space: "xxsmall",
181
178
  className: cx(css.dropdown, actionClassName)
@@ -188,7 +185,9 @@ export const BundleModules = _ref4 => {
188
185
  handleResetFilters: resetFilters
189
186
  }));
190
187
  }
191
- }, /*#__PURE__*/React.createElement(FlexStack, null, /*#__PURE__*/React.createElement(MetricsTableSearch, {
188
+ }, /*#__PURE__*/React.createElement(FlexStack, {
189
+ space: "xxsmall"
190
+ }, /*#__PURE__*/React.createElement(MetricsTableSearch, {
192
191
  className: css.toolbarSearch,
193
192
  search: search,
194
193
  updateSearch: updateSearch,
@@ -12,6 +12,15 @@
12
12
  margin-right: -1px; /** collapse border */
13
13
  }
14
14
 
15
- .namePopover {
16
- min-width: 280px;
15
+ .nameTagDuplicated {
16
+ margin-right: var(--space-xxxsmall);
17
+ vertical-align: baseline;
18
+ }
19
+
20
+ .nameTagDuplicated::before {
21
+ content: 'D';
22
+ }
23
+
24
+ .nameText {
25
+ vertical-align: middle;
17
26
  }
@@ -7,12 +7,15 @@ import { MODULE_CHUNK, MODULE_FILTERS, MODULE_FILE_TYPE, MODULE_SOURCE_TYPE, get
7
7
  import { SORT_BY_NAME, SORT_BY_SIZE, SORT_BY_DELTA } from './bundle-modules.constants';
8
8
  export const addRowSourceFlag = row => {
9
9
  const {
10
- key
11
- } = row;
12
- const thirdParty = Boolean(key.match(MODULE_PATH_PACKAGES));
13
- return { ...row,
14
- thirdParty
15
- };
10
+ key,
11
+ runs
12
+ } = row; // @NOTE Assign instead destructuring for perf reasons
13
+ // eslint-disable-next-line no-param-reassign
14
+
15
+ row.thirdParty = Boolean(key.match(MODULE_PATH_PACKAGES)); // eslint-disable-next-line no-param-reassign
16
+
17
+ row.duplicated = Boolean(runs.find(run => (run == null ? void 0 : run.duplicated) === true));
18
+ return row;
16
19
  };
17
20
  export const getCustomSort = sortBy => item => {
18
21
  if (sortBy === SORT_BY_NAME) {
@@ -33,6 +36,11 @@ export const getRowFilter = filters => row => {
33
36
  // Skip not changed rows
34
37
  if (filters[MODULE_FILTERS.CHANGED] && !row.changed) {
35
38
  return false;
39
+ } // Skip not duplicated rows
40
+
41
+
42
+ if (filters[MODULE_FILTERS.DUPLICATED] && !row.duplicated) {
43
+ return false;
36
44
  } // Skip not matching source type
37
45
 
38
46
 
@@ -5,7 +5,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
5
5
 
6
6
  import React, { useMemo } from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { getModuleChunkFilters, getModuleSourceTypeFilters, getModuleFileTypeFilters } from '@bundle-stats/utils';
8
+ import { MODULE_FILTERS, getModuleChunkFilters, getModuleSourceTypeFilters, getModuleFileTypeFilters } from '@bundle-stats/utils';
9
9
  import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
10
10
  import { useRowsFilter } from '../../hooks/rows-filter';
11
11
  import { useRowsSort } from '../../hooks/rows-sort';
@@ -45,13 +45,15 @@ export const BundleModules = props => {
45
45
  changed: (jobs == null ? void 0 : jobs.length) > 1,
46
46
  ...getModuleSourceTypeFilters(true),
47
47
  ...getModuleChunkFilters(chunkIds, true),
48
- ...getModuleFileTypeFilters(true)
48
+ ...getModuleFileTypeFilters(true),
49
+ [MODULE_FILTERS.DUPLICATED]: false
49
50
  },
50
51
  allEntriesFilters: {
51
52
  changed: false,
52
53
  ...getModuleSourceTypeFilters(true),
53
54
  ...getModuleChunkFilters(chunkIds, true),
54
- ...getModuleFileTypeFilters(true)
55
+ ...getModuleFileTypeFilters(true),
56
+ [MODULE_FILTERS.DUPLICATED]: false
55
57
  }
56
58
  }), [jobs]);
57
59
  const searchParams = useSearchParams({