Skip to content

Commit

Permalink
Merge pull request #4117 from relative-ci/order-module-chunks
Browse files Browse the repository at this point in the history
fix(ui): Respect filters order
  • Loading branch information
vio authored Dec 26, 2023
2 parents 66c66f6 + 69ba392 commit 6982aef
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 96 deletions.
58 changes: 28 additions & 30 deletions packages/ui/src/components/bundle-assets/bundle-assets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,11 @@ const RUNS_LABELS = [RUN_TITLE_CURRENT, RUN_TITLE_BASELINE];

const getFileTypeFilters = (filters) =>
Object.entries(FILE_TYPE_LABELS)
.map(([id, label]) => ({
[id]: {
label,
defaultValue: get(filters, `${ASSET_FILE_TYPE}.${id}`, true),
},
}))
.reduce(
(agg, current) => ({
...agg,
...current,
}),
{},
);
.map(([key, label]) => ({
key,
label,
defaultValue: get(filters, `${ASSET_FILE_TYPE}.${key}`, true),
}));

const getFilters = ({ compareMode, filters }) => ({
[ASSET_FILTERS.CHANGED]: {
Expand All @@ -58,26 +50,32 @@ const getFilters = ({ compareMode, filters }) => ({
},
[ASSET_ENTRY_TYPE]: {
label: 'Entry type',
[ASSET_FILTERS.ENTRY]: {
label: 'Entry',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`, true),
},
[ASSET_FILTERS.INITIAL]: {
label: 'Initial',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`, true),
},
[ASSET_FILTERS.CHUNK]: {
label: 'Chunk',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`, true),
},
[ASSET_FILTERS.OTHER]: {
label: 'Other',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`, true),
},
children: [
{
key: ASSET_FILTERS.ENTRY,
label: 'Entry',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.ENTRY}`, true),
},
{
key: ASSET_FILTERS.INITIAL,
label: 'Initial',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.INITIAL}`, true),
},
{
key: ASSET_FILTERS.CHUNK,
label: 'Chunk',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.CHUNK}`, true),
},
{
key: ASSET_FILTERS.OTHER,
label: 'Other',
defaultValue: get(filters, `${ASSET_ENTRY_TYPE}.${ASSET_FILTERS.OTHER}`, true),
},
],
},
[ASSET_FILE_TYPE]: {
label: 'File type',
...getFileTypeFilters(filters),
children: getFileTypeFilters(filters),
},
});

Expand Down
38 changes: 23 additions & 15 deletions packages/ui/src/components/bundle-modules/bundle-modules.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import union from 'lodash/union';
import uniqBy from 'lodash/uniqBy';
import orderBy from 'lodash/orderBy';
import type { MetricRunInfo, ReportMetricRow } from '@bundle-stats/utils';
// @ts-ignore
import { MODULE_PATH_PACKAGES, type Module } from '@bundle-stats/utils/lib-esm/webpack';
Expand Down Expand Up @@ -164,34 +165,41 @@ export const generateFilterFieldsData = (params: GetFiltersFormDataParams): Filt

result[MODULE_SOURCE_TYPE] = {
label: I18N.SOURCE,
[MODULE_FILTERS.FIRST_PARTY]: {
label: I18N.SOURCE_FIRST_PARTY,
defaultValue: get(filters, `${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.FIRST_PARTY}`, true),
},
[MODULE_FILTERS.THIRD_PARTY]: {
label: I18N.SOURCE_THIRD_PARTY,
defaultValue: get(filters, `${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.THIRD_PARTY}`, true),
},
children: [
{
key: MODULE_FILTERS.FIRST_PARTY,
label: I18N.SOURCE_FIRST_PARTY,
defaultValue: get(filters, `${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.FIRST_PARTY}`, true),
},
{
key: MODULE_FILTERS.THIRD_PARTY,
label: I18N.SOURCE_THIRD_PARTY,
defaultValue: get(filters, `${MODULE_SOURCE_TYPE}.${MODULE_FILTERS.THIRD_PARTY}`, true),
},
],
} as FilterGroupFieldData;

if (!isEmpty(chunks)) {
const chunksFilter = { label: I18N.CHUNK } as FilterGroupFieldData;
chunks?.forEach((chunk) => {
chunksFilter[chunk.id] = {
const chunksFilter = { label: I18N.CHUNK, children: [] } as FilterGroupFieldData;
const chunksOrderedByName = orderBy(chunks, 'name');
chunksOrderedByName.forEach((chunk) => {
chunksFilter.children.push({
key: chunk.id,
label: chunk.name,
defaultValue: filters[`${MODULE_CHUNK}.${chunk.id}`] ?? true,
};
});
});

result[MODULE_CHUNK] = chunksFilter;
}

const moduleFileTypeFilter = { label: I18N.FILE_TYPE } as FilterGroupFieldData;
const moduleFileTypeFilter = { label: I18N.FILE_TYPE, children: [] } as FilterGroupFieldData;
MODULE_SOURCE_FILE_TYPES.forEach((fileType: string) => {
moduleFileTypeFilter[fileType] = {
moduleFileTypeFilter.children.push({
key: fileType,
label: FILE_TYPE_LABELS[fileType as keyof typeof FILE_TYPE_LABELS],
defaultValue: get(filters, `${MODULE_FILE_TYPE}.${fileType}`, true),
};
});
});

result[MODULE_FILE_TYPE] = moduleFileTypeFilter;
Expand Down
5 changes: 4 additions & 1 deletion packages/ui/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ interface FilterFieldData {
defaultValue: boolean;
disabled?: boolean;
}
type FilterGroupFieldData = { label: string } & { [key: string]: FilterFieldData };
type FilterGroupFieldData = {
label: string;
children: Array<{ key: string } & FilterFieldData>;
};
type FilterFieldsData = Record<string, FilterFieldData | FilterGroupFieldData>;
76 changes: 39 additions & 37 deletions packages/ui/src/ui/filters/__tests__/filters.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,68 @@ describe('UI / Filters / utils', () => {
describe('getGroupFiltersLabelSuffix', () => {
test('should return none', () => {
const suffix = getGroupFiltersLabelSuffix([
['CSS', { label: 'CSS', defaultValue: false }],
['JS', { label: 'JS', defaultValue: false }],
['IMG', { label: 'IMG', defaultValue: false }],
['MEDIA', { label: 'Media', defaultValue: false }],
['FONTS', { label: 'Fonts', defaultValue: false }],
['HTML', { label: 'HTML', defaultValue: false }],
['OTHER', { label: 'Other', defaultValue: false }],
{ key: 'CSS', label: 'CSS', defaultValue: false },
{ key: 'JS', label: 'JS', defaultValue: false },
{ key: 'IMG', label: 'IMG', defaultValue: false },
{ key: 'MEDIA', label: 'Media', defaultValue: false },
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
{ key: 'HTML', label: 'HTML', defaultValue: false },
{ key: 'OTHER', label: 'Other', defaultValue: false },
]);

expect(suffix).toEqual('none');
});

test('should return all', () => {
const suffix = getGroupFiltersLabelSuffix([
['CSS', { label: 'CSS', defaultValue: true }],
['JS', { label: 'JS', defaultValue: true }],
['IMG', { label: 'IMG', defaultValue: true }],
['MEDIA', { label: 'Media', defaultValue: true }],
['FONTS', { label: 'Fonts', defaultValue: true }],
['HTML', { label: 'HTML', defaultValue: true }],
['OTHER', { label: 'Other', defaultValue: true }],
{ key: 'CSS', label: 'CSS', defaultValue: true },
{ key: 'JS', label: 'JS', defaultValue: true },
{ key: 'IMG', label: 'IMG', defaultValue: true },
{ key: 'MEDIA', label: 'Media', defaultValue: true },
{ key: 'FONTS', label: 'Fonts', defaultValue: true },
{ key: 'HTML', label: 'HTML', defaultValue: true },
{ key: 'OTHER', label: 'Other', defaultValue: true },
]);

expect(suffix).toEqual('all');
});
test('should return checked filters', () => {
const suffix = getGroupFiltersLabelSuffix([
['CSS', { label: 'CSS', defaultValue: true }],
['JS', { label: 'JS', defaultValue: true }],
['IMG', { label: 'IMG', defaultValue: false }],
['MEDIA', { label: 'Media', defaultValue: false }],
['FONTS', { label: 'Fonts', defaultValue: false }],
['HTML', { label: 'HTML', defaultValue: false }],
['OTHER', { label: 'Other', defaultValue: false }],
{ key: 'CSS', label: 'CSS', defaultValue: true },
{ key: 'JS', label: 'JS', defaultValue: true },
{ key: 'IMG', label: 'IMG', defaultValue: false },
{ key: 'MEDIA', label: 'Media', defaultValue: false },
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
{ key: 'HTML', label: 'HTML', defaultValue: false },
{ key: 'OTHER', label: 'Other', defaultValue: false },
]);

expect(suffix).toEqual('CSS, JS');
});

test('should crop last filter if need it', () => {
const suffix = getGroupFiltersLabelSuffix([
['CSS', { label: 'CSS', defaultValue: true }],
['JS', { label: 'JS', defaultValue: true }],
['IMG', { label: 'IMG', defaultValue: true }],
['MEDIA', { label: 'Meeeeeeedia', defaultValue: true }],
['FONTS', { label: 'Fonts', defaultValue: false }],
['HTML', { label: 'HTML', defaultValue: false }],
['OTHER', { label: 'Other', defaultValue: false }],
{ key: 'CSS', label: 'CSS', defaultValue: true },
{ key: 'JS', label: 'JS', defaultValue: true },
{ key: 'IMG', label: 'IMG', defaultValue: true },
{ key: 'MEDIA', label: 'Meeeeeeedia', defaultValue: true },
{ key: 'FONTS', label: 'Fonts', defaultValue: false },
{ key: 'HTML', label: 'HTML', defaultValue: false },
{ key: 'OTHER', label: 'Other', defaultValue: false },
]);

expect(suffix).toEqual('CSS, JS, IMG, Mee...');
});

test('should crop and add remaining filters count', () => {
const suffix = getGroupFiltersLabelSuffix([
['CSS', { label: 'CSS', defaultValue: true }],
['JS', { label: 'JS', defaultValue: true }],
['IMG', { label: 'IMG', defaultValue: true }],
['MEDIA', { label: 'Media', defaultValue: true }],
['FONTS', { label: 'Fonts', defaultValue: true }],
['HTML', { label: 'HTML', defaultValue: true }],
['OTHER', { label: 'Other', defaultValue: false }],
{ key: 'CSS', label: 'CSS', defaultValue: true },
{ key: 'JS', label: 'JS', defaultValue: true },
{ key: 'IMG', label: 'IMG', defaultValue: true },
{ key: 'MEDIA', label: 'Media', defaultValue: true },
{ key: 'FONTS', label: 'Fonts', defaultValue: true },
{ key: 'HTML', label: 'HTML', defaultValue: true },
{ key: 'OTHER', label: 'Other', defaultValue: false },
]);

expect(suffix).toEqual('CSS, JS, IMG, Media +2');
Expand All @@ -81,8 +81,10 @@ describe('UI / Filters / utils', () => {
},
fileType: {
label: 'File type',
CSS: { label: 'CSS', defaultValue: false },
JS: { label: 'JS', defaultValue: true },
children: [
{ key: 'CSS', label: 'CSS', defaultValue: false },
{ key: 'JS', label: 'JS', defaultValue: true },
],
},
});

Expand Down
16 changes: 6 additions & 10 deletions packages/ui/src/ui/filters/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,10 @@ const FilterGroup = (props: FilterGroupProps) => {
toggleFilters,
} = props;

const { label: groupLabel, ...groupData } = data;
const { label: groupLabel, children: groupItems } = data;

const groupItems = Object.entries(groupData);
const groupCheckboxes = groupItems.filter(
([_, item]) => typeof item?.defaultValue !== 'undefined',
);
const areAllGroupItemsChecked = groupCheckboxes
.map(([itemKey]) => values?.[`${groupKey}.${itemKey}`])
const areAllGroupItemsChecked = groupItems
.map(({ key: itemKey }) => values?.[`${groupKey}.${itemKey}`])
.reduce((agg, val) => agg && val, true);

const filterSuffix = getGroupFiltersLabelSuffix(groupItems);
Expand All @@ -98,8 +94,8 @@ const FilterGroup = (props: FilterGroupProps) => {
const getOnGroupCheck =
(value: boolean, overrides = {}) =>
() => {
const newFilters = groupCheckboxes.reduce(
(agg, [itemKey]) => ({
const newFilters = groupItems.reduce(
(agg, { key: itemKey }) => ({
...agg,
[`${groupKey}.${itemKey}`]: value,
}),
Expand All @@ -123,7 +119,7 @@ const FilterGroup = (props: FilterGroupProps) => {
return (
<>
<div className={css.filterGroupItems}>
{groupItems.map(([itemKey, itemData]) => {
{groupItems.map(({ key: itemKey, ...itemData }) => {
const id = [groupKey, itemKey].join('.');
const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true });

Expand Down
17 changes: 14 additions & 3 deletions packages/ui/src/ui/filters/filters.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export const LABELS = {
ALL: 'all',
};

export const getGroupFiltersLabelSuffix = (filters: Array<[string, FilterFieldData]>): string => {
export const getGroupFiltersLabelSuffix = (filters: FilterGroupFieldData['children']): string => {
const filterCount = filters.length;
const checkedFilters = filters.filter(([_, { defaultValue }]) => defaultValue);
const checkedFilters = filters.filter(({ defaultValue }) => defaultValue);
const filterCheckedCount = checkedFilters.length;

if (filterCheckedCount === 0) {
Expand All @@ -23,7 +23,7 @@ export const getGroupFiltersLabelSuffix = (filters: Array<[string, FilterFieldDa
}

// eslint-disable-next-line no-unused-vars
const checkedFilterLabels = checkedFilters.map(([_, { label }]) => label);
const checkedFilterLabels = checkedFilters.map(({ label }) => label);

let suffix = '';
let inlinedLabelCount = 0;
Expand Down Expand Up @@ -76,6 +76,17 @@ export const getInitialValues = (
};
}

if ('children' in filtersData) {
const result = {} as Record<string, boolean>;

(filtersData as FilterGroupFieldData).children.forEach(({ key: childKey, defaultValue }) => {
const fullKey = [...(key ? [key] : []), childKey].join('.');
result[fullKey] = defaultValue;
});

return result;
}

let result = {};

Object.entries(filtersData).forEach(([groupKey, groupFilters]) => {
Expand Down

0 comments on commit 6982aef

Please sign in to comment.