Skip to content
Snippets Groups Projects
information.box.view.tsx 4.07 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { faChevronDown, faHashtag, faUser } from '@fortawesome/free-solid-svg-icons'
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
    import { insertMarkTags } from '@helper/text'
    import { useAppSelector } from '@hooks'
    import { JsonViewer } from '@shared/components/json_viewer/view/json_viewer.view'
    import DOMPurify from 'dompurify'
    import { useCallback, useState } from 'react'
    import { Collapse } from 'react-bootstrap'
    
    interface DeviceListCollapsableProps {
        search?: string
    }
    
    enum Collapsables {
        Metadata = 1,
        Config = 2,
    }
    
    export const DeviceListCollapsable = ({ search }: DeviceListCollapsableProps) => {
        const { selected, pnds } = useAppSelector(state => state.device)
    
        const [collapseable, setCollapsable] = useState<Collapsables | undefined>(undefined)
    
        const user = pnds.find(pnd => pnd.id === selected?.device.pid)
        const username = user?.name || ''
        const deviceId = selected?.device.id || ''
    
        const json = JSON.parse(selected?.mne?.model || '{}')
    
    
        const metadataKey = Object.keys(json).at(2) as keyof typeof json
        const metadataObject = (json[metadataKey] as JSON) || {}
    
        const configKey = Object.keys(json).at(0) as keyof typeof json
        const configObject = (json[configKey] as JSON) || {}
    
        const setCollapsed = useCallback((section: Collapsables) => {
            setCollapsable(prev => (prev === section ? undefined : section))
        }, [])
    
        const renderDeviceInfo = useCallback(
            () => (
                <>
                    <div className="d-flex justify-content-between">
                        <div>
                            <FontAwesomeIcon className="me-2" icon={faHashtag} />
                            UUID:
                        </div>
                        <span
                            dangerouslySetInnerHTML={{
                                __html: search
                                    ? insertMarkTags(deviceId, search)
                                    : DOMPurify.sanitize(deviceId),
                            }}
                        />
                    </div>
                    <div className="d-flex justify-content-between">
                        <div>
                            <FontAwesomeIcon className="me-2" icon={faUser} />
                            User:
                        </div>
                        <span>{username}</span>
                    </div>
                </>
            ),
            [deviceId, search, username],
        )
    
        const renderCollapsableSection = useCallback(
            (title: string, section: Collapsables, content: JSON) => (
                <>
                    <div
                        className={`d-flex justify-content-between clickable ${
                            section === Collapsables.Config
                                ? 'mt-3'
                                : 'border-top border-dark mt-3 pt-3'
                        }`}
                        aria-expanded={collapseable === section}
                        onClick={() => setCollapsed(section)}>
                        <div>
                            <FontAwesomeIcon
                                icon={faChevronDown}
                                rotation={collapseable === section ? undefined : 270}
                            />
                            {title}
                        </div>
                    </div>
    
                    <Collapse in={collapseable === section}>
                        <div id={`collapse-${deviceId}-${section}`}>
                            {JsonViewer({
                                json: content,
                                options: {
                                    editable: false,
                                    searchEnabled: false,
                                },
                            })}
                        </div>
                    </Collapse>
                </>
            ),
            [collapseable, deviceId, setCollapsed],
        )
    
        return (
            <div id={`collapse-${deviceId}`}>
                <div className="pb-4 pt-1 d-flex flex-column gap-1">
                    {renderDeviceInfo()}
                    {renderCollapsableSection('Metadata', Collapsables.Metadata, metadataObject)}
                    {renderCollapsableSection('Config', Collapsables.Config, configObject)}
                </div>
            </div>
        )
    }