@bundle-stats/ui 4.3.0-beta.1 → 4.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.
Files changed (63) hide show
  1. package/lib/app/app.js +4 -5
  2. package/lib/app/app.js.map +1 -1
  3. package/lib/components/bundle-modules/bundle-modules.js +1 -2
  4. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  5. package/lib/components/bundle-modules/bundle-modules.module.css +4 -0
  6. package/lib/components/duplicate-packages-insight/duplicate-packages-insight.js +31 -0
  7. package/lib/components/duplicate-packages-insight/duplicate-packages-insight.js.map +1 -0
  8. package/lib/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
  9. package/lib/components/{duplicate-packages-warning → duplicate-packages-insight}/index.js +1 -1
  10. package/lib/components/duplicate-packages-insight/index.js.map +1 -0
  11. package/lib/components/index.js +3 -3
  12. package/lib/components/job-header/job-header.js +1 -1
  13. package/lib/components/job-header/job-header.js.map +1 -1
  14. package/lib/components/module-info/module-info.js +24 -16
  15. package/lib/components/module-info/module-info.js.map +1 -1
  16. package/lib/components/module-info/module-info.module.css +27 -8
  17. package/lib-esm/app/app.js +5 -5
  18. package/lib-esm/app/app.js.map +1 -1
  19. package/lib-esm/components/bundle-modules/bundle-modules.js +1 -2
  20. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  21. package/lib-esm/components/bundle-modules/bundle-modules.module.css +4 -0
  22. package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.js +24 -0
  23. package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.js.map +1 -0
  24. package/lib-esm/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
  25. package/lib-esm/components/duplicate-packages-insight/index.js +2 -0
  26. package/lib-esm/components/duplicate-packages-insight/index.js.map +1 -0
  27. package/lib-esm/components/index.js +1 -1
  28. package/lib-esm/components/job-header/job-header.js +2 -2
  29. package/lib-esm/components/job-header/job-header.js.map +1 -1
  30. package/lib-esm/components/module-info/module-info.js +25 -17
  31. package/lib-esm/components/module-info/module-info.js.map +1 -1
  32. package/lib-esm/components/module-info/module-info.module.css +27 -8
  33. package/package.json +7 -7
  34. package/src/app/app.jsx +7 -8
  35. package/src/components/bundle-modules/bundle-modules.jsx +11 -9
  36. package/src/components/bundle-modules/bundle-modules.module.css +4 -0
  37. package/src/components/duplicate-packages-insight/duplicate-packages-insight.module.css +18 -0
  38. package/src/components/duplicate-packages-insight/duplicate-packages-insight.stories.tsx +66 -0
  39. package/src/components/duplicate-packages-insight/duplicate-packages-insight.tsx +81 -0
  40. package/src/components/duplicate-packages-insight/index.ts +1 -0
  41. package/src/components/index.js +1 -1
  42. package/src/components/job-header/job-header.jsx +2 -2
  43. package/src/components/module-info/module-info.jsx +55 -25
  44. package/src/components/module-info/module-info.module.css +27 -8
  45. package/tsconfig.esm.json +1 -1
  46. package/tsconfig.lib.json +1 -1
  47. package/types/components/duplicate-packages-insight/duplicate-packages-insight.d.ts +11 -0
  48. package/types/components/duplicate-packages-insight/index.d.ts +1 -0
  49. package/types/components/index.d.ts +1 -1
  50. package/lib/components/duplicate-packages-warning/duplicate-packages-warning.js +0 -41
  51. package/lib/components/duplicate-packages-warning/duplicate-packages-warning.js.map +0 -1
  52. package/lib/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
  53. package/lib/components/duplicate-packages-warning/index.js.map +0 -1
  54. package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.js +0 -34
  55. package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.js.map +0 -1
  56. package/lib-esm/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
  57. package/lib-esm/components/duplicate-packages-warning/index.js +0 -2
  58. package/lib-esm/components/duplicate-packages-warning/index.js.map +0 -1
  59. package/src/components/duplicate-packages-warning/duplicate-packages-warning.jsx +0 -60
  60. package/src/components/duplicate-packages-warning/duplicate-packages-warning.module.css +0 -22
  61. package/src/components/duplicate-packages-warning/index.js +0 -1
  62. package/types/components/duplicate-packages-warning/duplicate-packages-warning.d.ts +0 -21
  63. package/types/components/duplicate-packages-warning/index.d.ts +0 -1
