import Aside, {AsideSection} from '~/components/Aside'; import {Documentation, Properties, SearchItem, SearchResult} from '~/resource/graphs/types'; import Graph, {GraphRef} from '~/components/GraphsPage/Graph'; import {NextI18NextPage, useTranslation} from '~/utils/i18n'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import Button from '~/components/Button'; import Checkbox from '~/components/Checkbox'; import Content from '~/components/Content'; import Field from '~/components/Field'; import ModelPropertiesDialog from '~/components/GraphsPage/ModelPropertiesDialog'; import NodeDocumentationSidebar from '~/components/GraphsPage/NodeDocumentationSidebar'; import NodePropertiesSidebar from '~/components/GraphsPage/NodePropertiesSidebar'; import Search from '~/components/GraphsPage/Search'; import Title from '~/components/Title'; import Uploader from '~/components/GraphsPage/Uploader'; import {rem} from '~/utils/style'; import styled from 'styled-components'; const FullWidthButton = styled(Button)` width: 100%; `; const ExportButtonWrapper = styled.div` display: flex; justify-content: space-between; > * { flex: 1 1 auto; &:not(:last-child) { margin-right: ${rem(20)}; } } `; // TODO: better way to auto fit height const SearchSection = styled(AsideSection)` max-height: calc(100% - ${rem(40)}); display: flex; flex-direction: column; &:not(:last-child) { padding-bottom: 0; } `; const Graphs: NextI18NextPage = () => { const {t} = useTranslation(['graphs', 'common']); const graph = useRef(null); const file = useRef(null); const [files, setFiles] = useState(null); const onClickFile = useCallback(() => { if (file.current) { file.current.value = ''; file.current.click(); } }, []); const onChangeFile = useCallback((e: React.ChangeEvent) => { const target = e.target; if (target && target.files && target.files.length) { setFiles(target.files); } }, []); const [search, setSearch] = useState(''); const [searching, setSearching] = useState(false); const [searchResult, setSearchResult] = useState({text: '', result: []}); const onSearch = useCallback((value: string) => { setSearch(value); graph.current?.search(value); }, []); const onSelect = useCallback((item: SearchItem) => { setSearch(item.name); graph.current?.select(item); }, []); const [showAttributes, setShowAttributes] = useState(false); const [showInitializers, setShowInitializers] = useState(true); const [showNames, setShowNames] = useState(false); const [modelData, setModelData] = useState(null); const [nodeData, setNodeData] = useState(null); const [nodeDocumentation, setNodeDocumentation] = useState(null); useEffect(() => setSearch(''), [showAttributes, showInitializers, showNames]); const bottom = useMemo( () => searching ? null : ( {t('graphs:change-model')} ), [t, onClickFile, searching] ); const [rendered, setRendered] = useState(false); const aside = useMemo(() => { if (!rendered) { return null; } if (nodeDocumentation) { return ( ); } if (nodeData) { return ( ); } return ( ); }, [ t, bottom, search, searching, searchResult, onSearch, onSelect, showAttributes, showInitializers, showNames, rendered, nodeData, nodeDocumentation ]); const uploader = useMemo(() => , [onClickFile]); return ( <> {t('common:graphs')} setModelData(null)} /> setRendered(true)} onSearch={data => setSearchResult(data)} onShowModelProperties={data => setModelData(data)} onShowNodeProperties={data => { setNodeData(data); setNodeDocumentation(null); }} onShowNodeDocumentation={data => setNodeDocumentation(data)} /> ); }; Graphs.getInitialProps = () => ({ namespacesRequired: ['graphs', 'common'] }); export default Graphs;