@ant-design/icons#ImportOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#ImportOutlined. 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: AiDrive.js    From network-rc with Apache License 2.0 5 votes vote down vote up
render() {
    const {
      state: { isPredicting, actionKey, probability, interval },
      props: { cameraEnabled, ai },
      drive,
      stop,
      test,
      loadModel,
    } = this;
    return (
      <div className="ai-train">
        <Form layout="inline">
          <Form.Item label="操作间隔">
            <InputNumber
              value={interval}
              onChange={(interval) => this.setState({ interval })}
            />
          </Form.Item>
          <Form.Item label="动作">
            <Tag>
              {aiAction[actionKey].name} {aiAction[actionKey].icon}{" "}
              {probability.toFixed(2)}
            </Tag>
          </Form.Item>
        </Form>
        <br />
        <Form layout="inline">
          <Form.Item>
            <Button
              icon={<ImportOutlined />}
              loading={isPredicting}
              onClick={loadModel}
            >
              导入模型
            </Button>
          </Form.Item>
          <Form.Item>
            <Button
              icon={<BugOutlined />}
              loading={isPredicting}
              onClick={test}
              disabled={!cameraEnabled || !ai || !ai.model}
            >
              测试
            </Button>
            &nbsp;&nbsp;&nbsp;&nbsp;
            <Button
              type="danger"
              key="predic"
              loading={isPredicting}
              onClick={drive}
              icon={<CarOutlined />}
              disabled={!cameraEnabled || !ai || !ai.model}
            >
              开始 Ai 驾驶
            </Button>
          </Form.Item>

          <Form.Item>
            <Button
              onClick={stop}
              icon={<StopOutlined />}
              disabled={!isPredicting}
              key="stop"
            >
              停止 Ai 驾驶
            </Button>
          </Form.Item>
          <br />
        </Form>
      </div>
    );
  }
