antd#AutoComplete JavaScript Examples

The following examples show how to use antd#AutoComplete. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From online-test-platform with Apache License 2.0 6 votes vote down vote up
render() {
    const { className, placeholder, open, ...restProps } = this.props;
    const { searchMode, value } = this.state;
    delete restProps.defaultOpen; // for rc-select not affected
    const inputClass = classNames(styles.input, {
      [styles.show]: searchMode,
    });
    return (
      <span
        className={classNames(className, styles.headerSearch)}
        onClick={this.enterSearchMode}
        onTransitionEnd={({ propertyName }) => {
          if (propertyName === 'width' && !searchMode) {
            const { onVisibleChange } = this.props;
            onVisibleChange(searchMode);
          }
        }}
      >
        <Icon type="search" key="Icon" />
        <AutoComplete
          key="AutoComplete"
          {...restProps}
          className={inputClass}
          value={value}
          onChange={this.onChange}
        >
          <Input
            ref={node => {
              this.input = node;
            }}
            aria-label={placeholder}
            placeholder={placeholder}
            onKeyDown={this.onKeyDown}
            onBlur={this.leaveSearchMode}
          />
        </AutoComplete>
      </span>
    );
  }
Example #2
Source File: autocomplete_filter.js    From art-dashboard-ui with Apache License 2.0 6 votes vote down vote up
render() {
        return (

                <AutoComplete style={{
                    width: "90%",
                    paddingRight: "10%"
                }}
                allowClear={true}
                options={this.state.options}
                placeholder={this.state.placeholder}
                value={this.state.value}
                onSelect={this.onChange}
                filterOption={(inputValue, option) =>
                                  option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
                              }
                />

        )
    }
Example #3
Source File: HighlightInput.js    From 4IZ268-2021-2022-ZS with MIT License 6 votes vote down vote up
HighlightInput = () => {

    const clubList = useDataStore((store) => store.clubList)
    const setHighlightClub = usePersonalSettings((store) => store.setHighlightClub)

    const onChange = (val) => {
        setHighlightClub(val)
    }

    const onSelect = (val) => {
        setHighlightClub(val)
    }

    return (
        <AutoComplete
            options={clubList.map((str) => { return { label: str, value: str } })}
            onSelect={onSelect}
            onChange={onChange}
            style={{width: 200}}
        />
    )
}
Example #4
Source File: index.js    From camel-store-admin with Apache License 2.0 6 votes vote down vote up
render() {
    const { className, placeholder, open, ...restProps } = this.props;
    const { searchMode, value } = this.state;
    delete restProps.defaultOpen; // for rc-select not affected
    const inputClass = classNames(styles.input, {
      [styles.show]: searchMode,
    });
    return (
      <span
        className={classNames(className, styles.headerSearch)}
        onClick={this.enterSearchMode}
        onTransitionEnd={({ propertyName }) => {
          if (propertyName === 'width' && !searchMode) {
            const { onVisibleChange } = this.props;
            onVisibleChange(searchMode);
          }
        }}
      >
        <Icon type="search" key="Icon" />
        <AutoComplete
          key="AutoComplete"
          {...restProps}
          className={inputClass}
          value={value}
          onChange={this.onChange}
        >
          <Input
            ref={node => {
              this.input = node;
            }}
            aria-label={placeholder}
            placeholder={placeholder}
            onKeyDown={this.onKeyDown}
            onBlur={this.leaveSearchMode}
          />
        </AutoComplete>
      </span>
    );
  }
Example #5
Source File: Search.js    From YApi-X with MIT License 6 votes vote down vote up
// getDataSource(groupList){
  //   const groupArr =[];
  //   groupList.forEach(item =>{
  //     groupArr.push("group: "+ item["group_name"]);
  //   })
  //   return groupArr;
  // }

  render() {
    const { dataSource } = this.state;

    return (
      <div className="search-wrapper">
        <AutoComplete
          className="search-dropdown"
          dataSource={dataSource}
          style={{ width: '100%' }}
          defaultActiveFirstOption={false}
          onSelect={this.onSelect}
          onSearch={this.handleSearch}
          // filterOption={(inputValue, option) =>
          //   option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
          // }
        >
          <Input
            prefix={<Icon type="search" className="srch-icon" />}
            placeholder="搜索分组/项目/接口"
            className="search-input"
          />
        </AutoComplete>
      </div>
    );
  }
Example #6
Source File: index.js    From gobench with Apache License 2.0 5 votes vote down vote up
render() {
    const { result } = this.state
    const children = result.map(email => <Option key={email}>{email}</Option>)

    return (
      <div>
        <div className="row">
          <div className="col-lg-6 mb-5">
            <h5 className="mb-3">
              <strong>Basic</strong>
            </h5>
            <AutoComplete
              dataSource={this.state.dataSource}
              style={{ width: 200 }}
              onSelect={onSelect}
              onSearch={this.onSearch}
              placeholder="input here"
            />
            <br />
            <br />
            <AutoComplete
              value={this.state.value}
              dataSource={this.state.dataSource}
              style={{ width: 200 }}
              onSelect={onSelect}
              onSearch={this.onSearch}
              onChange={this.onChange}
              placeholder="control mode"
            />
          </div>
          <div className="col-lg-6 mb-5">
            <h5 className="mb-3">
              <strong>Customized</strong>
            </h5>
            <AutoComplete
              style={{ width: 200 }}
              onSearch={this.handleSearch}
              placeholder="input here"
            >
              {children}
            </AutoComplete>
          </div>
        </div>
      </div>
    )
  }
