index.tsx 11.3 KB
Newer Older
1
import React, { Component } from 'react';
陈帅's avatar
陈帅 committed
2 3 4 5 6 7 8 9 10 11 12 13 14
import {
  Card,
  Form,
  Icon,
  Button,
  Col,
  Row,
  DatePicker,
  TimePicker,
  Input,
  Select,
  Popover,
} from 'antd';
15
import { connect } from 'dva';
16
import TableForm from './components/TableForm';
17
import styles from './style.less';
18 19
import { FormComponentProps } from 'antd/lib/form';
import { Dispatch } from 'redux';
陈帅's avatar
陈帅 committed
20
import FooterToolbar from './components/FooterToolbar';
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

const { Option } = Select;
const { RangePicker } = DatePicker;

const fieldLabels = {
  name: '仓库名',
  url: '仓库域名',
  owner: '仓库管理员',
  approver: '审批人',
  dateRange: '生效日期',
  type: '仓库类型',
  name2: '任务名',
  url2: '任务描述',
  owner2: '执行人',
  approver2: '责任人',
  dateRange2: '生效日期',
  type2: '任务类型',
};

jim's avatar
jim committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
const tableData = [
  {
    key: '1',
    workId: '00001',
    name: 'John Brown',
    department: 'New York No. 1 Lake Park',
  },
  {
    key: '2',
    workId: '00002',
    name: 'Jim Green',
    department: 'London No. 1 Lake Park',
  },
  {
    key: '3',
    workId: '00003',
    name: 'Joe Black',
    department: 'Sidney No. 1 Lake Park',
  },
];
60

61
interface PAGE_NAME_UPPER_CAMEL_CASEProps extends FormComponentProps {
陈帅's avatar
陈帅 committed
62
  dispatch: Dispatch<any>;
陈帅's avatar
陈帅 committed
63
  submitting: boolean;
64 65
}

