diff --git a/web/src/components/command/ChooseAsset.js b/web/src/components/command/ChooseAsset.js new file mode 100644 index 0000000..e647bd6 --- /dev/null +++ b/web/src/components/command/ChooseAsset.js @@ -0,0 +1,427 @@ +import React, {Component} from 'react'; + +import { + Badge, + Button, + Col, + Divider, + Input, + Layout, + Modal, + Row, + Select, + Space, + Table, + Tag, + Tooltip, + Typography +} from "antd"; +import qs from "qs"; +import request from "../../common/request"; +import {message} from "antd/es"; + + +import {PlusOutlined, SyncOutlined, UndoOutlined} from '@ant-design/icons'; +import {PROTOCOL_COLORS} from "../../common/constants"; +import {isEmpty} from "../../utils/utils"; +import dayjs from "dayjs"; + +const confirm = Modal.confirm; +const {Search} = Input; +const {Content} = Layout; +const {Title, Text} = Typography; + +class ChooseAsset extends Component { + + inputRefOfName = React.createRef(); + inputRefOfIp = React.createRef(); + changeOwnerFormRef = React.createRef(); + + state = { + items: [], + total: 0, + queryParams: { + pageIndex: 1, + pageSize: 10, + protocol: 'ssh' + }, + loading: false, + tags: [], + model: {}, + selectedRowKeys: [], + selectedRows: [], + delBtnLoading: false, + changeOwnerModalVisible: false, + changeSharerModalVisible: false, + changeOwnerConfirmLoading: false, + changeSharerConfirmLoading: false, + users: [], + selected: {}, + totalSelectedRows: [], + }; + + checkedAssets = undefined + + async componentDidMount() { + this.checkedAssets = this.props.setCheckedAssets; + this.loadTableData(); + let result = await request.get('/tags'); + if (result['code'] === 1) { + this.setState({ + tags: result['data'] + }) + } + } + + async loadTableData(queryParams) { + this.setState({ + loading: true + }); + + queryParams = queryParams || this.state.queryParams; + + // queryParams + let paramsStr = qs.stringify(queryParams); + + let data = { + items: [], + total: 0 + }; + + try { + let result = await request.get('/assets/paging?' + paramsStr); + if (result['code'] === 1) { + data = result['data']; + } else { + message.error(result['message']); + } + } catch (e) { + + } finally { + let sharer = this.state.sharer; + const items = data.items.map(item => { + let disabled = false; + if (sharer === item['owner']) { + disabled = true; + } + return {...item, 'key': item['id'], 'disabled': disabled} + }) + let totalSelectedRows = this.state.totalSelectedRows; + let selectedRowKeys = totalSelectedRows.map(item => item['id']); + this.setState({ + items: items, + total: data.total, + queryParams: queryParams, + loading: false, + selectedRowKeys: selectedRowKeys + }); + } + } + + handleChangPage = async (pageIndex, pageSize) => { + let queryParams = this.state.queryParams; + queryParams.pageIndex = pageIndex; + queryParams.pageSize = pageSize; + + this.setState({ + queryParams: queryParams + }); + + await this.loadTableData(queryParams) + }; + + handleSearchByName = name => { + let query = { + ...this.state.queryParams, + 'pageIndex': 1, + 'pageSize': this.state.queryParams.pageSize, + 'name': name, + } + + this.loadTableData(query); + }; + + handleSearchByIp = ip => { + let query = { + ...this.state.queryParams, + 'pageIndex': 1, + 'pageSize': this.state.queryParams.pageSize, + 'ip': ip, + } + + this.loadTableData(query); + }; + + handleTagsChange = tags => { + console.log(tags) + // this.setState({ + // tags: tags + // }) + let query = { + ...this.state.queryParams, + 'pageIndex': 1, + 'pageSize': this.state.queryParams.pageSize, + 'tags': tags.join(','), + } + + this.loadTableData(query); + } + + unSelectRow = async (assetId) => { + const selectedRowKeys = this.state.selectedRowKeys.filter(key => key !== assetId); + const totalSelectedRows = this.state.totalSelectedRows.filter(item => item['id'] !== assetId); + this.setState({ + selectedRowKeys: selectedRowKeys, + totalSelectedRows: totalSelectedRows + }) + } + + render() { + + const columns = [{ + title: '序号', + dataIndex: 'id', + key: 'id', + render: (id, record, index) => { + return index + 1; + } + }, { + title: '资产名称', + dataIndex: 'name', + key: 'name', + render: (name, record) => { + let short = name; + if (short && short.length > 20) { + short = short.substring(0, 20) + " ..."; + } + return ( + + {short} + + ); + } + }, { + title: '连接协议', + dataIndex: 'protocol', + key: 'protocol', + render: (text, record) => { + const title = `${record['ip'] + ':' + record['port']}` + return ( + + {text} + + ) + } + }, { + title: '标签', + dataIndex: 'tags', + key: 'tags', + render: tags => { + if (!isEmpty(tags)) { + let tagDocuments = [] + let tagArr = tags.split(','); + for (let i = 0; i < tagArr.length; i++) { + if (tags[i] === '-') { + continue; + } + tagDocuments.push({tagArr[i]}) + } + return tagDocuments; + } + } + }, { + title: '状态', + dataIndex: 'active', + key: 'active', + render: text => { + + if (text) { + return ( + + + + ) + } else { + return ( + + + + ) + } + } + }, { + title: '所有者', + dataIndex: 'ownerName', + key: 'ownerName' + }, { + title: '创建日期', + dataIndex: 'created', + key: 'created', + render: (text, record) => { + return ( + + {dayjs(text).fromNow()} + + ) + } + }, + ]; + + const selectedRowKeys = this.state.selectedRowKeys; + const rowSelection = { + selectedRowKeys: this.state.selectedRowKeys, + onChange: (selectedRowKeys, selectedRows) => { + this.setState({selectedRowKeys, selectedRows}); + }, + getCheckboxProps: (record) => ({ + disabled: record['disabled'], + }), + }; + let hasSelected = false; + if (selectedRowKeys.length > 0) { + let totalSelectedRows = this.state.totalSelectedRows; + let allSelectedRowKeys = totalSelectedRows.map(item => item['id']); + for (let i = 0; i < selectedRowKeys.length; i++) { + let selectedRowKey = selectedRowKeys[i]; + if (!allSelectedRowKeys.includes(selectedRowKey)) { + hasSelected = true; + break; + } + } + } + + return ( + <> + 已选择资产列表 +
+ { + this.state.totalSelectedRows.map(item => { + return this.unSelectRow(item['id'])} + key={item['id']}>{item['name']} + }) + } +
+ + + +
+ + + 全部资产列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + `总计 ${total} 条` + }} + loading={this.state.loading} + /> + + + ); + } +} + +export default ChooseAsset; diff --git a/web/src/components/command/DynamicCommand.js b/web/src/components/command/DynamicCommand.js index 08eea4d..c7161bc 100644 --- a/web/src/components/command/DynamicCommand.js +++ b/web/src/components/command/DynamicCommand.js @@ -32,10 +32,10 @@ import { SyncOutlined, UndoOutlined } from '@ant-design/icons'; -import {compare} from "../../utils/utils"; import {hasPermission, isAdmin} from "../../service/permission"; import dayjs from "dayjs"; +import ChooseAsset from "./ChooseAsset"; const confirm = Modal.confirm; const {Content} = Layout; @@ -191,6 +191,12 @@ class DynamicCommand extends Component { }); }; + setCheckedAssets = (checkedAssets) => { + this.setState({ + checkedAssets: checkedAssets + }) + } + executeCommand = e => { let checkedAssets = this.state.checkedAssets; if (checkedAssets.length === 0) { @@ -198,18 +204,10 @@ class DynamicCommand extends Component { return; } - let assets = this.state.assets; let cAssets = checkedAssets.map(item => { - let name = ''; - for (let i = 0; i < assets.length; i++) { - if (assets[i]['id'] === item) { - name = assets[i]['name']; - break; - } - } return { - id: item, - name: name + id: item['id'], + name: item['name'] } }); @@ -474,17 +472,6 @@ class DynamicCommand extends Component { assetsVisible: true, commandId: record['id'] }); - - let result = await request.get('/assets?protocol=ssh'); - if (result.code === 1) { - let assets = result.data; - assets.sort(compare('name')); - this.setState({ - assets: assets - }); - } else { - message.error(result.message); - } }}>执行 @@ -640,7 +627,8 @@ class DynamicCommand extends Component { { this.setState({ @@ -648,19 +636,11 @@ class DynamicCommand extends Component { }); }} > - - 全选 - - + - { - return { - label: item.name, - value: item.id, - key: item.id, - } - })} value={this.state.checkedAssets} onChange={this.onChange}/> +