Example #7
Source File: index.jsx    From prometheusPro with MIT License 5 votes vote down vote up
HeaderSearch = props => {
  const {
    className,
    defaultValue,
    onVisibleChange,
    placeholder,
    open,
    defaultOpen,
    ...restProps
  } = props;
  const inputRef = useRef(null);
  const [value, setValue] = useMergeValue(defaultValue, {
    value: props.value,
    onChange: props.onChange,
  });
  const [searchMode, setSearchMode] = useMergeValue(defaultOpen || false, {
    value: props.open,
    onChange: onVisibleChange,
  });
  const inputClass = classNames(styles.input, {
    [styles.show]: searchMode,
  });
  return (
    <div
      className={classNames(className, styles.headerSearch)}
      onClick={() => {
        setSearchMode(true);

        if (searchMode && inputRef.current) {
          inputRef.current.focus();
        }
      }}
      onTransitionEnd={({ propertyName }) => {
        if (propertyName === 'width' && !searchMode) {
          if (onVisibleChange) {
            onVisibleChange(searchMode);
          }
        }
      }}
    >
      <SearchOutlined
        key="Icon"
        style={{
          cursor: 'pointer',
        }}
      />
      <AutoComplete
        key="AutoComplete"
        className={inputClass}
        value={value}
        style={{
          height: 28,
          marginTop: -6,
        }}
        options={restProps.options}
        onChange={setValue}
      >
        <Input
          ref={inputRef}
          size="middle"
          defaultValue={defaultValue}
          aria-label={placeholder}
          placeholder={placeholder}
          onKeyDown={e => {
            if (e.key === 'Enter') {
              if (restProps.onSearch) {
                restProps.onSearch(value);
              }
            }
          }}
          onBlur={() => {
            setSearchMode(false);
          }}
        />
      </AutoComplete>
    </div>
  );
}
Example #8
Source File: align.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/Input', module).add('align', () => 
  <>
    <Mentions style={{ width: 100 }} rows={1} />
    <Input.TextArea rows={1} style={{ width: 100 }} />
    <Button type="primary">Button</Button>
    <Input style={{ width: 100 }} />
    <Text copyable>Ant Design</Text>
    <Input prefix="1" suffix="2" style={{ width: 100 }} />
    <Input addonBefore="1" addonAfter="2" style={{ width: 100 }} />
    <InputNumber style={{ width: 100 }} />
    <DatePicker style={{ width: 100 }} />
    <TimePicker style={{ width: 100 }} />
    <Select style={{ width: 100 }} defaultValue="jack">
      <Option value="jack">Jack</Option>
      <Option value="lucy">Lucy</Option>
      <Option value="disabled" disabled>
        Disabled
      </Option>
      <Option value="Yiminghe">yiminghe</Option>
    </Select>
    <TreeSelect style={{ width: 100 }} />
    <Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} />
    <RangePicker />
    <DatePicker picker="month" />
    <Radio.Group defaultValue="a">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
    </Radio.Group>
    <AutoComplete style={{ width: 100 }} placeholder="input here" />
    <br />
    <Input prefix="$" addonBefore="Http://" addonAfter=".com" defaultValue="mysite" />
    <Input style={narrowStyle} suffix="Y" />
    <Input style={narrowStyle} />
    <Input style={narrowStyle} defaultValue="1" suffix="Y" />
  </>,
  { docs: { page: () => (<><hr />
<p>order: 99
title:
  zh-CN: 文本对齐
  en-US: Text Align</p>
<h2 id="debugtrue">debug: true</h2></>) } });
Example #9
Source File: Playlists.js    From remixr with MIT License 5 votes vote down vote up
export default function Playlist() {
  const [accessToken] = useState(Cookies.get('access_token'));
  const [playlists, setPlaylists] = useState([]);
  const [filteredPlaylists, setFilteredPlaylists] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    if (accessToken) {
      ReactGA.pageview('/playlists');
      let url = process.env.REACT_APP_API_URL + '/playlists';

      transport.get(url).then(
        (response) => {
          setPlaylists(response.data.playlists);
          setFilteredPlaylists(response.data.playlists);
          setLoading(false);
        },
        (error) => {
          setError(true);
        }
      );
    }
  }, []);

  if (!accessToken) {
    return <Redirect to="/" />;
  }

  const filter = (searchTerm) => {
    setFilteredPlaylists(playlists.filter((item) => item.name.toLowerCase().includes(searchTerm.toLowerCase())));
    ReactGA.event({
      category: 'Playlist',
      action: 'Search playlists',
    });
  };

  if (error) {
    return <ErrorScreen />;
  }

  return (
    <div className="playlists">
      <Navbar />

      <Title> Select playlist </Title>

      <AutoComplete className="searchBox" onSearch={filter}>
        <Input className="rounded" size="large" placeholder="Filter Playlists" />
      </AutoComplete>

      <Divider />

      <div>
        <Row gutter={[16, 24]}>
          {loading && <Skeleton active />}
          {filteredPlaylists &&
            filteredPlaylists.map((item) => {
              return <PlaylistCard playlist={item} key={item.id} />;
            })}
        </Row>
      </div>
    </div>
  );
}
Example #10
Source File: index.js    From bank-client with MIT License 5 votes vote down vote up
function Recipient({ intl, onValidateFields }) {
  const { recipients } = useSelector(stateSelector);
  const dispatch = useDispatch();

  const onChangeRecipientAccountBill = (name, value) =>
    dispatch(changeInputAction({ name, value }));
  const onSearchRecipient = (value) =>
    value && dispatch(searchRecipientAction(value));

  const checkStringConsistsNumbersOnly = (_, value) => {
    if (value && !numberValidation(value)) {
      return Promise.reject(
        new Error(intl.formatMessage(messages.validationNumber)),
      );
    }

    if (!value) {
      return Promise.reject(new Error(intl.formatMessage(messages.validation)));
    }

    return Promise.resolve();
  };

  const options = recipients.map((recipient) => ({
    label: (
      <>
        <div>
          {recipient.user.firstName} {recipient.user.lastName}
        </div>
        <div>{recipient.accountBillNumber}</div>
      </>
    ),
    value: recipient.accountBillNumber.replace(/ /g, ''),
  }));

  return (
    <StyledFormItem
      label={intl.formatMessage(messages.label)}
      name="recipientBill"
      rules={[{ validator: checkStringConsistsNumbersOnly }]}
    >
      <AutoComplete
        onSearch={onSearchRecipient}
        onChange={(value) =>
          onChangeRecipientAccountBill('recipientAccountBillNumber', value)
        }
        options={options}
        notFoundContent={
          <div>
            <FormattedMessage {...messages.notFoundContent} />
          </div>
        }
      >
        <Input
          onPressEnter={onValidateFields}
          onKeyPress={disabledSpacesInput}
          maxLength="26"
          placeholder={intl.formatMessage(messages.placeholder)}
          suffix={
            <Tooltip title={intl.formatMessage(messages.tooltip)}>
              <QuestionCircleOutlined />
            </Tooltip>
          }
        />
      </AutoComplete>
    </StyledFormItem>
  );
}
Example #11
Source File: GeneSearchBar.jsx    From ui with MIT License 5 votes vote down vote up
GeneSearchBar = (props) => {
  const { plotUuid, experimentId, searchBarUuid } = props;

  const dispatch = useDispatch();

  const geneList = useSelector((state) => state.genes.properties.views[searchBarUuid]?.data);

  const config = useSelector((state) => state.componentConfig[plotUuid]?.config);

  const [options, setOptions] = useState([]);

  // pass reactive component as value (search text) to allow auto clear on select
  const [value, setValue] = useState('');

  const onSelect = (newGene) => {
    if (!geneList.includes(newGene) || config?.selectedGenes.includes(newGene)) {
      return;
    }

    const genes = _.clone(config?.selectedGenes);
    genes.push(newGene);
    dispatch(loadGeneExpression(experimentId, genes, plotUuid));
    setValue('');
  };

  const onSearch = (searchText) => {
    setValue(searchText);
    setOptions(!searchText ? [] : filterGenes(searchText, geneList, config?.selectedGenes));
  };

  return (
    <AutoComplete
      allowClear
      value={value}
      options={options}
      style={{ width: '100%' }}
      onSelect={onSelect}
      onSearch={onSearch}
      placeholder='Search for genes...'
    />
  );
}
Example #12
Source File: index.jsx    From egoshop with Apache License 2.0 5 votes vote down vote up
render() {
    const { className, placeholder, open, ...restProps } = this.props;
    const { searchMode, value } = this.state;
    delete restProps.defaultOpen; // for rc-select not affected

    const inputClass = classNames(styles.input, {
      [styles.show]: searchMode,
    });
    return (
      <span
        className={classNames(className, styles.headerSearch)}
        onClick={this.enterSearchMode}
        onTransitionEnd={({ propertyName }) => {
          if (propertyName === 'width' && !searchMode) {
            const { onVisibleChange } = this.props;
            onVisibleChange(searchMode);
          }
        }}
      >
        <Icon type="search" key="Icon" />
        <AutoComplete
          key="AutoComplete"
          {...restProps}
          className={inputClass}
          value={value}
          onChange={this.onChange}
        >
          <Input
            ref={node => {
              this.inputRef = node;
            }}
            aria-label={placeholder}
            placeholder={placeholder}
            onKeyDown={this.onKeyDown}
            onBlur={this.leaveSearchMode}
          />
        </AutoComplete>
      </span>
    );
  }
