import { uniqBy } from "lodash" ; import { FilterData , FilterDetailedOptions , FilterInput , FilterType , OnFilterChangeOpts , } from "./types" ; export function getAvailableFilters ( filterData ) { return filterData . filter ( ( filter ) => ! filter . active ) ; } export function getActiveFilters ( filterData ) { return filterData . filter ( ( filter ) => filter . active ) ; } export function validate ( filterData ) { if ( uniqBy ( filterData , "name" ) . length !== filterData . length ) { throw new Error ( "Filter names should be unique" ) ; } } function getDefaultValue ( filter ) { const { options } = filter ; return { value : options . multiple || options . type === FilterType . Range ? null : options . type === FilterType . Choice ? options . default ?? options . choices ! [ 0 ] . value : "" , values : filter . range && options . type === FilterType . Range ? [ "" , "" ] : options . multiple ? [ ] : null } ; } export function register ( filterData , name , label , initial , options ) { const existingFilter = initial . find ( ( f ) => f . name === name ) ; const filter = { active : ! ! existingFilter , label , name , range : false , sortIndex : filterData . length , options , value : null , values : null } ; return [ ... filterData , { ... filter , ... getDefaultValue ( filter ) , ... existingFilter } , ] ; } export function change ( filterData , name , value , opts = { } ) { const filterToUpdate = filterData . find ( ( filter ) => filter . name === name ) ! ; let update ; if ( filterToUpdate ! . options . multiple ) { update = { values : value as string [ ] } ; } else if ( filterToUpdate ! . options . type === FilterType . Range && opts . rangePart ) { update = { values : opts . rangePart === "min" ? [ value as string , filterToUpdate . values ! [ 1 ] ] : [ filterToUpdate . values ! [ 0 ] , value as string ] } ; } else { update = { value : value as string } ; } return filterData . map ( ( filter ) => filter . name === name ? { ... filter , ... update } : filter ) ; } export function toggle ( filterData , name ) { const selectedFilter = filterData . find ( ( filter ) => filter . name === name ) ! ; const sortIndex = selectedFilter . active ? selectedFilter . sortIndex : getActiveFilters ( filterData ) . length ; const value = selectedFilter . active ? getDefaultValue ( selectedFilter ) : { } ; return filterData . map ( ( filter ) => filter . name === name ? { ... filter , active : ! filter . active , sortIndex , ... value } : filter . active && filter . sortIndex > sortIndex ? { ... filter , sortIndex : filter . sortIndex - 1 } : filter ) ; } export function toggleRange ( filterData , name ) { return filterData . map ( ( filter ) => filter . name === name ? { ... filter , range : ! filter . range , ... getDefaultValue ( { ... filter , range : ! filter . range } ) } : filter ) ; }