陈帅's avatar
陈帅 committed
66
@connect(({ loading }: { loading: { effects: { [key: string]: boolean } } }) => ({
67
  submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitAdvancedForm'],
68
}))
69
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEProps> {
afc163's avatar
afc163 committed
70 71 72
  state = {
    width: '100%',
  };
陈帅's avatar
陈帅 committed
73

afc163's avatar
afc163 committed
74
  componentDidMount() {
jim's avatar
jim committed
75
    window.addEventListener('resize', this.resizeFooterToolbar, { passive: true });
afc163's avatar
afc163 committed
76
  }
陈帅's avatar
陈帅 committed
77

afc163's avatar
afc163 committed
78 79 80
  componentWillUnmount() {
    window.removeEventListener('resize', this.resizeFooterToolbar);
  }
陈帅's avatar
陈帅 committed
81

afc163's avatar
afc163 committed
82 83 84 85 86 87 88 89 90
  getErrorInfo = () => {
    const {
      form: { getFieldsError },
    } = this.props;
    const errors = getFieldsError();
    const errorCount = Object.keys(errors).filter(key => errors[key]).length;
    if (!errors || errorCount === 0) {
      return null;
    }
91
    const scrollToField = (fieldKey: string) => {
afc163's avatar
afc163 committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
      const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
      if (labelNode) {
        labelNode.scrollIntoView(true);
      }
    };
    const errorList = Object.keys(errors).map(key => {
      if (!errors[key]) {
        return null;
      }
      return (
        <li key={key} className={styles.errorListItem} onClick={() => scrollToField(key)}>
          <Icon type="cross-circle-o" className={styles.errorIcon} />
          <div className={styles.errorMessage}>{errors[key][0]}</div>
          <div className={styles.errorField}>{fieldLabels[key]}</div>
        </li>
      );
    });
    return (
      <span className={styles.errorIcon}>
        <Popover
          title="表单校验信息"
          content={errorList}
          overlayClassName={styles.errorPopover}
          trigger="click"
陈帅's avatar
陈帅 committed
116 117 118 119 120 121
          getPopupContainer={(trigger: HTMLElement) => {
            if (trigger && trigger.parentNode) {
              return trigger.parentNode as HTMLElement;
            }
            return trigger;
          }}
afc163's avatar
afc163 committed
122 123 124 125 126 127 128 129
        >
          <Icon type="exclamation-circle" />
        </Popover>
        {errorCount}
      </span>
    );
  };

afc163's avatar
afc163 committed
130
  resizeFooterToolbar = () => {
jim's avatar
jim committed
131
    requestAnimationFrame(() => {
132
      const sider = document.querySelectorAll('.ant-layout-sider')[0] as HTMLDivElement;
陈帅's avatar
陈帅 committed
133 134 135 136 137 138
      if (sider) {
        const width = `calc(100% - ${sider.style.width})`;
        const { width: stateWidth } = this.state;
        if (stateWidth !== width) {
          this.setState({ width });
        }
jim's avatar
jim committed
139 140
      }
    });
jim's avatar
jim committed
141
  };
陈帅's avatar
陈帅 committed
142

afc163's avatar
afc163 committed
143 144 145 146 147 148 149 150 151
  validate = () => {
    const {
      form: { validateFieldsAndScroll },
      dispatch,
    } = this.props;
    validateFieldsAndScroll((error, values) => {
      if (!error) {
        // submit the values
        dispatch({
152
          type: 'BLOCK_NAME_CAMEL_CASE/submitAdvancedForm',
afc163's avatar
afc163 committed
153 154
          payload: values,
        });
155
      }
afc163's avatar
afc163 committed
156 157 158 159 160 161
    });
  };

  render() {
    const {
      form: { getFieldDecorator },
陈帅's avatar
陈帅 committed
162
      submitting,
afc163's avatar
afc163 committed
163
    } = this.props;
陈帅's avatar
陈帅 committed
164
    const { width } = this.state;
165
    return (
166
      <>
afc163's avatar
afc163 committed
167 168 169 170 171 172 173
        <Card title="仓库管理" className={styles.card} bordered={false}>
          <Form layout="vertical" hideRequiredMark>
            <Row gutter={16}>
              <Col lg={6} md={12} sm={24}>
                <Form.Item label={fieldLabels.name}>
                  {getFieldDecorator('name', {
                    rules: [{ required: true, message: '请输入仓库名称' }],
jim's avatar
jim committed
174
                  })(<Input placeholder="请输入仓库名称" />)}
afc163's avatar
afc163 committed
175 176 177 178 179 180 181 182 183 184 185 186
                </Form.Item>
              </Col>
              <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
                <Form.Item label={fieldLabels.url}>
                  {getFieldDecorator('url', {
                    rules: [{ required: true, message: '请选择' }],
                  })(
                    <Input
                      style={{ width: '100%' }}
                      addonBefore="http://"
                      addonAfter=".com"
                      placeholder="请输入"
陈帅's avatar
陈帅 committed
187
                    />,
afc163's avatar
afc163 committed
188 189 190 191 192 193 194 195 196 197 198
                  )}
                </Form.Item>
              </Col>
              <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
                <Form.Item label={fieldLabels.owner}>
                  {getFieldDecorator('owner', {
                    rules: [{ required: true, message: '请选择管理员' }],
                  })(
                    <Select placeholder="请选择管理员">
                      <Option value="xiao">付晓晓</Option>
                      <Option value="mao">周毛毛</Option>
陈帅's avatar
陈帅 committed
199
                    </Select>,
afc163's avatar
afc163 committed
200 201 202 203 204 205 206 207 208 209 210 211 212
                  )}
                </Form.Item>
              </Col>
            </Row>
            <Row gutter={16}>
              <Col lg={6} md={12} sm={24}>
                <Form.Item label={fieldLabels.approver}>
                  {getFieldDecorator('approver', {
                    rules: [{ required: true, message: '请选择审批员' }],
                  })(
                    <Select placeholder="请选择审批员">
                      <Option value="xiao">付晓晓</Option>
                      <Option value="mao">周毛毛</Option>
陈帅's avatar
陈帅 committed
213
                    </Select>,
afc163's avatar
afc163 committed
214 215 216 217 218 219 220 221
                  )}
                </Form.Item>
              </Col>
              <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
                <Form.Item label={fieldLabels.dateRange}>
                  {getFieldDecorator('dateRange', {
                    rules: [{ required: true, message: '请选择生效日期' }],
                  })(
陈帅's avatar
陈帅 committed
222 223 224 225
                    <RangePicker
                      placeholder={['开始日期', '结束日期']}
                      style={{ width: '100%' }}
                    />,
afc163's avatar
afc163 committed
226 227 228 229 230 231 232 233 234 235 236
                  )}
                </Form.Item>
              </Col>
              <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
                <Form.Item label={fieldLabels.type}>
                  {getFieldDecorator('type', {
                    rules: [{ required: true, message: '请选择仓库类型' }],
                  })(
                    <Select placeholder="请选择仓库类型">
                      <Option value="private">私密</Option>
                      <Option value="public">公开</Option>
陈帅's avatar
陈帅 committed
237
                    </Select>,
afc163's avatar
afc163 committed
238 239 240 241 242 243 244 245 246 247 248 249 250
                  )}
                </Form.Item>
              </Col>
            </Row>
          </Form>
        </Card>
        <Card title="任务管理" className={styles.card} bordered={false}>
          <Form layout="vertical" hideRequiredMark>
            <Row gutter={16}>
              <Col lg={6} md={12} sm={24}>
                <Form.Item label={fieldLabels.name2}>
                  {getFieldDecorator('name2', {
                    rules: [{ required: true, message: '请输入' }],
jim's avatar
jim committed
251
                  })(<Input placeholder="请输入" />)}
afc163's avatar
afc163 committed
252 253 254 255 256 257
                </Form.Item>
              </Col>
              <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
                <Form.Item label={fieldLabels.url2}>
                  {getFieldDecorator('url2', {
                    rules: [{ required: true, message: '请选择' }],
jim's avatar
jim committed
258
                  })(<Input placeholder="请输入" />)}
afc163's avatar
afc163 committed
259 260 261 262 263 264 265 266 267 268
                </Form.Item>
              </Col>
              <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
                <Form.Item label={fieldLabels.owner2}>
                  {getFieldDecorator('owner2', {
                    rules: [{ required: true, message: '请选择管理员' }],
                  })(
                    <Select placeholder="请选择管理员">
                      <Option value="xiao">付晓晓</Option>
                      <Option value="mao">周毛毛</Option>
陈帅's avatar
陈帅 committed
269
                    </Select>,
afc163's avatar
afc163 committed
270 271 272 273 274 275 276 277 278 279 280 281 282
                  )}
                </Form.Item>
              </Col>
            </Row>
            <Row gutter={16}>
              <Col lg={6} md={12} sm={24}>
                <Form.Item label={fieldLabels.approver2}>
                  {getFieldDecorator('approver2', {
                    rules: [{ required: true, message: '请选择审批员' }],
                  })(
                    <Select placeholder="请选择审批员">
                      <Option value="xiao">付晓晓</Option>
                      <Option value="mao">周毛毛</Option>
陈帅's avatar
陈帅 committed
283
                    </Select>,
afc163's avatar
afc163 committed
284 285 286 287 288 289 290 291 292 293 294
                  )}
                </Form.Item>
              </Col>
              <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
                <Form.Item label={fieldLabels.dateRange2}>
                  {getFieldDecorator('dateRange2', {
                    rules: [{ required: true, message: '请输入' }],
                  })(
                    <TimePicker
                      placeholder="提醒时间"
                      style={{ width: '100%' }}
陈帅's avatar
陈帅 committed
295 296 297 298 299 300
                      getPopupContainer={trigger => {
                        if (trigger && trigger.parentNode) {
                          return trigger.parentNode as HTMLElement;
                        }
                        return trigger;
                      }}
陈帅's avatar
陈帅 committed
301
                    />,
afc163's avatar
afc163 committed
302 303 304 305 306 307 308 309 310 311 312
                  )}
                </Form.Item>
              </Col>
              <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
                <Form.Item label={fieldLabels.type2}>
                  {getFieldDecorator('type2', {
                    rules: [{ required: true, message: '请选择仓库类型' }],
                  })(
                    <Select placeholder="请选择仓库类型">
                      <Option value="private">私密</Option>
                      <Option value="public">公开</Option>
陈帅's avatar
陈帅 committed
313
                    </Select>,
afc163's avatar
afc163 committed
314 315 316 317 318 319
                  )}
                </Form.Item>
              </Col>
            </Row>
          </Form>
        </Card>
320
        <Card title="成员管理" bordered={false}>
afc163's avatar
afc163 committed
321 322 323 324
          {getFieldDecorator('members', {
            initialValue: tableData,
          })(<TableForm />)}
        </Card>
陈帅's avatar
陈帅 committed
325
        <FooterToolbar style={{ width }}>
afc163's avatar
afc163 committed
326 327
          {this.getErrorInfo()}
          <Button type="primary" onClick={this.validate} loading={submitting}>
afc163's avatar
afc163 committed
328 329
            提交
          </Button>
陈帅's avatar
陈帅 committed
330
        </FooterToolbar>
331
      </>
332
    );
afc163's avatar
afc163 committed
333
  }
334
}
陈帅's avatar
陈帅 committed
335

陈帅's avatar
陈帅 committed
336
export default Form.create<PAGE_NAME_UPPER_CAMEL_CASEProps>()(PAGE_NAME_UPPER_CAMEL_CASE);