Example #13
Source File: index.js    From gobench with Apache License 2.0 5 votes vote down vote up
{ Option } = AutoComplete
Example #14
Source File: index.jsx    From vpp with MIT License 5 votes vote down vote up
HeaderSearch = props => {
  const {
    className,
    defaultValue,
    onVisibleChange,
    placeholder,
    open,
    defaultOpen,
    ...restProps
  } = props;
  const inputRef = useRef(null);
  const [value, setValue] = useMergeValue(defaultValue, {
    value: props.value,
    onChange: props.onChange,
  });
  const [searchMode, setSearchMode] = useMergeValue(defaultOpen || false, {
    value: props.open,
    onChange: onVisibleChange,
  });
  const inputClass = classNames(styles.input, {
    [styles.show]: searchMode,
  });
  return (
    <div
      className={classNames(className, styles.headerSearch)}
      onClick={() => {
        setSearchMode(true);

        if (searchMode && inputRef.current) {
          inputRef.current.focus();
        }
      }}
      onTransitionEnd={({ propertyName }) => {
        if (propertyName === 'width' && !searchMode) {
          if (onVisibleChange) {
            onVisibleChange(searchMode);
          }
        }
      }}
    >
      <SearchOutlined
        key="Icon"
        style={{
          cursor: 'pointer',
        }}
      />
      <AutoComplete
        key="AutoComplete"
        className={inputClass}
        value={value}
        style={{
          height: 28,
          marginTop: -6,
        }}
        options={restProps.options}
        onChange={setValue}
      >
        <Input
          ref={inputRef}
          defaultValue={defaultValue}
          aria-label={placeholder}
          placeholder={placeholder}
          onKeyDown={e => {
            if (e.key === 'Enter') {
              if (restProps.onSearch) {
                restProps.onSearch(value);
              }
            }
          }}
          onBlur={() => {
            setSearchMode(false);
          }}
        />
      </AutoComplete>
    </div>
  );
}
Example #15
Source File: index.jsx    From spring-boot-plus-admin-react with Apache License 2.0 5 votes vote down vote up
render() {
    const { className, defaultValue, placeholder, open, ...restProps } = this.props;
    const { searchMode, value } = this.state;
    delete restProps.defaultOpen; // for rc-select not affected

    const inputClass = classNames(styles.input, {
      [styles.show]: searchMode,
    });
    return (
      <span
        className={classNames(className, styles.headerSearch)}
        onClick={this.enterSearchMode}
        onTransitionEnd={({ propertyName }) => {
          if (propertyName === 'width' && !searchMode) {
            const { onVisibleChange } = this.props;
            onVisibleChange(searchMode);
          }
        }}
      >
        <Icon type="search" key="Icon" />
        <AutoComplete
          key="AutoComplete"
          {...restProps}
          className={inputClass}
          value={value}
          onChange={this.onChange}
        >
          <Input
            ref={node => {
              this.inputRef = node;
            }}
            defaultValue={defaultValue}
            aria-label={placeholder}
            placeholder={placeholder}
            onKeyDown={this.onKeyDown}
            onBlur={this.leaveSearchMode}
          />
        </AutoComplete>
      </span>
    );
  }
Example #16
Source File: index.js    From QiskitFlow with Apache License 2.0 5 votes vote down vote up
FilterForm = ({
  filter,
  setFilterDateStart,
  setFilterDateEnd,
  setFilterQuery,
}) => {
  const onSearch = q => {
    setFilterQuery(q);
  };

  const onSelect = selection => {
    console.log('Selection:', selection);
  };

  const onDateChange = dates => {
    const format = 'DD-MM-YYYY';
    const [start, end] = dates;

    setFilterDateStart(start.format(format));
    setFilterDateEnd(end.format(format));
  };

  return(<span/>);

  return (
    <Form layout="inline" name="basic" style={{ padding: '16px' }}>
      <Form.Item label="Search" name="query">
        <AutoComplete
          options={[]}
          value={filter.query}
          style={{ width: 500 }}
          onSelect={onSelect}
          onSearch={debounce(onSearch, 500)}
          placeholder="Name..."
        />
      </Form.Item>

      <Form.Item name="dates" label="Dates">
        <RangePicker onChange={onDateChange} />
      </Form.Item>
    </Form>
  );
}
Example #17
Source File: TimeLine.js    From YApi-X with MIT License 5 votes vote down vote up
{ Option, OptGroup } = AutoComplete
Example #18
Source File: index.js    From scalable-form-platform with MIT License 5 votes vote down vote up
render() {
        const popupContainer = this.props.formContext && this.props.formContext.popupContainer;
        const {schema, id, options, disabled, readonly, autofocus, placeholder} = this.props;

        // 对于value值为空字符串的情况,value的值传入undefined,这样才能显示组件的placeholder
        let {value} = this.state;
        if (value === '') {
            value = undefined;
        }
        // enumOptions会由react-jsonschema-form注入到组件的options中 https://github.com/mozilla-services/react-jsonschema-form#custom-widget-components note
        let enumOptions = options.enumOptions || [];
        if (typeof schema.data !== 'undefined' && schema.data.length >= 0) {
            enumOptions = schema.data;
        }

        // 这个idPrefix决定所有字段的id的前缀,与react-jsonschema-form组件中的idPrefix属性相同https://github.com/mozilla-services/react-jsonschema-form#id-prefix
        const idPrefix = 'root';
        const fieldCode = id.slice(idPrefix.length + 1);

        //解析schema中约定的_errorType字段,用来标识是validate中哪种类型校验不通过
        let validateMessage = '';
        let _errorType = options._errorType || '';
        if (_errorType !== '' && typeof options.validate !== 'undefined') {
            validateMessage = this._getValidateMessage(_errorType, options.validate);
        }

        return (
            <div className={classnames({
                'ant-form-item-control': true,
                'xform-custom-widget': true,
                'xform-custom-suggest-select': true,
                'has-error': _errorType !== ''
            })}>
                <AutoComplete
                    defaultActiveFirstOption={false}
                    filterOption={false}
                    value={value}
                    disabled={disabled}
                    readonly={readonly}
                    onSearch={(value) => {
                        this.handleKeywordChange(fieldCode, value);
                    }}
                    onSelect={this.handleSelectChange}
                    autoFocus={autofocus}
                    placeholder={placeholder}
                    getPopupContainer={popupContainer}
                    {...options}
                >
                    {enumOptions.map((enums) => {
                        return <Option key={enums.value} value={enums.value}>{enums.label}</Option>
                    })}
                </AutoComplete>
                <div className="ant-form-explain">{validateMessage}</div>
            </div>
        );
    }
