import { useEffect, useMemo, useState } from 'react' import { flow, pipe } from 'fp-ts/lib/function' import * as O from 'fp-ts/lib/Option' import * as RA from 'fp-ts/lib/ReadonlyArray' import { useToggle } from '@monorail/helpers/hooks' import { xor } from '@monorail/sharedHelpers/fp-ts-ext/ReadonlyArray' import { elemLocaleLowerCase } from '@monorail/sharedHelpers/strings' import { CardListCommonProps, CardListEditProps, } from '@monorail/visualComponents/cardList/CardList' import { RenderChoiceProps } from '@monorail/visualComponents/cardList/OptionsList' export const useCardListForEditing = ( params: CardListCommonProps & CardListEditProps, ) => { const { allItems, eq, onChangeSelectedItems, toListItem, toSearchableStrings = flow(params.toListItem, item => [item.primaryText]), selectedItems, } = params const [searchValue, setSearchValue] = useState('') const [selectedItemsLocal, setSelectedItemsLocal] = useState< ReadonlyArray >(selectedItems) const [isSearchOpen, openSearch, closeSearch] = useToggle(false) useEffect(() => { // @NOTE - Pete Murphy 2020-09-22 - Overwrite local state with parent state // when parent state changes. If we were mounting and unmounting the // "options list" when toggling the `isSearchOpen` state, this would be // covered by initializing `selectedItemsLocal` with `selectedItems`, but // since we're not, this is a sufficient approximation. setSelectedItemsLocal(selectedItems) }, [selectedItems]) const isButtonDisabled = useMemo( () => RA.isEmpty(xor(eq)(selectedItemsLocal, selectedItems)), [eq, selectedItems, selectedItemsLocal], ) const handleCancel = closeSearch const handleConfirm = () => { onChangeSelectedItems(selectedItemsLocal) closeSearch() } const handleToggleItem = (item: A) => setSelectedItemsLocal(xor(eq)([item], selectedItemsLocal)) const options = pipe( allItems, RA.filterMap>(item => toSearchableStrings(item).some(elemLocaleLowerCase(searchValue)) ? O.some({ item, type: 'checkbox', onChange: () => handleToggleItem(item), checked: RA.elem(eq)(item)(selectedItemsLocal), ...toListItem(item), }) : O.none, ), ) return { closeSearch, handleCancel, handleConfirm, isButtonDisabled, isSearchOpen, openSearch, options, searchValue, setSearchValue, } as const }