import { AllHTMLAttributes } from 'react' ; import { ITableProps } from '../' ; import { SortingMode } from '../enums' ; import { Column } from '../models' ; import { ChildComponent } from '../Models/ChildComponent' ; import { ChildAttributesItem , DispatchFunc } from '../types' ; import { getValueByField } from './DataUtils' ; import { filterAndSearchData } from './FilterUtils' ; import { getGroupedData } from './GroupUtils' ; import { getPageData , getPagesCount } from './PagingUtils' ; import { getValidatedEditableCells } from './ReducerUtils' ; import { isRemoteSorting , sortColumns , sortData } from './SortUtils' ; import { getTreeData } from './TreeUtils' ; export function extendProps < T = HTMLElement > ( childElementAttributes , childProps , childComponent ? ) { let resultProps = childElementAttributes ; const childCustomAttributes = childComponent && childComponent . elementAttributes && childComponent . elementAttributes ( childProps ) ; if ( childCustomAttributes ) { const dispatch = childProps . dispatch ; resultProps = mergeProps ( childElementAttributes , childProps , childCustomAttributes , dispatch ) ; } return resultProps ; } ; const emptyFunc = ( ) => { } ; export function mergeProps < T = HTMLElement > ( childElementAttributes , childProps , childCustomAttributes , dispatch ) { const customPropsWithEvents = { } ; for ( const prop in childCustomAttributes ) { if ( childCustomAttributes . hasOwnProperty ( prop ) ) { const propName = prop as string ; const propValue = ( childCustomAttributes as any ) [ propName ] ; const baseFunc = ( childElementAttributes as any ) [ propName ] || emptyFunc ; if ( typeof propValue === 'function' ) { customPropsWithEvents [ prop ] = ( e ) => { propValue ( e , { baseFunc , childElementAttributes , childProps , dispatch , } ) ; } ; } } } const mergedResult = { ... childElementAttributes , ... childCustomAttributes , ... customPropsWithEvents , className : `${ childElementAttributes . className || '' } ${ childCustomAttributes . className || '' }` , style : { ... childElementAttributes . style , ... childCustomAttributes . style } } ; return mergedResult ; } ; export const areAllFilteredRowsSelected = ( props ) => { const { selectedRows = [ ] , rowKeyField } = props ; return filterAndSearchData ( props ) . every ( d => selectedRows . includes ( getValueByField ( d , rowKeyField ) ) ) ; } ; export const areAllVisibleRowsSelected = ( props ) => { const { selectedRows = [ ] , rowKeyField } = props ; return getData ( props ) . every ( d => selectedRows . includes ( getValueByField ( d , rowKeyField ) ) ) ; } ; export const getData = ( props ) => { const { columns , groups , groupsExpanded , paging , treeGroupKeyField , treeGroupsExpanded , rowKeyField , sort , sortingMode = SortingMode . None } = props ; const { data = [ ] , } = props ; let resultData = [ ... data ] ; resultData = filterAndSearchData ( props ) ; if ( ! isRemoteSorting ( sortingMode ) ) { resultData = sortData ( columns , resultData , sort ) ; } const groupedColumns = groups ? columns . filter ( ( c ) => groups . some ( ( g ) => g . columnKey === c . key ) ) : [ ] ; resultData = groups ? getGroupedData ( resultData , groups , groupedColumns , groupsExpanded ) : resultData ; resultData = treeGroupKeyField ? getTreeData ( { data : resultData , rowKeyField , treeGroupKeyField , treeGroupsExpanded , originalData : data } ) : resultData ; resultData = getPageData ( resultData , paging ) ; return resultData ; } ; export const isValid = ( props ) => { return ( ! props . validation || ! getValidatedEditableCells ( props ) . some ( cell => cell . validationMessage ) ) ; } ; export const getSelectedData = ( { data , selectedRows , rowKeyField } ) => { return data ? data . filter ( d => { const value = getValueByField ( d , rowKeyField ) ; return selectedRows ?. some ( v => v === value ) ; } ) : [ ] ; } ; export const getSortedColumns = ( props ) : Column [ ] => { return sortColumns ( props . columns ) ; } ; export const getPagesCountByProps = ( props ) => { const { paging , } = props ; let pagesCount = 1 ; if ( paging && paging . enabled ) { let data = filterAndSearchData ( props ) ; const { rowKeyField , treeGroupKeyField , treeGroupsExpanded } = props ; data = treeGroupKeyField ? getTreeData ( { data , rowKeyField , treeGroupKeyField , treeGroupsExpanded , originalData : props . data || [ ] } ) : data ; pagesCount = getPagesCount ( data , paging ) ; } return pagesCount ; } ; export const prepareTableOptions = ( props ) => { const { groups , } = props ; let { columns , } = props ; const groupedData = getData ( props ) ; let groupColumnsCount = 0 ; let groupedColumns = [ ] ; if ( groups ) { groupColumnsCount = groups . length ; groupedColumns = columns . filter ( ( c ) => groups . some ( ( g ) => g . columnKey === c . key ) ) ; columns = columns . filter ( ( c ) => ! groups . some ( ( g ) => g . columnKey === c . key ) ) ; } columns = columns . filter ( ( c ) => c . visible !== false ) ; return { columns , groupColumnsCount , groupedColumns , groupedData } ; } ; export const getDraggableProps = ( key , dispatch , actionCreator , draggedClass , dragOverClass ) : ChildAttributesItem < any > => { let count = 0 ; return { draggable : true , onDragStart : ( event ) => { count = 0 ; event . dataTransfer . setData ( 'ka-draggableKeyValue' , JSON . stringify ( key ) ) ; event . currentTarget . classList . add ( draggedClass ) ; event . dataTransfer . effectAllowed = 'move' ; } , onDragEnd : ( event ) => { event . currentTarget . classList . remove ( draggedClass ) ; } , onDrop : ( event ) => { event . currentTarget . classList . remove ( dragOverClass ) ; const draggableKeyValue = JSON . parse ( event . dataTransfer . getData ( 'ka-draggableKeyValue' ) ) ; dispatch ( actionCreator ( draggableKeyValue , key ) ) ; } , onDragEnter : ( event ) => { count ++ ; if ( ! event . currentTarget . classList . contains ( dragOverClass ) ) { event . currentTarget . classList . add ( dragOverClass ) ; } event . preventDefault ( ) ; } , onDragLeave : ( event ) => { count -- ; if ( count === 0 ) { event . currentTarget . classList . remove ( dragOverClass ) ; } } , onDragOver : ( event ) => { if ( ! event . currentTarget . classList . contains ( dragOverClass ) ) { event . currentTarget . classList . add ( dragOverClass ) ; } event . preventDefault ( ) ; } } ; } ;