/** * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug * Copyright (c) * Released under the AGPL-3.0 License. */ import React, { useState, useEffect } from 'react'; import { observer } from 'mobx-react'; import { Input, Card, Tree, Dropdown, Menu, Switch, message } from 'antd'; import { FolderOutlined, FolderAddOutlined, EditOutlined, DeleteOutlined, CopyOutlined, ScissorOutlined } from '@ant-design/icons'; import { LoadingOutlined } from '@ant-design/icons'; import styles from './index.module.css'; import { http } from 'libs'; import store from './store'; import lds from 'lodash'; export default observer(function () { const [loading, setLoading] = useState(false); const [visible, setVisible] = useState(false); const [draggable, setDraggable] = useState(false); const [action, setAction] = useState(''); const [expands, setExpands] = useState([]); const [treeData, setTreeData] = useState(); const [bakTreeData, setBakTreeData] = useState(); useEffect(() => { if (!loading) store.fetchGroups() }, [loading]) const menus = ( setVisible(false)}> } onClick={handleAddRoot}>新建根分组 } onClick={handleAdd}>新建子分组 } onClick={() => setAction('edit')}>重命名 } onClick={() => store.showSelector(true)}>添加至分组 } onClick={() => store.showSelector(false)}>移动至分组 } danger onClick={handleRemove}>删除此分组 ) function handleSubmit() { if (!store.group.title) { return message.error('请输入分组名称') } setLoading(true); const {key, parent_id, title} = store.group; http.post('/api/host/group/', {id: key || undefined, parent_id, name: title}) .then(() => setAction('')) .finally(() => setLoading(false)) } function handleRemove() { setAction('del'); setLoading(true); http.delete('/api/host/group/', {params: {id: store.group.key}}) .finally(() => { setAction(''); setLoading(false) }) } function handleAddRoot() { setBakTreeData(lds.cloneDeep(treeData)); const current = {key: 0, parent_id: 0, title: ''}; treeData.unshift(current); setTreeData(lds.cloneDeep(treeData)); store.group = current; setAction('edit') } function handleAdd() { setBakTreeData(lds.cloneDeep(treeData)); const current = {key: 0, parent_id: store.group.key, title: ''}; store.group.children.unshift(current); setTreeData(lds.cloneDeep(treeData)); if (!expands.includes(store.group.key)) setExpands([store.group.key, ...expands]); store.group = current; setAction('edit') } function handleDrag(v) { setLoading(true); const pos = v.node.pos.split('-'); const dropPosition = v.dropPosition - Number(pos[pos.length - 1]); http.patch('/api/host/group/', {s_id: v.dragNode.key, d_id: v.node.key, action: dropPosition}) .then(() => setLoading(false)) } function handleBlur() { if (store.group.key === 0) { setTreeData(bakTreeData) } setAction('') } function handleExpand(keys, {_, node}) { if (node.children.length > 0) { setExpands(keys) } } function treeRender(nodeData) { if (action === 'edit' && nodeData.key === store.group.key) { return : } onClick={e => e.stopPropagation()} onBlur={handleBlur} onChange={e => store.group.title = e.target.value} onPressEnter={handleSubmit}/> } else if (action === 'del' && nodeData.key === store.group.key) { return } else { return ( {nodeData.title}{nodeData.host_ids && nodeData.host_ids.length ? `(${nodeData.host_ids.length})` : null} ) } } return ( }> v || setVisible(v)}> store.group = node} onExpand={handleExpand} onDrop={handleDrag} onRightClick={v => { store.group = v.node; setVisible(true) }} /> ) })