Add column enum filter.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Madeorsk 2024-07-28 15:40:42 +02:00
parent 71b10a3c89
commit 267afa68dd
Signed by: Madeorsk
SSH key fingerprint: SHA256:J9G0ofIOLKf7kyS2IfrMqtMaPdfsk1W02+oGueZzDDU
2 changed files with 83 additions and 1 deletions

View file

@ -0,0 +1,69 @@
import React, {useCallback} from "react";
import {ColumnFilter, useFilterState} from "../Columns/ColumnFilter";
import {Select} from "@kernelui/core";
/**
* String column filter.
*/
export function EnumFilter<OptionKey extends keyof any, Option>(options: Record<OptionKey, Option>): ColumnFilter<OptionKey[], EnumFilterState<OptionKey>>
{
return (
{
filter: (data: OptionKey|OptionKey[], filterState: EnumFilterState<OptionKey>) => {
// Normalized data array.
const dataArray = Array.isArray(data) ? data : [data];
// Nothing in filter value, allow everything.
if (!filterState?.value?.length) return true;
// Get current filter result.
return filterState?.value?.some(
// Keep the row if any element in data match the current filter value.
(optionKey) => dataArray.includes(optionKey)
);
},
element: <EnumFilterComponent options={options} />
}
);
}
/**
* Enumeration filter state.
*/
export interface EnumFilterState<OptionKey extends keyof any>
{
/**
* Filter value.
*/
value: OptionKey[];
}
/**
* Enum filter component.
*/
export function EnumFilterComponent<OptionKey extends keyof any, Option>({options}: {
/**
* Enum options.
*/
options: Record<OptionKey, Option>;
})
{
// Initialize enum filter state.
const [enumFilterState, setEnumFilterState] =
useFilterState<EnumFilterState<OptionKey>>({ value: [] });
// Handle filter input change.
const handleChange = useCallback((filter: OptionKey[]) => {
// Save the current filter value.
setEnumFilterState({
value: filter,
})
}, [setEnumFilterState]);
return (
<Select<OptionKey, Option> options={options} multiple={true} size={1}
className={!enumFilterState.value?.length ? "empty" : undefined}
value={enumFilterState.value} onChange={handleChange} />
)
}

View file

@ -9,9 +9,22 @@ tr.filters
padding-left: 0.25em;
}
input
input, .select
{
margin: 0;
width: 100%;
}
.select
{
ul.selected
{
margin: 0 0 0.25em 0;
}
&.empty ul.selected
{
margin: 0;
}
}
}
}