Example #19
Source File: Search.js    From YApi-X with MIT License 5 votes vote down vote up
Option = AutoComplete.Option
Example #20
Source File: index.js    From scalable-form-platform with MIT License 5 votes vote down vote up
Option = AutoComplete.Option
Example #21
Source File: K8SClusterSetting.jsx    From juno with Apache License 2.0 5 votes vote down vote up
function ClusterForm(props) {
  const { form, onOk } = props;
  const { data: zoneEnvResp, loading: zoneEnvLoading } = useRequest(zoneEnvTree);
  const zoneCodes = {};
  const envs = [];
  zoneEnvResp &&
    Object.keys(zoneEnvResp.data).forEach((env) => {
      envs.push(env);

      zoneEnvResp.data[env].forEach((zone) => {
        zoneCodes[zone.zone_code] = zone.zone_name;
      });
    });

  return (
    <Form form={form} onFinish={onOk}>
      <Form.Item label={'名称'} name={'name'}>
        <Input />
      </Form.Item>

      <Form.Item label={'Env'} name={'env'}>
        <Select mode={'tags'} loading={zoneEnvLoading}>
          {envs.map((env) => (
            <Select.Option value={env}>{env}</Select.Option>
          ))}
        </Select>
      </Form.Item>

      <Form.Item label={'Zone Code'} name={'zone_code'}>
        <AutoComplete>
          {Object.keys(zoneCodes).map((code) => {
            return (
              <AutoComplete.Option value={code}>
                <span>{zoneCodes[code]}</span>
                <span style={{ fontWeight: 'bold', marginLeft: '10px' }}>[{code}]</span>
              </AutoComplete.Option>
            );
          })}
        </AutoComplete>
      </Form.Item>

      <Form.Item label={'Zone Name'} name={'zone_name'}>
        <Input />
      </Form.Item>

      <Form.Item label={'domain'} name={'domain'}>
        <Input />
      </Form.Item>

      <Form.Item label={'token'} name={'token'}>
        <Input />
      </Form.Item>
    </Form>
  );
}
Example #22
Source File: MyAutoComplete.jsx    From react-sendbird-messenger with GNU General Public License v3.0 5 votes vote down vote up
export function MyAutoComplete({
    style,
    options = [],
    value = '',
    onSelect = () => {},
    onSearch = () => {},
    onChange = () => {},
    placeholder = 'Search for people',
}) {
    return (
        <div style={style}>
            <AutoComplete
                options={options}
                style={{ width: '100%' }}
                onSelect={onSelect}
                onSearch={onSearch}
                filterOption={(inputValue, option) =>
                    option.value
                        .toUpperCase()
                        .indexOf(inputValue.toUpperCase()) !== -1
                }
                notFoundContent={<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
                allowClear={true}
                backfill={true}
                // autoFocus={true}
            >
                <Input
                    value={value}
                    onChange={onChange}
                    placeholder={placeholder}
                    prefix={
                        <SearchOutlined
                            style={{
                                fontSize: 16,
                                color: '#d9d9d9',
                            }}
                        />
                    }
                />
            </AutoComplete>
        </div>
    )
}
Example #23
Source File: index.jsx    From juno with Apache License 2.0 4 votes vote down vote up
render() {
    const {
      app_service_tree,
      use_cases,
      editor,
      selected_user_case,
      node_addr_list,
      selected_service,
      right_menu_visible,
      right_menu_position,
      right_menu,
      dispatch,
      response,
      active_tab,
      selected_history_id,
      public_cases,
      settings,
      setting_dialog_visible,
      service_bind_dialog_visible,
      proto_list,
      appList,
      use_case_loading,
    } = this.props;
    let addrOptions = node_addr_list?.hosts
      ? node_addr_list.hosts
          .filter((i) => i.env !== 'prod' && i.env !== 'gray')
          .map((item) => {
            return (
              <AutoComplete.Option key={item.addr} value={item.addr + ':' + node_addr_list.port}>
                <Tag>{item.env}</Tag>
                <span>
                  {item.addr}:{node_addr_list.port}
                </span>
              </AutoComplete.Option>
            );
          })
      : [];
    if (settings && settings.localhost) {
      addrOptions.push(
        <AutoComplete.Option
          key={settings.localhost}
          value={settings.localhost + ':' + node_addr_list.port}
        >
          <Tag>local</Tag>
          <span>
            {settings.localhost}:{node_addr_list.port}
          </span>
        </AutoComplete.Option>,
      );
    }

    let metadata = editor.form.metadata || [];
    if (!(metadata instanceof Array)) {
      try {
        metadata = JSON.parse(metadata);
      } catch (e) {
        metadata = [];
      }
    }

    return (
      <div className={styles.debugPage}>
        <div className={styles.layoutHeader}>
          <Cascader
            showSearch
            value={selected_service}
            className={styles.serviceCascader}
            displayRender={(labels) => {
              return labels.join('/');
            }}
            placeholder="切换服务"
            options={(app_service_tree || []).map((app) => {
              return {
                label: app.app_name,
                value: app.app_name,
                children: (app.services || []).map((service) => {
                  return {
                    value: '' + service.id,
                    label: service.name,
                  };
                }),
              };
            })}
            onChange={this.onChangeService}
          />
          <Button
            shape="circle"
            icon={<SettingOutlined />}
            className={styles.settingButton}
            onClick={this.onShowSettingDialog}
          />

          <Button
            shape="circle"
            icon={<LinkOutlined />}
            className={styles.bindServiceButton}
            onClick={this.onShowServiceBindDialog}
          />
        </div>
        <div className={styles.main}>
          <div className={styles.layoutSider}>
            <Tabs
              type={'card'}
              className={styles.leftTabs}
              activeKey={active_tab}
              onChange={this.onTabChange}
              renderTabBar={(props, DefaultTabBar) => {
                return (
                  <DefaultTabBar
                    {...props}
                    style={{
                      backgroundColor: 'rgb(250,250,250)',
                      padding: '10px 0 0 10px',
                      margin: '0',
                      flex: '0 0 50px',
                    }}
                  />
                );
              }}
            >
              <Tabs.TabPane key="history" tab="History">
                {active_tab === 'history' ? (
                  <History
                    selectedService={selected_service}
                    onChange={(id) => {
                      dispatch({ type: 'grpcDebugModel/loadHistoryItem', payload: id }).then(
                        (res) => {
                          if (res.code === 0) {
                            this.form.current.setFieldsValue({
                              case_name: editor.form.case_name,
                              address: res.data.addr,
                            });
                          }
                        },
                      );
                    }}
                    activeId={selected_history_id}
                  />
                ) : null}
              </Tabs.TabPane>
              <Tabs.TabPane key="api" tab="API">
                <ScrollArea style={{ height: '830px' }}>
                  <DirectoryTree
                    onRightClick={this.onUserCaseTreeRightClicked}
                    defaultExpandAll
                    onSelect={this.onSelectUserCaseTree}
                    selectedKeys={[selected_user_case]}
                    style={{ marginTop: '10px' }}
                  >
                    {(use_cases || []).map((method, id) => {
                      return (
                        <TreeNode
                          title={
                            method.description ? (
                              <Popover content={method.description}>{method.name}</Popover>
                            ) : (
                              method.name
                            )
                          }
                          key={`method:${method.id}`}
                        >
                          <TreeNode
                            icon={<PlusOutlined />}
                            key={`new:${method.id}`}
                            title="New"
                            isLeaf
                          />
                          {method.use_cases
                            ? method.use_cases.map((tc, id) => {
                                return <TreeNode title={tc.name} key={`case:${tc.id}`} isLeaf />;
                              })
                            : null}
                        </TreeNode>
                      );
                    })}
                  </DirectoryTree>
                </ScrollArea>
              </Tabs.TabPane>
            </Tabs>
          </div>

          {editor.form.method_id ? (
            <Spin spinning={use_case_loading} wrapperClassName={styles.formSpin}>
              {this.renderForm(editor, addrOptions, metadata, response)}
            </Spin>
          ) : (
            <div style={{ flex: '1 1 auto', padding: '100px' }}>
              <Empty desciption={'请选择用例'} />
            </div>
          )}
        </div>

        <SettingDialog
          onCancel={() => {
            dispatch({
              type: 'grpcDebugModel/showSettings',
              payload: false,
            });
          }}
          settings={settings}
          onSave={this.onSaveSettings}
          visible={setting_dialog_visible}
        />

        <ServiceBindDialog
          visible={service_bind_dialog_visible}
          protoList={proto_list}
          appList={appList}
          onSubmit={this.onBindAppService}
          onCancel={() => {
            dispatch({
              type: 'grpcDebugModel/showServiceBindDialog',
              payload: false,
            });
          }}
        />
      </div>
    );
  }
Example #24
Source File: group.jsx    From virtuoso-design-system with MIT License 4 votes vote down vote up
App = () => (
  <div className="site-input-group-wrapper">
    <Input.Group size="large">
      <Row gutter={8}>
        <Col span={5}>
          <Input defaultValue="0571" />
        </Col>
        <Col span={8}>
          <Input defaultValue="26888888" />
        </Col>
      </Row>
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input style={{ width: '20%' }} defaultValue="0571" />
      <Input style={{ width: '30%' }} defaultValue="26888888" />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select defaultValue="Zhejiang">
        <Option value="Zhejiang">Zhejiang</Option>
        <Option value="Jiangsu">Jiangsu</Option>
      </Select>
      <Input style={{ width: '50%' }} defaultValue="Xihu District, Hangzhou" />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input.Search style={{ width: '40%' }} defaultValue="0571" />
      <Input.Search allowClear style={{ width: '40%' }} defaultValue="26888888" />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input.Search allowClear style={{ width: '40%' }} defaultValue="0571" />
      <Input.Search allowClear style={{ width: '40%' }} defaultValue="26888888" />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select defaultValue="Option1">
        <Option value="Option1">Option1</Option>
        <Option value="Option2">Option2</Option>
      </Select>
      <Input style={{ width: '50%' }} defaultValue="input content" />
      <InputNumber />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input style={{ width: '50%' }} defaultValue="input content" />
      <DatePicker style={{ width: '50%' }} />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input style={{ width: '30%' }} defaultValue="input content" />
      <DatePicker.RangePicker style={{ width: '70%' }} />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select defaultValue="Option1-1">
        <Option value="Option1-1">Option1-1</Option>
        <Option value="Option1-2">Option1-2</Option>
      </Select>
      <Select defaultValue="Option2-2">
        <Option value="Option2-1">Option2-1</Option>
        <Option value="Option2-2">Option2-2</Option>
      </Select>
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select defaultValue="1">
        <Option value="1">Between</Option>
        <Option value="2">Except</Option>
      </Select>
      <Input style={{ width: 100, textAlign: 'center' }} placeholder="Minimum" />
      <Input
        className="site-input-split"
        style={{
          width: 30,
          borderLeft: 0,
          borderRight: 0,
          pointerEvents: 'none',
        }}
        placeholder="~"
        disabled
      />
      <Input
        className="site-input-right"
        style={{
          width: 100,
          textAlign: 'center',
        }}
        placeholder="Maximum"
      />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select defaultValue="Sign Up" style={{ width: '30%' }}>
        <Option value="Sign Up">Sign Up</Option>
        <Option value="Sign In">Sign In</Option>
      </Select>
      <AutoComplete
        style={{ width: '70%' }}
        placeholder="Email"
        options={[{ value: 'text 1' }, { value: 'text 2' }]}
      />
    </Input.Group>
    <br />
    <Input.Group compact>
      <Select style={{ width: '30%' }} defaultValue="Home">
        <Option value="Home">Home</Option>
        <Option value="Company">Company</Option>
      </Select>
      <Cascader style={{ width: '70%' }} options={options} placeholder="Select Address" />
    </Input.Group>
  </div>
)
Example #25
Source File: SearchSeeds.js    From remixr with MIT License 4 votes vote down vote up
SearchSeeds = (props) => {
  const [accessToken] = useState(Cookies.get('access_token'));
  const [value, setValue] = useState('');
  const [tracks, setTracks] = useState([]);
  const [artists, setArtists] = useState([]);
  const [playlists, setPlaylists] = useState([]);
  const [seed, setSeed] = useState(null);
  const [playlistSeed, setPlaylistSeed] = useState(null);

  const searchSpotify = async (searchTerm) => {
    if (searchTerm && searchTerm.length > 0) {
      let { artists, tracks, playlists } = await search(accessToken, searchTerm);

      artists = artists.map(extractArtistInfo);
      tracks = tracks.map(extractTrackInfo);
      playlists = playlists.map(extractArtistInfo);

      setArtists(artists);
      setTracks(tracks);
      setPlaylists(playlists);
    }
  };

  const renderTitle = (title) => <span>{title}</span>;

  const renderItem = (item, type) => ({
    key: item.id,
    data: item,
    type,
    value: item.id,
    label: (
      <div>
        <img src={item.image} className="rounded" width="50" height="50" alt="" />
        <span
          style={{
            marginLeft: '1em',
          }}
        >
          {item.name}
        </span>
      </div>
    ),
  });

  const options = [
    ...(!props || !props.addSeed
      ? [
          // Only display playlists on home page
          {
            label: renderTitle('Playlists'),
            options:
              playlists && playlists.length > 0 ? playlists.map((playlists) => renderItem(playlists, 'playlist')) : [],
          },
        ]
      : []),
    {
      label: renderTitle('Tracks'),
      options: tracks && tracks.length > 0 ? tracks.map((track) => renderItem(track, 'track')) : [],
    },
    {
      label: renderTitle('Artists'),
      options: artists && artists.length > 0 ? artists.map((artist) => renderItem(artist, 'artist')) : [],
    },
  ];

  const addSeed = (value, option) => {
    if (props && props.addSeed) {
      // Results page
      ReactGA.event({
        category: 'Seeds',
        action: 'Add seed',
        label: 'Results',
      });

      props.addSeed(option.data, option.type);
      setValue('');
    } else {
      // Home page - Seed search
      ReactGA.event({
        category: 'Seeds',
        action: 'Add seed',
        label: 'Home page',
      });

      if (option.type === 'playlist') {
        ReactGA.event({
          category: 'Seeds',
          action: 'Add playlist',
          label: 'Home page',
        });
        setPlaylistSeed(option.data);
      } else if (option.type === 'track') {
        setSeed({ artists: [], tracks: [option.data] });
      } else {
        setSeed({ artists: [option.data], tracks: [] });
      }
    }
  };

  if (playlistSeed) {
    return (
      <Redirect
        to={{
          pathname: '/results',
          state: {
            playlist: {
              id: playlistSeed.id,
              name: playlistSeed.name,
              image: playlistSeed.image,
            },
          },
        }}
      />
    );
  }

  // For home page. Go to results after seed is added
  if (seed) {
    return (
      <Redirect
        to={{
          pathname: '/results',
          state: { seed },
        }}
      />
    );
  }

  return (
    <div>
      <AutoComplete
        style={{
          marginBottom: '0.5em',
          width: '100%',
          borderRadius: '10px',
        }}
        dropdownClassName="certain-category-search-dropdown"
        options={options}
        value={value}
        onChange={(value) => {
          searchSpotify(value);
          setValue(value);
        }}
        onSelect={addSeed}
      >
        <Input
          style={{
            borderRadius: '10px',
          }}
          size="large"
          placeholder={props.addSeed ? 'Add or remove seeds' : 'Discover based on playlists, songs or artists'}
        />
      </AutoComplete>
    </div>
  );
}
Example #26
Source File: SearchPlaylists.js    From remixr with MIT License 4 votes vote down vote up
SearchPlaylists = (props) => {
  const [accessToken] = useState(Cookies.get('access_token'));
  const [value, setValue] = useState('');
  const [tracks, setTracks] = useState([]);
  const [artists, setArtists] = useState([]);
  const [seed, setSeed] = useState(null);

  const searchSpotify = async (searchTerm) => {
    if (searchTerm && searchTerm.length > 0) {
      let { artists, tracks } = await search(accessToken, searchTerm);
      console.log(artists);

      artists = artists.map(extractArtistInfo);
      tracks = tracks.map(extractTrackInfo);

      setArtists(artists);
      setTracks(tracks);
    }
  };

  const renderTitle = (title) => <span>{title}</span>;

  const renderItem = (item, type) => ({
    key: item.id,
    data: item,
    type,
    value: item.id,
    label: (
      <div>
        <img src={item.image} className="rounded" width="50" height="50" alt="" />
        <span
          style={{
            marginLeft: '1em',
          }}
        >
          {item.name}
        </span>
      </div>
    ),
  });

  const options = [
    {
      label: renderTitle('Tracks'),
      options: tracks && tracks.length > 0 ? tracks.map((track) => renderItem(track, 'track')) : [],
    },
    {
      label: renderTitle('Artists'),
      options: artists && artists.length > 0 ? artists.map((artist) => renderItem(artist, 'artist')) : [],
    },
  ];

  const addSeed = (value, option) => {
    if (props && props.addSeed) {
      // Results page
      ReactGA.event({
        category: 'Seeds',
        action: 'Add seed',
        label: 'Results',
      });

      props.addSeed(option.data, option.type);
      setValue('');
    } else {
      // Home page
      ReactGA.event({
        category: 'Seeds',
        action: 'Add seed',
        label: 'Home page',
      });

      if (option.type === 'track') {
        setSeed({ artists: [], tracks: [option.data] });
      } else {
        setSeed({ artists: [option.data], tracks: [] });
      }
    }
  };

  // For home page. Go to results after seed is added
  if (seed) {
    return (
      <Redirect
        to={{
          pathname: '/results',
          state: { seed },
        }}
      />
    );
  }

  return (
    <div>
      <AutoComplete
        style={{
          marginBottom: '0.5em',
          width: '100%',
          borderRadius: '10px',
        }}
        dropdownClassName="certain-category-search-dropdown"
        options={options}
        value={value}
        onChange={(value) => {
          searchSpotify(value);
          setValue(value);
        }}
        onSelect={addSeed}
      >
        <Input
          style={{
            borderRadius: '10px',
          }}
          size="large"
          placeholder={props.addSeed ? 'Add or remove seeds' : 'Discover based on artists or songs'}
        />
      </AutoComplete>
    </div>
  );
}
Example #27
Source File: index.js    From quick_redis_blog with MIT License 4 votes vote down vote up
render() {
        return (
            <div>
                <Row gutter={[16, 6]}>
                    <Col span={24}>
                        <Button
                            block
                            onClick={this.openCreateKeyMadal.bind(this)}
                        >
                            {intl.get("HostKey.create.key")}
                        </Button>
                    </Col>
                    <Col span={24}>
                        <Tooltip
                            placement="right"
                            title={intl.get("common.search.tooltip.limit")}
                        >
                            <AutoComplete
                                options={this.state.autoCompleteOptions}
                                onSelect={this.onAutoCompleteSelect.bind(this)}
                                onChange={this.onAutoCompleteChange.bind(this)}
                                style={{ width: "100%" }}
                            >
                                <Search
                                    ref={this.searchInput}
                                    onSearch={this.searchKey.bind(this)}
                                    enterButton={
                                        <Button
                                            icon={<SearchOutlined />}
                                        ></Button>
                                    }
                                    disabled={this.state.searchDisable}
                                />
                            </AutoComplete>
                        </Tooltip>
                    </Col>
                    <Col span={24}>
                        <Dropdown
                            overlay={this.showTreeRightClickMenu.bind(this)}
                            trigger={["contextMenu"]}
                        >
                            <div>
                                <DirectoryTree
                                    treeData={this.state.treeData}
                                    onSelect={this.onDirectoryTreeSelect.bind(
                                        this
                                    )}
                                    onDoubleClick={this.handleDoubleClick.bind(
                                        this
                                    )}
                                    height={750}
                                ></DirectoryTree>
                            </div>
                        </Dropdown>
                    </Col>
                </Row>
                <div>
                    <Modal
                        title={intl.get("HostKey.create.key")}
                        okText={intl.get("common.ok")}
                        cancelText={intl.get("common.cancel")}
                        visible={this.state.createKeyMadalVisible}
                        onOk={() => {
                            let form = this.refs.form;
                            if (form === undefined) {
                                return;
                            }
                            form.submit();
                        }}
                        onCancel={this.cancelCreateKeyMadal}
                    >
                        <Form
                            initialValues={{ ...this.initValues }}
                            {...this.layout}
                            ref="form"
                            onFinish={this.okCreateKeyMadal.bind(this)}
                        >
                            <Form.Item
                                name="key"
                                label="key"
                                rules={[
                                    {
                                        required: true,
                                        message: intl.get(
                                            "common.error.input.value"
                                        ),
                                    },
                                ]}
                            >
                                <Input />
                            </Form.Item>
                            <Form.Item
                                name="keyType"
                                label={intl.get("HostKey.modal.keyType")}
                                rules={[
                                    {
                                        required: true,
                                        message: intl.get(
                                            "common.error.input.value"
                                        ),
                                    },
                                ]}
                            >
                                <Select>
                                    <Option value={REDIS_DATA_TYPE.STRING}>
                                        {REDIS_DATA_TYPE.STRING}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.ZSET}>
                                        {REDIS_DATA_TYPE.ZSET}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.SET}>
                                        {REDIS_DATA_TYPE.SET}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.HASH}>
                                        {REDIS_DATA_TYPE.HASH}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.LIST}>
                                        {REDIS_DATA_TYPE.LIST}
                                    </Option>
                                </Select>
                            </Form.Item>
                        </Form>
                    </Modal>
                </div>
            </div>
        );
    }
