Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 27 additions & 51 deletions dashboard/src/components/BootsTable/BootsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import { FormattedMessage, useIntl } from 'react-intl';

import type {
TestByCommitHash,
PossibleTableFilters,
TableStatusOption,
TableStatusSelection,
TableStatusToggleValue,
TTestByCommitHashResponse,
} from '@/types/tree/TreeDetails';
import { possibleTableFilters } from '@/types/tree/TreeDetails';

import { getStatusGroup } from '@/utils/status';

Expand Down Expand Up @@ -53,7 +54,8 @@ import TooltipHardware from '@/components/Table/TooltipHardware';
import { EMPTY_VALUE } from '@/lib/string';
import { UNKNOWN_STRING } from '@/utils/constants/backend';
import { TableTopFilters } from '@/components/Table/TableTopFilters';
import type { TStatusFilters } from '@/components/Table/TableStatusFilter';
import { buildStatusFilterChips } from '@/components/Table/TableStatusFilter';
import { tableStatusFilterValueForColumn } from '@/utils/tableStatusFilter';

const defaultColumns: ColumnDef<TestByCommitHash>[] = [
{
Expand All @@ -65,7 +67,8 @@ const defaultColumns: ColumnDef<TestByCommitHash>[] = [
{
accessorKey: 'status',
filterFn: (row, columnId, filterValue) =>
getStatusGroup(row.getValue(columnId)) === filterValue,
!Array.isArray(filterValue) ||
filterValue.includes(getStatusGroup(row.getValue(columnId))),
header: ({ column }): JSX.Element => (
<TableHeader
column={column}
Expand Down Expand Up @@ -125,10 +128,10 @@ const defaultColumns: ColumnDef<TestByCommitHash>[] = [
interface IBootsTable {
tableKey: TableKeys;
testHistory?: TestHistory[];
filter: PossibleTableFilters;
filter: TableStatusSelection;
columns?: ColumnDef<TestByCommitHash>[];
getRowLink: (testId: TestHistory['id']) => LinkProps;
onClickFilter: (newFilter: PossibleTableFilters) => void;
onToggleFilter: (option: TableStatusToggleValue) => void;
updatePathFilter?: (pathFilter: string) => void;
currentPathFilter?: string;
}
Expand All @@ -142,7 +145,7 @@ export function BootsTable({
filter,
columns = defaultColumns,
getRowLink,
onClickFilter,
onToggleFilter,
updatePathFilter,
currentPathFilter,
}: IBootsTable): JSX.Element {
Expand Down Expand Up @@ -203,9 +206,8 @@ export function BootsTable({
},
});

const filterCount: Record<PossibleTableFilters, number> = useMemo(() => {
const count: Record<PossibleTableFilters, number> = {
all: 0,
const filterCount: Record<TableStatusOption, number> = useMemo(() => {
const count: Record<TableStatusOption, number> = {
success: 0,
failed: 0,
inconclusive: 0,
Expand All @@ -217,61 +219,34 @@ export function BootsTable({

const dataFilter = globalFilter ? rowsOriginal : testsData;

count.all = dataFilter.length;
dataFilter.forEach(test => count[getStatusGroup(test.status)]++);

return count;
}, [testsData, globalFilter, table]);

const checkIfFilterIsSelected = useCallback(
(possibleFilter: PossibleTableFilters): boolean => {
return possibleFilter === filter;
},
[filter],
);

const filters: TStatusFilters[] = useMemo(
() => [
{
label: intl.formatMessage(
{ id: 'global.allCount' },
{ count: filterCount[possibleTableFilters[0]] },
),
value: possibleTableFilters[0],
isSelected: checkIfFilterIsSelected(possibleTableFilters[0]),
},
{
label: intl.formatMessage(
const chips = useMemo(
() =>
buildStatusFilterChips({
success: intl.formatMessage(
{ id: 'global.successCount' },
{ count: filterCount[possibleTableFilters[1]] },
{ count: filterCount.success },
),
value: possibleTableFilters[1],
isSelected: checkIfFilterIsSelected(possibleTableFilters[1]),
},
{
label: intl.formatMessage(
failed: intl.formatMessage(
{ id: 'global.failedCount' },
{ count: filterCount[possibleTableFilters[2]] },
{ count: filterCount.failed },
),
value: possibleTableFilters[2],
isSelected: checkIfFilterIsSelected(possibleTableFilters[2]),
},
{
label: intl.formatMessage(
inconclusive: intl.formatMessage(
{ id: 'global.inconclusiveCount' },
{ count: filterCount[possibleTableFilters[3]] },
{ count: filterCount.inconclusive },
),
value: possibleTableFilters[3],
isSelected: checkIfFilterIsSelected(possibleTableFilters[3]),
},
],
[intl, filterCount, checkIfFilterIsSelected],
}),
[intl, filterCount],
);

useEffect(() => {
table
.getColumn('status')
?.setFilterValue(filter !== 'all' ? filter : undefined);
?.setFilterValue(tableStatusFilterValueForColumn(filter));
}, [filter, table]);

const onSearchChange = useCallback(
Expand Down Expand Up @@ -407,8 +382,9 @@ export function BootsTable({
>
<TableTopFilters
key="bootsTableSearch"
filters={filters}
onClickFilter={onClickFilter}
chips={chips}
selection={filter}
onToggleFilter={onToggleFilter}
onSearchChange={onSearchChange}
currentPathFilter={currentPathFilter}
/>
Expand Down
8 changes: 4 additions & 4 deletions dashboard/src/components/BuildDetails/BuildDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Sheet } from '@/components/Sheet';

import type {
TableFilter,
PossibleTableFilters,
TableStatusToggleValue,
} from '@/types/tree/TreeDetails';

import type {
Expand Down Expand Up @@ -63,14 +63,14 @@ import BuildDetailsTestSection from './BuildDetailsTestSection';

interface BuildDetailsProps {
breadcrumb?: JSX.Element;
onClickFilter: (filter: PossibleTableFilters) => void;
onToggleFilter: (option: TableStatusToggleValue) => void;
tableFilter: TableFilter;
getTestTableRowLink: (testId: string) => LinkProps;
}

const BuildDetails = ({
breadcrumb,
onClickFilter,
onToggleFilter,
tableFilter,
getTestTableRowLink,
}: BuildDetailsProps): JSX.Element => {
Expand Down Expand Up @@ -341,7 +341,7 @@ const BuildDetails = ({
<SectionGroup sections={generalSections} />
<BuildDetailsTestSection
buildId={buildId ?? ''}
onClickFilter={onClickFilter}
onToggleFilter={onToggleFilter}
tableFilter={tableFilter}
getRowLink={getTestTableRowLink}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useBuildTests } from '@/api/buildTests';

import type {
TableFilter,
PossibleTableFilters,
TableStatusToggleValue,
} from '@/types/tree/TreeDetails';

import { TestsTable } from '@/components/TestsTable/TestsTable';
Expand All @@ -20,14 +20,14 @@ import QuerySwitcher from '@/components/QuerySwitcher/QuerySwitcher';

interface IBuildDetailsTestSection {
buildId: string;
onClickFilter: (filter: PossibleTableFilters) => void;
onToggleFilter: (option: TableStatusToggleValue) => void;
tableFilter: TableFilter;
getRowLink: (testId: string) => LinkProps;
}

const BuildDetailsTestSection = ({
buildId,
onClickFilter,
onToggleFilter,
tableFilter,
getRowLink,
}: IBuildDetailsTestSection): JSX.Element => {
Expand Down Expand Up @@ -56,7 +56,7 @@ const BuildDetailsTestSection = ({
<TestsTable
tableKey="buildDetailsTests"
testHistory={data}
onClickFilter={onClickFilter}
onToggleFilter={onToggleFilter}
filter={tableFilter.testsTable}
getRowLink={getRowLink}
/>
Expand Down
68 changes: 25 additions & 43 deletions dashboard/src/components/BuildsTable/BuildsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import BaseTable, { TableHead } from '@/components/Table/BaseTable';
import { PaginationInfo } from '@/components/Table/PaginationInfo';
import { TableBody, TableCell, TableRow } from '@/components/ui/table';
import {
possibleTableFilters,
type AccordionItemBuilds,
type PossibleTableFilters,
type TableStatusOption,
type TableStatusSelection,
type TableStatusToggleValue,
} from '@/types/tree/TreeDetails';

import WrapperTableWithLogSheet from '@/pages/TreeDetails/Tabs/WrapperTableWithLogSheet';
Expand All @@ -39,16 +40,17 @@ import { getBuildStatusGroup } from '@/utils/status';

import { TableTopFilters } from '@/components/Table/TableTopFilters';

import type { TStatusFilters } from '@/components/Table/TableStatusFilter';
import { buildStatusFilterChips } from '@/components/Table/TableStatusFilter';
import { tableStatusFilterValueForColumn } from '@/utils/tableStatusFilter';

import { defaultBuildColumns } from './DefaultBuildsColumns';

export interface IBuildsTable {
tableKey: TableKeys;
buildItems: AccordionItemBuilds[];
columns?: ColumnDef<AccordionItemBuilds>[];
filter: PossibleTableFilters;
onClickFilter: (filter: PossibleTableFilters) => void;
filter: TableStatusSelection;
onToggleFilter: (option: TableStatusToggleValue) => void;
getRowLink: (buildId: string) => LinkProps;
sortKey?: string;
}
Expand All @@ -60,7 +62,7 @@ export function BuildsTable({
buildItems,
columns = defaultBuildColumns,
filter,
onClickFilter,
onToggleFilter,
getRowLink,
sortKey,
}: IBuildsTable): JSX.Element {
Expand Down Expand Up @@ -110,68 +112,47 @@ export function BuildsTable({

const { globalFilter } = table.getState();

const filterCount: Record<PossibleTableFilters, number> = useMemo(() => {
const filterCount: Record<TableStatusOption, number> = useMemo(() => {
const rowsOriginal = table
.getPrePaginationRowModel()
.rows.map(row => row.original);

const dataFilter = globalFilter ? rowsOriginal : rawData;

const count: Record<PossibleTableFilters, number> = {
all: 0,
const count: Record<TableStatusOption, number> = {
success: 0,
failed: 0,
inconclusive: 0,
};

count.all = dataFilter ? dataFilter.length : 0;
dataFilter.forEach(build => count[getBuildStatusGroup(build.status)]++);

return count;
}, [rawData, globalFilter, table]);

const filters: TStatusFilters[] = useMemo(
() => [
{
label: intl.formatMessage(
{ id: 'global.allCount' },
{ count: filterCount[possibleTableFilters[0]] },
),
value: possibleTableFilters[0],
isSelected: filter === possibleTableFilters[0],
},
{
label: intl.formatMessage(
const chips = useMemo(
() =>
buildStatusFilterChips({
success: intl.formatMessage(
{ id: 'global.successCount' },
{ count: filterCount[possibleTableFilters[1]] },
{ count: filterCount.success },
),
value: possibleTableFilters[1],
isSelected: filter === possibleTableFilters[1],
},
{
label: intl.formatMessage(
failed: intl.formatMessage(
{ id: 'global.failedCount' },
{ count: filterCount[possibleTableFilters[2]] },
{ count: filterCount.failed },
),
value: possibleTableFilters[2],
isSelected: filter === possibleTableFilters[2],
},
{
label: intl.formatMessage(
inconclusive: intl.formatMessage(
{ id: 'global.inconclusiveCount' },
{ count: filterCount[possibleTableFilters[3]] },
{ count: filterCount.inconclusive },
),
value: possibleTableFilters[3],
isSelected: filter === possibleTableFilters[3],
},
],
[intl, filterCount, filter],
}),
[intl, filterCount],
);

useEffect(() => {
table
.getColumn('status')
?.setFilterValue(filter !== 'all' ? filter : undefined);
?.setFilterValue(tableStatusFilterValueForColumn(filter));
}, [filter, table]);

const onSearchChange = useCallback(
Expand Down Expand Up @@ -306,8 +287,9 @@ export function BuildsTable({
>
<TableTopFilters
key="buildsTableSearch"
filters={filters}
onClickFilter={onClickFilter}
chips={chips}
selection={filter}
onToggleFilter={onToggleFilter}
onSearchChange={onSearchChange}
/>
<BaseTable headerComponents={tableHeaders}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export const defaultBuildColumns: ColumnDef<AccordionItemBuilds>[] = [
: 'NULL';
},
filterFn: (row, columnId, filterValue) =>
getBuildStatusGroup(row.getValue(columnId)) === filterValue,
!Array.isArray(filterValue) ||
filterValue.includes(getBuildStatusGroup(row.getValue(columnId))),
},
{
id: DETAILS_COLUMN_ID,
Expand Down
26 changes: 26 additions & 0 deletions dashboard/src/components/Button/FilterButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { ButtonHTMLAttributes, JSX } from 'react';

import { cn } from '@/lib/utils';

interface IFilterButton extends ButtonHTMLAttributes<HTMLButtonElement> {
selected: boolean;
}

export const FilterButton = ({
selected,
className,
...props
}: IFilterButton): JSX.Element => (
<button
type="button"
aria-pressed={selected}
className={cn(
'focus-visible:ring-blue h-9 rounded-full border px-3 text-sm font-medium transition duration-150 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none',
selected
? 'bg-blue hover:bg-blue border-[#0d9ac8] text-white shadow-[0_2px_4px_rgba(0,0,0,0.2)] hover:text-white'
: 'border-dark-gray bg-light-gray text-dim-gray hover:text-dim-black shadow-none',
className,
)}
{...props}
/>
);
Loading