mirror of
https://gitee.com/dcren/cloud-native-app-initializer.git
synced 2026-08-25 19:06:31 +08:00
Project initial
This commit is contained in:
122
initializer-page/src/components/common/explore/Tree.js
Normal file
122
initializer-page/src/components/common/explore/Tree.js
Normal file
@@ -0,0 +1,122 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import get from 'lodash.get'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
|
||||
import {IconCaretDown, IconFile, IconFolder} from '../icons'
|
||||
|
||||
function Tree({ tree, selected, onClickItem }) {
|
||||
const [folders, setFolders] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
const treeToArray = map => {
|
||||
const recursive = (mapRec, acc) => {
|
||||
mapRec.forEach(item => {
|
||||
if (item.type === 'folder') {
|
||||
acc.push({
|
||||
filename: get(item, 'filename'),
|
||||
path: get(item, 'path'),
|
||||
hidden: get(item, 'hidden', false),
|
||||
})
|
||||
if (get(item, 'children')) {
|
||||
recursive(item.children, acc)
|
||||
}
|
||||
}
|
||||
})
|
||||
return acc
|
||||
}
|
||||
return recursive(map, [])
|
||||
}
|
||||
setFolders(treeToArray(tree.children))
|
||||
}, [tree, setFolders])
|
||||
|
||||
const renderItem = (item, depth = 0) => {
|
||||
if (item.type === 'folder') {
|
||||
const folder = folders.find(f => f.path === item.path)
|
||||
const isHidden = get(folder, `hidden`, true)
|
||||
return (
|
||||
<li
|
||||
key={`li${item.path}`}
|
||||
className={`li-folder ${isHidden ? 'folder-hide' : ''}`}
|
||||
>
|
||||
<a
|
||||
href='/#'
|
||||
key={`s1${item.path}`}
|
||||
className={`folder level-${depth}`}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
const newFolders = [...folders]
|
||||
const newFolder = newFolders.find(f => f.path === item.path)
|
||||
if (newFolder) {
|
||||
newFolder.hidden = !get(newFolder, `hidden`, true)
|
||||
setFolders(newFolders)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span key={`s2${item.path}`} className='text'>
|
||||
{get(item, 'children.length', 0) > 0 && <IconCaretDown />}
|
||||
<span key={`s3${item.path}`} className='icon'>
|
||||
<IconFolder key={`s4${item.path}`} />
|
||||
</span>
|
||||
{item.filename}
|
||||
</span>
|
||||
</a>
|
||||
{get(item, 'children') && (
|
||||
<ul className='ul' key={`ul${item.path}`}>
|
||||
{item.children.map(it => renderItem(it, depth + 1))}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
// File
|
||||
const isDisabled = get(item, 'language') === null
|
||||
const isSelected = get(selected, 'path') === get(item, 'path')
|
||||
return (
|
||||
<li key={`li${item.path}`} className='li-file'>
|
||||
<a
|
||||
href='/#'
|
||||
key={`s1${item.path}`}
|
||||
tabIndex={`${isDisabled ? -1 : ''}`}
|
||||
className={`file level-${depth} ${isDisabled ? 'disabled' : ''} ${
|
||||
isSelected ? 'selected' : ''
|
||||
}`}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
if (!isDisabled) {
|
||||
onClickItem(item)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span key={`s2${item.path}`} className='text'>
|
||||
<span key={`s3${item.path}`} className='icon'>
|
||||
<IconFile key={`s4${item.path}`} />
|
||||
</span>
|
||||
{item.filename}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className='explorer-ul'>
|
||||
{tree.children.map(item => renderItem(item, 0))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
Tree.propTypes = {
|
||||
tree: PropTypes.shape({
|
||||
children: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
type: PropTypes.string,
|
||||
})
|
||||
),
|
||||
}).isRequired,
|
||||
selected: PropTypes.shape({
|
||||
path: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
onClickItem: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
export default Tree
|
||||
Reference in New Issue
Block a user