@@ -1,30 +1,38 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
3
4
  import isEmpty from 'lodash/isEmpty';
4
5
  import noop from 'lodash/noop';
5
- import { getBundleModulesByChunk } from '@bundle-stats/utils';
6
+ import { getBundleModulesByChunk, getBundleModulesBySearch } from '@bundle-stats/utils';
6
7
  import { Stack } from '../../layout/stack';
8
+ import { FlexStack } from '../../layout/flex-stack';
7
9
  import { FileName } from '../../ui/file-name';
10
+ import { Tag } from '../../ui/tag';
8
11
  import { ComponentLink } from '../component-link';
9
12
  import css from './module-info.module.css';
10
13
  export const ModuleInfo = (props) => {
11
14
  const { className, item, labels, chunks, chunkIds, customComponentLink: CustomComponentLink, onClick, } = props;
12
- return (React.createElement(Stack, { space: "xsmall", className: className }, item.runs.map((run, index) => {
13
- const TitleComponent = index !== 0 ? 'h4' : 'h3';
14
- const key = `module-info-${(run === null || run === void 0 ? void 0 : run.name) || index}-${index}`;
15
- return (React.createElement(Stack, { space: "xxxsmall", key: key },
16
- React.createElement(TitleComponent, null, labels[index]),
17
- index === 0 && !isEmpty(run === null || run === void 0 ? void 0 : run.chunkIds) && (React.createElement("div", { className: css.chunks },
18
- React.createElement("span", { className: css.chunksTitle }, "Chunks:"),
19
- run.chunkIds.map((chunkId) => {
20
- const chunk = chunks === null || chunks === void 0 ? void 0 : chunks.find(({ id }) => id === chunkId);
21
- if (!chunk) {
22
- return null;
23
- }
24
- return (React.createElement(CustomComponentLink, { ...getBundleModulesByChunk(chunkIds, chunkId), onClick: onClick, className: css.chunksItem }, chunk.name));
25
- }))),
26
- React.createElement(FileName, { className: css.fileName, as: "code", name: (run === null || run === void 0 ? void 0 : run.name) || '-' })));
27
- })));
15
+ return (React.createElement(Stack, { space: "small", className: cx(css.root, className) }, item.runs.map((run, index) => (React.createElement(Stack, { space: "xsmall", key: `module-info-${(run === null || run === void 0 ? void 0 : run.name) || index}-${index}`, className: css.run },
16
+ React.createElement(Stack, { space: "xxxsmall" },
17
+ React.createElement(FlexStack, { space: "xxxsmall", alignItems: "center", as: "h4", className: css.title },
18
+ React.createElement("span", null, labels[index]),
19
+ React.createElement(Tag, { className: css.titleTag }, index === 0 ? 'current' : 'baseline')),
20
+ React.createElement(FileName, { className: css.fileName, as: "code", name: (run === null || run === void 0 ? void 0 : run.name) || '-' })),
21
+ index === 0 && !isEmpty(run === null || run === void 0 ? void 0 : run.chunkIds) && (React.createElement(Stack, { className: css.chunks },
22
+ React.createElement("h5", null, "Chunks"),
23
+ React.createElement("ul", { className: css.list }, run.chunkIds.map((chunkId) => {
24
+ const chunk = chunks === null || chunks === void 0 ? void 0 : chunks.find(({ id }) => id === chunkId);
25
+ if (!chunk) {
26
+ return null;
27
+ }
28
+ return (React.createElement("li", null,
29
+ React.createElement(CustomComponentLink, { ...getBundleModulesByChunk(chunkIds, chunkId), onClick: onClick, className: css.chunksItem }, chunk.name)));
30
+ })))),
31
+ (run === null || run === void 0 ? void 0 : run.reasons) && (React.createElement(Stack, null,
32
+ React.createElement("h5", null, "Reasons"),
33
+ React.createElement("ul", { className: css.list }, run.reasons.map((reason) => (React.createElement("li", { key: reason },
34
+ React.createElement(CustomComponentLink, { ...getBundleModulesBySearch(`^${reason}$`), onClick: onClick, className: css.reasonLink },
35
+ React.createElement(FileName, { name: reason, className: css.reason })))))))))))));
28
36
  };