Example #2
Source File: MainPage.js    From bonded-stablecoin-ui with MIT License 4 votes vote down vote up
MainPage = ({ setWalletModalVisibility }) => {
  const {
    address,
    bonded_state,
    deposit_state,
    reserve_asset_symbol,
    fund_aa,
    fund_state,
    stable_state,
    params,
    symbol1,
    symbol2,
    symbol3,
    symbol4,
    loading
  } = useSelector((state) => state.active);
  const pendings = useSelector((state) => state.pendings);
  const { activeWallet, lang } = useSelector((state) => state.settings);
  const { loaded } = useSelector((state) => state.list);
  const [currentTab, setCurrentTab] = useState(undefined);
  const [handleSkip, setHandleSkip] = useState(false);
  const [tabInitialized, setTabInitialized] = useState(false);
  const [addressInitialized, setAddressInitialized] = useState(false);
  const actualParams = getParams(params, bonded_state);
  const urlParams = useParams();
  const history = useHistory();
  const location = useLocation();
  const dispatch = useDispatch();
  const { tab } = urlParams;
  const hash = location.hash.slice(1);
  const { t } = useTranslation();
  const basename = lang && lang !== "en" ? "/" + lang : "";

  useEffect(() => {
    if ((addressInitialized || !urlParams.address) && !loading && loaded && tabInitialized && currentTab && address && !tabList.includes(hash)) {
      let newTab;
      if (tab === "fund" && !(bonded_state?.fund_aa)) {
        if ("reserve" in bonded_state) {
          newTab = "deposits";
        } else {
          newTab = "buy-redeem";
        }
      } else if (currentTab === "deposits" && bonded_state?.fund_aa) {
        if ("reserve" in bonded_state) {
          newTab = "fund";
        } else {
          newTab = "buy-redeem";
        }
      }

      history.replace(`${basename}/trade/${address}/${newTab || currentTab || ""}${location.hash}`);
    }
  }, [currentTab, loaded, address, addressInitialized, loading]);

  useEffect(() => {
    if (!tabList.includes(hash)) {
      history.replace({ hash: undefined });
    }
  }, [address]);

  useEffect(() => {
    if (urlParams.address && address !== urlParams.address) {
      if (botCheck(navigator.userAgent)) {
        dispatch(changeActiveForBot(urlParams.address));
      } else {
        dispatch(changeActive(urlParams.address));
      }
    }
    setAddressInitialized(true);
  }, [])

  useEffect(() => {
    if (tabInitialized && tab !== currentTab) {
      setCurrentTab(tab);
    }
    if (tab !== "governance" && !tabList.includes(hash)) {
      history.replace({ hash: undefined });
    }
  }, [tab])

  useEffect(() => {
    if (loaded && !isEmpty(bonded_state) && !tabInitialized) {
      if (tabList.includes(hash)) {
        if ("reserve" in bonded_state || ["parameters", "charts"].includes(hash)) {
          setCurrentTab(hash === "buy" ? "buy-redeem" : hash);
        } else {
          setCurrentTab("buy-redeem");
        }
        history.replace({ hash: undefined });
      } else if (!tab) {
        if ("reserve" in bonded_state) {
          setCurrentTab("charts");
        } else {
          setCurrentTab("buy-redeem");
        }
      } else {
        if (tab === "fund") {
          if (bonded_state?.fund_aa) {
            setCurrentTab(tab);
          } else {
            if ("reserve" in bonded_state) {
              setCurrentTab("deposits");
            } else {
              setCurrentTab("buy-redeem");
            }
          }
        } if (tab === "deposits") {
          if (bonded_state?.fund_aa) {
            if ("reserve" in bonded_state) {
              setCurrentTab("fund");
            } else {
              setCurrentTab("buy-redeem");
            }
          } else {
            setCurrentTab(tab);
          }
        } else {
          setCurrentTab(tab);
        }
      }
      setTabInitialized(true);
    }
  }, [loaded, tabInitialized, bonded_state]);

  const handleClickToLiquidity = () => {
    ReactGA.event({
      category: "Stablecoin",
      action: "Click to liquidity"
    })
  }

  if (loading) {
    return <div style={{ padding: 40, textAlign: "center" }}>
      <Spin size="large" />
    </div>
  } else if (address === undefined || !loaded) {
    return null;
  } else if (
    !handleSkip &&
    address !== "undefined" &&
    ((!symbol1 && !pendings.tokens1) ||
      (!symbol2 && !pendings.tokens2) ||
      (!symbol3 && !pendings.tokens3 && bonded_state.interest_rate) || (fund_aa && !symbol4 && !pendings.tokens4))
  ) {
    return (
      <RegisterSymbols
        symbol1={symbol1}
        symbol2={symbol2}
        symbol3={symbol3}
        pendings={pendings}
        fund_aa={fund_aa}
        fund_asset={fund_state?.shares_asset}
        asset1={bonded_state.asset1}
        asset2={bonded_state.asset2}
        asset3={stable_state?.asset || deposit_state?.asset}
        decimals1={actualParams.decimals1}
        decimals2={actualParams.decimals2}
        reserve_asset_decimals={actualParams.reserve_asset_decimals}
        address={address}
        activeWallet={activeWallet}
        handleSkip={setHandleSkip}
        interest={stable_state?.asset || !!bonded_state.interest_rate}
        isV2={!!fund_aa}
      />
    );
  } else
    return (
      <div>
        <Helmet title="Bonded stablecoins - Trade" />
        <>
          <Tabs
            activeKey={currentTab}
            onChange={(key) => setCurrentTab(key)}
            animated={false}
          >
            <TabPane
              disabled={!("reserve" in bonded_state)}
              tab={
                <span>
                  <LineChartOutlined /> {t("trade.tabs.charts.name", "Charts")}
                </span>
              }
              key="charts"
            >
              <Charts isActive={currentTab === "charts"} params={actualParams} />
            </TabPane>
            <TabPane
              tab={
                <span>
                  <InteractionOutlined /> {t("trade.tabs.buy_redeem.name", "Buy/redeem")}
                </span>
              }
              key="buy-redeem"
            >
              {!fund_aa ? ("reserve" in bonded_state ? (
                <Row style={{ marginTop: 20 }}>
                  <Col md={{ span: 10 }} xs={{ span: 24 }}>
                    <Issue />
                  </Col>
                  <Col md={{ span: 10, offset: 4 }} xs={{ span: 24 }}>
                    <Redeem setWalletModalVisibility={setWalletModalVisibility} />
                  </Col>
                </Row>
              ) : (
                <Row style={{ marginTop: 20 }}>
                  <Col span={18}>
                    <Issue />
                  </Col>
                </Row>
              )) : <IssueAndRedeem />}

              <div style={{ textAlign: "center" }}>
                <Trans i18nKey="trade.tabs.buy_redeem.liquidity">
                  <p>You can earn additional interest by adding these tokens to liquidity pools, see <a target="_blank" rel="noopener" href="https://liquidity.obyte.org" onClick={handleClickToLiquidity}>liquidity.obyte.org</a>.</p>
                </Trans>
              </div>
            </TabPane>
            {fund_aa ? <TabPane
              disabled={!("reserve" in bonded_state)}
              tab={
                <span>
                  <FundIcon /> {t("trade.tabs.stability_fund.name", "Stability fund")}
                </span>
              }
              key="fund"
            >
              <StabilityFund />
            </TabPane> : <TabPane
              disabled={!("reserve" in bonded_state) || (!bonded_state.interest_rate && !deposit_state.supply)}
              tab={
                <span>
                  <ImportOutlined /> {t("trade.tabs.deposits.name", "Deposits")}
                </span>
              }
              key="deposits"
            >
              <Deposits params={actualParams} openWalletModal={setWalletModalVisibility} />
            </TabPane>}
            <TabPane
              disabled={!("reserve" in bonded_state)}
              tab={
                <span>
                  <CapacitorIcon />
                  {t("trade.tabs.capacitor.name", "Capacitors")}
                </span>
              }
              key="capacitor"
            >
              <Capacitors
                address={address}
                bonded_state={bonded_state}
                params={actualParams}
                reserve_asset_symbol={reserve_asset_symbol}
              />
            </TabPane>

            <TabPane
              disabled={!("reserve" in bonded_state)}
              tab={
                <span>
                  <GovernanceIcon />
                  {t("trade.tabs.governance.name", "Governance")}
                </span>
              }
              key="governance"
            >
              <Governance openWalletModal={setWalletModalVisibility} />
            </TabPane>
            <TabPane
              disabled={!("reserve" in bonded_state)}
              tab={
                <span>
                  <NodeIndexOutlined />
                  {t("trade.tabs.transactions.name", "Transactions")}
                </span>
              }
              key="transactions"
            >
              <Transactions />
            </TabPane>
            <TabPane
              tab={
                <span>
                  <SlidersOutlined />
                  {t("trade.tabs.parameters.name", "Parameters")}
                </span>
              }
              key="parameters"
            >
              <Parameters />
            </TabPane>
          </Tabs>
        </>

        <BackTop />
      </div>
    );
}
Example #3
Source File: GovernanceItem.js    From bonded-stablecoin-ui with MIT License 4 votes vote down vote up
GovernanceItem = ({
  value,
  width,
  name,
  challengingPeriodEndInSeconds,
  regularPeriod,
  supportParamsByAddress,
  supportList,
  leader,
  supports,
  decimals,
  choice,
  governance_aa,
  activeWallet,
  balance,
  freezePeriod,
  asset,
  symbol,
  base_governance,
  fund_aa,
  refEl
}) => {
  const [selectedParam, setSelectedParam] = useState(undefined);
  const [visible, setVisible] = useState(false);
  const [activeSupportValue, setActiveSupportValue] = useState(undefined);
  const [isExpired, setIsExpired] = useState(false);
  const { t } = useTranslation();
  const now = Math.floor(Date.now() / 1000);
  const source = [];
  const supportsByValue = {};
  const isChoice = !!choice;

  for (let address in supports) {
    if (supports[address].value in supportsByValue) {
      supportsByValue[supports[address].value] += supports[address].support;
    } else {
      supportsByValue[supports[address].value] = supports[address].support;
    }
  }

  for (let value in supportsByValue) {
    source.push({
      value: value,
      support: supportsByValue[value],
    });
  }

  const linkRemoveSupport = generateLink(
    1e4,
    { name },
    activeWallet,
    governance_aa
  );

  const linkCommit = generateLink(
    1e4,
    { name, commit: 1 },
    activeWallet,
    governance_aa
  );

  const columns = [
    {
      title: t("trade.tabs.governance.value", "Value"),
      dataIndex: "value",
      key: "value",
      render: (value) => {
        if (name === "oracles") {
          return parseOracle(value).map((item, index) => <div key={item.address + item.feed_name + index}>
            <div style={{ display: "flex" }}>
              <Label
                descr={paramsDescription["oracle" + (index + 1)]}
                label={"Oracle" + (index + 1)}
              /> <span style={{ marginLeft: 5, marginRight: 5 }}>:</span> {width >= 700 ? item.address : <Tooltip style={{ display: "inline" }} title={item.address}>
                <span>{item.address.slice(0, 8)}...</span>
              </Tooltip>}
            </div>
            <div style={{ display: "flex" }}>
              <Label
                descr={paramsDescription["feed_name" + (index + 1)]}
                label={"Feed name" + (index + 1)}
              /> <span style={{ marginLeft: 5, marginRight: 5 }}>:</span> {item.feed_name}</div>
            <div style={{ display: "flex" }}>
              <Label
                descr={paramsDescription["op" + (index + 1)]}
                label={"Op" + (index + 1)}
              /> <span style={{ marginLeft: 5, marginRight: 5 }}>:</span> {item.op}</div>
          </div>)
        } else if (percentageParams.includes(name)) {
          return value * 100 + "%";
        } else if (name === "decision_engine_aa") {
          return <a href={`https://${config.TESTNET ? "testnet" : ""
            }explorer.obyte.org/#${value}`}
            target="_blank"
            rel="noopener">
            {value}
          </a>
        } else {
          return value;
        }
      },
    },
    {
      title: t("trade.tabs.governance.support", "Support"),
      dataIndex: "support",
      key: "support",
      render: (value, records) => {
        return (
          <Button type="link" style={{ padding: 0 }} onClick={() => setActiveSupportValue(records.value)}>
            <ShowDecimalsValue decimals={decimals} value={value} /><>&nbsp;</>{symbol || (fund_aa ? "T_SF" : "T1")}
          </Button>
        );
      },
    },
    {
      render: (records) => {
        return (
          <Button
            type="link"
            disabled={choice && choice === leader && freezePeriod > now}
            onClick={() => { setSelectedParam({ name, value: records.value }); setVisible(true); }}>
            {(width <= 470 || (name === "oracles" && width <= 720)) ? <ImportOutlined /> : (records.value === String(choice)
              ? t("trade.tabs.governance.add_support", "add support for this value")
              : t("trade.tabs.governance.vote_for_this", "vote for this value"))}
          </Button>
        );
      },
    },
  ];

  const choiceView = viewParameter(choice, name);
  const leaderView = viewParameter(leader, name);
  const valueView = viewParameter(value, name);
  const info = paramsDescription();

  if (!(name.replace("deposits.", '') in info)) {
    return null
  }

  return (
    <div className={styles.itemWrap} ref={refEl}>
      <Row>
        <Col sm={name === "oracles" || name === "decision_engine_aa" ? { span: 24 } : { span: 12 }} xs={{ span: 24 }}>
          <div className={styles.itemName}>
            <Label
              label={info[name.replace("deposits.", '')].name}
              descr={info[name.replace("deposits.", '')].desc}
            />
          </div>
        </Col>
        <Col sm={name === "oracles" || name === "decision_engine_aa" ? { span: 24 } : { span: 12 }} xs={{ span: 24 }}>
          <div className={styles.itemCurrent} style={name === "oracles" || name === "decision_engine_aa" ? { textAlign: "left", wordBreak: "break-all" } : { wordBreak: "break-all" }}>
            <span style={name === "oracles" || name === "decision_engine_aa" ? { fontSize: width > 576 ? 16 : 14, display: width > 576 ? "inline" : "block", fontWeight: "bold" } : (width <= 576 ? { fontSize: 14, fontWeight: "bold" } : { display: "inline" })}>{t("trade.tabs.governance.current_value", "Current value")}:</span>{" "}
            {valueView}
          </div>
        </Col>
      </Row>
      <Row align="top">
        <Col sm={(name === "oracles" || name === "decision_engine_aa") && width < 720 ? { span: 24 } : { span: 12 }}>
          {(leader !== undefined && leader !== false) &&
            <div><b style={name === "oracles" ? { display: valueView !== "-" ? "block" : "inline" } : { display: "inline" }}>{t("trade.tabs.governance.leader", "Leader")}:</b> {leaderView}</div>}
          <div>{isChoice && <div><b>{t("trade.tabs.governance.my_choice", "My choice")}: </b>{choiceView}</div>}</div>
        </Col>
        {challengingPeriodEndInSeconds ? (
          <Col
            xs={{ span: 24 }}
            sm={{ span: 12 }}
            style={{ paddingRight: 10 }}
          >
            <div className={styles.secondInfo} style={(name === "oracles" || name === "decision_engine_aa") && width < 720 ? { textAlign: "left" } : {}}>
              <div>
                {now <= challengingPeriodEndInSeconds && !isExpired ? (
                  <>
                    {t("trade.tabs.governance.expires_period", "Challenging period expires in")} {" "}
                    <Countdown
                      valueStyle={{ fontSize: 14, display: "inline", wordBreak: "break-all" }}
                      value={moment.unix(challengingPeriodEndInSeconds)}
                      style={{ display: "inline" }}
                      format={regularPeriod > 86400 ? "D [days] HH:mm:ss" : "HH:mm:ss"}
                      onFinish={() => setIsExpired(true)}
                    />
                  </>
                ) : (
                  <div>
                      {(leader !== undefined && leader !== false) && <QRButton
                      type="link"
                      style={{ padding: 0, lineHeight: "1em", height: "auto" }}
                      href={linkCommit}
                      size="small"
                      disabled={
                        now < challengingPeriodEndInSeconds ||
                        leader === value ||
                        leader === undefined
                      }
                    >
                      {t("trade.tabs.governance.commit", "commit")}
                    </QRButton>}
                  </div>
                )}
              </div>
              {isChoice && <div>
                <QRButton
                  type="link"
                  href={linkRemoveSupport}
                  style={{ padding: 0, lineHeight: "1em", height: "auto" }}
                  size="small"
                  disabled={
                    !isChoice ||
                    (choice && choice === leader && freezePeriod > now)
                  }
                >
                  {t("trade.tabs.governance.remove_support", "remove support")}
                </QRButton>
              </div>}
            </div>
          </Col>
        ) : (
          <Col
            xs={{ span: 24 }}
            sm={{ span: 12 }}
            style={{
              textAlign: "right",
              paddingRight: 10,
            }}
          >
            <Button
              type="link"
              style={{ padding: 0, lineHeight: "1em", height: "auto" }}
              onClick={() => { setSelectedParam(name); setVisible(true); }}
              disabled={choice && choice === leader && freezePeriod > now}
            >
              {t("trade.tabs.governance.another_value", "suggest another value")}
            </Button>
          </Col>
        )}
      </Row>
      {source.length > 0 ? (
        <>
          <Divider style={{ marginTop: 10, marginBottom: 10 }} />
          <Row style={{ marginTop: 10 }}>
            <Col span={24}>
              <Table
                bordered={false}
                columns={columns}
                dataSource={source.sort((a, b) => b.support - a.support)}
                pagination={{ pageSize: 5, hideOnSinglePage: true }}
                size="small"
                rowKey={(record) => String('G-I-' + record.name + record.value)}
                footer={() => <>
                  <Button
                    type="link"
                    style={{ padding: 5 }}
                    onClick={() => { setSelectedParam(name); setVisible(true); }}
                    disabled={choice && choice === leader && freezePeriod > now}
                  >
                    {t("trade.tabs.governance.another_value", "suggest another value")}
                  </Button>
                </>}
              />
            </Col>
          </Row>
        </>) : <>
          {source.length === 0 && (now > challengingPeriodEndInSeconds || isExpired) && <div style={{ paddingRight: 10, textAlign: width > 576 ? "right" : "right" }}>
            <Button
              type="link"
              style={{ padding: 0, lineHeight: "1em", height: "auto" }}
              onClick={() => { setSelectedParam(name); setVisible(true); }}
            >
              {t("trade.tabs.governance.another_value", "suggest another value")}
            </Button>
          </div>}
        </>}
      <ChangeParamsModal
        visible={visible}
        choice={choice}
        param={name}
        value={selectedParam && viewParamSelected(selectedParam.value, name)}
        activeWallet={activeWallet}
        onCancel={() => setVisible(false)}
        governance_aa={governance_aa}
        base_governance={base_governance}
        asset={asset}
        decimals={decimals}
        symbol={symbol}
        balance={balance}
        fund_aa={fund_aa}
        supportParamsByAddress={supportParamsByAddress}
        supportsByValue={supportsByValue}
        isMyVote={
          selectedParam && String(choice) === String(selectedParam.value)
        }
      />
      <SupportListModal
        decimals={decimals}
        symbol={symbol}
        fund_aa={fund_aa}
        onCancel={() => setActiveSupportValue(undefined)}
        activeSupportValue={activeSupportValue}
        supportList={supportList.filter(a => a.value === activeSupportValue)} />
    </div>
  );
}
Example #4
Source File: Asset.js    From next-terminal with GNU Affero General Public License v3.0 4 votes vote down vote up
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 > 15) {
                    short = short.substring(0, 15) + " ...";
                }

                if (hasPermission(record['owner'])) {
                    return (
                        <Button type="link" size='small' onClick={() => this.update(record.id)}>
                            <Tooltip placement="topLeft" title={name}>
                                {short}
                            </Tooltip>
                        </Button>
                    );
                } else {
                    return (
                        <Tooltip placement="topLeft" title={name}>
                            {short}
                        </Tooltip>
                    );
                }
            },
            sorter: true,
        }, {
            title: '协议',
            dataIndex: 'protocol',
            key: 'protocol',
            render: (text, record) => {
                const title = `${record['ip'] + ':' + record['port']}`
                return (
                    <Tooltip title={title}>
                        <Tag color={PROTOCOL_COLORS[text]}>{text}</Tag>
                    </Tooltip>
                )
            }
        }, {
            title: '网络',
            dataIndex: 'network',
            key: 'network',
            render: (text, record) => {
                return `${record['ip'] + ':' + record['port']}`;
            }
        }, {
            title: '标签',
            dataIndex: 'tags',
            key: 'tags',
            render: tags => {
                if (!isEmpty(tags)) {
                    return this.renderTags(tags);
                }
            }
        }, {
            title: '状态',
            dataIndex: 'active',
            key: 'active',
            render: text => {
                if (text) {
                    return (
                        <Tooltip title='运行中'>
                            <Badge status="processing" text='运行中'/>
                        </Tooltip>
                    )
                } else {
                    return (
                        <Tooltip title='不可用'>
                            <Badge status="error" text='不可用'/>
                        </Tooltip>
                    )
                }
            }
        }, {
            title: '所有者',
            dataIndex: 'ownerName',
            key: 'ownerName'
        }, {
            title: '创建日期',
            dataIndex: 'created',
            key: 'created',
            render: (text, record) => {
                return (
                    <Tooltip title={text}>
                        {dayjs(text).fromNow()}
                    </Tooltip>
                )
            },
            sorter: true,
        },
            {
                title: '操作',
                key: 'action',
                render: (text, record) => {

                    const menu = (
                        <Menu>
                            <Menu.Item key="1">
                                <Button type="text" size='small'
                                        onClick={() => this.update(record.id)}>编辑</Button>
                            </Menu.Item>

                            <Menu.Item key="2">
                                <Button type="text" size='small'
                                        onClick={() => this.copy(record.id)}>复制</Button>
                            </Menu.Item>
                            <Menu.Item key="3">
                                <Button type="text" size='small'
                                        onClick={() => this.connTest(record.id)}>连通性测试</Button>
                            </Menu.Item>
                            <Menu.Item key="4">
                                <Button type="text" size='small'
                                        disabled={!hasPermission(record['owner'])}
                                        onClick={() => {
                                            this.handleSearchByNickname('')
                                                .then(() => {
                                                    this.setState({
                                                        changeOwnerModalVisible: true,
                                                        selected: record,
                                                    })
                                                    this.changeOwnerFormRef
                                                        .current
                                                        .setFieldsValue({
                                                            owner: record['owner']
                                                        })
                                                });

                                        }}>更换所有者</Button>
                            </Menu.Item>
                            <Menu.Divider/>
                            <Menu.Item key="5">
                                <Button type="text" size='small' danger
                                        disabled={!hasPermission(record['owner'])}
                                        onClick={() => this.showDeleteConfirm(record.id, record.name)}>删除</Button>
                            </Menu.Item>
                        </Menu>
                    );

                    const id = record['id'];
                    const protocol = record['protocol'];
                    const name = record['name'];
                    const sshMode = record['sshMode'];
                    let url = '';
                    if (protocol === 'ssh' && (sshMode === 'native' || sshMode === 'naive')) {
                        url = `#/term?assetId=${id}&assetName=${name}`;
                    } else {
                        url = `#/access?assetId=${id}&assetName=${name}&protocol=${protocol}`;
                    }

                    return (
                        <div>
                            <Button type="link" size='small' href={url} target='_blank'>接入</Button>
                            <Dropdown overlay={menu}>
                                <Button type="link" size='small'>
                                    更多 <DownOutlined/>
                                </Button>
                            </Dropdown>
                        </div>
                    )
                },
            }
        ];

        const selectedRowKeys = this.state.selectedRowKeys;
        const rowSelection = {
            selectedRowKeys: this.state.selectedRowKeys,
            onChange: (selectedRowKeys, selectedRows) => {
                this.setState({selectedRowKeys});
            },
        };
        const hasSelected = selectedRowKeys.length > 0;

        return (
            <>
                <Content key='page-content' className="site-layout-background page-content">
                    <div style={{marginBottom: 20}}>
                        <Row justify="space-around" align="middle" gutter={24}>
                            <Col span={4} key={1}>
                                <Title level={3}>资产列表</Title>
                            </Col>
                            <Col span={20} key={2} style={{textAlign: 'right'}}>
                                <Space>

                                    <Search
                                        ref={this.inputRefOfName}
                                        placeholder="资产名称"
                                        allowClear
                                        onSearch={this.handleSearchByName}
                                        style={{width: 200}}
                                    />

                                    <Search
                                        ref={this.inputRefOfIp}
                                        placeholder="资产IP"
                                        allowClear
                                        onSearch={this.handleSearchByIp}
                                        style={{width: 200}}
                                    />

                                    <Select mode="multiple"
                                            allowClear
                                            value={this.state.selectedTags}
                                            placeholder="资产标签" onChange={this.handleTagsChange}
                                            style={{minWidth: 150}}>
                                        {this.state.tags.map(tag => {
                                            if (tag === '-') {
                                                return undefined;
                                            }
                                            return (<Select.Option key={tag}>{tag}</Select.Option>)
                                        })}
                                    </Select>

                                    <Select onChange={this.handleSearchByProtocol}
                                            value={this.state.queryParams.protocol ? this.state.queryParams.protocol : ''}
                                            style={{width: 100}}>
                                        <Select.Option value="">全部协议</Select.Option>
                                        <Select.Option value="rdp">rdp</Select.Option>
                                        <Select.Option value="ssh">ssh</Select.Option>
                                        <Select.Option value="vnc">vnc</Select.Option>
                                        <Select.Option value="telnet">telnet</Select.Option>
                                        <Select.Option value="kubernetes">kubernetes</Select.Option>
                                    </Select>

                                    <Tooltip title='重置查询'>

                                        <Button icon={<UndoOutlined/>} onClick={() => {
                                            this.inputRefOfName.current.setValue('');
                                            this.inputRefOfIp.current.setValue('');
                                            this.setState({
                                                selectedTags: []
                                            })
                                            this.loadTableData({pageIndex: 1, pageSize: 10, protocol: '', tags: ''})
                                        }}>

                                        </Button>
                                    </Tooltip>

                                    <Divider type="vertical"/>
                                    <Tooltip title="批量导入">
                                        <Button type="dashed" icon={<ImportOutlined/>}
                                                onClick={() => {
                                                    this.setState({
                                                        importModalVisible: true
                                                    })
                                                }}>
                                        </Button>
                                    </Tooltip>
                                    <Tooltip title="新增">
                                        <Button icon={<PlusOutlined/>}
                                                onClick={() => this.showModal('新增资产', {})}
                                        >
                                        </Button>
                                    </Tooltip>


                                    <Tooltip title="刷新列表">
                                        <Button icon={<SyncOutlined/>} onClick={() => {
                                            this.loadTableData(this.state.queryParams)
                                        }}>

                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="批量删除">
                                        <Button type="primary" danger disabled={!hasSelected} icon={<DeleteOutlined/>}
                                                loading={this.state.delBtnLoading}
                                                onClick={() => {
                                                    const content = <div>
                                                        您确定要删除选中的<Text style={{color: '#1890FF'}}
                                                                       strong>{this.state.selectedRowKeys.length}</Text>条记录吗?
                                                    </div>;
                                                    confirm({
                                                        icon: <ExclamationCircleOutlined/>,
                                                        content: content,
                                                        onOk: () => {
                                                            this.batchDelete()
                                                        },
                                                        onCancel() {

                                                        },
                                                    });
                                                }}>

                                        </Button>
                                    </Tooltip>

                                </Space>
                            </Col>
                        </Row>
                    </div>

                    <Table key='assets-table'
                           rowSelection={rowSelection}
                           dataSource={this.state.items}
                           columns={columns}
                           position={'both'}
                           pagination={{
                               showSizeChanger: true,
                               current: this.state.queryParams.pageIndex,
                               pageSize: this.state.queryParams.pageSize,
                               onChange: this.handleChangPage,
                               onShowSizeChange: this.handleChangPage,
                               total: this.state.total,
                               showTotal: total => `总计 ${total} 条`
                           }}
                           loading={this.state.loading}
                           onChange={this.handleTableChange}
                    />

                    {
                        this.state.modalVisible ?
                            <AssetModal
                                visible={this.state.modalVisible}
                                title={this.state.modalTitle}
                                handleOk={this.handleOk}
                                handleCancel={this.handleCancelModal}
                                confirmLoading={this.state.modalConfirmLoading}
                                credentials={this.state.credentials}
                                tags={this.state.tags}
                                model={this.state.model}
                            />
                            : null
                    }

                    {
                        this.state.importModalVisible ?
                            <Modal title="资产导入" visible={true}
                                   onOk={() => {
                                       const formData = new FormData();
                                       formData.append("file", this.state.fileList[0]);

                                       let headers = getHeaders();
                                       headers['Content-Type'] = 'multipart/form-data';

                                       axios
                                           .post(server + "/assets/import", formData, {
                                               headers: headers
                                           })
                                           .then((resp) => {
                                               console.log("上传成功", resp);
                                               this.setState({
                                                   importModalVisible: false
                                               })
                                               let result = resp.data;
                                               if (result['code'] === 1) {
                                                   let data = result['data'];
                                                   let successCount = data['successCount'];
                                                   let errorCount = data['errorCount'];
                                                   if (errorCount === 0) {
                                                       notification['success']({
                                                           message: '导入资产成功',
                                                           description: '共导入成功' + successCount + '条资产。',
                                                       });
                                                   } else {
                                                       notification['info']({
                                                           message: '导入资产完成',
                                                           description: `共导入成功${successCount}条资产,失败${errorCount}条资产。`,
                                                       });
                                                   }
                                               } else {
                                                   notification['error']({
                                                       message: '导入资产失败',
                                                       description: result['message'],
                                                   });
                                               }
                                               this.loadTableData();
                                           });
                                   }}
                                   onCancel={() => {
                                       this.setState({
                                           importModalVisible: false
                                       })
                                   }}
                                   okButtonProps={{
                                       disabled: this.state.fileList.length === 0
                                   }}
                            >
                                <Space>
                                    <Upload
                                        maxCount={1}
                                        onRemove={file => {
                                            this.setState(state => {
                                                const index = state.fileList.indexOf(file);
                                                const newFileList = state.fileList.slice();
                                                newFileList.splice(index, 1);
                                                return {
                                                    fileList: newFileList,
                                                };
                                            });
                                        }}
                                        beforeUpload={(file) => {
                                            this.setState(state => ({
                                                fileList: [file],
                                            }));
                                            return false;
                                        }}
                                        fileList={this.state.fileList}
                                    >
                                        <Button icon={<UploadOutlined/>}>选择csv文件</Button>
                                    </Upload>

                                    <Button type="primary" onClick={() => {

                                        let csvString = 'name,ssh,127.0.0.1,22,username,password,privateKey,passphrase,description,tag1|tag2|tag3';
                                        //前置的"\uFEFF"为“零宽不换行空格”,可处理中文乱码问题
                                        const blob = new Blob(["\uFEFF" + csvString], {type: 'text/csv;charset=gb2312;'});
                                        let a = document.createElement('a');
                                        a.download = 'sample.csv';
                                        a.href = URL.createObjectURL(blob);
                                        a.click();
                                    }}>
                                        下载样本文件
                                    </Button>
                                </Space>

                            </Modal>
                            : undefined
                    }

                    <Modal title={<Text>更换资源「<strong style={{color: '#1890ff'}}>{this.state.selected['name']}</strong>」的所有者
                    </Text>}
                           visible={this.state.changeOwnerModalVisible}
                           confirmLoading={this.state.changeOwnerConfirmLoading}

                           onOk={() => {
                               this.setState({
                                   changeOwnerConfirmLoading: true
                               });

                               let changeOwnerModalVisible = false;
                               this.changeOwnerFormRef
                                   .current
                                   .validateFields()
                                   .then(async values => {
                                       let result = await request.post(`/assets/${this.state.selected['id']}/change-owner?owner=${values['owner']}`);
                                       if (result['code'] === 1) {
                                           message.success('操作成功');
                                           this.loadTableData();
                                       } else {
                                           message.error(result['message'], 10);
                                           changeOwnerModalVisible = true;
                                       }
                                   })
                                   .catch(info => {

                                   })
                                   .finally(() => {
                                       this.setState({
                                           changeOwnerConfirmLoading: false,
                                           changeOwnerModalVisible: changeOwnerModalVisible
                                       })
                                   });
                           }}
                           onCancel={() => {
                               this.setState({
                                   changeOwnerModalVisible: false
                               })
                           }}
                    >

                        <Form ref={this.changeOwnerFormRef}>

                            <Form.Item name='owner' rules={[{required: true, message: '请选择所有者'}]}>
                                <Select
                                    showSearch
                                    placeholder='请选择所有者'
                                    onSearch={this.handleSearchByNickname}
                                    filterOption={false}
                                >
                                    {this.state.users.map(d => <Select.Option key={d.id}
                                                                              value={d.id}>{d.nickname}</Select.Option>)}
                                </Select>
                            </Form.Item>
                            <Alert message="更换资产所有者不会影响授权凭证的所有者" type="info" showIcon/>

                        </Form>
                    </Modal>
                </Content>
            </>
        );
    }
