import { useEffect, useRef, useState } from 'react' import { TailSpin } from 'react-loader-spinner' import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' import { Collapse, Hidden, IconButton, InputAdornment, List, ListItem, ListItemIcon, TextField, Tooltip } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' import CloseIcon from '@material-ui/icons/Close' import ExpandLess from '@material-ui/icons/ExpandLess' import ExpandMore from '@material-ui/icons/ExpandMore' import SearchIcon from '@material-ui/icons/Search' import { fetchComponents, fetchComponentImages, fetchLibraries, toggleCollapse, toggleSimulate } from '../../redux/schematicEditorSlice' import api from '../../utils/Api' import './Helper/SchematicEditor.css' import SideComp from './SideComp' import SimulationProperties from './SimulationProperties' const COMPONENTS_PER_ROW = 3 const useStyles = makeStyles((theme) => ({ toolbar: { minHeight: '90px' }, nested: { paddingLeft: theme.spacing(2), width: '100%' }, head: { marginRight: 'auto' } })) const searchOptions = { NAME: 'name__istartswith' } export default function ComponentSidebar ({ _compRef }) { const classes = useStyles() const libraries = useSelector(state => state.schematicEditor.libraries) const collapse = useSelector(state => state.schematicEditor.collapse) const components = useSelector(state => state.schematicEditor.components) const isSimulate = useSelector(state => state.schematicEditor.isSimulate) const dispatch = useDispatch() const [isSearchedResultsEmpty, setIssearchedResultsEmpty] = useState(false) const [searchText, setSearchText] = useState('') const [loading, setLoading] = useState(false) const [searchedComponentList, setSearchedComponents] = useState([]) const searchOption = 'NAME' const timeoutId = useRef() const handleSearchText = (evt) => { if (searchText.length === 0) { setSearchedComponents([]) } setSearchText(evt.target.value.trim()) setSearchedComponents([]) // mimic the value so we can access the latest value in our API call. // call api from here. and set the result to searchedComponentList. } useEffect(() => { // if the user keeps typing, stop the API call! clearTimeout(timeoutId.current) setSearchedComponents([]) // don't make an API call with no data if (searchText.length === 0) return // capture the timeoutId so we can // stop the call if the user keeps typing timeoutId.current = setTimeout(() => { // call api here setLoading(true) api.get(`newblocks/?${searchOptions[searchOption]}=${searchText}`) .then( (res) => { if (res.data.length === 0) { setIssearchedResultsEmpty(true) } else { setIssearchedResultsEmpty(false) setSearchedComponents([...res.data]) } } ) .catch((err) => { console.error(err) }) setLoading(false) }, 800) }, [searchText, searchOption]) const handleCollapse = (id) => { // Fetches Components for given library if not already fetched if (collapse[id] === false && components[id].length === 0) { dispatch(fetchComponents(id)) } // Updates state of collapse to show/hide dropdown dispatch(toggleCollapse(id)) } // For Fetching Libraries useEffect(() => { dispatch(fetchLibraries()) }, [dispatch]) // Used to chunk array const chunk = (array, size) => { return array.reduce((chunks, item, i) => { if (i % size === 0) { chunks.push([item]) } else { chunks[chunks.length - 1].push(item) } return chunks }, []) } const link1 = process.env.REACT_APP_BLOCKS_NAME + ' List' const link2 = 'Search ' + process.env.REACT_APP_BLOCK_NAME const link3 = 'No ' + process.env.REACT_APP_BLOCKS_NAME + ' Found' return ( <>
{/* Display List of categorized components */}

{link1}

) }} />
{searchText.length !== 0 && searchedComponentList.length !== 0 && searchedComponentList.map((component, i) => { return ( ) } )} {!loading && searchText.length !== 0 && isSearchedResultsEmpty && {link3}} {/* Collapsing List Mapped by Libraries fetched by the API */} {searchText.length === 0 && libraries.map( (library) => { return (
handleCollapse(id)} button divider> {library.name} {collapse[library.id] ? : } {/* Chunked Blocks of Library */} { chunk(components[library.id], COMPONENTS_PER_ROW).map((componentChunk) => { return ( { componentChunk.map((component) => { return ( ) } ) } ) }) }
) } )}
{/* Display simulation modes parameters on left side pane */}

Simulation Modes

{ dispatch(toggleSimulate()) }}>
) } export function ComponentImages () { const componentImages = useSelector(state => state.schematicEditor.component_images) const dispatch = useDispatch() // For Fetching Image Paths useEffect(() => { dispatch(fetchComponentImages()) }, [dispatch]) return (
{(componentImages !== undefined) && componentImages.forEach((image) => { new Image().src = '/django_static/' + image })}
) } ComponentSidebar.propTypes = { compRef: PropTypes.object.isRequired }