Example #28
Source File: index.js    From quick_redis_blog with MIT License 4 votes vote down vote up
render() {
        return (
            <div>
                <Space size="small" direction="vertical">
                    <Button block onClick={this.openCreateKeyMadal.bind(this)}>
                        {intl.get("HostKey.create.key")}
                    </Button>
                    <Tooltip
                        placement="right"
                        title={intl.get("common.search.tooltip.limit")}
                    >
                        <AutoComplete
                            options={this.state.autoCompleteOptions}
                            onSelect={this.onAutoCompleteSelect.bind(this)}
                            onChange={this.onAutoCompleteChange.bind(this)}
                            style={{ width: "100%" }}
                        >
                            <Search
                                ref={this.searchInput}
                                onSearch={this.searchKey.bind(this)}
                                enterButton={
                                    <Button
                                        disabled={this.state.searchDisable}
                                        icon={<SearchOutlined />}
                                    ></Button>
                                }
                            />
                        </AutoComplete>
                    </Tooltip>
                    <Table
                        // columns={columns}
                        columns={[
                            {
                                title: "",
                                dataIndex: "name",
                                key: "key",
                                ellipsis: "true",
                            },
                        ]}
                        dataSource={this.state.tableData}
                        bordered={true}
                        size={"small"}
                        pagination={{
                            position: "bottom",
                            pageSize: this.state.pageSize,
                            total: this.state.tableTotal,
                            responsive: true,
                            current: this.state.currentPage,
                            onChange: this.onPaginationChange.bind(this),
                            onShowSizeChange: this.onShowSizeChange.bind(this),
                        }}
                        rowClassName={this.renderRowClassName.bind(this)}
                        onRow={this.onRowEvent.bind(this)}
                    />
                </Space>
                <div>
                    <Modal
                        title={intl.get("HostKey.create.key")}
                        okText={intl.get("common.ok")}
                        cancelText={intl.get("common.cancel")}
                        visible={this.state.createKeyMadalVisible}
                        onOk={() => {
                            let form = this.refs.form;
                            if (form === undefined) {
                                return;
                            }
                            form.submit();
                        }}
                        onCancel={this.cancelCreateKeyMadal}
                    >
                        <Form
                            initialValues={{ ...this.initValues }}
                            {...this.layout}
                            ref="form"
                            onFinish={this.okCreateKeyMadal.bind(this)}
                        >
                            <Form.Item
                                name="key"
                                label="key"
                                rules={[
                                    {
                                        required: true,
                                        message: intl.get(
                                            "common.error.input.value"
                                        ),
                                    },
                                ]}
                            >
                                <Input />
                            </Form.Item>
                            <Form.Item
                                name="keyType"
                                label={intl.get("HostKey.modal.keyType")}
                                rules={[
                                    {
                                        required: true,
                                        message: intl.get(
                                            "common.error.input.value"
                                        ),
                                    },
                                ]}
                            >
                                <Select>
                                    <Option value={REDIS_DATA_TYPE.STRING}>
                                        {REDIS_DATA_TYPE.STRING}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.ZSET}>
                                        {REDIS_DATA_TYPE.ZSET}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.SET}>
                                        {REDIS_DATA_TYPE.SET}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.HASH}>
                                        {REDIS_DATA_TYPE.HASH}
                                    </Option>
                                    <Option value={REDIS_DATA_TYPE.LIST}>
                                        {REDIS_DATA_TYPE.LIST}
                                    </Option>
                                </Select>
                            </Form.Item>
                        </Form>
                    </Modal>
                </div>
            </div>
        );
    }
