diff --git a/frontend/src/components/index-viewer.js b/frontend/src/components/index-viewer.js index 47a37dd355..16522b6e91 100644 --- a/frontend/src/components/index-viewer.js +++ b/frontend/src/components/index-viewer.js @@ -11,12 +11,33 @@ const viewerPropTypes = { onLinkClick: PropTypes.func.isRequired, }; +class TreeNode { + + constructor({ name, href, parentNode }) { + this.name = name; + this.href = href; + this.parentNode = parentNode || null; + this.children = []; + } + + setParent(parentNode) { + this.parentNode = parentNode; + } + + addChildren(nodeList) { + nodeList.forEach((node) => { + node.setParent(this); + }); + this.children = nodeList; + } +} + class IndexContentViewer extends React.Component { constructor(props) { super(props); this.links = []; - this.rootNode = {}; + this.treeRoot = new TreeNode({ name: '', href: '' }); } componentWillMount() { @@ -92,7 +113,6 @@ class IndexContentViewer extends React.Component { else if (item.type == 'link') { url = item.data.href; - /* eslint-disable */ let expression = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/ /* eslint-enable */ @@ -120,37 +140,45 @@ class IndexContentViewer extends React.Component { return item; } - modifyValueBeforeRender = (value) => { - let nodes = value.document.nodes; - let newNodes = Utils.changeMarkdownNodes(nodes, this.changeInlineNode); - value.document.nodes = newNodes; - return value; - } - getRootNode = () => { let value = deserialize(this.props.indexContent); value = value.toJSON(); - value = this.modifyValueBeforeRender(value); - value = Value.fromJSON(value); - const nodes = value.document.nodes; - nodes.map((node) => { - if (node.type ==='unordered_list' || node.type === 'ordered_list') { - this.rootNode = node; + const newNodes = Utils.changeMarkdownNodes(value.document.nodes, this.changeInlineNode); + newNodes.map((node) => { + if (node.type === 'unordered_list' || node.type === 'ordered_list') { + this.treeRoot = this.transSlateToTree(node.nodes, this.treeRoot); } }); } + transSlateToTree = (slateNodes, treeRoot) => { + let treeNodes = slateNodes.map((slateNode) => { + const inline = slateNode.nodes[0].nodes[0]; + if (slateNode.nodes.length === 2 && slateNode.nodes[1].type === 'unordered_list') { + let treeNode = new TreeNode({ name: inline.nodes[0].leaves[0].text, href: inline.data.href }); + return this.transSlateToTree(slateNode.nodes[1].nodes, treeNode); + } else { + return new TreeNode({ name: inline.nodes[0].leaves[0].text, href: inline.data.href }); + } + }); + treeRoot.addChildren(treeNodes); + return treeRoot; + } + render() { - return ; + return ( +
+ +
+ ); } } IndexContentViewer.propTypes = viewerPropTypes; const FolderItemPropTypes = { - rootNode: PropTypes.object.isRequired, + node: PropTypes.object.isRequired, bindClickEvent: PropTypes.func.isRequired, - hasChild: PropTypes.bool, }; class FolderItem extends React.Component { @@ -158,65 +186,45 @@ class FolderItem extends React.Component { constructor(props) { super(props); this.state = { - showChild: true + expanded: true }; } - toggleShowChild = () => { - this.setState({showChild: !this.state.showChild}, () => { - if (this.state.showChild) { - this.props.bindClickEvent(); - } + toggleExpanded = () => { + this.setState({ expanded: !this.state.expanded }, () => { + if (this.state.expanded) this.props.bindClickEvent(); }); } - componentDidMount() { - if (this.props.hasChild) { - this.setState({ showChild: false }); - } + renderLink = (node) => { + return
{node.name}
; } render() { - const { rootNode } = this.props; - return ( -
- { - rootNode.nodes.map((node) => { - if (node.type === 'paragraph') { - let href = ''; - node.nodes.map((linkNode) => { - // deal with node isn't a link - href = linkNode.data ? encodeURI(linkNode.data.get('href')) : 'javascript:void(0);'; - }); - return ( -
- {node.text} -
- ); - } else { - const hasChild = (rootNode.type === 'unordered_list' && rootNode.nodes.size > 1); - return ( - - {this.props.hasChild && - - {this.state.showChild ? : } - - } - {this.state.showChild && - - } - - ); - } - }) - } -
- ); + const { node } = this.props; + if (node.children.length > 0) { + return ( + + {node.parentNode && + + + {this.state.expanded ? : } + + {this.renderLink(node)} + + } + {this.state.expanded && node.children.map((child, index) => { + return ( +
+ +
+ ); + })} +
+ ); + } else { + return this.renderLink(node); + } } } diff --git a/frontend/src/css/index-viewer.css b/frontend/src/css/index-viewer.css index a6184f43f0..fe99a8ce36 100644 --- a/frontend/src/css/index-viewer.css +++ b/frontend/src/css/index-viewer.css @@ -1,16 +1,22 @@ -.folder-item { - position: relative; - margin-top: 5px; +.wiki-nav-content { + margin-bottom: 5px; } -.folder-item .wiki-nav-content a { +.wiki-nav-content a { color: #333; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + display: block; } -.folder-item .wiki-nav-content a:hover { +.wiki-nav-content a:hover { text-decoration: none; + color: #eb8205; } .switch-btn { + width: 1rem; position: absolute; - left: 0.5rem; + left: 0; top: 0; color: #c0c0c0; + cursor: pointer; } \ No newline at end of file