@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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { getGroupFiltersLabelSuffix, getInitialValues } from '../filters.utils';
|
|
2
|
+
|
|
3
|
+
describe('UI / Filters / utils', () => {
|
|
4
|
+
describe('getGroupFiltersLabelSuffix', () => {
|
|
5
|
+
test('should return none', () => {
|
|
6
|
+
const suffix = getGroupFiltersLabelSuffix([
|
|
7
|
+
{ key: 'CSS', label: 'CSS', defaultValue: false },
|
|
8
|
+
{ key: 'JS', label: 'JS', defaultValue: false },
|
|
9
|
+
{ key: 'IMG', label: 'IMG', defaultValue: false },
|
|
10
|
+
{ key: 'MEDIA', label: 'Media', defaultValue: false },
|
|
11
|
+
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
|
|
12
|
+
{ key: 'HTML', label: 'HTML', defaultValue: false },
|
|
13
|
+
{ key: 'OTHER', label: 'Other', defaultValue: false },
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
expect(suffix).toEqual('none');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('should return all', () => {
|
|
20
|
+
const suffix = getGroupFiltersLabelSuffix([
|
|
21
|
+
{ key: 'CSS', label: 'CSS', defaultValue: true },
|
|
22
|
+
{ key: 'JS', label: 'JS', defaultValue: true },
|
|
23
|
+
{ key: 'IMG', label: 'IMG', defaultValue: true },
|
|
24
|
+
{ key: 'MEDIA', label: 'Media', defaultValue: true },
|
|
25
|
+
{ key: 'FONTS', label: 'Fonts', defaultValue: true },
|
|
26
|
+
{ key: 'HTML', label: 'HTML', defaultValue: true },
|
|
27
|
+
{ key: 'OTHER', label: 'Other', defaultValue: true },
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
expect(suffix).toEqual('all');
|
|
31
|
+
});
|
|
32
|
+
test('should return checked filters', () => {
|
|
33
|
+
const suffix = getGroupFiltersLabelSuffix([
|
|
34
|
+
{ key: 'CSS', label: 'CSS', defaultValue: true },
|
|
35
|
+
{ key: 'JS', label: 'JS', defaultValue: true },
|
|
36
|
+
{ key: 'IMG', label: 'IMG', defaultValue: false },
|
|
37
|
+
{ key: 'MEDIA', label: 'Media', defaultValue: false },
|
|
38
|
+
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
|
|
39
|
+
{ key: 'HTML', label: 'HTML', defaultValue: false },
|
|
40
|
+
{ key: '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
|
+
{ key: 'CSS', label: 'CSS', defaultValue: true },
|
|
49
|
+
{ key: 'JS', label: 'JS', defaultValue: true },
|
|
50
|
+
{ key: 'IMG', label: 'IMG', defaultValue: true },
|
|
51
|
+
{ key: 'MEDIA', label: 'Meeeeeeedia', defaultValue: true },
|
|
52
|
+
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
|
|
53
|
+
{ key: 'HTML', label: 'HTML', defaultValue: false },
|
|
54
|
+
{ key: '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
|
+
{ key: 'CSS', label: 'CSS', defaultValue: true },
|
|
63
|
+
{ key: 'JS', label: 'JS', defaultValue: true },
|
|
64
|
+
{ key: 'IMG', label: 'IMG', defaultValue: true },
|
|
65
|
+
{ key: 'MEDIA', label: 'Media', defaultValue: true },
|
|
66
|
+
{ key: 'FONTS', label: 'Fonts', defaultValue: true },
|
|
67
|
+
{ key: 'HTML', label: 'HTML', defaultValue: true },
|
|
68
|
+
{ key: 'OTHER', label: 'Other', defaultValue: false },
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
expect(suffix).toEqual('CSS, JS, IMG, Media +2');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('getInitialValues', () => {
|
|
76
|
+
test('should return initial values', () => {
|
|
77
|
+
const initialValues = getInitialValues('', {
|
|
78
|
+
changed: {
|
|
79
|
+
label: 'Changed',
|
|
80
|
+
defaultValue: false,
|
|
81
|
+
},
|
|
82
|
+
fileType: {
|
|
83
|
+
label: 'File type',
|
|
84
|
+
children: [
|
|
85
|
+
{ key: 'CSS', label: 'CSS', defaultValue: false },
|
|
86
|
+
{ key: 'JS', label: 'JS', defaultValue: true },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(initialValues).toEqual({
|
|
92
|
+
changed: false,
|
|
93
|
+
'fileType.CSS': false,
|
|
94
|
+
'fileType.JS': true,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import cx from 'classnames';
|
|
4
3
|
|
|
4
|
+
import type { FilterFieldsData, FilterGroupFieldData } from '../../types';
|
|
5
5
|
import { FlexStack } from '../../layout/flex-stack';
|
|
6
6
|
import { Dropdown } from '../dropdown';
|
|
7
|
+
import * as I18N from './filters.i18n';
|
|
7
8
|
import { getGroupFiltersLabelSuffix, LABELS } from './filters.utils';
|
|
8
9
|
import css from './filters.module.css';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
interface FilterProps extends React.ComponentProps<'input'> {
|
|
12
|
+
as?: React.ElementType;
|
|
13
|
+
buttonClassName?: string;
|
|
14
|
+
label: string;
|
|
15
|
+
name: string;
|
|
16
|
+
getOnOnlyClick?: (name: string) => () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const Filter = (props: FilterProps) => {
|
|
11
20
|
const {
|
|
12
|
-
className,
|
|
21
|
+
className = '',
|
|
13
22
|
as: Component = 'div',
|
|
14
|
-
buttonClassName,
|
|
23
|
+
buttonClassName = '',
|
|
15
24
|
label,
|
|
16
25
|
name,
|
|
17
26
|
getOnOnlyClick,
|
|
@@ -24,16 +33,21 @@ const Filter = (props) => {
|
|
|
24
33
|
return (
|
|
25
34
|
<Component className={rootClassName}>
|
|
26
35
|
{/* eslint-disable */}
|
|
27
|
-
<FlexStack
|
|
36
|
+
<FlexStack
|
|
37
|
+
space="xxxsmall"
|
|
38
|
+
alignItems="center"
|
|
39
|
+
as="label"
|
|
40
|
+
className={cx(css.filterCheckbox, buttonClassName)}
|
|
41
|
+
>
|
|
28
42
|
{/* eslint-enabled */}
|
|
29
|
-
<input
|
|
30
|
-
<span className={css.filterLabel}
|
|
43
|
+
<input type="checkbox" id={id} name={name} {...inputProps} className={css.filterInput} />
|
|
44
|
+
<span title={label} className={css.filterLabel}>
|
|
31
45
|
{label}
|
|
32
46
|
</span>
|
|
33
47
|
</FlexStack>
|
|
34
48
|
|
|
35
49
|
{getOnOnlyClick && (
|
|
36
|
-
<button
|
|
50
|
+
<button type="button" onClick={getOnOnlyClick(name)} className={css.filterOnlyButton}>
|
|
37
51
|
only
|
|
38
52
|
</button>
|
|
39
53
|
)}
|
|
@@ -41,34 +55,30 @@ const Filter = (props) => {
|
|
|
41
55
|
);
|
|
42
56
|
};
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
Filter.defaultProps = {
|
|
54
|
-
className: '',
|
|
55
|
-
as: 'div',
|
|
56
|
-
buttonClassName: '',
|
|
57
|
-
getOnOnlyClick: null,
|
|
58
|
-
};
|
|
58
|
+
interface FilterGroupProps extends React.ComponentProps<'div'> {
|
|
59
|
+
buttonClassName?: string;
|
|
60
|
+
groupKey: string;
|
|
61
|
+
data: FilterGroupFieldData;
|
|
62
|
+
values: Record<string, boolean>;
|
|
63
|
+
onCheckboxChange: FilterProps['onChange'];
|
|
64
|
+
toggleFilters: (newFilters: Record<string, boolean>) => void;
|
|
65
|
+
}
|
|
59
66
|
|
|
60
|
-
const FilterGroup = (props) => {
|
|
61
|
-
const {
|
|
62
|
-
|
|
67
|
+
const FilterGroup = (props: FilterGroupProps) => {
|
|
68
|
+
const {
|
|
69
|
+
className = '',
|
|
70
|
+
buttonClassName = '',
|
|
71
|
+
groupKey,
|
|
72
|
+
data,
|
|
73
|
+
values,
|
|
74
|
+
onCheckboxChange,
|
|
75
|
+
toggleFilters,
|
|
76
|
+
} = props;
|
|
63
77
|
|
|
64
|
-
const { label: groupLabel,
|
|
78
|
+
const { label: groupLabel, children: groupItems } = data;
|
|
65
79
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
([itemKey, item]) => typeof item?.defaultValue !== 'undefined',
|
|
69
|
-
);
|
|
70
|
-
const areAllGroupItemsChecked = groupCheckboxes
|
|
71
|
-
.map(([itemKey]) => values?.[`${groupKey}.${itemKey}`])
|
|
80
|
+
const areAllGroupItemsChecked = groupItems
|
|
81
|
+
.map(({ key: itemKey }) => values?.[`${groupKey}.${itemKey}`])
|
|
72
82
|
.reduce((agg, val) => agg && val, true);
|
|
73
83
|
|
|
74
84
|
const filterSuffix = getGroupFiltersLabelSuffix(groupItems);
|
|
@@ -82,10 +92,10 @@ const FilterGroup = (props) => {
|
|
|
82
92
|
);
|
|
83
93
|
|
|
84
94
|
const getOnGroupCheck =
|
|
85
|
-
(value, overrides = {}) =>
|
|
95
|
+
(value: boolean, overrides = {}) =>
|
|
86
96
|
() => {
|
|
87
|
-
const newFilters =
|
|
88
|
-
(agg,
|
|
97
|
+
const newFilters = groupItems.reduce(
|
|
98
|
+
(agg, { key: itemKey }) => ({
|
|
89
99
|
...agg,
|
|
90
100
|
[`${groupKey}.${itemKey}`]: value,
|
|
91
101
|
}),
|
|
@@ -105,11 +115,11 @@ const FilterGroup = (props) => {
|
|
|
105
115
|
label={dropdownLabel}
|
|
106
116
|
ariaLabel={`${groupLabel}: ${filterSuffix}`}
|
|
107
117
|
>
|
|
108
|
-
{({ MenuItem,
|
|
118
|
+
{({ MenuItem, menuItemClassName }) => {
|
|
109
119
|
return (
|
|
110
120
|
<>
|
|
111
121
|
<div className={css.filterGroupItems}>
|
|
112
|
-
{groupItems.map((
|
|
122
|
+
{groupItems.map(({ key: itemKey, ...itemData }) => {
|
|
113
123
|
const id = [groupKey, itemKey].join('.');
|
|
114
124
|
const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true });
|
|
115
125
|
|
|
@@ -137,7 +147,7 @@ const FilterGroup = (props) => {
|
|
|
137
147
|
type="button"
|
|
138
148
|
onClick={getOnGroupCheck(false)}
|
|
139
149
|
>
|
|
140
|
-
|
|
150
|
+
{I18N.CLEAR}
|
|
141
151
|
</MenuItem>
|
|
142
152
|
) : (
|
|
143
153
|
<MenuItem
|
|
@@ -147,7 +157,7 @@ const FilterGroup = (props) => {
|
|
|
147
157
|
type="button"
|
|
148
158
|
onClick={getOnGroupCheck(true)}
|
|
149
159
|
>
|
|
150
|
-
|
|
160
|
+
{I18N.CHECK}
|
|
151
161
|
</MenuItem>
|
|
152
162
|
)}
|
|
153
163
|
</div>
|
|
@@ -158,38 +168,30 @@ const FilterGroup = (props) => {
|
|
|
158
168
|
);
|
|
159
169
|
};
|
|
160
170
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
onCheckboxChange: PropTypes.func.isRequired,
|
|
168
|
-
toggleFilters: PropTypes.func.isRequired,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
FilterGroup.defaultProps = {
|
|
172
|
-
className: '',
|
|
173
|
-
buttonClassName: '',
|
|
174
|
-
};
|
|
171
|
+
interface FiltersProps extends React.ComponentProps<'div'> {
|
|
172
|
+
values: Record<string, boolean>;
|
|
173
|
+
filters: FilterFieldsData;
|
|
174
|
+
toggleFilter: (name: string, value: boolean) => void;
|
|
175
|
+
toggleFilters: FilterGroupProps['toggleFilters'];
|
|
176
|
+
}
|
|
175
177
|
|
|
176
|
-
export const Filters = (props) => {
|
|
177
|
-
const { className, values, filters, toggleFilter, toggleFilters } = props;
|
|
178
|
+
export const Filters = (props: FiltersProps) => {
|
|
179
|
+
const { className = '', values, filters, toggleFilter, toggleFilters } = props;
|
|
178
180
|
|
|
179
181
|
const onCheckboxChange = useCallback(
|
|
180
|
-
(event) => {
|
|
182
|
+
(event: any) => {
|
|
181
183
|
const { name } = event.target;
|
|
182
184
|
toggleFilter(name, !values[name]);
|
|
183
185
|
},
|
|
184
|
-
[toggleFilter, values]
|
|
186
|
+
[toggleFilter, values],
|
|
185
187
|
);
|
|
186
188
|
const rootClassName = cx(css.root, className);
|
|
187
189
|
|
|
188
190
|
return (
|
|
189
191
|
<form className={rootClassName}>
|
|
190
|
-
<FlexStack space="xxsmall" alignItems="
|
|
192
|
+
<FlexStack space="xxsmall" alignItems="top" className={css.items}>
|
|
191
193
|
{Object.entries(filters).map(([name, data]) => {
|
|
192
|
-
if (
|
|
194
|
+
if ('defaultValue' in data) {
|
|
193
195
|
return (
|
|
194
196
|
<Filter
|
|
195
197
|
key={name}
|
|
@@ -199,7 +201,7 @@ export const Filters = (props) => {
|
|
|
199
201
|
label={data.label}
|
|
200
202
|
onChange={onCheckboxChange}
|
|
201
203
|
checked={values[name]}
|
|
202
|
-
disabled={data.disabled}
|
|
204
|
+
disabled={data.disabled as boolean}
|
|
203
205
|
/>
|
|
204
206
|
);
|
|
205
207
|
}
|
|
@@ -221,14 +223,3 @@ export const Filters = (props) => {
|
|
|
221
223
|
</form>
|
|
222
224
|
);
|
|
223
225
|
};
|
|
224
|
-
|
|
225
|
-
Filters.defaultProps = {
|
|
226
|
-
className: '',
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
Filters.propTypes = {
|
|
230
|
-
className: PropTypes.string,
|
|
231
|
-
values: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
|
232
|
-
filters: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
|
233
|
-
toggleFilter: PropTypes.func.isRequired,
|
|
234
|
-
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { FilterFieldData, FilterFieldsData, FilterGroupFieldData } from '../../types';
|
|
2
|
+
|
|
1
3
|
const FILTER_SUFFIX_MAX_LENGTH = 18;
|
|
2
4
|
const ELLIPSES = '...';
|
|
3
5
|
const JOIN = ', ';
|
|
@@ -7,14 +9,9 @@ export const LABELS = {
|
|
|
7
9
|
ALL: 'all',
|
|
8
10
|
};
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
* @param {Array<Array>} filters
|
|
12
|
-
* @return {String}
|
|
13
|
-
*/
|
|
14
|
-
export const getGroupFiltersLabelSuffix = (filters) => {
|
|
12
|
+
export const getGroupFiltersLabelSuffix = (filters: FilterGroupFieldData['children']): string => {
|
|
15
13
|
const filterCount = filters.length;
|
|
16
|
-
|
|
17
|
-
const checkedFilters = filters.filter(([_, { defaultValue }]) => defaultValue);
|
|
14
|
+
const checkedFilters = filters.filter(({ defaultValue }) => defaultValue);
|
|
18
15
|
const filterCheckedCount = checkedFilters.length;
|
|
19
16
|
|
|
20
17
|
if (filterCheckedCount === 0) {
|
|
@@ -26,7 +23,7 @@ export const getGroupFiltersLabelSuffix = (filters) => {
|
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
// eslint-disable-next-line no-unused-vars
|
|
29
|
-
const checkedFilterLabels = checkedFilters.map((
|
|
26
|
+
const checkedFilterLabels = checkedFilters.map(({ label }) => label);
|
|
30
27
|
|
|
31
28
|
let suffix = '';
|
|
32
29
|
let inlinedLabelCount = 0;
|
|
@@ -65,23 +62,43 @@ export const getGroupFiltersLabelSuffix = (filters) => {
|
|
|
65
62
|
return `${suffix}${skippedLabels > 0 ? ` +${skippedLabels}` : ''}`;
|
|
66
63
|
};
|
|
67
64
|
|
|
68
|
-
export const getInitialValues = (
|
|
69
|
-
|
|
65
|
+
export const getInitialValues = (
|
|
66
|
+
key: string,
|
|
67
|
+
filtersData: FilterFieldsData | FilterFieldData | FilterGroupFieldData | string,
|
|
68
|
+
): Record<string, boolean> => {
|
|
69
|
+
if (typeof filtersData !== 'object') {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if ('defaultValue' in filtersData) {
|
|
70
74
|
return {
|
|
71
|
-
[key]:
|
|
75
|
+
[key]: (filtersData as FilterFieldData).defaultValue,
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
if ('children' in filtersData) {
|
|
80
|
+
const result = {} as Record<string, boolean>;
|
|
81
|
+
|
|
82
|
+
(filtersData as FilterGroupFieldData).children.forEach(({ key: childKey, defaultValue }) => {
|
|
83
|
+
const fullKey = [...(key ? [key] : []), childKey].join('.');
|
|
84
|
+
result[fullKey] = defaultValue;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return result;
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
};
|
|
90
|
+
let result = {};
|
|
87
91
|
|
|
92
|
+
Object.entries(filtersData).forEach(([groupKey, groupFilters]) => {
|
|
93
|
+
if (typeof groupFilters === 'object') {
|
|
94
|
+
const fullKey = [...(key ? [key] : []), groupKey].join('.');
|
|
95
|
+
const groupInitialValues = getInitialValues(fullKey, groupFilters as any);
|
|
96
|
+
result = {
|
|
97
|
+
...result,
|
|
98
|
+
...groupInitialValues,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return result;
|
|
104
|
+
};
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import isEqual from 'lodash/isEqual';
|
|
4
3
|
import merge from 'lodash/merge';
|
|
5
4
|
|
|
5
|
+
import { FilterFieldsData } from '../../types';
|
|
6
6
|
import { getInitialValues } from './filters.utils';
|
|
7
7
|
import { Filters as BaseComponent } from './filters';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
interface FiltersProps
|
|
10
|
+
extends Omit<
|
|
11
|
+
React.ComponentProps<typeof BaseComponent>,
|
|
12
|
+
'onChange' | 'filters' | 'values' | 'toggleFilter' | 'toggleFilters'
|
|
13
|
+
> {
|
|
14
|
+
onChange?: (newValues: Record<string, boolean>) => void;
|
|
15
|
+
filters: FilterFieldsData;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Filters = (props: FiltersProps) => {
|
|
10
19
|
const { onChange, filters, ...restProps } = props;
|
|
11
20
|
const [values, setValues] = useState(getInitialValues('', filters));
|
|
12
21
|
|
|
@@ -26,7 +35,7 @@ export const Filters = (props) => {
|
|
|
26
35
|
);
|
|
27
36
|
|
|
28
37
|
const toggleFilter = useCallback(
|
|
29
|
-
(key, value) => {
|
|
38
|
+
(key: string, value: boolean) => {
|
|
30
39
|
const nextValues = merge({}, values, { [key]: value });
|
|
31
40
|
setValues(nextValues);
|
|
32
41
|
|
|
@@ -34,11 +43,11 @@ export const Filters = (props) => {
|
|
|
34
43
|
onChange(nextValues);
|
|
35
44
|
}
|
|
36
45
|
},
|
|
37
|
-
[onChange, setValues, values]
|
|
46
|
+
[onChange, setValues, values],
|
|
38
47
|
);
|
|
39
48
|
|
|
40
49
|
const toggleFilters = useCallback(
|
|
41
|
-
(newFilters) => {
|
|
50
|
+
(newFilters: Record<string, boolean>) => {
|
|
42
51
|
const nextValues = merge({}, values, newFilters);
|
|
43
52
|
setValues(nextValues);
|
|
44
53
|
|
|
@@ -59,15 +68,3 @@ export const Filters = (props) => {
|
|
|
59
68
|
/>
|
|
60
69
|
);
|
|
61
70
|
};
|
|
62
|
-
|
|
63
|
-
Filters.defaultProps = {
|
|
64
|
-
onChange: null,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
Filters.propTypes = {
|
|
68
|
-
/** Filter config */
|
|
69
|
-
filters: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
|
70
|
-
|
|
71
|
-
/** OnChange handler */
|
|
72
|
-
onChange: PropTypes.func,
|
|
73
|
-
};
|
|
@@ -1,64 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SortAction } from '../../types';
|
|
3
|
+
import type { Chunk, Job, ReportMetricModuleRow } from './bundle-modules.types';
|
|
4
|
+
interface BundleModulesProps extends React.ComponentProps<'div'> {
|
|
5
|
+
jobs?: Array<Job>;
|
|
6
|
+
items?: Array<ReportMetricModuleRow>;
|
|
7
|
+
allItems?: Array<ReportMetricModuleRow>;
|
|
8
|
+
chunks?: Array<Chunk>;
|
|
9
|
+
totalRowCount: number;
|
|
10
|
+
updateFilters: () => void;
|
|
11
|
+
resetFilters: () => void;
|
|
12
|
+
resetAllFilters: () => void;
|
|
13
|
+
filters: Record<string, boolean>;
|
|
12
14
|
sort: any;
|
|
13
|
-
updateSort:
|
|
14
|
-
search:
|
|
15
|
-
updateSearch:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
hideEntryInfo: any;
|
|
20
|
-
}): React.JSX.Element;
|
|
21
|
-
export namespace BundleModules {
|
|
22
|
-
namespace defaultProps {
|
|
23
|
-
export let className: string;
|
|
24
|
-
export let items: never[];
|
|
25
|
-
export let jobs: never[];
|
|
26
|
-
export let totalRowCount: number;
|
|
27
|
-
export let hasActiveFilters: boolean;
|
|
28
|
-
export { ComponentLink as customComponentLink };
|
|
29
|
-
}
|
|
30
|
-
namespace propTypes {
|
|
31
|
-
let className_1: PropTypes.Requireable<string>;
|
|
32
|
-
export { className_1 as className };
|
|
33
|
-
let items_1: PropTypes.Requireable<any[]>;
|
|
34
|
-
export { items_1 as items };
|
|
35
|
-
let jobs_1: PropTypes.Requireable<any[]>;
|
|
36
|
-
export { jobs_1 as jobs };
|
|
37
|
-
export let chunks: PropTypes.Validator<(PropTypes.InferProps<{
|
|
38
|
-
id: PropTypes.Requireable<string>;
|
|
39
|
-
name: PropTypes.Requireable<string>;
|
|
40
|
-
}> | null | undefined)[]>;
|
|
41
|
-
let totalRowCount_1: PropTypes.Requireable<number>;
|
|
42
|
-
export { totalRowCount_1 as totalRowCount };
|
|
43
|
-
export let updateFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
44
|
-
export let resetFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
45
|
-
export let resetAllFilters: PropTypes.Validator<(...args: any[]) => any>;
|
|
46
|
-
export let filters: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
47
|
-
changed: PropTypes.Requireable<boolean>;
|
|
48
|
-
}>>>;
|
|
49
|
-
let hasActiveFilters_1: PropTypes.Requireable<boolean>;
|
|
50
|
-
export { hasActiveFilters_1 as hasActiveFilters };
|
|
51
|
-
export let sort: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
52
|
-
sortBy: PropTypes.Requireable<string>;
|
|
53
|
-
direction: PropTypes.Requireable<string>;
|
|
54
|
-
}>>>;
|
|
55
|
-
export let updateSort: PropTypes.Validator<(...args: any[]) => any>;
|
|
56
|
-
export let search: PropTypes.Validator<string>;
|
|
57
|
-
export let updateSearch: PropTypes.Validator<(...args: any[]) => any>;
|
|
58
|
-
export let customComponentLink: PropTypes.Requireable<PropTypes.ReactComponentLike>;
|
|
59
|
-
export let hideEntryInfo: PropTypes.Validator<(...args: any[]) => any>;
|
|
60
|
-
}
|
|
15
|
+
updateSort: ({ field, direction }: SortAction) => void;
|
|
16
|
+
search: string;
|
|
17
|
+
updateSearch: (newSerarch: string) => void;
|
|
18
|
+
entryId?: string;
|
|
19
|
+
hideEntryInfo: () => void;
|
|
20
|
+
customComponentLink: React.ElementType;
|
|
61
21
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
import PropTypes from 'prop-types';
|
|
22
|
+
export declare const BundleModules: (props: BundleModulesProps) => React.JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const SEARCH = "Search by module name";
|
|
2
|
+
export declare const CHANGED = "Changed";
|
|
3
|
+
export declare const DUPLICATE = "Duplicate";
|
|
4
|
+
export declare const CHUNK = "Chunk";
|
|
5
|
+
export declare const FILE_TYPE = "File type";
|
|
6
|
+
export declare const SOURCE = "Source";
|
|
7
|
+
export declare const SOURCE_FIRST_PARTY = "First party";
|
|
8
|
+
export declare const SOURCE_THIRD_PARTY = "Third party";
|
|
@@ -1,5 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { ReportMetricRow } from '@bundle-stats/utils';
|
|
2
|
+
import { type Module } from '@bundle-stats/utils/lib-esm/webpack';
|
|
3
|
+
import type { FilterFieldsData } from '../../types';
|
|
4
|
+
import type { Chunk, Job, ReportMetricModuleRow } from './bundle-modules.types';
|
|
5
|
+
export declare const addRowFlags: (row: Module & ReportMetricRow) => ReportMetricModuleRow;
|
|
6
|
+
export declare const getCustomSort: (item: ReportMetricRow) => (string | boolean)[];
|
|
7
|
+
export declare const generateGetRowFilter: ({ chunkIds }: {
|
|
8
|
+
chunkIds: Array<string>;
|
|
9
|
+
}) => (filters: Record<string, unknown>) => (row: ReportMetricModuleRow) => boolean;
|
|
10
|
+
export declare const extractChunkData: (jobs: Array<Job>) => {
|
|
11
|
+
chunks: Chunk[];
|
|
12
|
+
chunkIds: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare const generateFilters: (chunkIds: Array<string>, multipleJobs: boolean) => {
|
|
15
|
+
defaultFilters: {
|
|
16
|
+
[x: string]: boolean;
|
|
17
|
+
};
|
|
18
|
+
allEntriesFilters: {
|
|
19
|
+
[x: string]: boolean;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
interface GetFiltersFormDataParams {
|
|
23
|
+
filters: Record<string, boolean>;
|
|
24
|
+
chunks: Array<Chunk>;
|
|
25
|
+
compareMode: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const generateFilterFieldsData: (params: GetFiltersFormDataParams) => FilterFieldsData;
|
|
28
|
+
export {};
|
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
export function BundleModules(props: any): React.JSX.Element;
|
|
2
|
-
export namespace BundleModules {
|
|
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 { SortAction } from '../../types';
|
|
3
|
+
import { BundleModules as BaseComponent } from './bundle-modules';
|
|
4
|
+
import * as types from './bundle-modules.types';
|
|
5
|
+
interface BundleModulesProps extends Omit<React.ComponentProps<typeof BaseComponent>, 'jobs' | 'items' | 'chunks' | 'updateFilters' | 'resetFilters' | 'resetAllFilters' | 'filters' | 'sort' | 'updateSort' | 'search' | 'updateSearch' | 'entryId' | 'allItems' | 'totalRowCount' | 'hideEntryInfo'> {
|
|
6
|
+
jobs: Array<types.Job>;
|
|
7
|
+
filters: Record<string, boolean>;
|
|
8
|
+
search?: string;
|
|
9
|
+
setState: (params: any) => void;
|
|
10
|
+
sortBy?: string;
|
|
11
|
+
direction?: SortAction['direction'];
|
|
12
|
+
}
|
|
13
|
+
export declare const BundleModules: (props: BundleModulesProps) => React.JSX.Element;
|
|
14
|
+
export {};
|