@bundle-stats/ui 4.17.0 → 4.18.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/components/asset-info/asset-info.js +8 -9
- package/lib/components/asset-info/asset-info.js.map +1 -1
- package/lib/components/bundle-assets/bundle-assets.js +7 -110
- package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib/components/bundle-assets/bundle-assets.utils.js +101 -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.js +9 -10
- package/lib-esm/components/asset-info/asset-info.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.js +8 -111
- package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.utils.js +98 -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.tsx +31 -28
- package/src/components/bundle-assets/__tests__/add-metric-report-asset-row-data.ts +2 -2
- package/src/components/bundle-assets/bundle-assets.stories.tsx +99 -0
- package/src/components/bundle-assets/{bundle-assets.jsx → bundle-assets.tsx} +65 -147
- package/src/components/bundle-assets/bundle-assets.utils.ts +260 -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/bundle-assets/bundle-assets.d.ts +24 -55
- 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
|
@@ -0,0 +1,260 @@
|
|
|
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
|
+
import type {
|
|
16
|
+
FilterFieldsData,
|
|
17
|
+
ReportMetricAssetRow,
|
|
18
|
+
ReportMetricAssetRowMetaStatus,
|
|
19
|
+
FilterGroupFieldData,
|
|
20
|
+
} from '../../types';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check if the asset cache is not predictive
|
|
24
|
+
*/
|
|
25
|
+
export const getIsNotPredictive = (row: ReportMetricRow): boolean => {
|
|
26
|
+
const { key, runs } = row;
|
|
27
|
+
|
|
28
|
+
return runs.reduce((agg, run, index) => {
|
|
29
|
+
if (agg) {
|
|
30
|
+
return agg;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (index + 1 === runs.length) {
|
|
34
|
+
return agg;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const preRun = runs[index + 1];
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
run &&
|
|
41
|
+
preRun &&
|
|
42
|
+
key !== run.name &&
|
|
43
|
+
run.name === preRun.name &&
|
|
44
|
+
run.value !== preRun.value
|
|
45
|
+
) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return agg;
|
|
50
|
+
}, false);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Return asset meta status
|
|
55
|
+
*/
|
|
56
|
+
export const getAssetMetaStatus = (
|
|
57
|
+
values: Array<boolean | undefined>,
|
|
58
|
+
): ReportMetricAssetRowMetaStatus | boolean => {
|
|
59
|
+
if (!values.includes(true)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// filter empty runs
|
|
64
|
+
const metaValues = values.filter((value) => typeof value !== 'undefined');
|
|
65
|
+
|
|
66
|
+
const current = metaValues[0];
|
|
67
|
+
const metaValuesLength = metaValues.length;
|
|
68
|
+
|
|
69
|
+
if (metaValuesLength === 1) {
|
|
70
|
+
return Boolean(current);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const baseline = metaValues[metaValuesLength - 1];
|
|
74
|
+
|
|
75
|
+
if (current && !baseline) {
|
|
76
|
+
return 'added';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!current && baseline) {
|
|
80
|
+
return 'removed';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return true;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Add asset row flags
|
|
88
|
+
*/
|
|
89
|
+
export const addMetricReportAssetRowData = (row: ReportMetricRow): ReportMetricAssetRow => {
|
|
90
|
+
const { changed, runs } = row;
|
|
91
|
+
|
|
92
|
+
// Collect meta for each run
|
|
93
|
+
const runsEntry: Array<boolean | undefined> = [];
|
|
94
|
+
const runsInitial: Array<boolean | undefined> = [];
|
|
95
|
+
const runsChunk: Array<boolean | undefined> = [];
|
|
96
|
+
|
|
97
|
+
(runs as Array<AssetMetricRun | null>).forEach((run) => {
|
|
98
|
+
runsEntry.push(run?.isEntry);
|
|
99
|
+
runsInitial.push(run?.isInitial);
|
|
100
|
+
runsChunk.push(run?.isChunk);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const isEntry = getAssetMetaStatus(runsEntry);
|
|
104
|
+
const isInitial = getAssetMetaStatus(runsInitial);
|
|
105
|
+
const isChunk = getAssetMetaStatus(runsChunk);
|
|
106
|
+
const isAsset = !(isEntry || isInitial || isChunk);
|
|
107
|
+
const isNotPredictive = getIsNotPredictive(row);
|
|
108
|
+
const fileType = getFileType(row.key);
|
|
109
|
+
|
|
110
|
+
// Flag asset as changed if name and value are identical, if one of the meta tags is changed
|
|
111
|
+
const assetChanged =
|
|
112
|
+
changed ||
|
|
113
|
+
typeof isEntry !== 'boolean' ||
|
|
114
|
+
typeof isInitial !== 'boolean' ||
|
|
115
|
+
typeof isChunk !== 'boolean';
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
...row,
|
|
119
|
+
changed: assetChanged,
|
|
120
|
+
isEntry,
|
|
121
|
+
isInitial,
|
|
122
|
+
isChunk,
|
|
123
|
+
isAsset,
|
|
124
|
+
isNotPredictive,
|
|
125
|
+
fileType,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
type GenerateGetRowFilterOptions = {
|
|
130
|
+
chunkIds: Array<string>;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const getCustomSort = (item: ReportMetricAssetRow): Array<boolean | string> => [
|
|
134
|
+
!item.isNotPredictive,
|
|
135
|
+
!item.changed,
|
|
136
|
+
!item.isInitial,
|
|
137
|
+
!item.isEntry,
|
|
138
|
+
!item.isChunk,
|
|
139
|
+
item.key,
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const getFileTypeFilters = (filters: Record<string, unknown>): FilterGroupFieldData['children'] =>
|
|
143
|
+
Object.entries(FILE_TYPE_LABELS).map(([key, label]) => ({
|
|
144
|
+
key,
|
|
145
|
+
label,
|
|
146
|
+
defaultValue: get(filters, `${ASSET_FILE_TYPE}.${key}`, true) as boolean,
|
|
147
|
+
}));
|
|
148
|
+
|
|
149
|
+
type GetFiltersOptions = {
|
|
150
|
+
compareMode: boolean;
|
|
151
|
+
filters: Record<string, boolean>;
|
|
152
|
+
chunks: Array<WebpackChunk>;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const getFilters = ({
|
|
156
|
+
compareMode,
|
|
157
|
+
filters,
|
|
158
|
+
chunks,
|
|
159
|
+
}: GetFiltersOptions): FilterFieldsData => {
|
|
160
|
+
const result: FilterFieldsData = {
|
|
161
|
+
[ASSET_FILTERS.CHANGED]: {
|
|
162
|
+
label: 'Changed',
|
|
163
|
+
defaultValue: filters[ASSET_FILTERS.CHANGED],
|
|
164
|
+
disabled: !compareMode,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (!isEmpty(chunks)) {
|
|
169
|
+
const chunksFilter: FilterGroupFieldData = { label: 'Chunks', children: [] };
|
|
170
|
+
const chunksOrderedByName = orderBy(chunks, 'name');
|
|
171
|
+
|
|
172
|
+
chunksOrderedByName.forEach((chunk) => {
|
|
173
|
+
chunksFilter.children.push({
|
|
174
|
+
key: chunk.id,
|
|
175
|
+
label: chunk.name,
|
|
176
|
+
defaultValue: filters[`${ASSET_CHUNK}.${chunk.id}`] ?? true,
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
result[ASSET_CHUNK] = chunksFilter;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
result[ASSET_ENTRY_TYPE] = {
|
|
184
|
+
label: 'Type',
|
|
185
|
+
children: [
|
|
186
|
+
{
|
|
187
|
+
key: ASSET_FILTERS.ENTRY,
|
|
188
|
+
label: 'Entry',
|
|
189
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`, true),
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
key: ASSET_FILTERS.INITIAL,
|
|
193
|
+
label: 'Initial',
|
|
194
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`, true),
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
key: ASSET_FILTERS.CHUNK,
|
|
198
|
+
label: 'Chunk',
|
|
199
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`, true),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
key: ASSET_FILTERS.OTHER,
|
|
203
|
+
label: 'Other',
|
|
204
|
+
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`, true),
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
result[ASSET_FILE_TYPE] = {
|
|
210
|
+
label: 'File type',
|
|
211
|
+
children: getFileTypeFilters(filters),
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return result;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/* eslint-disable prettier/prettier */
|
|
218
|
+
export const generateGetRowFilter =
|
|
219
|
+
({ chunkIds }: GenerateGetRowFilterOptions) => (filters: Record<string, unknown>) => {
|
|
220
|
+
// List of chunkIds with filter value set to `true`
|
|
221
|
+
const checkedChunkIds: Array<string> = [];
|
|
222
|
+
|
|
223
|
+
chunkIds.forEach((chunkId) => {
|
|
224
|
+
if (filters[`${ASSET_CHUNK}.${chunkId}`]) {
|
|
225
|
+
checkedChunkIds.push(chunkId);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const hasChunkFilters =
|
|
230
|
+
checkedChunkIds.length > 0 && checkedChunkIds.length !== chunkIds.length;
|
|
231
|
+
|
|
232
|
+
return (item: ReportMetricAssetRow) => {
|
|
233
|
+
if (filters[ASSET_FILTERS.CHANGED] && !item.changed) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (
|
|
238
|
+
!(
|
|
239
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`] && item.isEntry) ||
|
|
240
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`] && item.isInitial) ||
|
|
241
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`] && item.isChunk) ||
|
|
242
|
+
(filters[`${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`] && item.isAsset)
|
|
243
|
+
)
|
|
244
|
+
) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!filters[`${ASSET_FILE_TYPE}.${item.fileType}`]) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Filter if any of the chunkIds are checked
|
|
253
|
+
if (hasChunkFilters) {
|
|
254
|
+
const rowRunsChunkIds = item?.runs?.map((run) => run?.chunkId) || [];
|
|
255
|
+
return intersection(rowRunsChunkIds, checkedChunkIds).length > 0;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return true;
|
|
259
|
+
};
|
|
260
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
|
|
3
|
+
import type { Job } from '@bundle-stats/utils';
|
|
4
4
|
import { ASSET_FILTERS } from '@bundle-stats/utils';
|
|
5
5
|
import {
|
|
6
6
|
getAssetEntryTypeFilters,
|
|
@@ -13,13 +13,37 @@ import { useSearchParams } from '../../hooks/search-params';
|
|
|
13
13
|
import { useEntryInfo } from '../../hooks/entry-info';
|
|
14
14
|
import { getJobsChunksData } from '../../utils/jobs';
|
|
15
15
|
import { BundleAssets as BundleAssetsComponent } from './bundle-assets';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
addMetricReportAssetRowData,
|
|
18
|
+
generateGetRowFilter,
|
|
19
|
+
getCustomSort,
|
|
20
|
+
} from './bundle-assets.utils';
|
|
21
|
+
import { ReportMetricAssetRow } from '../../types';
|
|
17
22
|
|
|
18
|
-
export
|
|
19
|
-
|
|
23
|
+
export type BundleAssetsProps = {
|
|
24
|
+
jobs: Array<Job>;
|
|
25
|
+
filters?: Record<string, boolean>;
|
|
26
|
+
search?: string;
|
|
27
|
+
sortBy?: string;
|
|
28
|
+
direction?: string;
|
|
29
|
+
setState: () => void;
|
|
30
|
+
};
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
export const BundleAssets = (props: BundleAssetsProps) => {
|
|
33
|
+
const {
|
|
34
|
+
jobs,
|
|
35
|
+
filters = undefined,
|
|
36
|
+
search = undefined,
|
|
37
|
+
sortBy = undefined,
|
|
38
|
+
direction = undefined,
|
|
39
|
+
setState,
|
|
40
|
+
...restProps
|
|
41
|
+
} = props;
|
|
22
42
|
|
|
43
|
+
// Get chunks data
|
|
44
|
+
const { chunks, chunkIds } = useMemo(() => getJobsChunksData(jobs), [jobs]);
|
|
45
|
+
|
|
46
|
+
// Get filters
|
|
23
47
|
const { defaultFilters, allEntriesFilters } = useMemo(
|
|
24
48
|
() => ({
|
|
25
49
|
defaultFilters: {
|
|
@@ -36,7 +60,8 @@ export const BundleAssets = (props) => {
|
|
|
36
60
|
[jobs],
|
|
37
61
|
);
|
|
38
62
|
|
|
39
|
-
|
|
63
|
+
// Get search params data
|
|
64
|
+
const searchProps = useSearchParams({
|
|
40
65
|
search,
|
|
41
66
|
filters,
|
|
42
67
|
defaultFilters,
|
|
@@ -44,19 +69,22 @@ export const BundleAssets = (props) => {
|
|
|
44
69
|
setState,
|
|
45
70
|
});
|
|
46
71
|
|
|
72
|
+
// Get metric rows
|
|
47
73
|
const { rows, totalRowCount } = useMemo(() => {
|
|
48
74
|
const result = webpack.compareBySection.assets(jobs, [addMetricReportAssetRowData]);
|
|
49
75
|
return { rows: result, totalRowCount: result.length };
|
|
50
76
|
}, [jobs]);
|
|
51
77
|
|
|
78
|
+
// Filter rows
|
|
52
79
|
const filteredRows = useRowsFilter({
|
|
53
80
|
rows,
|
|
54
|
-
searchPattern:
|
|
55
|
-
filters:
|
|
56
|
-
getRowFilter,
|
|
81
|
+
searchPattern: searchProps.searchPattern,
|
|
82
|
+
filters: searchProps.filters,
|
|
83
|
+
getRowFilter: generateGetRowFilter({ chunkIds }),
|
|
57
84
|
});
|
|
58
85
|
|
|
59
|
-
|
|
86
|
+
// Sort rows
|
|
87
|
+
const sortProps = useRowsSort<ReportMetricAssetRow>({
|
|
60
88
|
rows: filteredRows,
|
|
61
89
|
initialField: sortBy,
|
|
62
90
|
initialDirection: direction,
|
|
@@ -68,31 +96,17 @@ export const BundleAssets = (props) => {
|
|
|
68
96
|
|
|
69
97
|
return (
|
|
70
98
|
<BundleAssetsComponent
|
|
99
|
+
{...restProps}
|
|
100
|
+
{...searchProps}
|
|
71
101
|
jobs={jobs}
|
|
72
102
|
chunks={chunks}
|
|
73
|
-
{
|
|
74
|
-
{
|
|
75
|
-
{...sortParams}
|
|
103
|
+
sort={sortProps.sort}
|
|
104
|
+
items={sortProps.items}
|
|
76
105
|
allItems={rows}
|
|
77
106
|
totalRowCount={totalRowCount}
|
|
107
|
+
updateSort={sortProps.updateSort}
|
|
78
108
|
hideEntryInfo={hideEntryInfo}
|
|
79
109
|
showEntryInfo={showEntryInfo}
|
|
80
110
|
/>
|
|
81
111
|
);
|
|
82
112
|
};
|
|
83
|
-
|
|
84
|
-
BundleAssets.propTypes = {
|
|
85
|
-
jobs: PropTypes.arrayOf(PropTypes.object).isRequired, // eslint-disable-line react/forbid-prop-types
|
|
86
|
-
filters: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
|
87
|
-
search: PropTypes.string,
|
|
88
|
-
sortBy: PropTypes.string,
|
|
89
|
-
direction: PropTypes.string,
|
|
90
|
-
setState: PropTypes.func.isRequired,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
BundleAssets.defaultProps = {
|
|
94
|
-
filters: undefined,
|
|
95
|
-
search: undefined,
|
|
96
|
-
sortBy: undefined,
|
|
97
|
-
direction: undefined,
|
|
98
|
-
};
|
|
@@ -9,7 +9,7 @@ import { Table } from '../../ui/table';
|
|
|
9
9
|
import { Stack } from '../../layout/stack';
|
|
10
10
|
import { Metric } from '../metric';
|
|
11
11
|
import { Delta } from '../delta';
|
|
12
|
-
import { MetricsTableHeader } from '../metrics-table-header';
|
|
12
|
+
import { MetricsTableHeader, MetricsTableHeaderProps } from '../metrics-table-header';
|
|
13
13
|
import * as I18N from './metrics-table.i18n';
|
|
14
14
|
import css from './metrics-table.module.css';
|
|
15
15
|
|
|
@@ -74,8 +74,8 @@ interface MetricsTableProps extends Omit<React.ComponentProps<typeof Table>, 'ti
|
|
|
74
74
|
items: Array<ReportMetricRow>;
|
|
75
75
|
title?: React.ReactNode;
|
|
76
76
|
showHeaderSum?: boolean;
|
|
77
|
-
sort?:
|
|
78
|
-
updateSort?:
|
|
77
|
+
sort?: MetricsTableHeaderProps['sort'];
|
|
78
|
+
updateSort?: MetricsTableHeaderProps['updateSort'];
|
|
79
79
|
renderRowHeader?: (item: ReportMetricRow) => React.ReactNode;
|
|
80
80
|
emptyMessage?: React.ReactNode;
|
|
81
81
|
showAllItems: boolean;
|
|
@@ -12,7 +12,7 @@ import { Table } from '../../ui/table';
|
|
|
12
12
|
import { Delta } from '../delta';
|
|
13
13
|
import { JobName } from '../job-name';
|
|
14
14
|
import { Metric } from '../metric';
|
|
15
|
-
import { SortButton } from '../sort-button';
|
|
15
|
+
import { SortButton, SortButtonProps } from '../sort-button';
|
|
16
16
|
import * as I18N from './metrics-table-header.i18n';
|
|
17
17
|
import css from './metrics-table-header.module.css';
|
|
18
18
|
|
|
@@ -53,8 +53,8 @@ interface ColumnSumProps {
|
|
|
53
53
|
rows: Array<ReportMetricRow>;
|
|
54
54
|
isBaseline: boolean;
|
|
55
55
|
runIndex: number;
|
|
56
|
-
sort?:
|
|
57
|
-
updateSort?:
|
|
56
|
+
sort?: SortButtonProps['sort'];
|
|
57
|
+
updateSort?: SortButtonProps['updateSort'];
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const SumColumn = ({ rows, isBaseline, runIndex, updateSort, sort }: ColumnSumProps) => {
|
|
@@ -110,7 +110,7 @@ const SumColumn = ({ rows, isBaseline, runIndex, updateSort, sort }: ColumnSumPr
|
|
|
110
110
|
);
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
interface MetricsTableHeaderProps {
|
|
113
|
+
export interface MetricsTableHeaderProps {
|
|
114
114
|
/**
|
|
115
115
|
* Metric column title
|
|
116
116
|
*/
|
|
@@ -36,7 +36,7 @@ const getDescAction = (label: string): SortInfo => {
|
|
|
36
36
|
return { direction: SORT.DESC, title: `Order ${label} descending` };
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
interface SortButtonProps {
|
|
39
|
+
export interface SortButtonProps {
|
|
40
40
|
fieldPath: string;
|
|
41
41
|
fieldName: string;
|
|
42
42
|
label: string;
|
package/src/hooks/rows-sort.ts
CHANGED
|
@@ -5,6 +5,21 @@ import orderBy from 'lodash/orderBy';
|
|
|
5
5
|
import type { SortAction } from '../types';
|
|
6
6
|
import { SORT } from '../constants';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Get sort direction field from a string param
|
|
10
|
+
*/
|
|
11
|
+
const getSortDirection = (directionParam: string | undefined): SortAction['direction'] => {
|
|
12
|
+
if (typeof directionParam === 'undefined') {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (['asc', 'desc'].includes(directionParam)) {
|
|
17
|
+
return directionParam as SortAction['direction'];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return '';
|
|
21
|
+
};
|
|
22
|
+
|
|
8
23
|
export const getSortFn =
|
|
9
24
|
<TRow>(fieldPath: string, getCustomSort: UseRowsSortParams<TRow>['getCustomSort']) =>
|
|
10
25
|
(item: TRow) => {
|
|
@@ -18,7 +33,7 @@ export const getSortFn =
|
|
|
18
33
|
interface UseRowsSortParams<TRow> {
|
|
19
34
|
rows: Array<TRow>;
|
|
20
35
|
initialField?: string;
|
|
21
|
-
initialDirection?:
|
|
36
|
+
initialDirection?: string;
|
|
22
37
|
getCustomSort: (item: any) => Array<string | number | boolean>;
|
|
23
38
|
setQueryState: (queryParams: {
|
|
24
39
|
sortBy: SortAction['field'];
|
|
@@ -35,11 +50,14 @@ interface UseRowsSort<TRow> {
|
|
|
35
50
|
export const useRowsSort = <TRow>({
|
|
36
51
|
rows,
|
|
37
52
|
initialField = 'runs[0].delta',
|
|
38
|
-
initialDirection
|
|
53
|
+
initialDirection,
|
|
39
54
|
getCustomSort,
|
|
40
55
|
setQueryState,
|
|
41
56
|
}: UseRowsSortParams<TRow>): UseRowsSort<TRow> => {
|
|
42
|
-
const [sort, setSort] = useState({
|
|
57
|
+
const [sort, setSort] = useState({
|
|
58
|
+
field: initialField,
|
|
59
|
+
direction: getSortDirection(initialDirection),
|
|
60
|
+
});
|
|
43
61
|
|
|
44
62
|
const updateSort = useCallback(
|
|
45
63
|
(newState: SortAction) => {
|
package/src/types.d.ts
CHANGED
|
@@ -12,9 +12,13 @@ interface FilterFieldData {
|
|
|
12
12
|
disabled?: boolean;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
interface ChildFilterFieldData extends FilterFieldData {
|
|
16
|
+
key: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
type FilterGroupFieldData = {
|
|
16
20
|
label: string;
|
|
17
|
-
children: Array<
|
|
21
|
+
children: Array<ChildFilterFieldData>;
|
|
18
22
|
};
|
|
19
23
|
|
|
20
24
|
type FilterFieldsData = Record<string, FilterFieldData | FilterGroupFieldData>;
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import type { ComponentProps, ElementType } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
3
|
+
import type { WebpackChunk } from '@bundle-stats/utils';
|
|
4
|
+
import type { ReportMetricAssetRow } from '../../types';
|
|
5
5
|
interface AssetInfoProps {
|
|
6
|
-
item:
|
|
7
|
-
|
|
8
|
-
changed?: boolean;
|
|
9
|
-
isChunk?: boolean;
|
|
10
|
-
isEntry?: boolean;
|
|
11
|
-
isInitial?: boolean;
|
|
12
|
-
isNotPredictive?: boolean;
|
|
13
|
-
fileType?: string;
|
|
14
|
-
runs: Array<AssetMetricRun & MetricRunInfo>;
|
|
15
|
-
};
|
|
16
|
-
chunks?: Array<MetaChunk>;
|
|
6
|
+
item: ReportMetricAssetRow;
|
|
7
|
+
chunks?: Array<WebpackChunk>;
|
|
17
8
|
labels: Array<string>;
|
|
18
9
|
customComponentLink?: ElementType;
|
|
19
10
|
onClose: () => void;
|
|
@@ -1,56 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}> | null | undefined)[]>;
|
|
25
|
-
}> | null | undefined)[]>;
|
|
26
|
-
export let updateFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
27
|
-
export let resetFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
28
|
-
export let resetAllFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
29
|
-
let totalRowCount_1: PropTypes.Requireable<number>;
|
|
30
|
-
export { totalRowCount_1 as totalRowCount };
|
|
31
|
-
export let filters: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
32
|
-
changed: PropTypes.Requireable<boolean>;
|
|
33
|
-
id: PropTypes.Requireable<string>;
|
|
34
|
-
}>>>;
|
|
35
|
-
let entryId_1: PropTypes.Requireable<string>;
|
|
36
|
-
export { entryId_1 as entryId };
|
|
37
|
-
let hasActiveFilters_1: PropTypes.Requireable<boolean>;
|
|
38
|
-
export { hasActiveFilters_1 as hasActiveFilters };
|
|
39
|
-
export let search: PropTypes.Validator<string>;
|
|
40
|
-
export let updateSearch: PropTypes.Validator<(...args: any[]) => any>;
|
|
41
|
-
export let sort: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
42
|
-
field: PropTypes.Requireable<string>;
|
|
43
|
-
direction: PropTypes.Requireable<string>;
|
|
44
|
-
}>>>;
|
|
45
|
-
export let updateSort: PropTypes.Validator<(...args: any[]) => any>;
|
|
46
|
-
export let allItems: PropTypes.Validator<(PropTypes.InferProps<{
|
|
47
|
-
key: PropTypes.Requireable<string>;
|
|
48
|
-
}> | null | undefined)[]>;
|
|
49
|
-
export let customComponentLink: PropTypes.Requireable<PropTypes.ReactComponentLike>;
|
|
50
|
-
export let hideEntryInfo: PropTypes.Validator<(...args: any[]) => any>;
|
|
51
|
-
export let showEntryInfo: PropTypes.Validator<(...args: any[]) => any>;
|
|
52
|
-
}
|
|
1
|
+
import type { ElementType } from 'react';
|
|
2
|
+
import React, { ComponentProps } from 'react';
|
|
3
|
+
import type { Job, WebpackChunk } from '@bundle-stats/utils';
|
|
4
|
+
import type { ReportMetricAssetRow, SortAction } from '../../types';
|
|
5
|
+
import { Stack } from '../../layout/stack';
|
|
6
|
+
export interface BundleAssetsProps extends ComponentProps<typeof Stack> {
|
|
7
|
+
jobs: Array<Job>;
|
|
8
|
+
chunks: Array<WebpackChunk>;
|
|
9
|
+
items: Array<ReportMetricAssetRow>;
|
|
10
|
+
allItems: Array<ReportMetricAssetRow>;
|
|
11
|
+
filters: Record<string, boolean>;
|
|
12
|
+
updateFilters: (newFilters: Record<string, boolean>) => void;
|
|
13
|
+
resetFilters: () => void;
|
|
14
|
+
resetAllFilters: () => void;
|
|
15
|
+
totalRowCount?: number;
|
|
16
|
+
entryId?: string;
|
|
17
|
+
sort: SortAction;
|
|
18
|
+
updateSort: (params: SortAction) => void;
|
|
19
|
+
search: string;
|
|
20
|
+
updateSearch: (search: string) => void;
|
|
21
|
+
customComponentLink?: ElementType;
|
|
22
|
+
hideEntryInfo: () => void;
|
|
23
|
+
showEntryInfo: (entryId: string) => void;
|
|
53
24
|
}
|
|
54
|
-
|
|
55
|
-
import { ComponentLink } from '../component-link';
|
|
56
|
-
import PropTypes from 'prop-types';
|
|
25
|
+
export declare const BundleAssets: (props: BundleAssetsProps) => React.JSX.Element;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
1
|
+
import type { ReportMetricRow, WebpackChunk } from '@bundle-stats/utils';
|
|
2
|
+
import type { FilterFieldsData, ReportMetricAssetRow, ReportMetricAssetRowMetaStatus } from '../../types';
|
|
3
|
+
export declare const getIsNotPredictive: (row: ReportMetricRow) => boolean;
|
|
4
|
+
export declare const getAssetMetaStatus: (values: Array<boolean | undefined>) => ReportMetricAssetRowMetaStatus | boolean;
|
|
5
|
+
export declare const addMetricReportAssetRowData: (row: ReportMetricRow) => ReportMetricAssetRow;
|
|
6
|
+
type GenerateGetRowFilterOptions = {
|
|
7
|
+
chunkIds: Array<string>;
|
|
8
|
+
};
|
|
9
|
+
export declare const getCustomSort: (item: ReportMetricAssetRow) => Array<boolean | string>;
|
|
10
|
+
type GetFiltersOptions = {
|
|
11
|
+
compareMode: boolean;
|
|
12
|
+
filters: Record<string, boolean>;
|
|
13
|
+
chunks: Array<WebpackChunk>;
|
|
14
|
+
};
|
|
15
|
+
export declare const getFilters: ({ compareMode, filters, chunks, }: GetFiltersOptions) => FilterFieldsData;
|
|
16
|
+
export declare const generateGetRowFilter: ({ chunkIds }: GenerateGetRowFilterOptions) => (filters: Record<string, unknown>) => (item: ReportMetricAssetRow) => boolean;
|
|
17
|
+
export {};
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
export function BundleAssets(props: any): React.JSX.Element;
|
|
2
|
-
export namespace BundleAssets {
|
|
3
|
-
namespace propTypes {
|
|
4
|
-
let jobs: PropTypes.Validator<(object | null | undefined)[]>;
|
|
5
|
-
let filters: PropTypes.Requireable<object>;
|
|
6
|
-
let search: PropTypes.Requireable<string>;
|
|
7
|
-
let sortBy: PropTypes.Requireable<string>;
|
|
8
|
-
let direction: PropTypes.Requireable<string>;
|
|
9
|
-
let setState: PropTypes.Validator<(...args: any[]) => any>;
|
|
10
|
-
}
|
|
11
|
-
namespace defaultProps {
|
|
12
|
-
let filters_1: undefined;
|
|
13
|
-
export { filters_1 as filters };
|
|
14
|
-
let search_1: undefined;
|
|
15
|
-
export { search_1 as search };
|
|
16
|
-
let sortBy_1: undefined;
|
|
17
|
-
export { sortBy_1 as sortBy };
|
|
18
|
-
let direction_1: undefined;
|
|
19
|
-
export { direction_1 as direction };
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
1
|
import React from 'react';
|
|
23
|
-
import
|
|
2
|
+
import type { Job } from '@bundle-stats/utils';
|
|
3
|
+
export type BundleAssetsProps = {
|
|
4
|
+
jobs: Array<Job>;
|
|
5
|
+
filters?: Record<string, boolean>;
|
|
6
|
+
search?: string;
|
|
7
|
+
sortBy?: string;
|
|
8
|
+
direction?: string;
|
|
9
|
+
setState: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const BundleAssets: (props: BundleAssetsProps) => React.JSX.Element;
|