29
37
  ModuleInfo.propTypes = {
30
38
  className: PropTypes.string,
@@ -1 +1 @@
1
- {"version":3,"file":"module-info.js","sourceRoot":"","sources":["../../../src/components/module-info/module-info.jsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module-info.js","sourceRoot":"","sources":["../../../src/components/module-info/module-info.jsx"],"names":[],"mappings":"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"}
@@ -1,21 +1,40 @@
1
- .chunksTitle {
2
- margin-right: var(--space-xxxsmall);
1
+ .titleTag {
2
+ border: 1px solid var(--color-outline);
3
+ background: var(--color-highlight);
4
+ color: var(--color-text-light);
3
5
  }
4
6
 
5
- .chunksItems {
6
- display: inline;
7
+ .run:first-child .title {
8
+ font-size: var(--size-xlarge);
7
9
  }
8
10
 
9
11
  .chunksItem {
10
12
  overflow-wrap: break-word;
11
13
  }
12
14
 
13
- .chunksItem + .chunksItem {
14
- margin-left: var(--space-xxxsmall);
15
- }
16
-
17
15
  .fileName {
18
16
  max-width: 100%;
19
17
  padding: 2px;
20
18
  background: var(--color-highlight-warning);
21
19
  }
20
+
21
+ .reasonLink {
22
+ text-decoration: underline;
23
+ }
24
+
25
+ .reasonLink .reason {
26
+ text-decoration: inherit;
27
+ }
28
+
29
+ .reason {
30
+ display: inline;
31
+ }
32
+
33
+ .list {
34
+ padding: 0 0 0 var(--space-small);
35
+ list-style: outside;
36
+ }
37
+
38
+ .list li::marker {
39
+ color: var(--color-text-ultra-light);
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bundle-stats/ui",
3
- "version": "4.3.0-beta.1",
3
+ "version": "4.4.0-beta.0",
4
4
  "description": "UI components for BundleStats projects.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -51,7 +51,7 @@
51
51
  "@storybook/react": "6.5.15",
52
52
  "@types/react": "18.0.26",
53
53
  "babel-plugin-require-context-hook": "1.0.0",
54
- "chromatic": "6.14.0",
54
+ "chromatic": "6.15.0",
55
55
  "classnames": "2.3.2",
56
56
  "colormap": "2.3.2",
57
57
  "cross-env": "7.0.3",
@@ -60,9 +60,9 @@
60
60
  "enzyme-to-json": "3.6.2",
61
61
  "hex-rgb": "5.0.0",
62
62
  "identity-obj-proxy": "3.0.0",
63
- "jest": "29.3.1",
63
+ "jest": "29.4.0",
64
64
  "jest-date-mock": "1.0.8",
65
- "jest-environment-jsdom": "29.3.1",
65
+ "jest-environment-jsdom": "29.4.0",
66
66
  "lodash": "4.17.21",
67
67
  "postcss": "8.4.21",
68
68
  "prop-types": "15.8.1",
@@ -70,7 +70,7 @@
70
70
  "react-dom": "17.0.2",
71
71
  "react-router-dom": "5.3.4",
72
72
  "react-test-renderer": "18.2.0",
73
- "rimraf": "4.1.1",
73
+ "rimraf": "4.1.2",
74
74
  "typescript": "4.9.4"
75
75
  },
76
76
  "peerDependencies": {
@@ -82,11 +82,11 @@
82
82
  "react-router-dom": "^5.0.0"
83
83
  },
84
84
  "dependencies": {
85
- "@bundle-stats/utils": "^4.3.0-beta.1",
85
+ "@bundle-stats/utils": "^4.4.0-beta.0",
86
86
  "ariakit": "2.0.0-next.43",
87
87
  "modern-css-reset": "1.4.0",
88
88
  "query-string": "7.1.3",
89
89
  "use-query-params": "2.1.2"
90
90
  },
91
- "gitHead": "3f34b96d46d38d7324d9460fd19bc060786eb320"
91
+ "gitHead": "e2c2b5a9b7bd31c07baad4f5fefa682d21470600"
92
92
  }
package/src/app/app.jsx CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  } from '../constants';
13
13
  import { Box } from '../layout/box';
14
14
  import { Container } from '../ui/container';
15
- import { DuplicatePackagesWarning } from '../components/duplicate-packages-warning';
15
+ import { DuplicatePackagesInsight } from '../components/duplicate-packages-insight';
16
16
  import { Summary } from '../components/summary';
17
17
  import { BundleAssets } from '../components/bundle-assets';
18
18
  import { BundleAssetsTotalsChartBars } from '../components/bundle-assets-totals-chart-bars';
@@ -68,17 +68,16 @@ JobsProvider.propTypes = {
68
68
 
69
69
  const OverviewContent = () => {
70
70
  const { jobs } = useContext(JobsContext);
71
- const { duplicatePackagesCount } = jobs[0].summary.webpack;
72
- const duplicatePackagesInsights = Boolean(
73
- duplicatePackagesCount.current || duplicatePackagesCount.baseline,
74
- );
71
+ const duplicatePackagesInsight = jobs[0].insights?.webpack?.duplicatePackagesV3;
75
72
 
76
73
  return (
77
74
  <Stack space="medium">
78
- {duplicatePackagesInsights && (
75
+ {duplicatePackagesInsight && (
79
76
  <Container>
80
- <DuplicatePackagesWarning
81
- duplicatePackagesCount={duplicatePackagesCount}
77
+ <DuplicatePackagesInsight
78
+ type={duplicatePackagesInsight.type}
79
+ data={duplicatePackagesInsight.data}
80
+ summary={jobs[0].summary.webpack?.duplicatePackagesCount}
82
81
  showDelta={jobs.length > 1}
83
82
  />
84
83
  </Container>
@@ -107,15 +107,17 @@ const RowHeader = ({ row, chunks, labels, CustomComponentLink }) => {
107
107
  }
108
108
 
109
109
  return (
110
- <HoverCard label={content}>
111
- <ModuleInfo
112
- className={css.namePopover}
113
- item={row}
114
- chunks={chunks}
115
- chunkIds={chunkIds}
116
- labels={labels}
117
- customComponentLink={CustomComponentLink}
118
- />
110
+ <HoverCard label={content} hoverCardClassName={css.nameHoverCard}>
111
+ {({ close }) => (
112
+ <ModuleInfo
113
+ item={row}
114
+ chunks={chunks}
115
+ chunkIds={chunkIds}
116
+ labels={labels}
117
+ customComponentLink={CustomComponentLink}
118
+ onClick={close}
119
+ />
120
+ )}
119
121
  </HoverCard>
120
122
  );
121
123
  };
@@ -25,3 +25,7 @@
25
25
  display: inline;
26
26
  vertical-align: middle;
27
27
  }
28
+
29
+ .nameHoverCard {
30
+ max-width: 480px;
31
+ }
@@ -0,0 +1,18 @@
1
+ .metric {
2
+ font-weight: bold;
3
+ }
4
+
5
+ .metric::before,
6
+ .link::before {
7
+ content: '\00A0\2014\00A0';
8
+ font-weight: normal;
9
+ color: var(--color-text-ultra-light);
10
+ }
11
+
12
+ .delta {
13
+ margin-left: var(--space-xxxsmall);
14
+ padding: 1px 2px;
15
+ vertical-align: super;
16
+ font-size: 9px;
17
+ line-height: 1;
18
+ }
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import { MemoryRouter } from 'react-router-dom';
3
+ import { DuplicatePackagesInsight } from '.';
4
+
5
+ export default {
6
+ title: 'Components/DuplicatePackagesInsight',
7
+ component: DuplicatePackagesInsight,
8
+ };
9
+
10
+ const Template = (props: any) => <MemoryRouter><DuplicatePackagesInsight {...props} /></MemoryRouter>;
11
+
12
+ export const Default = Template.bind({});
13
+
14
+ Default.args = {
15
+ type: 'INFO',
16
+ data: {
17
+ packages: {},
18
+ text: 'Bundle does not contain duplicate packages',
19
+ },
20
+ summary: {
21
+ current: 0,
22
+ baseline: 0,
23
+ },
24
+ };
25
+
26
+ export const NewDuplicates = Template.bind({});
27
+
28
+ NewDuplicates.args = {
29
+ type: 'ERROR',
30
+ data: {
31
+ packages: {},
32
+ text: 'Bundle introduced 2 duplicate packages',
33
+ },
34
+ summary: {
35
+ current: 4,
36
+ baseline: 2,
37
+ },
38
+ };
39
+
40
+ export const NewDuplicatesAndRemovals = Template.bind({});
41
+
42
+ NewDuplicatesAndRemovals.args = {
43
+ type: 'ERROR',
44
+ data: {
45
+ packages: {},
46
+ text: 'Bundle introduced 2 and removed 1 duplicate packages',
47
+ },
48
+ summary: {
49
+ current: 4,
50
+ baseline: 3,
51
+ },
52
+ };
53
+
54
+ export const NoChangeDuplicates = Template.bind({});
55
+
56
+ NoChangeDuplicates.args = {
57
+ type: 'WARNING',
58
+ data: {
59
+ packages: {},
60
+ text: 'Bundle contains 4 duplicate packages',
61
+ },
62
+ summary: {
63
+ current: 4,
64
+ baseline: 4,
65
+ },
66
+ };
@@ -0,0 +1,81 @@
1
+ import React from 'react';
2
+ import {
3
+ BUNDLE_PACKAGES_DUPLICATE,
4
+ BUNDLE_PACKAGES_COUNT,
5
+ InsightType,
6
+ JobSummaryItem,
7
+ getMetricRunInfo,
8
+ JobInsightDuplicatePackagesV3Data,
9
+ getGlobalMetricType,
10
+ } from '@bundle-stats/utils';
11
+
12
+ import { Alert } from '../../ui/alert';
13
+ import { ComponentLink } from '../component-link';
14
+ import { Delta } from '../delta';
15
+ // @ts-ignore
16
+ import css from './duplicate-packages-insight.module.css';
17
+
18
+ interface DuplicatePackagesInsightProps extends React.HTMLAttributes<HTMLDivElement> {
19
+ type: InsightType;
20
+ data: JobInsightDuplicatePackagesV3Data;
21
+ summary: JobSummaryItem;
22
+ showDelta?: boolean;
23
+ customComponentLink?: React.FunctionComponent<React.HTMLAttributes<HTMLLinkElement>>;
24
+ }
25
+
26
+ const AlertKindMap = new Map([
27
+ [InsightType.INFO, 'info'],
28
+ [InsightType.ERROR, 'danger'],
29
+ [InsightType.WARNING, 'warning'],
30
+ ]);
31
+
32
+ export const DuplicatePackagesInsight = (props: DuplicatePackagesInsightProps) => {
33
+ const {
34
+ type,
35
+ data,
36
+ summary,
37
+ showDelta = true,
38
+ customComponentLink: CustomComponentLink = ComponentLink,
39
+ ...restProps
40
+ } = props;
41
+
42
+ const metric = getGlobalMetricType('webpack.duplicatePackageCount');
43
+
44
+ const metricRunInfo = getMetricRunInfo(
45
+ metric,
46
+ summary.current,
47
+ summary.baseline,
48
+ );
49
+
50
+ const hasDuplicatePackages = metricRunInfo.value > 0 || (metricRunInfo && (metricRunInfo.delta !== 0));
51
+
52
+ return (
53
+ <Alert kind={AlertKindMap.get(type)} {...restProps}>
54
+ <span className={css.message}>{data.text}</span>
55
+ {hasDuplicatePackages && (
56
+ <span className={css.metric}>
57
+ {metricRunInfo.value}
58
+ {showDelta && typeof metricRunInfo.delta !== 'undefined' && (
59
+ <Delta
60
+ className={css.delta}
61
+ inverted
62
+ displayValue={metricRunInfo.displayDelta as string}
63
+ deltaType={metricRunInfo.deltaType as string}
64
+ />
65
+ )}
66
+ </span>
67
+ )}
68
+ <span className={css.link}>
69
+ {hasDuplicatePackages ? (
70
+ <CustomComponentLink {...BUNDLE_PACKAGES_DUPLICATE as any}>
71
+ View duplicate packages
72
+ </CustomComponentLink>
73
+ ) : (
74
+ <CustomComponentLink {...BUNDLE_PACKAGES_COUNT as any}>
75
+ View packages
76
+ </CustomComponentLink>
77
+ )}
78
+ </span>
79
+ </Alert>
80
+ );
81
+ };
@@ -0,0 +1 @@
1
+ export * from './duplicate-packages-insight';
@@ -5,7 +5,7 @@ export { BundleAssetsTotalsChartBars } from './bundle-assets-totals-chart-bars';
5
5
  export { BundlePackages } from './bundle-packages';
6
6
  export { BundleModules } from './bundle-modules';
7
7
  export { ComponentLink } from './component-link';
8
- export { DuplicatePackagesWarning } from './duplicate-packages-warning';
8
+ export { DuplicatePackagesInsight } from './duplicate-packages-insight';
9
9
  export { Delta } from './delta';
10
10
  export { JobName } from './job-name';
11
11
  export { JobHeader } from './job-header';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import cx from 'classnames';
4
4
  import get from 'lodash/get';
5
- import { SOURCE_PATH_WEBPACK_STATS, formatDateTime } from '@bundle-stats/utils';
5
+ import { Source, formatDateTime } from '@bundle-stats/utils';
6
6
 
7
7
  import { FlexStack } from '../../layout/flex-stack';
8
8
  import { Stack } from '../../layout/stack';
@@ -13,7 +13,7 @@ import css from './job-header.module.css';
13
13
  export const JobHeader = (props) => {
14
14
  const { className, tag, job, children } = props;
15
15
 
16
- const { builtAt, hash } = get(job, `meta.${SOURCE_PATH_WEBPACK_STATS}`, {});
16
+ const { builtAt, hash } = get(job, `meta.${Source.webpack}`, {});
17
17
  const rootClassName = cx(css.root, className);
18
18
 
19
19
  return (
@@ -1,11 +1,14 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
3
4
  import isEmpty from 'lodash/isEmpty';
4
5
  import noop from 'lodash/noop';
5
- import { getBundleModulesByChunk } from '@bundle-stats/utils';
6
+ import { getBundleModulesByChunk, getBundleModulesBySearch } from '@bundle-stats/utils';
6
7
 
7
8
  import { Stack } from '../../layout/stack';
9
+ import { FlexStack } from '../../layout/flex-stack';
8
10
  import { FileName } from '../../ui/file-name';
11
+ import { Tag } from '../../ui/tag';
9
12
  import { ComponentLink } from '../component-link';
10
13
  import css from './module-info.module.css';
11
14
 
@@ -21,25 +24,34 @@ export const ModuleInfo = (props) => {
21
24
  } = props;
22
25
 
23
26
  return (
24
- <Stack space="xsmall" className={className}>
25
- {item.runs.map((run, index) => {
26
- const TitleComponent = index !== 0 ? 'h4' : 'h3';
27
- const key = `module-info-${run?.name || index}-${index}`;
27
+ <Stack space="small" className={cx(css.root, className)}>
28
+ {item.runs.map((run, index) => (
29
+ <Stack space="xsmall" key={`module-info-${run?.name || index}-${index}`} className={css.run}>
30
+ <Stack space="xxxsmall">
31
+ <FlexStack space="xxxsmall" alignItems="center" as="h4" className={css.title}>
32
+ <span>{labels[index]}</span>
33
+ <Tag className={css.titleTag}>{index === 0 ? 'current' : 'baseline'}</Tag>
34
+ </FlexStack>
35
+ <FileName className={css.fileName} as="code" name={run?.name || '-'} />
36
+ </Stack>
28
37
 
29
- return (
30
- <Stack space="xxxsmall" key={key}>
31
- <TitleComponent>{labels[index]}</TitleComponent>
32
- {index === 0 && !isEmpty(run?.chunkIds) && (
33
- <div className={css.chunks}>
34
- <span className={css.chunksTitle}>Chunks:</span>
35
- {run.chunkIds.map((chunkId) => {
36
- const chunk = chunks?.find(({ id }) => id === chunkId);
38
+ {/**
39
+ * Render chunks only for the current run
40
+ * we do not have the correct chunk ids for baselines
41
+ */}
42
+ {index === 0 && !isEmpty(run?.chunkIds) && (
43
+ <Stack className={css.chunks}>
44
+ <h5>Chunks</h5>
45
+ <ul className={css.list}>
46
+ {run.chunkIds.map((chunkId) => {
47
+ const chunk = chunks?.find(({ id }) => id === chunkId);
37
48
 
38
- if (!chunk) {
39
- return null;
40
- }
49
+ if (!chunk) {
50
+ return null;
51
+ }
41
52
 
42
- return (
53
+ return (
54
+ <li>
43
55
  <CustomComponentLink
44
56
  {...getBundleModulesByChunk(chunkIds, chunkId)}
45
57
  onClick={onClick}
@@ -47,15 +59,33 @@ export const ModuleInfo = (props) => {
47
59
  >
48
60
  {chunk.name}
49
61
  </CustomComponentLink>
50
- );
51
- })}
52
- </div>
53
- )}
62
+ </li>
63
+ );
64
+ })}
65
+ </ul>
66
+ </Stack>
67
+ )}
54
68
 
55
- <FileName className={css.fileName} as="code" name={run?.name || '-'} />
56
- </Stack>
57
- );
58
- })}
69
+ {run?.reasons && (
70
+ <Stack>
71
+ <h5>Reasons</h5>
72
+ <ul className={css.list}>
73
+ {run.reasons.map((reason) => (
74
+ <li key={reason}>
75
+ <CustomComponentLink
76
+ {...getBundleModulesBySearch(`^${reason}$`)}
77
+ onClick={onClick}
78
+ className={css.reasonLink}
79
+ >
80
+ <FileName name={reason} className={css.reason} />
81
+ </CustomComponentLink>
82
+ </li>
83
+ ))}
84
+ </ul>
85
+ </Stack>
86
+ )}
87
+ </Stack>
88
+ ))}
59
89
  </Stack>
60
90
  );
61
91
  };
@@ -1,21 +1,40 @@
1
- .chunksTitle {
2
- margin-right: var(--space-xxxsmall);
1
+ .titleTag {
2
+ border: 1px solid var(--color-outline);
3
+ background: var(--color-highlight);
4
+ color: var(--color-text-light);
3
5
  }
4
6
 
5
- .chunksItems {
6
- display: inline;
7
+ .run:first-child .title {
8
+ font-size: var(--size-xlarge);
7
9
  }
8
10
 
9
11
  .chunksItem {
10
12
  overflow-wrap: break-word;
11
13
  }
12
14
 
13
- .chunksItem + .chunksItem {
14
- margin-left: var(--space-xxxsmall);
15
- }
16
-
17
15
  .fileName {
18
16
  max-width: 100%;
19
17
  padding: 2px;
20
18
  background: var(--color-highlight-warning);
21
19
  }
20
+
21
+ .reasonLink {
22
+ text-decoration: underline;
23
+ }
24
+
25
+ .reasonLink .reason {
26
+ text-decoration: inherit;
27
+ }
28
+
29
+ .reason {
30
+ display: inline;
31
+ }
32
+
33
+ .list {
34
+ padding: 0 0 0 var(--space-small);
35
+ list-style: outside;
36
+ }
37
+
38
+ .list li::marker {
39
+ color: var(--color-text-ultra-light);
40
+ }
package/tsconfig.esm.json CHANGED
@@ -9,5 +9,5 @@
9
9
  "declarationDir": "./types",
10
10
  "noEmit": false
11
11
  },
12
- "exclude": ["**/__tests__/*", "**/*.stories.jsx"]
12
+ "exclude": ["**/__tests__/*", "**/*.stories.*"]
13
13
  }
package/tsconfig.lib.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "resolveJsonModule": true,
6
6
  "noEmit": false
7
7
  },
8
- "exclude": ["**/__tests__/*", "**/*.stories.jsx"]
8
+ "exclude": ["**/__tests__/*", "**/*.stories.*"]
9
9
  }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { InsightType, JobSummaryItem, JobInsightDuplicatePackagesV3Data } from '@bundle-stats/utils';
3
+ interface DuplicatePackagesInsightProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ type: InsightType;
5
+ data: JobInsightDuplicatePackagesV3Data;
6
+ summary: JobSummaryItem;
7
+ showDelta?: boolean;
8
+ customComponentLink?: React.FunctionComponent<React.HTMLAttributes<HTMLLinkElement>>;
9
+ }
10
+ export declare const DuplicatePackagesInsight: (props: DuplicatePackagesInsightProps) => JSX.Element;
11
+ export {};
@@ -0,0 +1 @@
1
+ export * from './duplicate-packages-insight';
@@ -5,7 +5,7 @@ export { BundleAssetsTotalsChartBars } from "./bundle-assets-totals-chart-bars";
5
5
  export { BundlePackages } from "./bundle-packages";
6
6
  export { BundleModules } from "./bundle-modules";
7
7
  export { ComponentLink } from "./component-link";
8
- export { DuplicatePackagesWarning } from "./duplicate-packages-warning";
8
+ export { DuplicatePackagesInsight } from "./duplicate-packages-insight";
9
9
  export { Delta } from "./delta";
10
10
  export { JobName } from "./job-name";
11
11
  export { JobHeader } from "./job-header";