Example #5
Source File: AiSample.js    From network-rc with Apache License 2.0 4 votes vote down vote up
render() {
    const {
      clear,
      download,
      upload,
      props: { onFinish, cameraEnabled },
    } = this;
    const { sampleList } = this.state;
    return (
      <div className="ai-sample">
        <Form layout="inline" className="ai-sample-form">
          {Object.keys(aiAction).map((key) => (
            <Form.Item>
              <Button
                icon={aiAction[key].icon}
                onClick={() => this.add({ action: key })}
                disabled={!cameraEnabled}
              >{aiAction[key].name}</Button>
            </Form.Item>
          ))}
          <Form.Item>
            <Upload
              customRequest={upload}
              accept="application/json"
              showUploadList={false}
            >
              <Button icon={<ImportOutlined />}>导入</Button>
            </Upload>
          </Form.Item>
          <Form.Item>
            <Button
              icon={<ExportOutlined />}
              disabled={!sampleList.length}
              onClick={download}
            >
              导出
            </Button>
          </Form.Item>
          <Form.Item>
            <Button type="danger" disabled={!sampleList.length} onClick={clear}>
              清除
            </Button>
          </Form.Item>
          <Form.Item>
            <Link to="../train">
              <Button
                type="primary"
                disabled={sampleList.length < 10}
                onClick={() => {
                  onFinish(sampleList);
                }}
              >
                下一步
              </Button>
            </Link>
          </Form.Item>
        </Form>
        <List
          size="small"
          className="ai-example-list"
          grid={{ gutter: 16, column: 4 }}
          itemLayout="vertical"
          pagination={{
            pageSize: 12,
          }}
          dataSource={sampleList}
          renderItem={({ img, action }, index) => (
            <List.Item>
              <Card
                size="small"
                title={aiAction[action].icon}
                actions={[
                  <Button
                    size="small"
                    icon={<CloseOutlined />}
                    type="danger"
                    onClick={() => this.remove(index)}
                  />,
                ]}
              >
                <img
                  style={{ width: "100%" }}
                  src={img}
                  alt="example"
                  onLoad={function ({ target }) {
                    target.height = target.width * 0.75;
                  }}
                />
              </Card>
            </List.Item>
          )}
        />
      </div>
    );
  }