Example #29
Source File: ProjectEnvContent.js    From YApi-X with MIT License 4 votes vote down vote up
render() {
    const { projectMsg } = this.props;
    const { getFieldDecorator } = this.props.form;
    const headerTpl = (item, index) => {
      const headerLength = this.state.header.length - 1;
      return (
        <Row gutter={2} key={index}>
          <Col span={10}>
            <FormItem>
              {getFieldDecorator('header[' + index + '].name', {
                validateTrigger: ['onChange', 'onBlur'],
                initialValue: item.name || ''
              })(
                <AutoComplete
                  style={{ width: '200px' }}
                  allowClear={true}
                  dataSource={constants.HTTP_REQUEST_HEADER}
                  placeholder="请输入header名称"
                  onChange={() => this.addHeader(item, index, 'header')}
                  filterOption={(inputValue, option) =>
                    option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
                  }
                />
              )}
            </FormItem>
          </Col>
          <Col span={12}>
            <FormItem>
              {getFieldDecorator('header[' + index + '].value', {
                validateTrigger: ['onChange', 'onBlur'],
                initialValue: item.value || ''
              })(<Input placeholder="请输入参数内容" style={{ width: '90%', marginRight: 8 }} />)}
            </FormItem>
          </Col>
          <Col span={2} className={index === headerLength ? ' env-last-row' : null}>
            {/* 新增的项中,只有最后一项没有有删除按钮 */}
            <Icon
              className="dynamic-delete-button delete"
              type="delete"
              onClick={e => {
                e.stopPropagation();
                this.delHeader(index, 'header');
              }}
            />
          </Col>
        </Row>
      );
    };

    const commonTpl = (item, index, name) => {
      const length = this.state[name].length - 1;
      return (
        <Row gutter={2} key={index}>
          <Col span={10}>
            <FormItem>
              {getFieldDecorator(`${name}[${index}].name`, {
                validateTrigger: ['onChange', 'onBlur'],
                initialValue: item.name || ''
              })(
                <Input
                  placeholder={`请输入 ${name} Name`}
                  style={{ width: '200px' }}
                  onChange={() => this.addHeader(item, index, name)}
                />
              )}
            </FormItem>
          </Col>
          <Col span={12}>
            <FormItem>
              {getFieldDecorator(`${name}[${index}].value`, {
                validateTrigger: ['onChange', 'onBlur'],
                initialValue: item.value || ''
              })(<Input placeholder="请输入参数内容" style={{ width: '90%', marginRight: 8 }} />)}
            </FormItem>
          </Col>
          <Col span={2} className={index === length ? ' env-last-row' : null}>
            {/* 新增的项中,只有最后一项没有有删除按钮 */}
            <Icon
              className="dynamic-delete-button delete"
              type="delete"
              onClick={e => {
                e.stopPropagation();
                this.delHeader(index, name);
              }}
            />
          </Col>
        </Row>
      );
    };

    const envTpl = data => {
      return (
        <div>
          <h3 className="env-label">环境名称</h3>
          <FormItem required={false}>
            {getFieldDecorator('env.name', {
              validateTrigger: ['onChange', 'onBlur'],
              initialValue: data.name === '新环境' ? '' : data.name || '',
              rules: [
                {
                  required: false,
                  whitespace: true,
                  validator(rule, value, callback) {
                    if (value) {
                      if (value.length === 0) {
                        callback('请输入环境名称');
                      } else if (!/\S/.test(value)) {
                        callback('请输入环境名称');
                      } else {
                        return callback();
                      }
                    } else {
                      callback('请输入环境名称');
                    }
                  }
                }
              ]
            })(
              <Input
                onChange={e => this.props.handleEnvInput(e.target.value)}
                placeholder="请输入环境名称"
                style={{ width: '90%', marginRight: 8 }}
              />
            )}
          </FormItem>
          <h3 className="env-label">环境域名</h3>
          <FormItem required={false}>
            {getFieldDecorator('env.domain', {
              validateTrigger: ['onChange', 'onBlur'],
              initialValue: data.domain ? data.domain.split('//')[1] : '',
              rules: [
                {
                  required: false,
                  whitespace: true,
                  validator(rule, value, callback) {
                    if (value) {
                      if (value.length === 0) {
                        callback('请输入环境域名!');
                      } else if (/\s/.test(value)) {
                        callback('环境域名不允许出现空格!');
                      } else {
                        return callback();
                      }
                    } else {
                      callback('请输入环境域名!');
                    }
                  }
                }
              ]
            })(
              <Input
                placeholder="请输入环境域名"
                style={{ width: '90%', marginRight: 8 }}
                addonBefore={getFieldDecorator('env.protocol', {
                  initialValue: data.domain ? data.domain.split('//')[0] + '//' : 'http://',
                  rules: [
                    {
                      required: true
                    }
                  ]
                })(
                  <Select>
                    <Option value="http://">{'http://'}</Option>
                    <Option value="https://">{'https://'}</Option>
                  </Select>
                )}
              />
            )}
          </FormItem>
          <h3 className="env-label">Header</h3>
          {this.state.header.map((item, index) => {
            return headerTpl(item, index);
          })}

          <h3 className="env-label">Cookie</h3>
          {this.state.cookie.map((item, index) => {
            return commonTpl(item, index, 'cookie');
          })}

          <h3 className="env-label">
            global
            <a
              target="_blank"
              rel="noopener noreferrer"
              href="https://hellosean1025.github.io/yapi/documents/project.html#%E9%85%8D%E7%BD%AE%E7%8E%AF%E5%A2%83"
              style={{ marginLeft: 8 }}
            >
              <Tooltip title="点击查看文档">
                <Icon type="question-circle-o" style={{fontSize: '13px'}}/>
              </Tooltip>
            </a>
          </h3>
          {this.state.global.map((item, index) => {
            return commonTpl(item, index, 'global');
          })}
        </div>
      );
    };

    return (
      <div>
        {envTpl(projectMsg)}
        <div className="btnwrap-changeproject">
          <Button
            className="m-btn btn-save"
            icon="save"
            type="primary"
            size="large"
            onClick={this.handleOk}
          >
            保 存
          </Button>
        </div>
      </div>
    );
  }