@bundle-stats/ui 4.17.0 → 4.18.0-beta.1
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/components/asset-info/asset-info.i18n.js +11 -0
- package/lib/components/asset-info/asset-info.i18n.js.map +1 -0
- package/lib/components/asset-info/asset-info.js +16 -16
- package/lib/components/asset-info/asset-info.js.map +1 -1
- package/lib/components/bundle-assets/bundle-assets.i18n.js +9 -1
- package/lib/components/bundle-assets/bundle-assets.i18n.js.map +1 -1
- package/lib/components/bundle-assets/bundle-assets.js +9 -112
- package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib/components/bundle-assets/bundle-assets.utils.js +136 -23
- package/lib/components/bundle-assets/bundle-assets.utils.js.map +1 -1
- package/lib/components/bundle-assets/index.js +8 -26
- package/lib/components/bundle-assets/index.js.map +1 -1
- package/lib/components/metrics-table/metrics-table.js.map +1 -1
- package/lib/components/metrics-table-header/metrics-table-header.js.map +1 -1
- package/lib/hooks/rows-sort.js +14 -2
- package/lib/hooks/rows-sort.js.map +1 -1
- package/lib/hooks/search-params.js.map +1 -1
- package/lib-esm/components/asset-info/asset-info.i18n.js +8 -0
- package/lib-esm/components/asset-info/asset-info.i18n.js.map +1 -0
- package/lib-esm/components/asset-info/asset-info.js +17 -17
- package/lib-esm/components/asset-info/asset-info.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.i18n.js +8 -0
- package/lib-esm/components/bundle-assets/bundle-assets.i18n.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.js +10 -113
- package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.utils.js +111 -22
- package/lib-esm/components/bundle-assets/bundle-assets.utils.js.map +1 -1
- package/lib-esm/components/bundle-assets/index.js +9 -24
- package/lib-esm/components/bundle-assets/index.js.map +1 -1
- package/lib-esm/components/metrics-table/metrics-table.js.map +1 -1
- package/lib-esm/components/metrics-table-header/metrics-table-header.js.map +1 -1
- package/lib-esm/hooks/rows-sort.js +14 -2
- package/lib-esm/hooks/rows-sort.js.map +1 -1
- package/lib-esm/hooks/search-params.js.map +1 -1
- package/package.json +3 -3
- package/src/components/asset-info/asset-info.i18n.ts +7 -0
- package/src/components/asset-info/asset-info.tsx +36 -38
- package/src/components/bundle-assets/__tests__/add-metric-report-asset-row-data.ts +2 -2
- package/src/components/bundle-assets/bundle-assets.i18n.ts +8 -0
- package/src/components/bundle-assets/bundle-assets.stories.tsx +99 -0
- package/src/components/bundle-assets/{bundle-assets.jsx → bundle-assets.tsx} +67 -149
- package/src/components/bundle-assets/bundle-assets.utils.ts +276 -0
- package/src/components/bundle-assets/{index.jsx → index.tsx} +43 -29
- package/src/components/metrics-table/metrics-table.tsx +3 -3
- package/src/components/metrics-table-header/metrics-table-header.tsx +4 -4
- package/src/components/sort-button/sort-button.tsx +1 -1
- package/src/hooks/rows-sort.ts +21 -3
- package/src/hooks/search-params.js +0 -1
- package/src/types.d.ts +5 -1
- package/types/components/asset-info/asset-info.d.ts +4 -13
- package/types/components/asset-info/asset-info.i18n.d.ts +7 -0
- package/types/components/bundle-assets/bundle-assets.d.ts +24 -55
- package/types/components/bundle-assets/bundle-assets.i18n.d.ts +8 -0
- package/types/components/bundle-assets/bundle-assets.utils.d.ts +17 -5
- package/types/components/bundle-assets/index.d.ts +10 -22
- package/types/components/metrics-table/metrics-table.d.ts +3 -2
- package/types/components/metrics-table-header/metrics-table-header.d.ts +1 -2
- package/types/components/sort-button/sort-button.d.ts +1 -2
- package/types/hooks/rows-sort.d.ts +1 -1
- package/src/components/bundle-assets/bundle-assets.utils.js +0 -149
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import type { ElementType, ReactNode } from 'react';
|
|
2
|
+
import React, { ComponentProps, useCallback, useMemo, useState } from 'react';
|
|
3
3
|
import cx from 'classnames';
|
|
4
|
-
import get from 'lodash/get';
|
|
5
4
|
import escapeRegExp from 'lodash/escapeRegExp';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
ASSET_FILE_TYPE,
|
|
9
|
-
ASSET_FILTERS,
|
|
10
|
-
COMPONENT,
|
|
11
|
-
FILE_TYPE_LABELS,
|
|
12
|
-
SECTIONS,
|
|
13
|
-
} from '@bundle-stats/utils';
|
|
5
|
+
import type { Job, ReportMetricRow, WebpackChunk } from '@bundle-stats/utils';
|
|
6
|
+
import { COMPONENT, SECTIONS } from '@bundle-stats/utils';
|
|
14
7
|
|
|
8
|
+
import type { ReportMetricAssetRow, SortAction } from '../../types';
|
|
15
9
|
import config from '../../config.json';
|
|
16
10
|
import I18N from '../../i18n';
|
|
17
11
|
import { MetricsDisplayType } from '../../constants';
|
|
@@ -26,6 +20,7 @@ import { Filters } from '../../ui/filters';
|
|
|
26
20
|
import { EmptySet } from '../../ui/empty-set';
|
|
27
21
|
import { Toolbar } from '../../ui/toolbar';
|
|
28
22
|
import { AssetInfo } from '../asset-info';
|
|
23
|
+
import { AssetName } from '../asset-name';
|
|
29
24
|
import { ComponentLink } from '../component-link';
|
|
30
25
|
import { MetricsTable } from '../metrics-table';
|
|
31
26
|
import { MetricsTableExport } from '../metrics-table-export';
|
|
@@ -34,59 +29,26 @@ import { MetricsTableTitle } from '../metrics-table-title';
|
|
|
34
29
|
import { MetricsDisplaySelector } from '../metrics-display-selector';
|
|
35
30
|
import { MetricsTableHeader } from '../metrics-table-header';
|
|
36
31
|
import { MetricsTreemap, getTreemapNodes, getTreemapNodesGroupedByPath } from '../metrics-treemap';
|
|
37
|
-
import
|
|
32
|
+
import * as BUNDLE_ASSETS_I18N from './bundle-assets.i18n';
|
|
33
|
+
import { getFilters } from './bundle-assets.utils';
|
|
38
34
|
import css from './bundle-assets.module.css';
|
|
39
|
-
import { AssetName } from '../asset-name';
|
|
40
35
|
|
|
41
36
|
const DISPLAY_TYPE_GROUPS = {
|
|
42
37
|
[MetricsDisplayType.TREEMAP]: ['folder'],
|
|
43
38
|
};
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
defaultValue: filters[ASSET_FILTERS.CHANGED],
|
|
56
|
-
disabled: !compareMode,
|
|
57
|
-
},
|
|
58
|
-
[ASSET_ENTRY_TYPE]: {
|
|
59
|
-
label: 'Type',
|
|
60
|
-
children: [
|
|
61
|
-
{
|
|
62
|
-
key: ASSET_FILTERS.ENTRY,
|
|
63
|
-
label: 'Entry',
|
|
64
|
-
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`, true),
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
key: ASSET_FILTERS.INITIAL,
|
|
68
|
-
label: 'Initial',
|
|
69
|
-
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`, true),
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
key: ASSET_FILTERS.CHUNK,
|
|
73
|
-
label: 'Chunk',
|
|
74
|
-
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`, true),
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
key: ASSET_FILTERS.OTHER,
|
|
78
|
-
label: 'Other',
|
|
79
|
-
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`, true),
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
[ASSET_FILE_TYPE]: {
|
|
84
|
-
label: 'File type',
|
|
85
|
-
children: getFileTypeFilters(filters),
|
|
86
|
-
},
|
|
87
|
-
});
|
|
40
|
+
interface ViewMetricsTreemapProps {
|
|
41
|
+
metricsTableTitle: ReactNode;
|
|
42
|
+
jobs: Array<Job>;
|
|
43
|
+
items: Array<ReportMetricAssetRow>;
|
|
44
|
+
displayType: { value: MetricsDisplayType; groupBy?: string };
|
|
45
|
+
emptyMessage: ReactNode;
|
|
46
|
+
showEntryInfo: (entryId: string) => void;
|
|
47
|
+
updateSearch: (search: string) => void;
|
|
48
|
+
search: string;
|
|
49
|
+
}
|
|
88
50
|
|
|
89
|
-
const ViewMetricsTreemap = (props) => {
|
|
51
|
+
const ViewMetricsTreemap = (props: ViewMetricsTreemapProps) => {
|
|
90
52
|
const {
|
|
91
53
|
metricsTableTitle,
|
|
92
54
|
jobs,
|
|
@@ -109,7 +71,7 @@ const ViewMetricsTreemap = (props) => {
|
|
|
109
71
|
|
|
110
72
|
// Search based on the group path on group title click
|
|
111
73
|
const onGroupClick = useCallback(
|
|
112
|
-
(groupPath) => {
|
|
74
|
+
(groupPath: string) => {
|
|
113
75
|
// Clear seach when groupPath is emty (root)
|
|
114
76
|
if (groupPath === '') {
|
|
115
77
|
updateSearch('');
|
|
@@ -147,22 +109,29 @@ const ViewMetricsTreemap = (props) => {
|
|
|
147
109
|
);
|
|
148
110
|
};
|
|
149
111
|
|
|
150
|
-
|
|
151
|
-
jobs:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
112
|
+
export interface BundleAssetsProps extends ComponentProps<typeof Stack> {
|
|
113
|
+
jobs: Array<Job>;
|
|
114
|
+
chunks: Array<WebpackChunk>;
|
|
115
|
+
items: Array<ReportMetricAssetRow>;
|
|
116
|
+
allItems: Array<ReportMetricAssetRow>;
|
|
117
|
+
filters: Record<string, boolean>;
|
|
118
|
+
updateFilters: (newFilters: Record<string, boolean>) => void;
|
|
119
|
+
resetFilters: () => void;
|
|
120
|
+
resetAllFilters: () => void;
|
|
121
|
+
totalRowCount?: number;
|
|
122
|
+
entryId?: string;
|
|
123
|
+
sort: SortAction;
|
|
124
|
+
updateSort: (params: SortAction) => void;
|
|
125
|
+
search: string;
|
|
126
|
+
updateSearch: (search: string) => void;
|
|
127
|
+
customComponentLink?: ElementType;
|
|
128
|
+
hideEntryInfo: () => void;
|
|
129
|
+
showEntryInfo: (entryId: string) => void;
|
|
130
|
+
}
|
|
162
131
|
|
|
163
|
-
export const BundleAssets = (props) => {
|
|
132
|
+
export const BundleAssets = (props: BundleAssetsProps) => {
|
|
164
133
|
const {
|
|
165
|
-
className,
|
|
134
|
+
className = '',
|
|
166
135
|
jobs,
|
|
167
136
|
chunks,
|
|
168
137
|
items,
|
|
@@ -170,15 +139,14 @@ export const BundleAssets = (props) => {
|
|
|
170
139
|
updateFilters,
|
|
171
140
|
resetFilters,
|
|
172
141
|
resetAllFilters,
|
|
173
|
-
totalRowCount,
|
|
142
|
+
totalRowCount = 0,
|
|
174
143
|
filters,
|
|
175
|
-
entryId,
|
|
176
|
-
hasActiveFilters,
|
|
144
|
+
entryId = '',
|
|
177
145
|
sort,
|
|
178
146
|
updateSort,
|
|
179
147
|
search,
|
|
180
148
|
updateSearch,
|
|
181
|
-
customComponentLink: CustomComponentLink,
|
|
149
|
+
customComponentLink: CustomComponentLink = ComponentLink,
|
|
182
150
|
hideEntryInfo,
|
|
183
151
|
showEntryInfo,
|
|
184
152
|
} = props;
|
|
@@ -187,9 +155,9 @@ export const BundleAssets = (props) => {
|
|
|
187
155
|
|
|
188
156
|
const [displayType, setDisplayType] = useMetricsDisplayType(DISPLAY_TYPE_GROUPS);
|
|
189
157
|
|
|
190
|
-
const
|
|
191
|
-
() => getFilters({ compareMode: jobs?.length > 1, filters }),
|
|
192
|
-
[jobs, filters],
|
|
158
|
+
const filterFieldsData = useMemo(
|
|
159
|
+
() => getFilters({ compareMode: jobs?.length > 1, filters, chunks }),
|
|
160
|
+
[jobs, filters, chunks],
|
|
193
161
|
);
|
|
194
162
|
|
|
195
163
|
const metricsTableTitle = useMemo(
|
|
@@ -205,7 +173,10 @@ export const BundleAssets = (props) => {
|
|
|
205
173
|
);
|
|
206
174
|
|
|
207
175
|
const EntryComponentLink = useCallback(
|
|
208
|
-
({
|
|
176
|
+
({
|
|
177
|
+
entryId: assetEntryId,
|
|
178
|
+
...assetNameRestProps
|
|
179
|
+
}: { entryId: string } & ComponentProps<typeof CustomComponentLink>) => (
|
|
209
180
|
<CustomComponentLink
|
|
210
181
|
section={SECTIONS.ASSETS}
|
|
211
182
|
params={{
|
|
@@ -224,8 +195,12 @@ export const BundleAssets = (props) => {
|
|
|
224
195
|
);
|
|
225
196
|
|
|
226
197
|
const renderRowHeader = useCallback(
|
|
227
|
-
(row) => (
|
|
228
|
-
<AssetName
|
|
198
|
+
(row: ReportMetricRow) => (
|
|
199
|
+
<AssetName
|
|
200
|
+
row={row as ReportMetricAssetRow}
|
|
201
|
+
EntryComponentLink={EntryComponentLink}
|
|
202
|
+
className={css.assetName}
|
|
203
|
+
/>
|
|
229
204
|
),
|
|
230
205
|
[EntryComponentLink],
|
|
231
206
|
);
|
|
@@ -251,12 +226,15 @@ export const BundleAssets = (props) => {
|
|
|
251
226
|
}, [allItems, entryId]);
|
|
252
227
|
|
|
253
228
|
const exportDialog = useDialogState();
|
|
254
|
-
const [exportSourceType, setExportSourceType] = useState(
|
|
229
|
+
const [exportSourceType, setExportSourceType] = useState<string>();
|
|
255
230
|
|
|
256
|
-
const handleExportClick = useCallback(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
231
|
+
const handleExportClick = useCallback(
|
|
232
|
+
(sourceType: string) => {
|
|
233
|
+
setExportSourceType(sourceType);
|
|
234
|
+
exportDialog.toggle();
|
|
235
|
+
},
|
|
236
|
+
[exportDialog, setExportSourceType],
|
|
237
|
+
);
|
|
260
238
|
|
|
261
239
|
return (
|
|
262
240
|
<>
|
|
@@ -281,14 +259,13 @@ export const BundleAssets = (props) => {
|
|
|
281
259
|
<FlexStack space="xxsmall">
|
|
282
260
|
<InputSearch
|
|
283
261
|
className={css.toolbarSearch}
|
|
284
|
-
placeholder={SEARCH_PLACEHOLDER}
|
|
262
|
+
placeholder={BUNDLE_ASSETS_I18N.SEARCH_PLACEHOLDER}
|
|
285
263
|
defaultValue={search}
|
|
286
264
|
onChange={updateSearch}
|
|
287
265
|
/>
|
|
288
266
|
<Filters
|
|
289
267
|
className={css.toolbarFilters}
|
|
290
|
-
filters={
|
|
291
|
-
hasActiveFilters={hasActiveFilters}
|
|
268
|
+
filters={filterFieldsData}
|
|
292
269
|
onChange={updateFilters}
|
|
293
270
|
/>
|
|
294
271
|
</FlexStack>
|
|
@@ -344,62 +321,3 @@ export const BundleAssets = (props) => {
|
|
|
344
321
|
</>
|
|
345
322
|
);
|
|
346
323
|
};
|
|
347
|
-
|
|
348
|
-
BundleAssets.defaultProps = {
|
|
349
|
-
className: '',
|
|
350
|
-
totalRowCount: 0,
|
|
351
|
-
hasActiveFilters: false,
|
|
352
|
-
customComponentLink: ComponentLink,
|
|
353
|
-
entryId: '',
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
BundleAssets.propTypes = {
|
|
357
|
-
className: PropTypes.string,
|
|
358
|
-
jobs: PropTypes.arrayOf(
|
|
359
|
-
PropTypes.shape({
|
|
360
|
-
internalBuildNumber: PropTypes.number,
|
|
361
|
-
label: PropTypes.string,
|
|
362
|
-
}),
|
|
363
|
-
).isRequired,
|
|
364
|
-
chunks: PropTypes.arrayOf({
|
|
365
|
-
id: PropTypes.string,
|
|
366
|
-
name: PropTypes.string,
|
|
367
|
-
}).isRequired,
|
|
368
|
-
items: PropTypes.arrayOf(
|
|
369
|
-
PropTypes.shape({
|
|
370
|
-
key: PropTypes.string,
|
|
371
|
-
label: PropTypes.string,
|
|
372
|
-
runs: PropTypes.arrayOf(
|
|
373
|
-
PropTypes.shape({
|
|
374
|
-
displayValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
375
|
-
displayDelta: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
376
|
-
}),
|
|
377
|
-
),
|
|
378
|
-
}),
|
|
379
|
-
).isRequired,
|
|
380
|
-
updateFilters: PropTypes.func.isRequired,
|
|
381
|
-
resetFilters: PropTypes.func.isRequired,
|
|
382
|
-
resetAllFilters: PropTypes.func.isRequired,
|
|
383
|
-
totalRowCount: PropTypes.number,
|
|
384
|
-
filters: PropTypes.shape({
|
|
385
|
-
changed: PropTypes.bool,
|
|
386
|
-
id: PropTypes.string,
|
|
387
|
-
}).isRequired,
|
|
388
|
-
entryId: PropTypes.string,
|
|
389
|
-
hasActiveFilters: PropTypes.bool,
|
|
390
|
-
search: PropTypes.string.isRequired,
|
|
391
|
-
updateSearch: PropTypes.func.isRequired,
|
|
392
|
-
sort: PropTypes.shape({
|
|
393
|
-
field: PropTypes.string,
|
|
394
|
-
direction: PropTypes.string,
|
|
395
|
-
}).isRequired,
|
|
396
|
-
updateSort: PropTypes.func.isRequired,
|
|
397
|
-
allItems: PropTypes.arrayOf(
|
|
398
|
-
PropTypes.shape({
|
|
399
|
-
key: PropTypes.string,
|
|
400
|
-
}),
|
|
401
|
-
).isRequired,
|
|
402
|
-
customComponentLink: PropTypes.elementType,
|
|
403
|
-
hideEntryInfo: PropTypes.func.isRequired,
|
|
404
|
-
showEntryInfo: PropTypes.func.isRequired,
|
|
405
|
-
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import intersection from 'lodash/intersection';
|
|
3
|
+
import isEmpty from 'lodash/isEmpty';
|
|
4
|
+
import orderBy from 'lodash/orderBy';
|
|
5
|
+
import type { ReportMetricRow, WebpackChunk } from '@bundle-stats/utils';
|
|
6
|
+
import type { AssetMetricRun } from '@bundle-stats/utils/types/webpack';
|
|
7
|
+
import {
|
|
8
|
+
ASSET_CHUNK,
|
|
9
|
+
ASSET_ENTRY_TYPE,
|
|
10
|
+
ASSET_FILE_TYPE,
|
|
11
|
+
ASSET_FILTERS,
|
|
12
|
+
FILE_TYPE_LABELS,
|
|
13
|
+
getFileType,
|
|
14
|
+
} from '@bundle-stats/utils';
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
FilterFieldsData,
|
|
18
|
+
ReportMetricAssetRow,
|
|
19
|
+
ReportMetricAssetRowMetaStatus,
|
|
20
|
+
FilterGroupFieldData,
|
|
21
|
+
} from '../../types';
|
|
22
|
+
import * as I18N from './bundle-assets.i18n';
|
|
23
|
+
|
|
24
|
+
const NO_CHUNK_FILTER = 'NO_CHUNK';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check if the asset cache is not predictive
|
|
28
|
+
*/
|
|
29
|
+
export const getIsNotPredictive = (row: ReportMetricRow): boolean => {
|
|
30
|
+
const { key, runs } = row;
|
|
31
|
+
|
|
32
|
+
return runs.reduce((agg, run, index) => {
|
|
33
|
+
if (agg) {
|
|
34
|
+
return agg;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (index + 1 === runs.length) {
|
|
38
|
+
return agg;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const preRun = runs[index + 1];
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
run &&
|
|
45
|
+
preRun &&
|
|
46
|
+
key !== run.name &&
|
|
47
|
+
run.name === preRun.name &&
|
|
48
|
+
run.value !== preRun.value
|
|
49
|
+
) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return agg;
|
|
54
|
+
}, false);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Return asset meta status
|
|
59
|
+
*/
|
|
60
|
+
export const getAssetMetaStatus = (
|
|
61
|
+
values: Array<boolean | undefined>,
|
|
62
|
+
): ReportMetricAssetRowMetaStatus | boolean => {
|
|
63
|
+
if (!values.includes(true)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// filter empty runs
|
|
68
|
+
const metaValues = values.filter((value) => typeof value !== 'undefined');
|
|
69
|
+
|
|
70
|
+
const current = metaValues[0];
|
|
71
|
+
const metaValuesLength = metaValues.length;
|
|
72
|
+
|
|
73
|
+
if (metaValuesLength === 1) {
|
|
74
|
+
return Boolean(current);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const baseline = metaValues[metaValuesLength - 1];
|
|
78
|
+
|
|
79
|
+
if (current && !baseline) {
|
|
80
|
+
return 'added';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!current && baseline) {
|
|
84
|
+
return 'removed';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return true;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Add asset row flags
|
|
92
|
+
*/
|
|
93
|
+
export const addMetricReportAssetRowData = (row: ReportMetricRow): ReportMetricAssetRow => {
|
|
94
|
+
const { changed, runs } = row;
|
|
95
|
+
|
|
96
|
+
// Collect meta for each run
|
|
97
|
+
const runsEntry: Array<boolean | undefined> = [];
|
|
98
|
+
const runsInitial: Array<boolean | undefined> = [];
|
|
99
|
+
const runsChunk: Array<boolean | undefined> = [];
|
|
100
|
+
|
|
101
|
+
(runs as Array<AssetMetricRun | null>).forEach((run) => {
|
|
102
|
+
runsEntry.push(run?.isEntry);
|
|
103
|
+
runsInitial.push(run?.isInitial);
|
|
104
|
+
runsChunk.push(run?.isChunk);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const isEntry = getAssetMetaStatus(runsEntry);
|
|
108
|
+
const isInitial = getAssetMetaStatus(runsInitial);
|
|
109
|
+
const isChunk = getAssetMetaStatus(runsChunk);
|
|
110
|
+
const isAsset = !(isEntry || isInitial || isChunk);
|
|
111
|
+
const isNotPredictive = getIsNotPredictive(row);
|
|
112
|
+
const fileType = getFileType(row.key);
|
|
113
|
+
|
|
114
|
+
// Flag asset as changed if name and value are identical, if one of the meta tags is changed
|
|
115
|
+
const assetChanged =
|
|
116
|
+
changed ||
|
|
117
|
+
typeof isEntry !== 'boolean' ||
|
|
118
|
+
typeof isInitial !== 'boolean' ||
|
|
119
|
+
typeof isChunk !== 'boolean';
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
...row,
|
|
123
|
+
changed: assetChanged,
|
|
124
|
+
isEntry,
|
|
125
|
+
isInitial,
|
|
126
|
+
isChunk,
|
|
127
|
+
isAsset,
|
|
128
|
+
isNotPredictive,
|
|
129
|
+
fileType,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
type GenerateGetRowFilterOptions = {
|
|
134
|
+
chunkIds: Array<string>;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const getCustomSort = (item: ReportMetricAssetRow): Array<boolean | string> => [
|
|
138
|
+
!item.isNotPredictive,
|
|
139
|
+
!item.changed,
|
|
140
|
+
!item.isInitial,
|
|
141
|
+
!item.isEntry,
|
|
142
|
+
!item.isChunk,
|
|
143
|
+
item.key,
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
/* eslint-disable prettier/prettier */
|
|
147
|
+
const getFileTypeFilters = (filters: Record<string, unknown>): FilterGroupFieldData['children'] => Object.entries(FILE_TYPE_LABELS).map(([key, label]) => ({
|
|
148
|
+
key,
|
|
149
|
+
label,
|
|
150
|
+
defaultValue: get(filters, `${ASSET_FILE_TYPE}.${key}`, true) as boolean,
|
|
151
|
+
}));
|
|
152
|
+
|
|
153
|
+
type GetFiltersOptions = {
|
|
154
|
+
compareMode: boolean;
|
|
155
|
+
filters: Record<string, boolean>;
|
|
156
|
+
chunks: Array<WebpackChunk>;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const getFilters = ({
|
|
160
|
+
compareMode,
|
|
161
|
+
filters,
|
|
162
|
+
chunks,
|
|
163
|
+
}: GetFiltersOptions): FilterFieldsData => {
|
|
164
|
+
const result: FilterFieldsData = {
|
|
165
|
+
[ASSET_FILTERS.CHANGED]: {
|
|
166
|
+
label: I18N.CHANGED,
|
|
167
|
+
defaultValue: filters[ASSET_FILTERS.CHANGED],
|
|
168
|
+
disabled: !compareMode,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (!isEmpty(chunks)) {
|
|
173
|
+
const chunksFilter: FilterGroupFieldData = {
|
|
174
|
+
label: I18N.CHUNKS,
|
|
175
|
+
children: [
|
|
176
|
+
{
|
|
177
|
+
key: NO_CHUNK_FILTER,
|
|
178
|
+
label: I18N.NO_CHUNK,
|
|
179
|
+
defaultValue: filters[`${ASSET_CHUNK}.${NO_CHUNK_FILTER}`] ?? true,
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const chunksOrderedByName = orderBy(chunks, 'name');
|
|
185
|
+
|
|
186
|
+
chunksOrderedByName.forEach((chunk) => {
|
|
187
|
+
chunksFilter.children.push({
|
|
188
|
+
key: chunk.id,
|
|
189
|
+
label: chunk.name,
|
|
190
|
+
defaultValue: filters[`${ASSET_CHUNK}.${chunk.id}`] ?? true,
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
result[ASSET_CHUNK] = chunksFilter;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
result[ASSET_ENTRY_TYPE] = {
|
|
198
|
+
label: I18N.FILE_TYPE,
|
|
199
|
+
children: [
|
|
200
|
+
{
|
|
201
|
+
key: ASSET_FILTERS.ENTRY,
|
|
202
|
+
label: I18N.ENTRY,
|
|
203
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`, true),
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
key: ASSET_FILTERS.INITIAL,
|
|
207
|
+
label: I18N.INITIAL,
|
|
208
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`, true),
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
key: ASSET_FILTERS.CHUNK,
|
|
212
|
+
label: I18N.CHUNK,
|
|
213
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`, true),
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
key: ASSET_FILTERS.OTHER,
|
|
217
|
+
label: I18N.OTHER,
|
|
218
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`, true),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
result[ASSET_FILE_TYPE] = {
|
|
224
|
+
label: I18N.FILE_TYPE,
|
|
225
|
+
children: getFileTypeFilters(filters),
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/* eslint-disable prettier/prettier */
|
|
232
|
+
export const generateGetRowFilter =
|
|
233
|
+
({ chunkIds }: GenerateGetRowFilterOptions) => (filters: Record<string, unknown>) => {
|
|
234
|
+
// List of chunkIds with filter value set to `true`
|
|
235
|
+
const checkedChunkIds: Array<string> = [];
|
|
236
|
+
// List of chunks ids, including the NO_CHUNK
|
|
237
|
+
const filtersChunkIds = [NO_CHUNK_FILTER, ...chunkIds];
|
|
238
|
+
|
|
239
|
+
filtersChunkIds.forEach((chunkId) => {
|
|
240
|
+
if (filters[`${ASSET_CHUNK}.${chunkId}`]) {
|
|
241
|
+
checkedChunkIds.push(chunkId);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const hasChunkFilters =
|
|
246
|
+
checkedChunkIds.length > 0 && checkedChunkIds.length !== filtersChunkIds.length;
|
|
247
|
+
|
|
248
|
+
return (item: ReportMetricAssetRow) => {
|
|
249
|
+
if (filters[ASSET_FILTERS.CHANGED] && !item.changed) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (
|
|
254
|
+
!(
|
|
255
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`] && item.isEntry) ||
|
|
256
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`] && item.isInitial) ||
|
|
257
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`] && item.isChunk) ||
|
|
258
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`] && item.isAsset)
|
|
259
|
+
)
|
|
260
|
+
) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (!filters[`${ASSET_FILE_TYPE}.${item.fileType}`]) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Filter if any of the chunkIds are checked
|
|
269
|
+
if (hasChunkFilters) {
|
|
270
|
+
const rowRunsChunkIds = item?.runs?.map((run) => run?.chunkId || NO_CHUNK_FILTER) || [];
|
|
271
|
+
return intersection(rowRunsChunkIds, checkedChunkIds).length > 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return true;
|
|
275
|
+
};
|
|
276
|
+
};
|