@bundle-stats/ui 4.8.3 → 4.8.4
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/bundle-assets/bundle-assets.js +28 -27
- package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.i18n.js +12 -0
- package/lib/components/bundle-modules/bundle-modules.i18n.js.map +1 -0
- package/lib/components/bundle-modules/bundle-modules.js +12 -99
- package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.utils.js +108 -1
- package/lib/components/bundle-modules/bundle-modules.utils.js.map +1 -1
- package/lib/components/bundle-modules/index.js +6 -45
- package/lib/components/bundle-modules/index.js.map +1 -1
- package/lib/components/entry-info/entry-info.i18n.js +7 -0
- package/lib/components/entry-info/entry-info.i18n.js.map +1 -0
- package/lib/components/entry-info/entry-info.js +27 -3
- package/lib/components/entry-info/entry-info.js.map +1 -1
- package/lib/components/job-name/job-name.js +1 -1
- package/lib/components/job-name/job-name.js.map +1 -1
- package/lib/components/metric-run-info/metric-run-info.js +10 -5
- package/lib/components/metric-run-info/metric-run-info.js.map +1 -1
- package/lib/components/metrics-table/index.js +1 -1
- package/lib/components/metrics-table/index.js.map +1 -1
- package/lib/components/metrics-table/metrics-table.i18n.js +12 -0
- package/lib/components/metrics-table/metrics-table.i18n.js.map +1 -0
- package/lib/components/metrics-table/metrics-table.js +50 -69
- package/lib/components/metrics-table/metrics-table.js.map +1 -1
- package/lib/components/metrics-table/metrics-table.module.css +2 -2
- package/lib/components/sort-button/sort-button.js +10 -4
- package/lib/components/sort-button/sort-button.js.map +1 -1
- package/lib/components/sort-button/sort-button.module.css +9 -9
- package/lib/hooks/rows-sort.js +1 -1
- package/lib/hooks/rows-sort.js.map +1 -1
- package/lib/ui/filters/filters.i18n.js +6 -0
- package/lib/ui/filters/filters.i18n.js.map +1 -0
- package/lib/ui/filters/filters.js +16 -54
- package/lib/ui/filters/filters.js.map +1 -1
- package/lib/ui/filters/filters.utils.js +27 -11
- package/lib/ui/filters/filters.utils.js.map +1 -1
- package/lib/ui/filters/index.js +0 -8
- package/lib/ui/filters/index.js.map +1 -1
- package/lib-esm/components/bundle-assets/bundle-assets.js +28 -27
- package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.i18n.js +9 -0
- package/lib-esm/components/bundle-modules/bundle-modules.i18n.js.map +1 -0
- package/lib-esm/components/bundle-modules/bundle-modules.js +13 -101
- package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.utils.js +83 -1
- package/lib-esm/components/bundle-modules/bundle-modules.utils.js.map +1 -1
- package/lib-esm/components/bundle-modules/index.js +9 -45
- package/lib-esm/components/bundle-modules/index.js.map +1 -1
- package/lib-esm/components/entry-info/entry-info.i18n.js +4 -0
- package/lib-esm/components/entry-info/entry-info.i18n.js.map +1 -0
- package/lib-esm/components/entry-info/entry-info.js +4 -3
- package/lib-esm/components/entry-info/entry-info.js.map +1 -1
- package/lib-esm/components/job-name/job-name.js +1 -1
- package/lib-esm/components/job-name/job-name.js.map +1 -1
- package/lib-esm/components/metric-run-info/metric-run-info.js +10 -5
- package/lib-esm/components/metric-run-info/metric-run-info.js.map +1 -1
- package/lib-esm/components/metrics-table/index.js +1 -1
- package/lib-esm/components/metrics-table/index.js.map +1 -1
- package/lib-esm/components/metrics-table/metrics-table.i18n.js +9 -0
- package/lib-esm/components/metrics-table/metrics-table.i18n.js.map +1 -0
- package/lib-esm/components/metrics-table/metrics-table.js +37 -79
- package/lib-esm/components/metrics-table/metrics-table.js.map +1 -1
- package/lib-esm/components/metrics-table/metrics-table.module.css +2 -2
- package/lib-esm/components/sort-button/sort-button.js +10 -4
- package/lib-esm/components/sort-button/sort-button.js.map +1 -1
- package/lib-esm/components/sort-button/sort-button.module.css +9 -9
- package/lib-esm/hooks/rows-sort.js +1 -1
- package/lib-esm/hooks/rows-sort.js.map +1 -1
- package/lib-esm/ui/filters/filters.i18n.js +3 -0
- package/lib-esm/ui/filters/filters.i18n.js.map +1 -0
- package/lib-esm/ui/filters/filters.js +16 -54
- package/lib-esm/ui/filters/filters.js.map +1 -1
- package/lib-esm/ui/filters/filters.utils.js +27 -11
- package/lib-esm/ui/filters/filters.utils.js.map +1 -1
- package/lib-esm/ui/filters/index.js +0 -8
- package/lib-esm/ui/filters/index.js.map +1 -1
- package/package.json +10 -10
- package/src/components/bundle-assets/bundle-assets.jsx +28 -30
- package/src/components/bundle-modules/bundle-modules.i18n.ts +8 -0
- package/src/components/bundle-modules/bundle-modules.tsx +200 -0
- package/src/components/bundle-modules/bundle-modules.types.d.ts +24 -0
- package/src/components/bundle-modules/bundle-modules.utils.ts +208 -0
- package/src/components/bundle-modules/index.tsx +102 -0
- package/src/components/entry-info/entry-info.i18n.ts +3 -0
- package/src/components/entry-info/entry-info.tsx +10 -4
- package/src/components/job-name/job-name.jsx +7 -1
- package/src/components/metric-run-info/metric-run-info.tsx +12 -5
- package/src/components/metrics-table/index.tsx +14 -0
- package/src/components/metrics-table/metrics-table.i18n.ts +10 -0
- package/src/components/metrics-table/metrics-table.module.css +2 -2
- package/src/components/metrics-table/metrics-table.stories.tsx +225 -0
- package/src/components/metrics-table/metrics-table.tsx +301 -0
- package/src/components/sort-button/sort-button.module.css +9 -9
- package/src/components/sort-button/sort-button.tsx +14 -6
- package/src/hooks/rows-sort.ts +9 -9
- package/src/types.d.ts +11 -0
- package/src/ui/filters/__tests__/filters.utils.ts +98 -0
- package/src/ui/filters/filters.i18n.ts +2 -0
- package/src/ui/filters/{filters.jsx → filters.tsx} +63 -72
- package/src/ui/filters/{filters.utils.js → filters.utils.ts} +38 -21
- package/src/ui/filters/{index.jsx → index.tsx} +14 -17
- package/types/components/bundle-modules/bundle-modules.d.ts +21 -62
- package/types/components/bundle-modules/bundle-modules.i18n.d.ts +8 -0
- package/types/components/bundle-modules/bundle-modules.utils.d.ts +28 -5
- package/types/components/bundle-modules/index.d.ts +13 -22
- package/types/components/entry-info/entry-info.i18n.d.ts +3 -0
- package/types/components/job-name/job-name.d.ts +1 -1
- package/types/components/metrics-table/index.d.ts +4 -1
- package/types/components/metrics-table/metrics-table.d.ts +25 -47
- package/types/components/metrics-table/metrics-table.i18n.d.ts +8 -0
- package/types/components/sort-button/sort-button.d.ts +2 -2
- package/types/hooks/rows-sort.d.ts +4 -4
- package/types/layout/box/box.d.ts +1 -1
- package/types/layout/flex-stack/flex-stack.d.ts +1 -1
- package/types/ui/filters/filters.d.ts +24 -14
- package/types/ui/filters/filters.i18n.d.ts +2 -0
- package/types/ui/filters/filters.utils.d.ts +7 -6
- package/types/ui/filters/index.d.ts +8 -12
- package/types/ui/table/table.d.ts +5 -5
- package/types/ui/tooltip/tooltip.d.ts +1 -1
- package/src/components/bundle-modules/bundle-modules.jsx +0 -291
- package/src/components/bundle-modules/bundle-modules.utils.js +0 -82
- package/src/components/bundle-modules/index.jsx +0 -113
- package/src/components/metrics-table/index.jsx +0 -11
- package/src/components/metrics-table/metrics-table.jsx +0 -309
- package/src/ui/filters/__tests__/filters-dropdown.utils.js +0 -74
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useMemo } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import uniqBy from 'lodash/uniqBy';
|
|
4
|
-
import {
|
|
5
|
-
MODULE_FILTERS,
|
|
6
|
-
getModuleChunkFilters,
|
|
7
|
-
getModuleSourceTypeFilters,
|
|
8
|
-
getModuleFileTypeFilters,
|
|
9
|
-
} from '@bundle-stats/utils';
|
|
10
|
-
import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
|
|
11
|
-
|
|
12
|
-
import { useRowsFilter } from '../../hooks/rows-filter';
|
|
13
|
-
import { useRowsSort } from '../../hooks/rows-sort';
|
|
14
|
-
import { useSearchParams } from '../../hooks/search-params';
|
|
15
|
-
import { BundleModules as BundleModulesComponent } from './bundle-modules';
|
|
16
|
-
import { addRowFlags, generateGetRowFilter, getCustomSort } from './bundle-modules.utils';
|
|
17
|
-
|
|
18
|
-
export const BundleModules = (props) => {
|
|
19
|
-
const { jobs, filters, search, setState, sortBy, direction, ...restProps } = props;
|
|
20
|
-
|
|
21
|
-
const { chunks, chunkIds } = useMemo(() => {
|
|
22
|
-
const bundleChunks = uniqBy(
|
|
23
|
-
jobs.map((job) => job?.meta?.webpack?.chunks || []).flat(),
|
|
24
|
-
({ id }) => id,
|
|
25
|
-
);
|
|
26
|
-
const bundleChunkIds = bundleChunks?.map(({ id }) => id);
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
chunks: bundleChunks,
|
|
30
|
-
chunkIds: bundleChunkIds,
|
|
31
|
-
};
|
|
32
|
-
}, [jobs]);
|
|
33
|
-
|
|
34
|
-
const { defaultFilters, allEntriesFilters } = useMemo(
|
|
35
|
-
() => ({
|
|
36
|
-
defaultFilters: {
|
|
37
|
-
changed: jobs?.length > 1,
|
|
38
|
-
...getModuleSourceTypeFilters(true),
|
|
39
|
-
...getModuleChunkFilters(chunkIds, true),
|
|
40
|
-
...getModuleFileTypeFilters(true),
|
|
41
|
-
[MODULE_FILTERS.DUPLICATED]: false,
|
|
42
|
-
},
|
|
43
|
-
allEntriesFilters: {
|
|
44
|
-
changed: false,
|
|
45
|
-
...getModuleSourceTypeFilters(true),
|
|
46
|
-
...getModuleChunkFilters(chunkIds, true),
|
|
47
|
-
...getModuleFileTypeFilters(true),
|
|
48
|
-
[MODULE_FILTERS.DUPLICATED]: false,
|
|
49
|
-
},
|
|
50
|
-
}),
|
|
51
|
-
[jobs],
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const searchParams = useSearchParams({
|
|
55
|
-
search,
|
|
56
|
-
filters,
|
|
57
|
-
defaultFilters,
|
|
58
|
-
allEntriesFilters,
|
|
59
|
-
setState,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const { rows, totalRowCount } = useMemo(() => {
|
|
63
|
-
const result = webpack.compareBySection.modules(jobs, [addRowFlags]);
|
|
64
|
-
return { rows: result, totalRowCount: result.length };
|
|
65
|
-
}, [jobs]);
|
|
66
|
-
|
|
67
|
-
const filteredRows = useRowsFilter({
|
|
68
|
-
rows,
|
|
69
|
-
searchPattern: searchParams.searchPattern,
|
|
70
|
-
filters: searchParams.filters,
|
|
71
|
-
getRowFilter: generateGetRowFilter({ chunkIds }),
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const sortParams = useRowsSort({
|
|
75
|
-
rows: filteredRows,
|
|
76
|
-
initialField: sortBy,
|
|
77
|
-
initialDirection: direction,
|
|
78
|
-
getCustomSort,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const hideEntryInfo = useCallback(() => {
|
|
82
|
-
setState({ entryId: '' });
|
|
83
|
-
}, [setState]);
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<BundleModulesComponent
|
|
87
|
-
jobs={jobs}
|
|
88
|
-
chunks={chunks}
|
|
89
|
-
{...restProps}
|
|
90
|
-
{...searchParams}
|
|
91
|
-
{...sortParams}
|
|
92
|
-
allItems={rows}
|
|
93
|
-
totalRowCount={totalRowCount}
|
|
94
|
-
hideEntryInfo={hideEntryInfo}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
BundleModules.propTypes = {
|
|
100
|
-
jobs: PropTypes.arrayOf(PropTypes.object).isRequired, // eslint-disable-line react/forbid-prop-types
|
|
101
|
-
filters: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
|
102
|
-
search: PropTypes.string,
|
|
103
|
-
sortBy: PropTypes.string,
|
|
104
|
-
direction: PropTypes.string,
|
|
105
|
-
setState: PropTypes.func.isRequired,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
BundleModules.defaultProps = {
|
|
109
|
-
filters: undefined,
|
|
110
|
-
search: undefined,
|
|
111
|
-
sortBy: undefined,
|
|
112
|
-
direction: undefined,
|
|
113
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import { MetricsTable as BaseComponent } from './metrics-table';
|
|
4
|
-
|
|
5
|
-
export const MetricsTable = (props) => {
|
|
6
|
-
const [showAllItems, setShowAllItems] = useState(false);
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<BaseComponent {...props} showAllItems={showAllItems} setShowAllItems={setShowAllItems} />
|
|
10
|
-
);
|
|
11
|
-
};
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import cx from 'classnames';
|
|
4
|
-
import isEmpty from 'lodash/isEmpty';
|
|
5
|
-
import sum from 'lodash/sum';
|
|
6
|
-
import { MetricTypes, getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils';
|
|
7
|
-
|
|
8
|
-
import { Icon } from '../../ui/icon';
|
|
9
|
-
import { Table } from '../../ui/table';
|
|
10
|
-
import { Stack } from '../../layout/stack';
|
|
11
|
-
import { Metric } from '../metric';
|
|
12
|
-
import { Delta } from '../delta';
|
|
13
|
-
import { JobName } from '../job-name';
|
|
14
|
-
import { SortButton } from '../sort-button';
|
|
15
|
-
import styles from './metrics-table.module.css';
|
|
16
|
-
|
|
17
|
-
const METRIC_TYPE_DATA = getGlobalMetricType(null, MetricTypes.FileSize);
|
|
18
|
-
const VISIBLE_COUNT = 500;
|
|
19
|
-
const BASELINE_COLUMN_SPAN = 1;
|
|
20
|
-
const CURRENT_COLUMN_SPAN = 3;
|
|
21
|
-
const BASELINE_TITLE = 'Baseline';
|
|
22
|
-
const CURRENT_TITLE = 'Current';
|
|
23
|
-
|
|
24
|
-
const getRowsRunTotal = (rows, runIndex) =>
|
|
25
|
-
sum(rows.map((row) => row?.runs?.[runIndex]?.value || 0));
|
|
26
|
-
|
|
27
|
-
const ColumnJob = ({ run, isBaseline }) => {
|
|
28
|
-
const colSpan = isBaseline ? BASELINE_COLUMN_SPAN : CURRENT_COLUMN_SPAN;
|
|
29
|
-
|
|
30
|
-
if (!run) {
|
|
31
|
-
return <Table.Th colSpan={colSpan}>-</Table.Th>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const { label, internalBuildNumber } = run;
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<Table.Th className={styles.job} colSpan={colSpan}>
|
|
38
|
-
<JobName
|
|
39
|
-
title={isBaseline ? BASELINE_TITLE : CURRENT_TITLE}
|
|
40
|
-
internalBuildNumber={internalBuildNumber}
|
|
41
|
-
className={styles.jobName}
|
|
42
|
-
>
|
|
43
|
-
{label}
|
|
44
|
-
</JobName>
|
|
45
|
-
</Table.Th>
|
|
46
|
-
);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const ColumnSum = ({ rows, isBaseline, runIndex, updateSort, sort }) => {
|
|
50
|
-
const currentRunTotal = getRowsRunTotal(rows, runIndex);
|
|
51
|
-
const baselineRunTotal = !isBaseline && getRowsRunTotal(rows, runIndex + 1);
|
|
52
|
-
const infoTotal = getMetricRunInfo(METRIC_TYPE_DATA, currentRunTotal, baselineRunTotal);
|
|
53
|
-
const fieldPath = `runs[${runIndex}]`;
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<>
|
|
57
|
-
<Table.Th className={cx(styles.value, styles.sum)}>
|
|
58
|
-
{(updateSort && sort) ? (
|
|
59
|
-
<SortButton
|
|
60
|
-
fieldPath={fieldPath}
|
|
61
|
-
fieldName="value"
|
|
62
|
-
label="absolute value"
|
|
63
|
-
updateSort={updateSort}
|
|
64
|
-
sort={sort}
|
|
65
|
-
>
|
|
66
|
-
<Metric value={infoTotal.displayValue} />
|
|
67
|
-
</SortButton>
|
|
68
|
-
) : (
|
|
69
|
-
<Metric value={infoTotal.displayValue} />
|
|
70
|
-
)}
|
|
71
|
-
</Table.Th>
|
|
72
|
-
{!isBaseline && (
|
|
73
|
-
<>
|
|
74
|
-
<Table.Th className={cx(styles.delta, styles.sum)}>
|
|
75
|
-
{(updateSort && sort) ? (
|
|
76
|
-
<SortButton
|
|
77
|
-
fieldPath={fieldPath}
|
|
78
|
-
fieldName="delta"
|
|
79
|
-
label="absolute change"
|
|
80
|
-
updateSort={updateSort}
|
|
81
|
-
sort={sort}
|
|
82
|
-
>
|
|
83
|
-
<Delta displayValue={infoTotal.displayDelta} deltaType={infoTotal.deltaType} />
|
|
84
|
-
</SortButton>
|
|
85
|
-
) : (
|
|
86
|
-
<Delta displayValue={infoTotal.displayDelta} deltaType={infoTotal.deltaType} />
|
|
87
|
-
)}
|
|
88
|
-
</Table.Th>
|
|
89
|
-
<Table.Th className={cx(styles.delta, styles.deltaPercentage, styles.sum)}>
|
|
90
|
-
{(updateSort && sort) ? (
|
|
91
|
-
<SortButton
|
|
92
|
-
fieldPath={fieldPath}
|
|
93
|
-
fieldName="deltaPercentage"
|
|
94
|
-
label="absolute percentual change"
|
|
95
|
-
updateSort={updateSort}
|
|
96
|
-
sort={sort}
|
|
97
|
-
>
|
|
98
|
-
<Delta
|
|
99
|
-
displayValue={infoTotal.displayDeltaPercentage}
|
|
100
|
-
deltaType={infoTotal.deltaType}
|
|
101
|
-
/>
|
|
102
|
-
</SortButton>
|
|
103
|
-
) : (
|
|
104
|
-
<Delta
|
|
105
|
-
displayValue={infoTotal.displayDeltaPercentage}
|
|
106
|
-
deltaType={infoTotal.deltaType}
|
|
107
|
-
/>
|
|
108
|
-
)}
|
|
109
|
-
</Table.Th>
|
|
110
|
-
</>
|
|
111
|
-
)}
|
|
112
|
-
</>
|
|
113
|
-
);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const Row = ({ item, renderRowHeader }) => (
|
|
117
|
-
<Table.Tr className={cx(!item.changed && styles.unchanged)}>
|
|
118
|
-
<Table.Th className={styles.metricName}>{renderRowHeader(item)}</Table.Th>
|
|
119
|
-
|
|
120
|
-
{item.runs.map((run, index) => {
|
|
121
|
-
const isBaseline = index === item.runs.length - 1;
|
|
122
|
-
const valueClassName = cx(styles.value, !isBaseline && styles.current);
|
|
123
|
-
|
|
124
|
-
// Empty cells if no value
|
|
125
|
-
if (!run || typeof run.value === 'undefined') {
|
|
126
|
-
return (
|
|
127
|
-
<>
|
|
128
|
-
<Table.Td className={valueClassName}>-</Table.Td>
|
|
129
|
-
{!isBaseline && <Table.Td className={styles.delta} />}
|
|
130
|
-
{!isBaseline && <Table.Td className={cx(styles.delta, styles.deltaPercentage)} />}
|
|
131
|
-
</>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const { displayValue, deltaPercentage, displayDelta, displayDeltaPercentage, deltaType } =
|
|
136
|
-
run;
|
|
137
|
-
|
|
138
|
-
return (
|
|
139
|
-
<>
|
|
140
|
-
<Table.Td className={valueClassName}>
|
|
141
|
-
<Metric value={displayValue} />
|
|
142
|
-
</Table.Td>
|
|
143
|
-
{!isBaseline && typeof deltaPercentage === 'number' && (
|
|
144
|
-
<>
|
|
145
|
-
<Table.Td className={styles.delta}>
|
|
146
|
-
<Delta displayValue={displayDelta} deltaType={deltaType} />
|
|
147
|
-
</Table.Td>
|
|
148
|
-
<Table.Td className={cx(styles.delta, styles.deltaPercentage)}>
|
|
149
|
-
<Delta displayValue={displayDeltaPercentage} deltaType={deltaType} />
|
|
150
|
-
</Table.Td>
|
|
151
|
-
</>
|
|
152
|
-
)}
|
|
153
|
-
</>
|
|
154
|
-
);
|
|
155
|
-
})}
|
|
156
|
-
</Table.Tr>
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
Row.propTypes = {
|
|
160
|
-
item: PropTypes.shape({
|
|
161
|
-
changed: PropTypes.bool,
|
|
162
|
-
runs: PropTypes.arrayOf(
|
|
163
|
-
PropTypes.shape({
|
|
164
|
-
value: PropTypes.number,
|
|
165
|
-
displayValue: PropTypes.string,
|
|
166
|
-
deltaPercentage: PropTypes.number,
|
|
167
|
-
displayDeltaPercentage: PropTypes.string,
|
|
168
|
-
deltaType: PropTypes.string,
|
|
169
|
-
}),
|
|
170
|
-
),
|
|
171
|
-
}).isRequired,
|
|
172
|
-
renderRowHeader: PropTypes.func.isRequired,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export const MetricsTable = ({
|
|
176
|
-
className,
|
|
177
|
-
renderRowHeader,
|
|
178
|
-
runs,
|
|
179
|
-
items,
|
|
180
|
-
emptyMessage,
|
|
181
|
-
showHeaderSum,
|
|
182
|
-
title,
|
|
183
|
-
showAllItems,
|
|
184
|
-
setShowAllItems,
|
|
185
|
-
sort,
|
|
186
|
-
updateSort,
|
|
187
|
-
...restProps
|
|
188
|
-
}) => {
|
|
189
|
-
const columnCount = (runs.length - 1) * CURRENT_COLUMN_SPAN + BASELINE_COLUMN_SPAN + 1;
|
|
190
|
-
|
|
191
|
-
const rootClassName = cx(
|
|
192
|
-
styles.root,
|
|
193
|
-
className,
|
|
194
|
-
runs.length > 1 && styles.multipleRuns,
|
|
195
|
-
showHeaderSum && styles.showHeaderSum,
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
const showEmpty = isEmpty(items);
|
|
199
|
-
const showItems = !showEmpty;
|
|
200
|
-
const hasHiddenItems = items?.length > VISIBLE_COUNT;
|
|
201
|
-
const visibleItems = !hasHiddenItems || showAllItems ? items : items?.slice(0, VISIBLE_COUNT);
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<Table className={rootClassName} compact {...restProps}>
|
|
205
|
-
<Table.THead>
|
|
206
|
-
<Table.Tr className={styles.headerRow}>
|
|
207
|
-
<Table.Th className={styles.metricName} rowSpan={showHeaderSum ? 2 : 1}>
|
|
208
|
-
{title || ' '}
|
|
209
|
-
</Table.Th>
|
|
210
|
-
{runs.map((run, runIndex) => (
|
|
211
|
-
<ColumnJob run={run} isBaseline={runIndex === runs.length - 1} />
|
|
212
|
-
))}
|
|
213
|
-
</Table.Tr>
|
|
214
|
-
{showHeaderSum && (
|
|
215
|
-
<Table.Tr className={styles.headerRow}>
|
|
216
|
-
{runs.map((run, runIndex) => (
|
|
217
|
-
<ColumnSum
|
|
218
|
-
rows={items}
|
|
219
|
-
isBaseline={runIndex === runs.length - 1}
|
|
220
|
-
runIndex={runIndex}
|
|
221
|
-
updateSort={updateSort}
|
|
222
|
-
sort={sort}
|
|
223
|
-
/>
|
|
224
|
-
))}
|
|
225
|
-
</Table.Tr>
|
|
226
|
-
)}
|
|
227
|
-
</Table.THead>
|
|
228
|
-
<Table.TBody>
|
|
229
|
-
{showEmpty && (
|
|
230
|
-
<Table.Tr>
|
|
231
|
-
<Table.Td className={styles.empty} colSpan={columnCount}>
|
|
232
|
-
<Stack space="xxsmall">
|
|
233
|
-
<div>
|
|
234
|
-
<Icon glyph={Icon.ICONS.INFO} className={styles.emptyIcon} size="large" />
|
|
235
|
-
</div>
|
|
236
|
-
{emptyMessage}
|
|
237
|
-
</Stack>
|
|
238
|
-
</Table.Td>
|
|
239
|
-
</Table.Tr>
|
|
240
|
-
)}
|
|
241
|
-
|
|
242
|
-
{showItems && (
|
|
243
|
-
<>
|
|
244
|
-
{visibleItems.map((item) => (
|
|
245
|
-
<Row key={item.key} item={item} renderRowHeader={renderRowHeader} />
|
|
246
|
-
))}
|
|
247
|
-
|
|
248
|
-
{hasHiddenItems && (
|
|
249
|
-
<Table.Tr>
|
|
250
|
-
<Table.Td className={styles.showAllItems} colSpan={columnCount}>
|
|
251
|
-
{showAllItems ? (
|
|
252
|
-
<button
|
|
253
|
-
onClick={() => setShowAllItems(false)}
|
|
254
|
-
type="button"
|
|
255
|
-
className={styles.showAllItemsButton}
|
|
256
|
-
>
|
|
257
|
-
Show less
|
|
258
|
-
</button>
|
|
259
|
-
) : (
|
|
260
|
-
<button
|
|
261
|
-
onClick={() => setShowAllItems(true)}
|
|
262
|
-
type="button"
|
|
263
|
-
className={styles.showAllItemsButton}
|
|
264
|
-
>
|
|
265
|
-
Show all
|
|
266
|
-
</button>
|
|
267
|
-
)}
|
|
268
|
-
</Table.Td>
|
|
269
|
-
</Table.Tr>
|
|
270
|
-
)}
|
|
271
|
-
</>
|
|
272
|
-
)}
|
|
273
|
-
</Table.TBody>
|
|
274
|
-
</Table>
|
|
275
|
-
);
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
MetricsTable.defaultProps = {
|
|
279
|
-
className: '',
|
|
280
|
-
renderRowHeader: (item) => item.label,
|
|
281
|
-
emptyMessage: 'No entries found.',
|
|
282
|
-
showHeaderSum: false,
|
|
283
|
-
title: '',
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
MetricsTable.propTypes = {
|
|
287
|
-
className: PropTypes.string,
|
|
288
|
-
renderRowHeader: PropTypes.func,
|
|
289
|
-
runs: PropTypes.arrayOf(
|
|
290
|
-
PropTypes.shape({
|
|
291
|
-
internalBuildNumber: PropTypes.number,
|
|
292
|
-
}),
|
|
293
|
-
).isRequired,
|
|
294
|
-
items: PropTypes.arrayOf(
|
|
295
|
-
PropTypes.shape({
|
|
296
|
-
key: PropTypes.string,
|
|
297
|
-
label: PropTypes.string,
|
|
298
|
-
runs: PropTypes.arrayOf(
|
|
299
|
-
PropTypes.shape({
|
|
300
|
-
displayValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
301
|
-
displayDelta: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
302
|
-
}),
|
|
303
|
-
),
|
|
304
|
-
}),
|
|
305
|
-
).isRequired,
|
|
306
|
-
emptyMessage: PropTypes.element,
|
|
307
|
-
showHeaderSum: PropTypes.bool,
|
|
308
|
-
title: PropTypes.element,
|
|
309
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { getGroupFiltersLabelSuffix } from '../filters.utils';
|
|
2
|
-
|
|
3
|
-
describe('UI / Filters / utils', () => {
|
|
4
|
-
describe('getGroupFiltersLabelSuffix', () => {
|
|
5
|
-
test('should return none', () => {
|
|
6
|
-
const suffix = getGroupFiltersLabelSuffix([
|
|
7
|
-
['CSS', { label: 'CSS', defaultValue: false }],
|
|
8
|
-
['JS', { label: 'JS', defaultValue: false }],
|
|
9
|
-
['IMG', { label: 'IMG', defaultValue: false }],
|
|
10
|
-
['MEDIA', { label: 'Media', defaultValue: false }],
|
|
11
|
-
['FONTS', { label: 'Fonts', defaultValue: false }],
|
|
12
|
-
['HTML', { label: 'HTML', defaultValue: false }],
|
|
13
|
-
['OTHER', { label: 'Other', defaultValue: false }],
|
|
14
|
-
]);
|
|
15
|
-
|
|
16
|
-
expect(suffix).toEqual('none');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('should return all', () => {
|
|
20
|
-
const suffix = getGroupFiltersLabelSuffix([
|
|
21
|
-
['CSS', { label: 'CSS', defaultValue: true }],
|
|
22
|
-
['JS', { label: 'JS', defaultValue: true }],
|
|
23
|
-
['IMG', { label: 'IMG', defaultValue: true }],
|
|
24
|
-
['MEDIA', { label: 'Media', defaultValue: true }],
|
|
25
|
-
['FONTS', { label: 'Fonts', defaultValue: true }],
|
|
26
|
-
['HTML', { label: 'HTML', defaultValue: true }],
|
|
27
|
-
['OTHER', { label: 'Other', defaultValue: true }],
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
expect(suffix).toEqual('all');
|
|
31
|
-
});
|
|
32
|
-
test('should return checked filters', () => {
|
|
33
|
-
const suffix = getGroupFiltersLabelSuffix([
|
|
34
|
-
['CSS', { label: 'CSS', defaultValue: true }],
|
|
35
|
-
['JS', { label: 'JS', defaultValue: true }],
|
|
36
|
-
['IMG', { label: 'IMG', defaultValue: false }],
|
|
37
|
-
['MEDIA', { label: 'Media', defaultValue: false }],
|
|
38
|
-
['FONTS', { label: 'Fonts', defaultValue: false }],
|
|
39
|
-
['HTML', { label: 'HTML', defaultValue: false }],
|
|
40
|
-
['OTHER', { label: 'Other', defaultValue: false }],
|
|
41
|
-
]);
|
|
42
|
-
|
|
43
|
-
expect(suffix).toEqual('CSS, JS');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('should crop last filter if need it', () => {
|
|
47
|
-
const suffix = getGroupFiltersLabelSuffix([
|
|
48
|
-
['CSS', { label: 'CSS', defaultValue: true }],
|
|
49
|
-
['JS', { label: 'JS', defaultValue: true }],
|
|
50
|
-
['IMG', { label: 'IMG', defaultValue: true }],
|
|
51
|
-
['MEDIA', { label: 'Meeeeeeedia', defaultValue: true }],
|
|
52
|
-
['FONTS', { label: 'Fonts', defaultValue: false }],
|
|
53
|
-
['HTML', { label: 'HTML', defaultValue: false }],
|
|
54
|
-
['OTHER', { label: 'Other', defaultValue: false }],
|
|
55
|
-
]);
|
|
56
|
-
|
|
57
|
-
expect(suffix).toEqual('CSS, JS, IMG, Mee...');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('should crop and add remaining filters count', () => {
|
|
61
|
-
const suffix = getGroupFiltersLabelSuffix([
|
|
62
|
-
['CSS', { label: 'CSS', defaultValue: true }],
|
|
63
|
-
['JS', { label: 'JS', defaultValue: true }],
|
|
64
|
-
['IMG', { label: 'IMG', defaultValue: true }],
|
|
65
|
-
['MEDIA', { label: 'Media', defaultValue: true }],
|
|
66
|
-
['FONTS', { label: 'Fonts', defaultValue: true }],
|
|
67
|
-
['HTML', { label: 'HTML', defaultValue: true }],
|
|
68
|
-
['OTHER', { label: 'Other', defaultValue: false }],
|
|
69
|
-
]);
|
|
70
|
-
|
|
71
|
-
expect(suffix).toEqual('CSS, JS, IMG, Media +2');
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|