Example #6
Source File: newtask.js    From hashcat.launcher with MIT License 4 votes vote down vote up
render() {
		return (
			<>
				<PageHeader
					title="New Task"
					extra={[
						<Upload
							key="Import Config"
							accept=".json"
							maxCount={1}
							showUploadList={false}
							onChange={this.onClickImportConfig}
							beforeUpload={() => {return false;}}
						>
							<Button
								type="text"
								icon={<ImportOutlined />}
								loading={this.state.isLoadingImportConfig}
							>
								Import Config
							</Button>
						</Upload>,
						<Button
							key="Export Config"
							type="text"
							icon={<ExportOutlined />}
							onClick={this.onClickExportConfig}
							loading={this.state.isLoadingExportConfig}
						>
							Export Config
						</Button>
					]}
				/>
				<Content style={{ padding: '16px 24px' }}>
					<Row gutter={[16]}>
						<Col span={4}>
							<Steps direction="vertical" current={this.state.step} onChange={this.onChangeStep}>
								<Step title="Target" icon={<AimOutlined />} description="Select Target" />
								<Step title="Attack" icon={<ToolOutlined />} description="Configure Attack" />
								<Step title="Advanced" icon={<ExperimentOutlined />} description="Advanced Options" />
								<Step title="Output" icon={<ExportOutlined />} description="Set Output" />
								<Step title="Finalize" icon={<FileDoneOutlined />} description="Review and Finalize" />
							</Steps>
						</Col>
						<Col span={20}>
							<div className="steps-content">
								{this.state.step === 0 ? (
									<Form layout="vertical">
										<Form.Item
											label="Hash"
										>
											<Select
												showSearch
												style={{ width: "100%" }}
												size="large"
												placeholder="Select Hash"
												value={this.state.hash}
												onChange={this.onChangeHash}
												filterOption={(input, option) =>
													String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
													String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
												}
											>
												{this.state._hashes.map(hash =>
													<Option value={hash} key={hash} title={hash}>{filename(hash)}</Option>
												)}
											</Select>
										</Form.Item>
										<Form.Item
											label="Algorithm"
										>
											<Select
												showSearch
												style={{ width: "100%" }}
												size="large"
												placeholder="Select Algorithm"
												value={this.state.algorithm}
												onChange={this.onChangeAlgorithm}
												filterOption={(input, option) =>
													String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
													String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
												}
											>
												{Object.keys(this.state._algorithms).map(key =>
													<Option value={Number(key)} key={Number(key)}>{key + " - " + this.state._algorithms[key]}</Option>
												)}
											</Select>
										</Form.Item>
									</Form>
								) : this.state.step === 1 ? (
									<Form layout="vertical" requiredMark="optional">
										<Form.Item
											label="Attack Mode"
											required
										>
											<Radio.Group value={this.state.attackMode} onChange={this.onChangeAttackMode}>
												<Radio value={0}>Dictionary Attack</Radio>
												<Radio value={1}>Combinator Attack</Radio>
												<Radio value={3}>Mask Attack</Radio>
												<Radio value={6}>Hybrid1 (Dictionary + Mask)</Radio>
												<Radio value={7}>Hybrid2 (Mask + Dictionary)</Radio>
											</Radio.Group>
										</Form.Item>
											{this.state.attackMode === 0 ? (
												<>
													<Form.Item
														label="Dictionaries"
														required
													>
														<Select
															mode="multiple"
															allowClear
															style={{ width: '100%' }}
															placeholder="Select Dictionaries"
															size="large"
															onChange={this.onChangeDictionaries}
															value={this.state.dictionaries}
															filterOption={(input, option) =>
																String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
															}
														>
															{this.state._dictionaries.map(dictionary =>
																<Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option>
															)}
														</Select>
													</Form.Item>
													<Form.Item
														label="Rules"
													>
														<Select
															mode="multiple"
															allowClear
															style={{ width: '100%' }}
															placeholder={"Select Rules [max. "+maxRules+"]"}
															size="large"
															onChange={this.onChangeRules}
															value={this.state.rules}
															filterOption={(input, option) =>
																String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
															}
														>
															{this.state._rules.map(rule =>
																<Option value={rule} key={rule} title={rule}>{filename(rule)}</Option>
															)}
														</Select>
													</Form.Item>
												</>
											) : this.state.attackMode === 1 ? (
												<Row gutter={[18, 16]}>
													<Col span={12}>
														<Row>
															<Col span={24}>
																<Form.Item
																	label="Left Dictionary"
																	required
																>
																	<Select
																		showSearch
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Select Left Dictionary"
																		size="large"
																		onChange={this.onChangeLeftDictionary}
																		value={this.state.leftDictionary}
																		filterOption={(input, option) =>
																			String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																			String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																		}
																	>
																		{this.state._dictionaries.map(dictionary =>
																			<Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option>
																		)}
																	</Select>
																</Form.Item>
															</Col>
															<Col span={24}>
																<Form.Item
																	label="Left Rule"
																>
																	<Input
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Set Left Rule"
																		size="large"
																		onChange={this.onChangeLeftRule}
																		value={this.state.leftRule}
																	/>
																</Form.Item>
															</Col>
														</Row>
													</Col>
													<Col span={12}>
														<Row>
															<Col span={24}>
																<Form.Item
																	label="Right Dictionary"
																	required
																>
																	<Select
																		showSearch
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Select Right Dictionary"
																		size="large"
																		onChange={this.onChangeRightDictionary}
																		value={this.state.rightDictionary}
																		filterOption={(input, option) =>
																			String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																			String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																		}
																	>
																		{this.state._dictionaries.map(dictionary =>
																			<Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option>
																		)}
																	</Select>
																</Form.Item>
															</Col>
															<Col span={24}>
																<Form.Item
																	label="Right Rule"
																>
																	<Input
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Set Right Rule"
																		size="large"
																		onChange={this.onChangeRightRule}
																		value={this.state.rightRule}
																	/>
																</Form.Item>
															</Col>
														</Row>
													</Col>
												</Row>
											) : this.state.attackMode === 3 ? (
												<Row gutter={[18, 16]}>
													<Col span={12}>
														{this.state.maskInputType === "text" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Input
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Set Mask"
																	size="large"
																	onChange={this.onChangeMask}
																	value={this.state.mask}
																	suffix={
																		this.state.mask ? maskLength(this.state.mask) : undefined
																	}
																/>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "file"})}
																>
																	Use .hcmask file instead
																</Button>
															</Form.Item>
														) : this.state.maskInputType === "file" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Select
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Select Mask"
																	size="large"
																	onChange={this.onChangeMaskFile}
																	value={this.state.maskFile}
																	filterOption={(input, option) =>
																		String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																		String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																	}
																>
																	{this.state._masks.map(mask =>
																		<Option value={mask} key={mask} title={mask}>{filename(mask)}</Option>
																	)}
																</Select>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "text"})}
																>
																	Use mask text instead
																</Button>
															</Form.Item>
														) : "unsupported mask input type" }
														<Form.Item
															label="Mask increment mode"
														>
															<Checkbox
																checked={this.state.enableMaskIncrementMode}
																onChange={this.onChangeEnableMaskIncrementMode}
															>
																Enable
															</Checkbox>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMin}
																onChange={this.onChangeMaskIncrementMin}
															/>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMax}
																onChange={this.onChangeMaskIncrementMax}
															/>
														</Form.Item>
													</Col>
													<Col span={12}>
														<Form.Item
															label="Custom charset 1"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 1"
																size="large"
																onChange={this.onChangeCustomCharset1}
																value={this.state.customCharset1}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 2"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 2"
																size="large"
																onChange={this.onChangeCustomCharset2}
																value={this.state.customCharset2}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 3"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 3"
																size="large"
																onChange={this.onChangeCustomCharset3}
																value={this.state.customCharset3}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 4"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 4"
																size="large"
																onChange={this.onChangeCustomCharset4}
																value={this.state.customCharset4}
															/>
														</Form.Item>
													</Col>
												</Row>
											) : this.state.attackMode === 6 ? (
												<Row gutter={[18, 16]}>
													<Col span={24}>
														<Row gutter={[18, 16]}>
															<Col span={12}>
																<Form.Item
																	label="Dictionary"
																	required
																>
																	<Select
																		showSearch
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Select Dictionary"
																		size="large"
																		onChange={this.onChangeLeftDictionary}
																		value={this.state.leftDictionary}
																		filterOption={(input, option) =>
																			String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																			String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																		}
																	>
																		{this.state._dictionaries.map(dictionary =>
																			<Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option>
																		)}
																	</Select>
																</Form.Item>
															</Col>
															<Col span={12}>
																<Form.Item
																	label="Rule"
																>
																	<Input
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Set Rule"
																		size="large"
																		onChange={this.onChangeLeftRule}
																		value={this.state.leftRule}
																	/>
																</Form.Item>
															</Col>
														</Row>
													</Col>
													<Col span={12}>
														{this.state.maskInputType === "text" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Input
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Set Mask"
																	size="large"
																	onChange={this.onChangeMask}
																	value={this.state.mask}
																	suffix={
																		this.state.mask ? maskLength(this.state.mask) : undefined
																	}
																/>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "file"})}
																>
																	Use .hcmask file instead
																</Button>
															</Form.Item>
														) : this.state.maskInputType === "file" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Select
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Select Mask"
																	size="large"
																	onChange={this.onChangeMaskFile}
																	value={this.state.maskFile}
																	filterOption={(input, option) =>
																		String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																		String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																	}
																>
																	{this.state._masks.map(mask =>
																		<Option value={mask} key={mask} title={mask}>{filename(mask)}</Option>
																	)}
																</Select>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "text"})}
																>
																	Use mask text instead
																</Button>
															</Form.Item>
														) : "unsupported mask input type" }
														<Form.Item
															label="Mask increment mode"
														>
															<Checkbox
																checked={this.state.enableMaskIncrementMode}
																onChange={this.onChangeEnableMaskIncrementMode}
															>
																Enable
															</Checkbox>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMin}
																onChange={this.onChangeMaskIncrementMin}
															/>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMax}
																onChange={this.onChangeMaskIncrementMax}
															/>
														</Form.Item>
													</Col>
													<Col span={12}>
														<Form.Item
															label="Custom charset 1"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 1"
																size="large"
																onChange={this.onChangeCustomCharset1}
																value={this.state.customCharset1}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 2"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 2"
																size="large"
																onChange={this.onChangeCustomCharset2}
																value={this.state.customCharset2}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 3"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 3"
																size="large"
																onChange={this.onChangeCustomCharset3}
																value={this.state.customCharset3}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 4"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 4"
																size="large"
																onChange={this.onChangeCustomCharset4}
																value={this.state.customCharset4}
															/>
														</Form.Item>
													</Col>
												</Row>
											) : this.state.attackMode === 7 ? (
												<Row gutter={[18, 16]}>
													<Col span={12}>
														{this.state.maskInputType === "text" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Input
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Set Mask"
																	size="large"
																	onChange={this.onChangeMask}
																	value={this.state.mask}
																	suffix={
																		this.state.mask ? maskLength(this.state.mask) : undefined
																	}
																/>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "file"})}
																>
																	Use .hcmask file instead
																</Button>
															</Form.Item>
														) : this.state.maskInputType === "file" ? (
															<Form.Item
																label="Mask"
																required
															>
																<Select
																	allowClear
																	style={{ width: '100%' }}
																	placeholder="Select Mask"
																	size="large"
																	onChange={this.onChangeMaskFile}
																	value={this.state.maskFile}
																	filterOption={(input, option) =>
																		String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																		String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																	}
																>
																	{this.state._masks.map(mask =>
																		<Option value={mask} key={mask} title={mask}>{filename(mask)}</Option>
																	)}
																</Select>
																<Button
																	type="link"
																	style={{ padding: '0' }}
																	onClick={() => this.onChangeMaskInputType({type: "text"})}
																>
																	Use mask text instead
																</Button>
															</Form.Item>
														) : "unsupported mask input type" }
														<Form.Item
															label="Mask increment mode"
														>
															<Checkbox
																checked={this.state.enableMaskIncrementMode}
																onChange={this.onChangeEnableMaskIncrementMode}
															>
																Enable
															</Checkbox>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMin}
																onChange={this.onChangeMaskIncrementMin}
															/>
															<InputNumber
																disabled={!this.state.enableMaskIncrementMode}
																min={maskIncrementMin}
																max={maskIncrementMax}
																value={this.state.maskIncrementMax}
																onChange={this.onChangeMaskIncrementMax}
															/>
														</Form.Item>
													</Col>
													<Col span={12}>
														<Form.Item
															label="Custom charset 1"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 1"
																size="large"
																onChange={this.onChangeCustomCharset1}
																value={this.state.customCharset1}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 2"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 2"
																size="large"
																onChange={this.onChangeCustomCharset2}
																value={this.state.customCharset2}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 3"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 3"
																size="large"
																onChange={this.onChangeCustomCharset3}
																value={this.state.customCharset3}
															/>
														</Form.Item>
														<Form.Item
															label="Custom charset 4"
														>
															<Input
																allowClear
																style={{ width: '100%' }}
																placeholder="Set Custom charset 4"
																size="large"
																onChange={this.onChangeCustomCharset4}
																value={this.state.customCharset4}
															/>
														</Form.Item>
													</Col>
													<Col span={24}>
														<Row gutter={[18, 16]}>
															<Col span={12}>
																<Form.Item
																	label="Dictionary"
																	required
																>
																	<Select
																		showSearch
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Select Dictionary"
																		size="large"
																		onChange={this.onChangeRightDictionary}
																		value={this.state.rightDictionary}
																		filterOption={(input, option) =>
																			String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																			String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																		}
																	>
																		{this.state._dictionaries.map(dictionary =>
																			<Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option>
																		)}
																	</Select>
																</Form.Item>
															</Col>
															<Col span={12}>
																<Form.Item
																	label="Rule"
																>
																	<Input
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Set Rule"
																		size="large"
																		onChange={this.onChangeRightRule}
																		value={this.state.rightRule}
																	/>
																</Form.Item>
															</Col>
														</Row>
													</Col>
												</Row>
											) : (
												"Select Attack Mode"
											)}
									</Form>
								) : this.state.step === 2 ? (
									<Form layout="vertical">
										<Collapse ghost onChange={this.onChangeAdvancedOptionsCollapse} activeKey={this.state.advancedOptionsCollapse}>
											<Panel header="General" key="General">
												<Row gutter={[18, 16]}>
													<Col>
														<Checkbox
															checked={this.state.quiet}
															onChange={this.onChangeQuiet}
														>
															Quiet
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.disablePotFile}
															onChange={this.onChangeDisablePotFile}
														>
															Disable Pot File
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.disableLogFile}
															onChange={this.onChangeDisableLogFile}
														>
															Disable Log File
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.enableOptimizedKernel}
															onChange={this.onChangeEnableOptimizedKernel}
														>
															Enable optimized kernel
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.enableSlowerCandidateGenerators}
															onChange={this.onChangeEnableSlowerCandidateGenerators}
														>
															Enable slower candidate generators
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.removeFoundHashes}
															onChange={this.onChangeRemoveFoundHashes}
														>
															Remove found hashes
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.ignoreUsernames}
															onChange={this.onChangeIgnoreUsernames}
														>
															Ignore Usernames
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.disableSelfTest}
															onChange={this.onChangeDisableSelfTest}
														>
															Disable self-test (Not Recommended)
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.ignoreWarnings}
															onChange={this.onChangeIgnoreWarnings}
														>
															Ignore warnings (Not Recommended)
														</Checkbox>
													</Col>
												</Row>
											</Panel>
											<Panel header="Devices" key="Devices">
												<Row gutter={[18, 16]}>
													<Col span={8}>
														<Form.Item
															label="Devices IDs"
														>
															<Select
																mode="multiple"
																allowClear
																style={{ width: '100%' }}
																placeholder="Select Devices IDs"
																size="large"
																onChange={this.onChangeDevicesIDs}
																value={this.state.devicesIDs}
																filterOption={(input, option) =>
																	String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																	String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																}
															>
																{Array.from(Array(16)).map((x,i) =>
																	<Option value={i+1} key={i+1}>{"Device #"+(i+1)}</Option>
																)}
															</Select>
														</Form.Item>
													</Col>
													<Col span={8}>
														<Form.Item
															label="Devices Types"
														>
															<Select
																mode="multiple"
																allowClear
																style={{ width: '100%' }}
																placeholder="Select Devices Types"
																size="large"
																onChange={this.onChangeDevicesTypes}
																value={this.state.devicesTypes}
																filterOption={(input, option) =>
																	String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																	String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																}
															>
																<Option value={1} key={1}>CPU</Option>
																<Option value={2} key={2}>GPU</Option>
																<Option value={3} key={3}>FPGA, DSP, Co-Processor</Option>
															</Select>
														</Form.Item>
													</Col>
													<Col span={8}>
														<Form.Item
															label="Workload Profile"
															tooltip={
																<Table
																	columns={[
																		{
																			title: 'Performance',
																			dataIndex: 'performance',
																			key: 'Performance'
																		},
																		{
																			title: 'Runtime',
																			dataIndex: 'runtime',
																			key: 'Runtime'
																		},
																		{
																			title: 'Power Consumption',
																			dataIndex: 'powerConsumption',
																			key: 'Power Consumption'
																		},
																		{
																			title: 'Desktop Impact',
																			dataIndex: 'desktopImpact',
																			key: 'Desktop Impact'
																		}
																	]}
																	dataSource={[
																		{
																			key: '1',
																			performance: 'Low',
																			runtime: '2 ms',
																			powerConsumption: 'Low',
																			desktopImpact: 'Minimal'
																		},
																		{
																			key: '2',
																			performance: 'Default',
																			runtime: '12 ms',
																			powerConsumption: 'Economic',
																			desktopImpact: 'Noticeable'
																		},
																		{
																			key: '3',
																			performance: 'High',
																			runtime: '96 ms',
																			powerConsumption: 'High',
																			desktopImpact: 'Unresponsive'
																		},
																		{
																			key: '4',
																			performance: 'Nightmare',
																			runtime: '480 ms',
																			powerConsumption: 'Insane',
																			desktopImpact: 'Headless'
																		}
																	]}
																	size="small"
																	pagination={false}
																	style={{ overflow: 'auto' }}
																/>
															}
														>
															<Select
																allowClear
																style={{ width: '100%' }}
																placeholder="Select Workload Profile"
																size="large"
																onChange={this.onChangeWorkloadProfile}
																value={this.state.workloadProfile}
																filterOption={(input, option) =>
																	String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																	String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																}
															>
																<Option value={1} key={1}>Low</Option>
																<Option value={2} key={2}>Default</Option>
																<Option value={3} key={3}>High</Option>
																<Option value={4} key={4}>Nightmare</Option>
															</Select>
														</Form.Item>
													</Col>
												</Row>
												<Row gutter={[18, 16]}>
													<Col>
														<Button
															loading={this.state.isLoadingDevicesInfo}
															onClick={this.onClickDevicesInfo}
														>
															Devices Info
														</Button>
													</Col>
													<Col>
														<Button
															loading={this.state.isLoadingBenchmark}
															onClick={this.onClickBenchmark}
														>
															Benchmark
														</Button>
													</Col>
												</Row>
											</Panel>
											<Panel header="Markov" key="Markov">
												<Row gutter={[18, 16]}>
													<Col>
														<Checkbox
															checked={this.state.markovDisable}
															onChange={this.onChangeMarkovDisable}
														>
															Disables markov-chains, emulates classic brute-force
														</Checkbox>
													</Col>
													<Col>
														<Checkbox
															checked={this.state.markovClassic}
															onChange={this.onChangeMarkovClassic}
														>
															Enables classic markov-chains, no per-position
														</Checkbox>
													</Col>
													<Col span={24}>
														<Row gutter={[18, 16]}>
															<Col span={8}>
																<Form.Item
																	label="Threshold X when to stop accepting new markov-chains"
																>
																	<InputNumber
																		value={this.state.markovThreshold}
																		onChange={this.onChangeMarkovThreshold}
																	/>
																</Form.Item>
															</Col>
														</Row>
													</Col>
												</Row>
											</Panel>
											<Panel header="Monitor" key="Monitor">
												<Row gutter={[18, 16]}>
													<Col>
														<Checkbox
															checked={this.state.disableMonitor}
															onChange={this.onChangeDisableMonitor}
														>
															Disable Monitor
														</Checkbox>
													</Col>
													<Col span={24}>
														<Row gutter={[18, 16]}>
															<Col span={8}>
																<Form.Item
																	label="Temp Abort (°C)"
																>
																	<Select
																		allowClear
																		style={{ width: '100%' }}
																		placeholder="Select Temp Abort (°C)"
																		size="large"
																		onChange={this.onChangeTempAbort}
																		value={this.state.tempAbort}
																		disabled={this.state.disableMonitor}
																		filterOption={(input, option) =>
																			String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
																			String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
																		}
																	>
																		<Option value={60} key={60}>60 °C</Option>
																		<Option value={65} key={65}>65 °C</Option>
																		<Option value={70} key={70}>70 °C</Option>
																		<Option value={75} key={75}>75 °C</Option>
																		<Option value={80} key={80}>80 °C</Option>
																		<Option value={85} key={85}>85 °C</Option>
																		<Option value={90} key={90}>90 °C</Option>
																		<Option value={95} key={95}>95 °C</Option>
																		<Option value={100} key={100}>100 °C</Option>
																	</Select>
																</Form.Item>
															</Col>
														</Row>
													</Col>
												</Row>
											</Panel>
											<Panel header="Extra Arguments" key="Extra Arguments">
												<Form.Item
													label="Extra Arguments"
												>
													<Input
														allowClear
														style={{ width: '100%' }}
														placeholder="Set Extra Arguments"
														size="large"
														onChange={this.onChangeExtraArguments}
														value={this.state.extraArguments.join(" ")}
													/>
												</Form.Item>
											</Panel>
											<Panel header="Misc" key="Misc">
												<Form.Item
													label="Status Timer"
												>
													<Select
														allowClear
														style={{ width: '100%' }}
														placeholder="Select Status Timer"
														size="large"
														onChange={this.onChangeStatusTimer}
														value={this.state.statusTimer}
														filterOption={(input, option) =>
															String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
															String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
														}
													>
														<Option value={10} key={10}>10 Seconds</Option>
														<Option value={20} key={20}>20 Seconds</Option>
														<Option value={30} key={30}>30 Seconds</Option>
														<Option value={45} key={45}>45 Seconds</Option>
														<Option value={60} key={60}>60 Seconds</Option>
														<Option value={90} key={90}>90 Seconds</Option>
														<Option value={120} key={120}>120 Seconds</Option>
														<Option value={300} key={300}>300 Seconds</Option>
													</Select>
												</Form.Item>
											</Panel>
										</Collapse>
									</Form>
								) : this.state.step === 3 ? (
									<Form layout="vertical">
										<Form.Item
											label="Output File"
											extra={this.state.outputFile ? this.state.outputFile : null}
										>
											<Button
												type="primary"
												onClick={this.onChangeOutputFile}
												loading={this.state.isLoadingSetOutputFile}
											>
												Set Output File
											</Button>
										</Form.Item>
										<Form.Item
											label="Output Format"
										>
											<Select
												mode="multiple"
												allowClear
												style={{ width: '100%' }}
												placeholder="Select Output Format"
												size="large"
												onChange={this.onChangeOutputFormat}
												value={this.state.outputFormat}
												filterOption={(input, option) =>
													String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
													String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
												}
											>
												<Option value={1} key={1}>hash[:salt]</Option>
												<Option value={2} key={2}>plain</Option>
												<Option value={3} key={3}>hex_plain</Option>
												<Option value={4} key={4}>crack_pos</Option>
												<Option value={5} key={5}>timestamp absolute</Option>
												<Option value={6} key={6}>timestamp relative</Option>
											</Select>
										</Form.Item>
									</Form>
								) : this.state.step === 4 ? (
									<Space direction="vertical">
										<Form layout="vertical">
											<Form.Item
												label="Priority"
												tooltip={
													<Typography>
														Tasks are started automatically in a descending order of priority.
													<br />
														Set to -1 to disable auto-start.
													</Typography>
												}
											>
												<InputNumber
													min={-1}
													max={999}
													value={this.state.priority}
													onChange={this.onChangePriority}
													bordered={true}
												/>
											</Form.Item>
										</Form>
										<Space size="large" direction="horizontal">
											<Button
												type="primary"
												icon={<PlusOutlined />}
												onClick={this.onClickCreateTask}
												loading={this.state.isLoadingCreateTask}
											>
												Create Task
											</Button>
												<Checkbox
													checked={this.state.preserveTaskConfig}
													onChange={this.onChangePreserveTaskConfig}
												>
													Preserve task config
												</Checkbox>
										</Space>
									</Space>
								) : null }
							</div>
						</Col>
					</Row>
				</Content>
			</>
		)
	}