|
|
@@ -0,0 +1,286 @@
|
|
|
+import React, { PureComponent } from 'react';
|
|
|
+import { PageHeader, Button, Descriptions, Modal, Card, Icon, Row, Col, Form, Popconfirm, Input, Space, Divider, Table } from 'antd';
|
|
|
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
|
|
+import { connect } from 'umi'
|
|
|
+import styles from './VolumeModal.less'
|
|
|
+
|
|
|
+const EditableCell = ({
|
|
|
+ editing,
|
|
|
+ dataIndex,
|
|
|
+ title,
|
|
|
+ inputType,
|
|
|
+ record,
|
|
|
+ index,
|
|
|
+ children,
|
|
|
+ ...restProps
|
|
|
+}) => {
|
|
|
+ return (
|
|
|
+ <td key={`${record?.name}-${dataIndex}`} {...restProps}>
|
|
|
+ {editing ? (
|
|
|
+ <Form.Item
|
|
|
+ key={`formitem-${record.name}-${dataIndex}`}
|
|
|
+ name={dataIndex}
|
|
|
+ style={{ margin: 0 }}
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: `该项不能为空!`,
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ >
|
|
|
+ <Input></Input>
|
|
|
+ </Form.Item>
|
|
|
+ ) : (
|
|
|
+ dataIndex == 'name' ? record.name.substring(record.name.indexOf('-') + 1) : children
|
|
|
+ )}
|
|
|
+ </td>
|
|
|
+ );
|
|
|
+};
|
|
|
+@connect(({app}) => ({
|
|
|
+ app
|
|
|
+}))
|
|
|
+export default class VolumeModal extends PureComponent {
|
|
|
+ tableFormRef = React.createRef();
|
|
|
+ createFormRef = React.createRef();
|
|
|
+ state = {
|
|
|
+ editingKey: null,
|
|
|
+ showCreateModal: false,
|
|
|
+ currentApp: null,
|
|
|
+ }
|
|
|
+
|
|
|
+ fetchData(id) {
|
|
|
+ this.props.dispatch({
|
|
|
+ type: 'app/get',
|
|
|
+ payload: {
|
|
|
+ id,
|
|
|
+ callback: (response) => {
|
|
|
+ if (response && response.code == 0) {
|
|
|
+ this.setState({
|
|
|
+ currentApp: response.result,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ componentWillReceiveProps(props) {
|
|
|
+ if (props.visible && !this.props.visible) {
|
|
|
+ this.fetchData(props.appId);
|
|
|
+ this.setState({
|
|
|
+ editingKey: null,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ save(record) {
|
|
|
+ this.tableFormRef.current.validateFields().then((values) => {
|
|
|
+ this.props.dispatch({
|
|
|
+ type: 'app/updateVolume',
|
|
|
+ payload: {
|
|
|
+ ...values,
|
|
|
+ name: record.name.substring(record.name.indexOf('-') + 1),
|
|
|
+ appId: this.props.appId,
|
|
|
+ callback: (response) => {
|
|
|
+ if (response && response.code == 0) {
|
|
|
+ this.fetchData(this.props.appId);
|
|
|
+ this.setState({
|
|
|
+ editingKey: null,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ cancel() {
|
|
|
+ this.setState({
|
|
|
+ editingKey: null,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ edit(record) {
|
|
|
+ this.setState({
|
|
|
+ editingKey: record.name,
|
|
|
+ });
|
|
|
+ this.tableFormRef.current.setFieldsValue({
|
|
|
+ ...record,
|
|
|
+ name: record.name.substring(record.name.indexOf('-') + 1)
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ deleteVolume(record) {
|
|
|
+ this.props.dispatch({
|
|
|
+ type: 'app/deleteVolume',
|
|
|
+ payload: {
|
|
|
+ ...record,
|
|
|
+ appId: this.props.appId,
|
|
|
+ callback: (response) => {
|
|
|
+ if (response && response.code == 0) {
|
|
|
+ this.fetchData(this.props.appId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ create() {
|
|
|
+ this.createFormRef.current.validateFields().then(values => {
|
|
|
+ this.props.dispatch({
|
|
|
+ type: 'app/createVolume',
|
|
|
+ payload: {
|
|
|
+ ...values,
|
|
|
+ appId: this.props.appId,
|
|
|
+ callback: (response) => {
|
|
|
+ if (response && response.code == 0) {
|
|
|
+ this.fetchData(this.props.appId);
|
|
|
+ this.setState({
|
|
|
+ showCreateModal: false,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ hideCreate() {
|
|
|
+ this.setState({
|
|
|
+ showCreateModal: false,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ showCreate() {
|
|
|
+ this.setState({
|
|
|
+ showCreateModal: true,
|
|
|
+ }, () => {
|
|
|
+ this.createFormRef.current.setFieldsValue({
|
|
|
+ name: '',
|
|
|
+ quantity: ''
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ const columns = [
|
|
|
+ {
|
|
|
+ title: '名称',
|
|
|
+ dataIndex: 'name',
|
|
|
+ render: (text) => {
|
|
|
+ return <span>{text.substring(text.indexOf('-') + 1)}</span>;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '容量',
|
|
|
+ dataIndex: 'quantity',
|
|
|
+ editable: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ width: '10%',
|
|
|
+ dataIndex: 'operation',
|
|
|
+ render: (_, record) => {
|
|
|
+ const editable = record.name == this.state.editingKey;
|
|
|
+ return editable ? (
|
|
|
+ <span key={record.name}>
|
|
|
+ <a href="javascript:;" onClick={() => this.save(record)} style={{ marginRight: 8 }}>
|
|
|
+ 保存
|
|
|
+ </a>
|
|
|
+ <a onClick={this.cancel.bind(this)}>取消</a>
|
|
|
+ </span>
|
|
|
+ ) : (
|
|
|
+ <span key={record.name}>
|
|
|
+ <a disabled={this.state.editingKey != null} onClick={() => this.edit(record)} style={{marginRight: 5}}>
|
|
|
+ 编辑
|
|
|
+ </a>
|
|
|
+ <Popconfirm title="确认要删除吗?当前Volume策略为保留,请及时迁移数据以免被删除" onConfirm={() => this.deleteVolume(record)} okText="确定" cancelText="取消">
|
|
|
+ <a disabled={this.state.editingKey != null} >
|
|
|
+ 删除
|
|
|
+ </a>
|
|
|
+ </Popconfirm>
|
|
|
+ </span>
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ const mergedColumns = columns.map(col => {
|
|
|
+ if (!col.editable) {
|
|
|
+ return col;
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ ...col,
|
|
|
+ onCell: (record) => ({
|
|
|
+ record,
|
|
|
+ dataIndex: col.dataIndex,
|
|
|
+ title: col.title,
|
|
|
+ editing: record.name == this.state.editingKey,
|
|
|
+ }),
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ visible={this.props.visible}
|
|
|
+ forceRender
|
|
|
+ onCancel={() => this.props.onCancel()}
|
|
|
+ title={"更新配置"}
|
|
|
+ okText="确认"
|
|
|
+ cancelText="取消"
|
|
|
+ onOk={() => this.props.onOk()}
|
|
|
+ className={styles.modal}
|
|
|
+ width="80%"
|
|
|
+ >
|
|
|
+ <Button onClick={this.showCreate.bind(this)}>新建</Button>
|
|
|
+ <Modal
|
|
|
+ title="新建持久卷"
|
|
|
+ okText="确认"
|
|
|
+ cancelText="取消"
|
|
|
+ visible={this.state.showCreateModal}
|
|
|
+ onCancel={this.hideCreate.bind(this)}
|
|
|
+ onOk={this.create.bind(this)}
|
|
|
+ >
|
|
|
+ <Form
|
|
|
+ ref={this.createFormRef}
|
|
|
+ labelCol={{ span: 4 }}
|
|
|
+ wrapperCol={{ span: 20 }}
|
|
|
+ labelAlign="right"
|
|
|
+ >
|
|
|
+ <Form.Item
|
|
|
+ name="name"
|
|
|
+ label="名称"
|
|
|
+ rules={[{required: true, message: '名称不能为空'}]}
|
|
|
+ >
|
|
|
+ <Input></Input>
|
|
|
+ </Form.Item >
|
|
|
+ <Form.Item
|
|
|
+ name="quantity"
|
|
|
+ label="容量"
|
|
|
+ rules={[{required: true, message: '容量不能为空'}, {pattern:/[0-9][MBKG]i/, message: '格式错误!'}]}
|
|
|
+ tooltip="格式为[0-9][MBKG]i"
|
|
|
+ >
|
|
|
+ <Input></Input>
|
|
|
+ </Form.Item >
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ <Form
|
|
|
+ ref={this.tableFormRef}
|
|
|
+ >
|
|
|
+ <Table
|
|
|
+ components={{
|
|
|
+ body: {
|
|
|
+ cell: EditableCell,
|
|
|
+ },
|
|
|
+ }}
|
|
|
+ bordered
|
|
|
+ dataSource={this.state.currentApp?.pvcs || []}
|
|
|
+ columns={mergedColumns}
|
|
|
+ rowClassName="editable-row"
|
|
|
+ pagination={{
|
|
|
+ onChange: this.cancel.bind(this),
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|