import classnames from 'classnames' ; import { isUndefined } from 'lodash' ; import { ChangeEvent , useEffect , useState } from 'react' ; import { FaSearch } from 'react-icons/fa' ; import { ChartTemplate , ChartTmplTypeFile } from '../../../types' ; import ResourceLabel from './ResourceLabel' ; import styles from './TemplatesList.module.css' ; interface Props { templates : ChartTemplate [ ] ; activeTemplateName ? : string ; onTemplateChange : ( template : ChartTemplate | null ) => void ; } const TemplatesList = ( props ) => { const [ inputValue , setInputValue ] = useState < string > ( '' ) ; const [ visibleTemplates , setVisibleTemplates ] = useState < ChartTemplate [ ] > ( props . templates ) ; const onChange = ( e ) => { e . stopPropagation ( ) ; e . preventDefault ( ) ; setInputValue ( e . target . value ) ; } ; useEffect ( ( ) => { const getVisibleTemplates = ( ) : ChartTemplate [ ] => { return props . templates . filter ( ( tmpl ) => { const term = `${ tmpl . name } ${ tmpl . resourceKinds ? tmpl . resourceKinds . join ( ' ' ) : '' }` . toLowerCase ( ) ; return term . includes ( inputValue . toLowerCase ( ) ) ; } ) ; } ; const reviewActiveTemplate = ( filteredTemplates ) => { if ( filteredTemplates . length === 0 && ! isUndefined ( props . activeTemplateName ) ) { props . onTemplateChange ( null ) ; } else { if ( props . activeTemplateName ) { const activeTemplate = filteredTemplates . find ( ( tmpl ) => tmpl . name === props . activeTemplateName ) ; if ( isUndefined ( activeTemplate ) ) { props . onTemplateChange ( filteredTemplates [ 0 ] ) ; } } else { props . onTemplateChange ( filteredTemplates [ 0 ] ) ; } } } ; if ( inputValue === '' ) { setVisibleTemplates ( props . templates ) ; if ( isUndefined ( props . activeTemplateName ) ) { props . onTemplateChange ( props . templates [ 0 ] ) ; } } else { const filteredTemplates = getVisibleTemplates ( ) ; reviewActiveTemplate ( filteredTemplates ) ; setVisibleTemplates ( filteredTemplates ) ; } } , [ inputValue ] ) ; return ( < div className = "h-100 d-flex flex-column overflow-auto pe-2" > < div className = "position-relative w-100" > < div className = "mb-3 input-group-sm" > < input type = "text" placeholder = "Search by template or resource kind" className = { `flex-grow-1 form-control ps-3 pe-4 ${ styles . input }` } name = "chartTemplateInput" value = { inputValue } onChange = { onChange } spellCheck = "false" / > < FaSearch className = { `text-muted position-absolute ${ styles . searchIcon }` } /> < div className = "alert p-0 mt-3" > < small className = "text-muted text-break fst-italic" > This chart version contains < span className = "fw-bold" > { props . templates . length } < /span>{' '} { props . templates . length === 1 ? 'template' : 'templates' } < /small> < /div> < /div> < /div> { visibleTemplates . length === 0 ? ( < div className = { `alert alert-dark p-2 text-center ${ styles . alert }` } role = "alert" aria - live = "assertive" aria - atomic = "true" > < small className = "text-muted" > Sorry , no matches found < /small> < /div>) : (<> { visibleTemplates . map ( ( template , index ) => { const isActive = ! isUndefined ( props . activeTemplateName ) && props . activeTemplateName === template . name ; return ( < div key = { `template_${ index }` } > < button className = { classnames ( 'btn btn-light btn-sm mb-2 text-start w-100' , styles . btn , { [ `activeTemplate ${ styles . active }` ] : isActive , } ) } onClick = { ( ) => { if ( ! isActive ) { props . onTemplateChange ( template ) ; } } } aria - label = { `Show template ${ template . name }` } aria - pressed = { isActive } > < div className = "d-flex flex-column" > { ( ( ) => { switch ( template . type ) { case ChartTmplTypeFile . Template : return ( < > < div className = "d-flex flex-row align-items-baseline mb-1" > < div className = { styles . legend } > < small className = "text-muted text-uppercase" > Template : < /small> < /div> < div className = { `text-truncate ${ styles . templateName }` } > { template . name } < /div> < /div> < div className = "d-flex flex-row mb-1" > < div className = { styles . legend } > < small className = "text-muted text-uppercase" > Resource : < /small> < /div> { template . resourceKinds && template . resourceKinds . length > 0 ? ( < > { template . resourceKinds . length > 1 ? ( < > < ResourceLabel text = "Multiple kinds" / > < />) : (<ResourceLabel text={template.resourceKinds[0]}/ > ) } < />) : (<>-</ > ) } < /div> < />); case ChartTmplTypeFile . Helper : return ( < div className = "mb-1 text-truncate" > < div className = { `d-inline-block ${ styles . legend }` } > < small className = "text-muted text-uppercase" > Helper : < /small> < /div> { template . name } < /div>); } } ) ( ) } < /div> < /button> < /div>); } ) } < />)} < /div>); } ; export default TemplatesList ;