antd#Drawer JavaScript Examples

The following examples show how to use antd#Drawer. 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 acy-dex-interface with MIT License 6 votes vote down vote up
SiderMenuWrapper = React.memo(props => {
  const { isMobile, menuData, collapsed, onCollapse } = props;
  const flatMenuKeys = getFlatMenuKeys(menuData);
  return isMobile ? (
    <Drawer
      visible={!collapsed}
      placement="left"
      onClose={() => onCollapse(true)}
      style={{
        padding: 0,
        height: '100vh',
      }}
    >
      <SiderMenu {...props} flatMenuKeys={flatMenuKeys} collapsed={isMobile ? false : collapsed} />
    </Drawer>
  ) : (
    <SiderMenu {...props} flatMenuKeys={flatMenuKeys} />
  );
})
Example #2
Source File: index.js    From gobench with Apache License 2.0 6 votes vote down vote up
render() {
    return (
      <div>
        <h5 className="mb-3">
          <strong>Basic</strong>
        </h5>
        <div className="mb-5">
          <Button type="primary" onClick={this.showDrawer}>
            Open
          </Button>
        </div>
        <Drawer
          title="Basic Drawer"
          placement="right"
          closable={false}
          onClose={this.onClose}
          visible={this.state.visible}
        >
          <p>Some contents...</p>
          <p>Some contents...</p>
          <p>Some contents...</p>
        </Drawer>
      </div>
    )
  }
Example #3
Source File: index.js    From camel-store-admin with Apache License 2.0 6 votes vote down vote up
SiderMenuWrapper = props => {
  const { isMobile, menuData, collapsed, onCollapse } = props;
  return isMobile ? (
    <Drawer
      visible={!collapsed}
      placement="left"
      onClose={() => onCollapse(true)}
      style={{
        padding: 0,
        height: '100vh',
      }}
    >
      <SiderMenu
        {...props}
        flatMenuKeys={getFlatMenuKeys(menuData)}
        collapsed={isMobile ? false : collapsed}
      />
    </Drawer>
  ) : (
    <SiderMenu {...props} flatMenuKeys={getFlatMenuKeys(menuData)} />
  );
}
Example #4
Source File: multi-level-drawer.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
render() {
    return (
      <>
        <Button type="primary" onClick={this.showDrawer}>
          Open drawer
        </Button>
        <Drawer
          title="Multi-level drawer"
          width={520}
          closable={false}
          onClose={this.onClose}
          visible={this.state.visible}
        >
          <Button type="primary" onClick={this.showChildrenDrawer}>
            Two-level drawer
          </Button>
          <Drawer
            title="Two-level Drawer"
            width={320}
            closable={false}
            onClose={this.onChildrenDrawerClose}
            visible={this.state.childrenDrawer}
          >
            This is two-level drawer
          </Drawer>
        </Drawer>
      </>
    );
  }
Example #5
Source File: SideBarDrawer.js    From dexwebapp with Apache License 2.0 5 votes vote down vote up
SideBarDrawer = ({ header, body, footer, onClose, visible }) => {
  const theme = useContext(ThemeContext);
  return (
    <Drawer
      width={241}
      placement="right"
      closable={false}
      onClose={onClose}
      visible={visible}
      drawerStyle={{
        fontSize: '0.85rem',
        background: theme.sidePanelBackground,
      }}
      bodyStyle={{
        padding: '0',
      }}
      headerStyle={{
        height: 0,
      }}
    >
      <Layout
        onMouseLeave={onClose}
        style={{
          background: 'transparent',
          height: '100vh',
        }}
      >
        <div
          style={{
            background: theme.popupHeaderBackground,
            textAlign: 'center',
            width: '100%',
            height: AppLayout.topNavBarHeight,
            lineHeight: AppLayout.topNavBarHeight,
          }}
        >
          {header}
        </div>
        <Content>{body}</Content>
      </Layout>
    </Drawer>
  );
}
Example #6
Source File: header.js    From portfolyo-mern with MIT License 5 votes vote down vote up
function AppHeader() {
  const [visible, setVisible] = useState(false);

  const showDrawer = () => {
    setVisible(true);
  };

  const onClose = () => {
    setVisible(false);
  };

  return (
    <div className="container-fluid">
      <div className="header">
        <div className="logo">
          <b>Portfolyo</b>  
        </div>
        <div className="mobileHidden">
          <Anchor targetOffset="65">
            <Link href="#hero" title="Home" />
            <Link href="#about" title="About" />
            <Link href="#creator" title="Creator" />
            <Link href="#feature" title="Features" />
            <Link href="#works" title="How it works" />
            <Link href="#faq" title="FAQ" />
            <Link href="#contact" title="Contact" />
          </Anchor>
        </div>
        <div className="mobileVisible">
          <Button type="primary" onClick={showDrawer}>
            <i className="fas fa-bars"></i>
          </Button>
          <Drawer
            placement="right"
            closable={false}
            onClose={onClose}
            visible={visible}
          >
            <Anchor targetOffset="65">
              <Link href="#hero" title="Home" />
              <Link href="#about" title="About" />
              <Link href="#feature" title="Features" />
              <Link href="#creator" title="Creator" />
              <Link href="#works" title="How it works" />
              <Link href="#faq" title="FAQ" />
              <Link href="#contact" title="Contact" />
            </Anchor>
          </Drawer>
        </div>
      </div>
    </div>
  );
}
Example #7
Source File: NavBar.js    From relay_08 with MIT License 5 votes vote down vote up
function NavBar() {
  const [visible, setVisible] = useState(false);

  const showDrawer = () => {
    setVisible(true);
  };

  const onClose = () => {
    setVisible(false);
  };

  return (
    <nav className="menu" style={{ position: "fixed", zIndex: 5, width: "100%" }}>
      <div className="menu__logo">
        <a href="/">
          <span>?</span>
        </a>
      </div>
      <div className="menu__container">
        <div className="menu_left">
          <LeftMenu mode="horizontal" />
        </div>
        <Button className="menu__mobile-button" type="primary" onClick={showDrawer}>
          <Icon type="align-right" />
        </Button>
        <Drawer
          title="Basic Drawer"
          placement="right"
          className="menu_drawer"
          closable={false}
          onClose={onClose}
          visible={visible}
        >
          <LeftMenu mode="inline" />
          <RightMenu mode="inline" />
        </Drawer>
      </div>
    </nav>
  );
}
Example #8
Source File: Edit.js    From Peppermint with GNU General Public License v3.0 5 votes vote down vote up
Edit = (props) => {
  const [visible, setVisible] = useState(false);
  const [isActive, setIsActive] = useState(props.n.active);
  const [title, setTitle] = useState(props.n.title);
  const [text, setText] = useState(props.n.text);

  const onClose = async (e) => {
    e.stopPropagation();
    setVisible(false);
    await postData();
  };

  const postData = async () => {
    await fetch(`/api/v1/newsletter/update`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + localStorage.getItem("jwt"),
      },
      body: JSON.stringify({
        id: props.n._id,
        text,
        title,
        active: isActive,
      }),
    }).then((res) => res.json());
  };

  return (
    <div>
      <Button onClick={() => setVisible(true)}>
        Edit
        <Drawer
          width={640}
          placement="right"
          onClose={onClose}
          visible={visible}
        >
          <h4>Active : {props.n.active.toString()}</h4>
          <h4>Created By : {props.n.createdBy.name}</h4>
          <Divider />
          <h4>
            Title :{" "}
            <Input
              style={{ width: 300 }}
              onChange={(e) => setTitle(e.target.value)}
            />
          </h4>
          <Divider />
          <h5>Detail</h5>
          <Input.TextArea
            defaultValue={props.n.text}
            rows={10}
            onChange={(e) => setText(e.target.value)}
          />
          <Divider />
          <h5>Select the button below to change visability </h5>
          <Radio.Group
            buttonStyle="solid"
            value={isActive}
            onChange={(e) => setIsActive(e.target.value)}
            style={{ textAlign: "center" }}
          >
            <Space>
              <Radio.Button value={true}>Active</Radio.Button>
              <Radio.Button value={false}>Hidden</Radio.Button>
            </Space>
          </Radio.Group>
        </Drawer>
      </Button>
    </div>
  );
}
Example #9
Source File: EventOptions.js    From react-portal with MIT License 5 votes vote down vote up
EventOptions = props => {
	const [isDrawerVisible, setIsDrawerVisible] = useState(false);
	const [userData] = useState(getRole());
	const handleEventAdd = () => {
		setIsDrawerVisible(false);
		props.onAddEvent();
	};

	const handleChange = val => {
		props.onTypeChange(val);
	};

	return (
		<div style={{ marginBottom: 12 }}>
			{userData.role === "lead" ? (
				<>
					<Button onClick={() => setIsDrawerVisible(true)}>
						Create Event
					</Button>
					<Divider type="vertical" />
				</>
			) : null}

			<Select
				style={{ minWidth: 180 }}
				defaultValue="Upcoming Events"
				onChange={handleChange}
			>
				<Option value="upcoming">Upcoming Events</Option>
				<Option value="past">Past Events</Option>
				<Option value="running">Running Events</Option>
			</Select>

			<Drawer
				title="Create Event"
				placement="right"
				closable={true}
				width="40%"
				destroyOnClose={true}
				onClose={() => setIsDrawerVisible(false)}
				visible={isDrawerVisible}
			>
				<CreateEvent onAddEvent={handleEventAdd} />
			</Drawer>
		</div>
	);
}
Example #10
Source File: TopicConsumerGroup.js    From kafka-map with Apache License 2.0 5 votes vote down vote up
render() {

        const columns = [{
            title: 'Group ID',
            dataIndex: 'groupId',
            key: 'groupId',
            render: (groupId, record) => {
                return <Button type='link' onClick={() => {
                    this.setState({
                        consumerDetailVisible: true,
                        selectedRow: record
                    })
                }}>{groupId}</Button>;
            }
        }, {
            title: 'Lag',
            dataIndex: 'lag',
            key: 'lag',
            render: (lag) => {
                return lag;
            }
        }];

        return (
            <div>
                <Table
                    rowKey='id'
                    dataSource={this.state.items}
                    columns={columns}
                    position={'both'}
                    size={'small'}
                    loading={this.state.loading}
                    pagination={{
                        showSizeChanger: true,
                        total: this.state.items.length,
                        showTotal: total => <FormattedMessage id="total-items" values={{total}}/>
                    }}
                />

                <Drawer
                    title={'Topic:' + this.state.topic}
                    width={window.innerWidth * 0.8}
                    placement="right"
                    closable={true}
                    onClose={() => {
                        this.setState({
                            consumerDetailVisible: false
                        })
                    }}
                    visible={this.state.consumerDetailVisible}
                >
                    {
                        this.state.consumerDetailVisible ?
                            <TopicConsumerGroupOffset
                                clusterId={this.state.clusterId}
                                topic={this.state.topic}
                                groupId={this.state.selectedRow['groupId']}
                            /> : undefined
                    }

                </Drawer>
            </div>
        );
    }
Example #11
Source File: index.js    From ant-simple-pro with MIT License 5 votes vote down vote up
Layouts = memo(function Layouts({ route, location }) {
  const { Header } = Layout;

  const [collapsed, setCollapsed] = useState(false);

  const [isMobileStatus, setIsMobileStatus] = useState(false); // 用来控制是否到了手机端的尺寸

  const { width } = useOnResize();

  let routeArr = matchRoutes(route.routes, location.pathname)[0].route; // 取出当前的路由信息

  const topBarProps = () => ({
    collapsed,
    onToggle: (collapsed) => setCollapsed(collapsed),
  });

  useEffect(() => {
    setCollapsed(width < responsiveConfig.collapsedInnerWidth ? true : false);
  }, [width]);

  return (
    <Layout className={style.layouts}>
      {width < responsiveConfig.mobileInnerWidth ? (
        <Drawer
          bodyStyle={{ padding: '0' }}
          placement="left"
          closable={false}
          visible={isMobileStatus}
          width={responsiveConfig.sliderExpansionLeft}
          onClose={() => [setIsMobileStatus(false), setCollapsed(true)]}
        >
          <SlideNav collapsed={collapsed} />
        </Drawer>
      ) : (
        <SlideNav collapsed={collapsed} />
      )}
      <Layout>
        <Header
          style={{
            height: '48px',
            lineHeight: '48px',
            background: 'transparent',
            padding: '0',
          }}
        >
          <Head
            {...topBarProps()}
            width={width}
            setIsMobileDrawer={setIsMobileStatus}
          ></Head>
        </Header>
        <div
          className={style.contentWrapper}
          style={{
            left: collapsed
              ? width < responsiveConfig.mobileInnerWidth && !isMobileStatus
                ? `${responsiveConfig.sliderMobileLeft}`
                : `${responsiveConfig.sliderPackUpLeft}px`
              : `${responsiveConfig.sliderExpansionLeft}px`,
          }}
        >
          <Tag collapsed={collapsed} route={routeArr} />
          <div className={style.content} id="content">
            <div className={style.pageContent}>
              {renderRoutes(route.routes, {}, { location })}
            </div>
            <Footer name="Ant Simple Pro" ahthor="lgf&qyh" />
          </div>
        </div>
        <BackTop element="#content" />
      </Layout>
    </Layout>
  );
})
Example #12
Source File: Manager.js    From kite-admin with MIT License 5 votes vote down vote up
render() {
    const { collapsed, isMobile } = this.state

    const asideProps = {
      collapsed,
      onCollapseChange: this.onCollapseChange
    }

    const headerProps = {
      collapsed,
      onCollapseChange: this.onCollapseChange
    }

    return (
      <Layout className="admin-manager">
        {isMobile ? (
          <Drawer
            maskClosable
            placement="left"
            closable={false}
            onClose={this.onCollapseChange.bind(this, !collapsed)}
            visible={!collapsed}
            width={200}
            style={{
              padding: 0,
              height: '100vh'
            }}
          >
            <Aside
              {...{
                ...asideProps,
                collapsed: false,
                onCollapseChange: () => {}
              }}
            />
          </Drawer>
        ) : (
          <Aside {...asideProps} />
        )}
        <Layout className="admin-wrapper">
          <Header {...headerProps} />
          <Content className="admin-content">
            {this.props.children}
            <Footer style={{ textAlign: 'center' }}>
              <a href="https://github.com/maoxiaoquan/kite" target="_blank">
                Kite
              </a>
              ©2019
            </Footer>
          </Content>
        </Layout>
      </Layout>
    )
  }
Example #13
Source File: SideBarDrawer.js    From loopring-pay with Apache License 2.0 5 votes vote down vote up
SideBarDrawer = ({ header, body, footer, onClose, visible }) => {
  const theme = useContext(ThemeContext);
  return (
    <Drawer
      width={241}
      placement="right"
      closable={false}
      onClose={onClose}
      visible={visible}
      drawerStyle={{
        fontSize: "0.85rem",
        background: theme.sidePanelBackground,
      }}
      bodyStyle={{
        padding: "0",
      }}
      headerStyle={{
        height: 0,
      }}
    >
      <Layout
        onMouseLeave={onClose}
        style={{
          background: "transparent",
          height: "100vh",
        }}
      >
        <div
          style={{
            background: theme.popupHeaderBackground,
            textAlign: "center",
            width: "100%",
            height: AppLayout.topNavBarHeight,
            lineHeight: AppLayout.topNavBarHeight,
          }}
        >
          {header}
        </div>
        <Content>{body}</Content>
      </Layout>
    </Drawer>
  );
}
Example #14
Source File: Card.js    From ncovis-2020 with MIT License 5 votes vote down vote up
StyledDrawer = styled(Drawer)`
  position: absolute;
`
Example #15
Source File: styles.js    From bank-client with MIT License 5 votes vote down vote up
StyledDrawer = styled(Drawer)`
  .ant-drawer-body {
    padding: 0;
  }
`
Example #16
Source File: EditProfile.js    From placement-portal with MIT License 5 votes vote down vote up
render(){

        const {
            onClose,
            editVisible,
            loading,
            profileData,
            isMobile
        } = this.props

        let contact_designation = []
        let contact_email = []
        let contact_number = []

        for (var i = 0; i < profileData.contact_details.length; i++) {
            contact_designation[i] = profileData.contact_details[i].designation
            contact_email[i] = profileData.contact_details[i].email
            contact_number[i] = profileData.contact_details[i].phone
        }

        const fileList = [
            {
                uid: '1',
                name: "Logo.jpeg",
                status: 'done',
                url: profileData.logo_link,
                thumbUrl: profileData.logo_link
            }
        ]

        const fieldsValues = {
            ...profileData,
            contact_email,
            contact_number,
            contact_designation,
            fileList
        }

        return(
            <Drawer
                visible={editVisible}
                onClose={onClose}
                placement='right'
                width={isMobile ? '100vw' : '40vw'}
                >
                <Spin spinning = {loading} tip="Submitting profile ...">
                    <Row type= 'flex' justify='center'>
                        <Typography.Title>
                            Edit Profile
                        </Typography.Title>
                    </Row>
                    <Row type= 'flex' justify='center' style={{background: '#fff'}}>
                        <CompanyDetailsForm {...fieldsValues} handleSubmit={this.handleSubmit}/>
                    </Row>
                </Spin>
            </Drawer>
        )
    }
Example #17
Source File: index.js    From crawel with MIT License 4 votes vote down vote up
export default function() {
  const [list, setList] = useState([
    'https://www.jd.com/',
    // 'https://zhuanlan.zhihu.com/p/67491524',
    'https://ai.taobao.com/'
  ]);
  const [fetchData, setFetchData] = useState([]);
  const [recentData, setRecentData] = useState(() => {
    try {
      let dataStr = localStorage.getItem('recent') || []
      return JSON.parse(dataStr)
    }catch(err) {
      return []
    }
  });
  const [isLoading, setLoading] = useState(false);
  const handleChange = (value) => {
    console.log(`selected ${value}`);
    data = value;
  }

  const crawel = () => {
    setLoading(true)
    data && fetch(`${SERVER_URL}/mz/fetch`, {
      method: 'POST',
      body: data
    }).then(res => res.json()).then(res => {
      if(res.state) {
        notification.success({
          message: '抓取完成',
          description: `已成功截取${data.length}张图和网页文本`
        })
        if(res.data) {
          // 求出数据增量
          let curAddItem = res.data.filter(item => !recentData.includes(item))
          setFetchData(curAddItem)
          // 更新最近爬取数据
          setRecentData(res.data)
          // 将爬取数据存入storage
          localStorage.setItem('recent', JSON.stringify(res.data))
        }
      }else {
        notification.error({
          message: '抓取失败',
          description: res.msg
        })
      }
      res && setLoading(false)
    })
  }

  useEffect(() => {
    
  }, [])
  return (
    <div className={styles.normal}>
      <Spin tip="正在疯狂爬取中..." spinning={isLoading}>
        <>
          <Select mode="tags" style={{ width: '50%', marginRight: '20px' }} placeholder="Tags Mode" onChange={handleChange}>
            {list.map(item => {
              return <Option key={item}>{ item }</Option>
            })}
          </Select>
          <Button type="primary" onClick={crawel}>爬取</Button>
          <h3>抓取结果</h3>
          <div className={styles.result}>
            {
              fetchData.length ? fetchData.map(item => {
                return <div className={styles.item} key={item}>
                  <div className={styles.bg} style={{backgroundImage: `url(${`http://192.168.31.123/${item}.jpg`})`}}></div>
                  <div className={styles.viewLink}>
                    <a href={`http://192.168.31.123/${item}.json`} download={`${item}.json`} target="_blank">下载数据</a>
                    <a href={`http://192.168.31.123/${item}.jpg`} target="_blank">查看图片</a>
                  </div>
                </div>
              }) :
              <Result
                status="404"
                title="赶快试试搜索你想要爬取的网站吧~"
                subTitle="在搜索框输入网址,即可自动抓取网页, 支持多选输入."
              />
            }
          </div>
        </>
      </Spin>
      <Drawer
          title="最近抓取"
          placement="right"
          closable={false}
          visible={true}
          mask={false}
          width={360}
        >
          {
              recentData.length ? recentData.map(item => {
                return <div className={classnames(styles.item, styles.recent)} key={item}>
                  <div className={styles.bg} style={{backgroundImage: `url(${`http://192.168.31.123/${item}.jpg`})`}}></div>
                  <div className={styles.viewLink}>
                    <a href={`http://192.168.31.123/${item}.json`} download={`${item}.json`} target="_blank">下载数据</a>
                    <a href={`http://192.168.31.123/${item}.jpg`} target="_blank">查看图片</a>
                  </div>
                </div>
              }) :
              <div style={{marginTop: '160px'}}><Empty description="还没有爬取数据哦~" /></div> 
            }
        </Drawer>
    </div>
  );
}
Example #18
Source File: index.jsx    From react-antd-admin-template with MIT License 4 votes vote down vote up
RightPanel = (props) => {
  const {
    settingPanelVisible,
    toggleSettingPanel,
    changeSetting,
    sidebarLogo: defaultSidebarLogo,
    fixedHeader: defaultFixedHeader,
    tagsView: defaultTagsView,
  } = props;

  const [sidebarLogo, setSidebarLogo] = useState(defaultSidebarLogo);
  const [fixedHeader, setFixedHeader] = useState(defaultFixedHeader);
  const [tagsView, setTagsView] = useState(defaultTagsView);

  const sidebarLogoChange = (checked) => {
    setSidebarLogo(checked);
    changeSetting({ key: "sidebarLogo", value: checked });
  };

  const fixedHeaderChange = (checked) => {
    setFixedHeader(checked);
    changeSetting({ key: "fixedHeader", value: checked });
  };

  const tagsViewChange = (checked) => {
    setTagsView(checked);
    changeSetting({ key: "tagsView", value: checked });
  };

  const handleCopy = (e) => {
    let config = `
    export default {
      showSettings: true,
      sidebarLogo: ${sidebarLogo},
      fixedHeader: ${fixedHeader},
      tagsView: ${tagsView},
    }
    `;
    clip(config, e);
  };

  return (
    <div className="rightSettings">
      <Drawer
        title="系统设置"
        placement="right"
        width={350}
        onClose={toggleSettingPanel}
        visible={settingPanelVisible}
      >
        <Row>
          <Col span={12}>
            <span>侧边栏 Logo</span>
          </Col>
          <Col span={12}>
            <Switch
              checkedChildren="开"
              unCheckedChildren="关"
              defaultChecked={sidebarLogo}
              onChange={sidebarLogoChange}
            />
          </Col>
        </Row>
        <Divider dashed />
        <Row>
          <Col span={12}>
            <span>固定 Header</span>
          </Col>
          <Col span={12}>
            <Switch
              checkedChildren="开"
              unCheckedChildren="关"
              defaultChecked={fixedHeader}
              onChange={fixedHeaderChange}
            />
          </Col>
        </Row>
        <Divider dashed />
        <Row>
          <Col span={12}>
            <span>开启 Tags-View</span>
          </Col>
          <Col span={12}>
            <Switch
              checkedChildren="开"
              unCheckedChildren="关"
              defaultChecked={tagsView}
              onChange={tagsViewChange}
            />
          </Col>
        </Row>
        <Divider dashed />
        <Row>
          <Col span={24}>
            <Alert
              message="开发者请注意:"
              description="配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改/src/defaultSettings.js配置文件"
              type="warning"
              showIcon
              icon={<Icon type="notification" />}
              style={{ marginBottom: "16px" }}
            />
            <Button style={{ width: "100%" }} icon="copy" onClick={handleCopy}>
              拷贝配置
            </Button>
          </Col>
        </Row>
      </Drawer>
    </div>
  );
}
Example #19
Source File: Swap.jsx    From Tai-Shang-NFT-Wallet with MIT License 4 votes vote down vote up
function Swap({ selectedProvider, tokenListURI }) {
  const [tokenIn, setTokenIn] = useState(defaultToken);
  const [tokenOut, setTokenOut] = useState(defaultTokenOut);
  const [exact, setExact] = useState();
  const [amountIn, setAmountIn] = useState();
  const [amountInMax, setAmountInMax] = useState();
  const [amountOut, setAmountOut] = useState();
  const [amountOutMin, setAmountOutMin] = useState();
  const [trades, setTrades] = useState();
  const [routerAllowance, setRouterAllowance] = useState();
  const [balanceIn, setBalanceIn] = useState();
  const [balanceOut, setBalanceOut] = useState();
  const [slippageTolerance, setSlippageTolerance] = useState(
    new Percent(Math.round(defaultSlippage * 100).toString(), "10000"),
  );
  const [timeLimit, setTimeLimit] = useState(defaultTimeLimit);
  const [swapping, setSwapping] = useState(false);
  const [approving, setApproving] = useState(false);
  const [settingsVisible, setSettingsVisible] = useState(false);
  const [swapModalVisible, setSwapModalVisible] = useState(false);

  const [tokenList, setTokenList] = useState([]);

  const [tokens, setTokens] = useState();

  const [invertPrice, setInvertPrice] = useState(false);

  const blockNumber = useBlockNumber(selectedProvider, 3000);

  const signer = selectedProvider.getSigner();
  const routerContract = new ethers.Contract(ROUTER_ADDRESS, IUniswapV2Router02ABI, signer);

  const _tokenListUri = tokenListURI || "https://gateway.ipfs.io/ipns/tokens.uniswap.org";

  const debouncedAmountIn = useDebounce(amountIn, 500);
  const debouncedAmountOut = useDebounce(amountOut, 500);

  const activeChainId = process.env.REACT_APP_NETWORK === "kovan" ? ChainId.KOVAN : ChainId.MAINNET;

  useEffect(() => {
    const getTokenList = async () => {
      console.log(_tokenListUri);
      try {
        const tokenList = await fetch(_tokenListUri);
        const tokenListJson = await tokenList.json();
        const filteredTokens = tokenListJson.tokens.filter(function (t) {
          return t.chainId === activeChainId;
        });
        const ethToken = WETH[activeChainId];
        ethToken.name = "Ethereum";
        ethToken.symbol = "ETH";
        ethToken.logoURI =
          "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png";
        const _tokenList = [ethToken, ...filteredTokens];
        setTokenList(_tokenList);
        const _tokens = tokenListToObject(_tokenList);
        setTokens(_tokens);
      } catch (e) {
        console.log(e);
      }
    };
    getTokenList();
  }, [tokenListURI]);

  const getTrades = async () => {
    if (tokenIn && tokenOut && (amountIn || amountOut)) {
      const pairs = arr => arr.map((v, i) => arr.slice(i + 1).map(w => [v, w])).flat();

      const baseTokens = tokenList
        .filter(function (t) {
          return ["DAI", "USDC", "USDT", "COMP", "ETH", "MKR", "LINK", tokenIn, tokenOut].includes(t.symbol);
        })
        .map(el => {
          return new Token(el.chainId, el.address, el.decimals, el.symbol, el.name);
        });

      const listOfPairwiseTokens = pairs(baseTokens);

      const getPairs = async list => {
        const listOfPromises = list.map(item => Fetcher.fetchPairData(item[0], item[1], selectedProvider));
        return Promise.all(listOfPromises.map(p => p.catch(() => undefined)));
      };

      const listOfPairs = await getPairs(listOfPairwiseTokens);

      let bestTrade;

      if (exact === "in") {
        setAmountInMax();
        bestTrade = Trade.bestTradeExactIn(
          listOfPairs.filter(item => item),
          new TokenAmount(tokens[tokenIn], ethers.utils.parseUnits(amountIn.toString(), tokens[tokenIn].decimals)),
          tokens[tokenOut],
          { maxNumResults: 3, maxHops: 1 },
        );
        if (bestTrade[0]) {
          setAmountOut(bestTrade[0].outputAmount.toSignificant(6));
        } else {
          setAmountOut();
        }
      } else if (exact === "out") {
        setAmountOutMin();
        bestTrade = Trade.bestTradeExactOut(
          listOfPairs.filter(item => item),
          tokens[tokenIn],
          new TokenAmount(tokens[tokenOut], ethers.utils.parseUnits(amountOut.toString(), tokens[tokenOut].decimals)),
          { maxNumResults: 3, maxHops: 1 },
        );
        if (bestTrade[0]) {
          setAmountIn(bestTrade[0].inputAmount.toSignificant(6));
        } else {
          setAmountIn();
        }
      }

      setTrades(bestTrade);

      console.log(bestTrade);
    }
  };

  useEffect(() => {
    getTrades();
  }, [tokenIn, tokenOut, debouncedAmountIn, debouncedAmountOut, slippageTolerance, selectedProvider]);

  useEffect(() => {
    if (trades && trades[0]) {
      if (exact === "in") {
        setAmountOutMin(trades[0].minimumAmountOut(slippageTolerance));
      } else if (exact === "out") {
        setAmountInMax(trades[0].maximumAmountIn(slippageTolerance));
      }
    }
  }, [slippageTolerance, amountIn, amountOut, trades]);

  const getBalance = async (_token, _account, _contract) => {
    let newBalance;
    if (_token === "ETH") {
      newBalance = await selectedProvider.getBalance(_account);
    } else {
      newBalance = await makeCall("balanceOf", _contract, [_account]);
    }
    return newBalance;
  };

  const getAccountInfo = async () => {
    if (tokens) {
      const accountList = await selectedProvider.listAccounts();

      if (tokenIn) {
        const tempContractIn = new ethers.Contract(tokens[tokenIn].address, erc20Abi, selectedProvider);
        const newBalanceIn = await getBalance(tokenIn, accountList[0], tempContractIn);
        setBalanceIn(newBalanceIn);

        let allowance;

        if (tokenIn === "ETH") {
          setRouterAllowance();
        } else {
          allowance = await makeCall("allowance", tempContractIn, [accountList[0], ROUTER_ADDRESS]);
          setRouterAllowance(allowance);
        }
      }

      if (tokenOut) {
        const tempContractOut = new ethers.Contract(tokens[tokenOut].address, erc20Abi, selectedProvider);
        const newBalanceOut = await getBalance(tokenOut, accountList[0], tempContractOut);
        setBalanceOut(newBalanceOut);
      }
    }
  };

  usePoller(getAccountInfo, 6000);

  const route = trades
    ? trades.length > 0
      ? trades[0].route.path.map(function (item) {
          return item.symbol;
        })
      : []
    : [];

  const updateRouterAllowance = async newAllowance => {
    setApproving(true);
    try {
      const tempContract = new ethers.Contract(tokens[tokenIn].address, erc20Abi, signer);
      const result = await makeCall("approve", tempContract, [ROUTER_ADDRESS, newAllowance]);
      console.log(result);
      setApproving(false);
      return true;
    } catch (e) {
      notification.open({
        message: "Approval unsuccessful",
        description: `Error: ${e.message}`,
      });
    }
  };

  const approveRouter = async () => {
    const approvalAmount =
      exact === "in"
        ? ethers.utils.hexlify(ethers.utils.parseUnits(amountIn.toString(), tokens[tokenIn].decimals))
        : amountInMax.raw.toString();
    console.log(approvalAmount);
    const approval = updateRouterAllowance(approvalAmount);
    if (approval) {
      notification.open({
        message: "Token transfer approved",
        description: `You can now swap up to ${amountIn} ${tokenIn}`,
      });
    }
  };

  const removeRouterAllowance = async () => {
    const approvalAmount = ethers.utils.hexlify(0);
    console.log(approvalAmount);
    const removal = updateRouterAllowance(approvalAmount);
    if (removal) {
      notification.open({
        message: "Token approval removed",
        description: `The router is no longer approved for ${tokenIn}`,
      });
    }
  };

  const executeSwap = async () => {
    setSwapping(true);
    try {
      let args;
      const metadata = {};

      let call;
      const deadline = Math.floor(Date.now() / 1000) + timeLimit;
      const path = trades[0].route.path.map(function (item) {
        return item.address;
      });
      console.log(path);
      const accountList = await selectedProvider.listAccounts();
      const address = accountList[0];

      if (exact === "in") {
        const _amountIn = ethers.utils.hexlify(ethers.utils.parseUnits(amountIn.toString(), tokens[tokenIn].decimals));
        const _amountOutMin = ethers.utils.hexlify(ethers.BigNumber.from(amountOutMin.raw.toString()));
        if (tokenIn === "ETH") {
          call = "swapExactETHForTokens";
          args = [_amountOutMin, path, address, deadline];
          metadata.value = _amountIn;
        } else {
          call = tokenOut === "ETH" ? "swapExactTokensForETH" : "swapExactTokensForTokens";
          args = [_amountIn, _amountOutMin, path, address, deadline];
        }
      } else if (exact === "out") {
        const _amountOut = ethers.utils.hexlify(
          ethers.utils.parseUnits(amountOut.toString(), tokens[tokenOut].decimals),
        );
        const _amountInMax = ethers.utils.hexlify(ethers.BigNumber.from(amountInMax.raw.toString()));
        if (tokenIn === "ETH") {
          call = "swapETHForExactTokens";
          args = [_amountOut, path, address, deadline];
          metadata.value = _amountInMax;
        } else {
          call = tokenOut === "ETH" ? "swapTokensForExactETH" : "swapTokensForExactTokens";
          args = [_amountOut, _amountInMax, path, address, deadline];
        }
      }
      console.log(call, args, metadata);
      const result = await makeCall(call, routerContract, args, metadata);
      console.log(result);
      notification.open({
        message: "Swap complete ?",
        description: (
          <>
            <Text>{`Swapped ${tokenIn} for ${tokenOut}, transaction: `}</Text>
            <Text copyable>{result.hash}</Text>
          </>
        ),
      });
      setSwapping(false);
    } catch (e) {
      console.log(e);
      setSwapping(false);
      notification.open({
        message: "Swap unsuccessful",
        description: `Error: ${e.message}`,
      });
    }
  };

  const showSwapModal = () => {
    setSwapModalVisible(true);
  };

  const handleSwapModalOk = () => {
    setSwapModalVisible(false);
    executeSwap();
  };

  const handleSwapModalCancel = () => {
    setSwapModalVisible(false);
  };

  const insufficientBalance = balanceIn
    ? parseFloat(ethers.utils.formatUnits(balanceIn, tokens[tokenIn].decimals)) < amountIn
    : null;
  const inputIsToken = tokenIn !== "ETH";
  const insufficientAllowance = !inputIsToken
    ? false
    : routerAllowance
    ? parseFloat(ethers.utils.formatUnits(routerAllowance, tokens[tokenIn].decimals)) < amountIn
    : null;
  const formattedBalanceIn = balanceIn
    ? parseFloat(ethers.utils.formatUnits(balanceIn, tokens[tokenIn].decimals)).toPrecision(6)
    : null;
  const formattedBalanceOut = balanceOut
    ? parseFloat(ethers.utils.formatUnits(balanceOut, tokens[tokenOut].decimals)).toPrecision(6)
    : null;

  const metaIn =
    tokens && tokenList && tokenIn
      ? tokenList.filter(function (t) {
          return t.address === tokens[tokenIn].address;
        })[0]
      : null;
  const metaOut =
    tokens && tokenList && tokenOut
      ? tokenList.filter(function (t) {
          return t.address === tokens[tokenOut].address;
        })[0]
      : null;

  const cleanIpfsURI = uri => {
    try {
      return uri.replace("ipfs://", "https://ipfs.io/ipfs/");
    } catch (e) {
      console.log(e, uri);
      return uri;
    }
  };

  const logoIn = metaIn ? cleanIpfsURI(metaIn.logoURI) : null;
  const logoOut = metaOut ? cleanIpfsURI(metaOut.logoURI) : null;

  const rawPrice = trades && trades[0] ? trades[0].executionPrice : null;
  const price = rawPrice ? rawPrice.toSignificant(7) : null;
  const priceDescription = rawPrice
    ? invertPrice
      ? `${rawPrice.invert().toSignificant(7)} ${tokenIn} per ${tokenOut}`
      : `${price} ${tokenOut} per ${tokenIn}`
    : null;

  const priceWidget = (
    <Space>
      <Text type="secondary">{priceDescription}</Text>
      <Button
        type="text"
        onClick={() => {
          setInvertPrice(!invertPrice);
        }}
      >
        <RetweetOutlined />
      </Button>
    </Space>
  );

  const swapModal = (
    <Modal title="Confirm swap" visible={swapModalVisible} onOk={handleSwapModalOk} onCancel={handleSwapModalCancel}>
      <Row>
        <Space>
          <img src={logoIn} alt={tokenIn} width="30" />
          {amountIn}
          {tokenIn}
        </Space>
      </Row>
      <Row justify="center" align="middle" style={{ width: 30 }}>
        <span>↓</span>
      </Row>
      <Row>
        <Space>
          <img src={logoOut} alt={tokenOut} width="30" />
          {amountOut}
          {tokenOut}
        </Space>
      </Row>
      <Divider />
      <Row>{priceWidget}</Row>
      <Row>
        {trades && ((amountOutMin && exact === "in") || (amountInMax && exact === "out"))
          ? exact === "in"
            ? `Output is estimated. You will receive at least ${amountOutMin.toSignificant(
                6,
              )} ${tokenOut} or the transaction will revert.`
            : `Input is estimated. You will sell at most ${amountInMax.toSignificant(
                6,
              )} ${tokenIn} or the transaction will revert.`
          : null}
      </Row>
    </Modal>
  );

  return (
    <Card
      title={
        <Space>
          <img src="https://ipfs.io/ipfs/QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg" width="40" alt="uniswapLogo" />
          <Typography>Uniswapper</Typography>
        </Space>
      }
      extra={
        <Button
          type="text"
          onClick={() => {
            setSettingsVisible(true);
          }}
        >
          <SettingOutlined />
        </Button>
      }
    >
      <Space direction="vertical">
        <Row justify="center" align="middle">
          <Card
            size="small"
            type="inner"
            title={`From${exact === "out" && tokenIn && tokenOut ? " (estimate)" : ""}`}
            extra={
              <>
                <img src={logoIn} alt={tokenIn} width="30" />
                <Button
                  type="link"
                  onClick={() => {
                    setAmountOut();
                    setAmountIn(ethers.utils.formatUnits(balanceIn, tokens[tokenIn].decimals));
                    setAmountOutMin();
                    setAmountInMax();
                    setExact("in");
                  }}
                >
                  {formattedBalanceIn}
                </Button>
              </>
            }
            style={{ width: 400, textAlign: "left" }}
          >
            <InputNumber
              style={{ width: "160px" }}
              min={0}
              size="large"
              value={amountIn}
              onChange={e => {
                setAmountOut();
                setTrades();
                setAmountIn(e);
                setExact("in");
              }}
            />
            <Select
              showSearch
              value={tokenIn}
              style={{ width: "120px" }}
              size="large"
              bordered={false}
              defaultValue={defaultToken}
              onChange={value => {
                console.log(value);
                if (value === tokenOut) {
                  console.log("switch!", tokenIn);
                  setTokenOut(tokenIn);
                  setAmountOut(amountIn);
                  setBalanceOut(balanceIn);
                }
                setTokenIn(value);
                setTrades();
                setAmountIn();
                setExact("out");
                setBalanceIn();
              }}
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              optionFilterProp="children"
            >
              {tokenList.map(token => (
                <Option key={token.symbol} value={token.symbol}>
                  {token.symbol}
                </Option>
              ))}
            </Select>
          </Card>
        </Row>
        <Row justify="center" align="middle">
          <Tooltip title={route.join("->")}>
            <span>↓</span>
          </Tooltip>
        </Row>
        <Row justify="center" align="middle">
          <Card
            size="small"
            type="inner"
            title={`To${exact === "in" && tokenIn && tokenOut ? " (estimate)" : ""}`}
            extra={
              <>
                <img src={logoOut} width="30" alt={tokenOut} />
                <Button type="text">{formattedBalanceOut}</Button>
              </>
            }
            style={{ width: 400, textAlign: "left" }}
          >
            <InputNumber
              style={{ width: "160px" }}
              size="large"
              min={0}
              value={amountOut}
              onChange={e => {
                setAmountOut(e);
                setAmountIn();
                setTrades();
                setExact("out");
              }}
            />
            <Select
              showSearch
              value={tokenOut}
              style={{ width: "120px" }}
              size="large"
              bordered={false}
              onChange={value => {
                console.log(value, tokenIn, tokenOut);
                if (value === tokenIn) {
                  console.log("switch!", tokenOut);
                  setTokenIn(tokenOut);
                  setAmountIn(amountOut);
                  setBalanceIn(balanceOut);
                }
                setTokenOut(value);
                setExact("in");
                setAmountOut();
                setTrades();
                setBalanceOut();
              }}
              filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
              optionFilterProp="children"
            >
              {tokenList.map(token => (
                <Option key={token.symbol} value={token.symbol}>
                  {token.symbol}
                </Option>
              ))}
            </Select>
          </Card>
        </Row>
        <Row justify="center" align="middle">
          {priceDescription ? priceWidget : null}
        </Row>
        <Row justify="center" align="middle">
          <Space>
            {inputIsToken ? (
              <Button size="large" loading={approving} disabled={!insufficientAllowance} onClick={approveRouter}>
                {!insufficientAllowance && amountIn && amountOut ? "Approved" : "Approve"}
              </Button>
            ) : null}
            <Button
              size="large"
              loading={swapping}
              disabled={insufficientAllowance || insufficientBalance || !amountIn || !amountOut}
              onClick={showSwapModal}
            >
              {insufficientBalance ? "Insufficient balance" : "Swap!"}
            </Button>
            {swapModal}
          </Space>
        </Row>
      </Space>
      <Drawer
        visible={settingsVisible}
        onClose={() => {
          setSettingsVisible(false);
        }}
        width={500}
      >
        <Descriptions title="Details" column={1} style={{ textAlign: "left" }}>
          <Descriptions.Item label="blockNumber">{blockNumber}</Descriptions.Item>
          <Descriptions.Item label="routerAllowance">
            <Space>
              {routerAllowance ? ethers.utils.formatUnits(routerAllowance, tokens[tokenIn].decimals) : null}
              {routerAllowance > 0 ? <Button onClick={removeRouterAllowance}>Remove Allowance</Button> : null}
            </Space>
          </Descriptions.Item>
          <Descriptions.Item label="route">{route.join("->")}</Descriptions.Item>
          <Descriptions.Item label="exact">{exact}</Descriptions.Item>
          <Descriptions.Item label="bestPrice">
            {trades ? (trades.length > 0 ? trades[0].executionPrice.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="nextMidPrice">
            {trades ? (trades.length > 0 ? trades[0].nextMidPrice.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="priceImpact">
            {trades ? (trades.length > 0 ? trades[0].priceImpact.toSignificant(6) : null) : null}
          </Descriptions.Item>
          <Descriptions.Item label="slippageTolerance">
            <InputNumber
              defaultValue={defaultSlippage}
              min={0}
              max={100}
              precision={2}
              formatter={value => `${value}%`}
              parser={value => value.replace("%", "")}
              onChange={value => {
                console.log(value);

                const slippagePercent = new Percent(Math.round(value * 100).toString(), "10000");
                setSlippageTolerance(slippagePercent);
              }}
            />
          </Descriptions.Item>
          <Descriptions.Item label="amountInMax">{amountInMax ? amountInMax.toExact() : null}</Descriptions.Item>
          <Descriptions.Item label="amountOutMin">{amountOutMin ? amountOutMin.toExact() : null}</Descriptions.Item>
          <Descriptions.Item label="timeLimitInSeconds">
            <InputNumber
              min={0}
              max={3600}
              defaultValue={defaultTimeLimit}
              onChange={value => {
                console.log(value);
                setTimeLimit(value);
              }}
            />
          </Descriptions.Item>
        </Descriptions>
      </Drawer>
    </Card>
  );
}
Example #20
Source File: index.js    From online-test-platform with Apache License 2.0 4 votes vote down vote up
render() {
    const { setting } = this.props;
    const { navTheme, primaryColor, layout, colorWeak } = setting;
    const { collapse } = this.state;
    return (
      <Drawer
        visible={collapse}
        width={300}
        onClose={this.togglerContent}
        placement="right"
        handler={
          <div className={styles.handle} onClick={this.togglerContent}>
            <Icon
              type={collapse ? 'close' : 'setting'}
              style={{
                color: '#fff',
                fontSize: 20,
              }}
            />
          </div>
        }
        style={{
          zIndex: 999,
        }}
      >
        <div className={styles.content}>
          <Body title={formatMessage({ id: 'app.setting.pagestyle' })}>
            <BlockCheckbox
              list={[
                {
                  key: 'dark',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg',
                  title: formatMessage({ id: 'app.setting.pagestyle.dark' }),
                },
                {
                  key: 'light',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg',
                  title: formatMessage({ id: 'app.setting.pagestyle.light' }),
                },
              ]}
              value={navTheme}
              onChange={value => this.changeSetting('navTheme', value)}
            />
          </Body>

          <ThemeColor
            title={formatMessage({ id: 'app.setting.themecolor' })}
            value={primaryColor}
            onChange={color => this.changeSetting('primaryColor', color)}
          />

          <Divider />

          <Body title={formatMessage({ id: 'app.setting.navigationmode' })}>
            <BlockCheckbox
              list={[
                {
                  key: 'sidemenu',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg',
                  title: formatMessage({ id: 'app.setting.sidemenu' }),
                },
                {
                  key: 'topmenu',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg',
                  title: formatMessage({ id: 'app.setting.topmenu' }),
                },
              ]}
              value={layout}
              onChange={value => this.changeSetting('layout', value)}
            />
          </Body>

          <List
            split={false}
            dataSource={this.getLayoutSetting()}
            renderItem={this.renderLayoutSettingItem}
          />

          <Divider />

          <Body title={formatMessage({ id: 'app.setting.othersettings' })}>
            <List
              split={false}
              renderItem={this.renderLayoutSettingItem}
              dataSource={[
                {
                  title: formatMessage({ id: 'app.setting.weakmode' }),
                  action: (
                    <Switch
                      size="small"
                      checked={!!colorWeak}
                      onChange={checked => this.changeSetting('colorWeak', checked)}
                    />
                  ),
                },
              ]}
            />
          </Body>
          <Divider />
          <CopyToClipboard
            text={JSON.stringify(omit(setting, ['colorWeak']), null, 2)}
            onCopy={() => message.success(formatMessage({ id: 'app.setting.copyinfo' }))}
          >
            <Button block icon="copy">
              {formatMessage({ id: 'app.setting.copy' })}
            </Button>
          </CopyToClipboard>
          <Alert
            type="warning"
            className={styles.productionHint}
            message={
              <div>
                {formatMessage({ id: 'app.setting.production.hint' })}{' '}
                <a
                  href="https://u.ant.design/pro-v2-default-settings"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  src/defaultSettings.js
                </a>
              </div>
            }
          />
        </div>
      </Drawer>
    );
  }
Example #21
Source File: Swap.jsx    From moonshot with MIT License 4 votes vote down vote up
function Swap({ selectedProvider, tokenListURI }) {

  const [tokenIn, setTokenIn] = useState(defaultToken)
  const [tokenOut, setTokenOut] = useState(defaultTokenOut)
  const [exact, setExact] = useState()
  const [amountIn, setAmountIn] = useState()
  const [amountInMax, setAmountInMax] = useState()
  const [amountOut, setAmountOut] = useState()
  const [amountOutMin, setAmountOutMin] = useState()
  const [trades, setTrades] = useState()
  const [routerAllowance, setRouterAllowance] = useState()
  const [balanceIn, setBalanceIn] = useState()
  const [balanceOut, setBalanceOut] = useState()
  const [slippageTolerance, setSlippageTolerance] = useState(new Percent(Math.round(defaultSlippage*100).toString(), "10000"))
  const [timeLimit, setTimeLimit] = useState(defaultTimeLimit)
  const [swapping, setSwapping] = useState(false)
  const [approving, setApproving] = useState(false)
  const [settingsVisible, setSettingsVisible] = useState(false)
  const [swapModalVisible, setSwapModalVisible] = useState(false)

  const [tokenList, setTokenList] = useState([])

  const [tokens, setTokens] = useState()

  const [invertPrice, setInvertPrice] = useState(false)

  let blockNumber = useBlockNumber(selectedProvider, 3000)

  let signer = selectedProvider.getSigner()
  let routerContract = new ethers.Contract(ROUTER_ADDRESS, IUniswapV2Router02ABI, signer);

  let _tokenListUri = tokenListURI ? tokenListURI : 'https://gateway.ipfs.io/ipns/tokens.uniswap.org'

  const debouncedAmountIn = useDebounce(amountIn, 500);
  const debouncedAmountOut = useDebounce(amountOut, 500);

  const activeChainId = (process.env.REACT_APP_NETWORK === 'kovan' ? ChainId.KOVAN : ChainId.MAINNET)

  useEffect(() => {
    const getTokenList = async () => {
      console.log(_tokenListUri)
      try {
      let tokenList = await fetch(_tokenListUri)
      let tokenListJson = await tokenList.json()
      let filteredTokens = tokenListJson.tokens.filter(function (t) {
        return t.chainId === activeChainId
      })
      let ethToken = WETH[activeChainId]
      ethToken.name = 'Ethereum'
      ethToken.symbol = 'ETH'
      ethToken.logoURI = "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
      let _tokenList = [ethToken, ...filteredTokens]
      setTokenList(_tokenList)
      let _tokens = tokenListToObject(_tokenList)
      setTokens(_tokens)
    } catch (e) {
      console.log(e)
    }
    }
    getTokenList()
  },[tokenListURI])

  const getTrades = async () => {
    if(tokenIn && tokenOut && (amountIn || amountOut)) {

    let pairs = (arr) => arr.map( (v, i) => arr.slice(i + 1).map(w => [v,w]) ).flat();

    let baseTokens = tokenList.filter(function (t) {
      return ['DAI', 'USDC', 'USDT', 'COMP', 'ETH', 'MKR', 'LINK', tokenIn, tokenOut].includes(t.symbol)
    }).map((el) => {
      return new Token(el.chainId, el.address, el.decimals, el.symbol, el.name)
    })

    let listOfPairwiseTokens = pairs(baseTokens)

    const getPairs = async (list) => {

      let listOfPromises = list.map(item => Fetcher.fetchPairData(item[0], item[1], selectedProvider))
      return Promise.all(listOfPromises.map(p => p.catch(() => undefined)));
    }

    let listOfPairs = await getPairs(listOfPairwiseTokens)

    let bestTrade

    if(exact === 'in') {
      setAmountInMax()
      bestTrade = Trade.bestTradeExactIn(
      listOfPairs.filter(item => item),
      new TokenAmount(tokens[tokenIn], parseUnits(amountIn.toString(), tokens[tokenIn].decimals)),
      tokens[tokenOut], { maxNumResults: 3, maxHops: 1 })
      if(bestTrade[0]) {
        setAmountOut(bestTrade[0].outputAmount.toSignificant(6))
      } else { setAmountOut() }
    } else if (exact === 'out') {
      setAmountOutMin()
      bestTrade = Trade.bestTradeExactOut(
      listOfPairs.filter(item => item),
      tokens[tokenIn],
      new TokenAmount(tokens[tokenOut], parseUnits(amountOut.toString(), tokens[tokenOut].decimals)),
     { maxNumResults: 3, maxHops: 1 })
      if(bestTrade[0]) {
        setAmountIn(bestTrade[0].inputAmount.toSignificant(6))
      } else { setAmountIn() }
    }

    setTrades(bestTrade)

    console.log(bestTrade)

  }
  }

  useEffect(() => {
      getTrades()
  },[tokenIn, tokenOut, debouncedAmountIn, debouncedAmountOut, slippageTolerance, selectedProvider])

  useEffect(() => {
    if(trades && trades[0]) {
      if(exact === 'in') {
        setAmountOutMin(trades[0].minimumAmountOut(slippageTolerance))
      } else if (exact === 'out') {
        setAmountInMax(trades[0].maximumAmountIn(slippageTolerance))
      }
    }
  }, [slippageTolerance, amountIn, amountOut, trades])

  const getBalance = async (_token, _account, _contract) => {

    let newBalance
    if(_token === 'ETH') {
      newBalance = await selectedProvider.getBalance(_account)
    } else {
      newBalance = await makeCall('balanceOf', _contract, [_account])
    }
    return newBalance
  }

  const getAccountInfo = async () => {

    if(tokens) {

      let accountList = await selectedProvider.listAccounts()

      if(tokenIn) {
        let tempContractIn = new ethers.Contract(tokens[tokenIn].address, erc20Abi, selectedProvider);
        let newBalanceIn = await getBalance(tokenIn, accountList[0], tempContractIn)
        setBalanceIn(newBalanceIn)

        let allowance

        if(tokenIn === 'ETH') {
          setRouterAllowance()
        } else {
          allowance = await makeCall('allowance',tempContractIn,[accountList[0],ROUTER_ADDRESS])
          setRouterAllowance(allowance)
        }
        }

      if(tokenOut) {
        let tempContractOut = new ethers.Contract(tokens[tokenOut].address, erc20Abi, selectedProvider);
        let newBalanceOut = await getBalance(tokenOut, accountList[0], tempContractOut)
        setBalanceOut(newBalanceOut)
      }
    }
  }

  usePoller(getAccountInfo, 6000)

  let route = trades ? (trades.length > 0 ? trades[0].route.path.map(function(item) {
    return item['symbol'];
  }) : []) : []

  const updateRouterAllowance = async (newAllowance) => {
    setApproving(true)
    try {
    let tempContract = new ethers.Contract(tokens[tokenIn].address, erc20Abi, signer);
    let result = await makeCall('approve', tempContract, [ROUTER_ADDRESS, newAllowance])
    console.log(result)
    setApproving(false)
    return true
  } catch(e) {
      notification.open({
        message: 'Approval unsuccessful',
        description:
        `Error: ${e.message}`,
      });
    }
  }

  const approveRouter = async () => {
    let approvalAmount = exact === 'in' ? ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals)) : amountInMax.raw.toString()
    console.log(approvalAmount)
    let approval = updateRouterAllowance(approvalAmount)
    if(approval) {
      notification.open({
        message: 'Token transfer approved',
        description:
        `You can now swap up to ${amountIn} ${tokenIn}`,
      });
    }
  }

  const removeRouterAllowance = async () => {
    let approvalAmount = ethers.utils.hexlify(0)
    console.log(approvalAmount)
    let removal = updateRouterAllowance(approvalAmount)
    if(removal) {
      notification.open({
        message: 'Token approval removed',
        description:
        `The router is no longer approved for ${tokenIn}`,
      });
    }
  }

  const executeSwap = async () => {
    setSwapping(true)
    try {
      let args
      let metadata = {}

      let call
      let deadline = Math.floor(Date.now() / 1000) + timeLimit
      let path = trades[0].route.path.map(function(item) {
        return item['address'];
      })
      console.log(path)
      let accountList = await selectedProvider.listAccounts()
      let address = accountList[0]

      if (exact === 'in') {
        let _amountIn = ethers.utils.hexlify(parseUnits(amountIn.toString(), tokens[tokenIn].decimals))
        let _amountOutMin = ethers.utils.hexlify(ethers.BigNumber.from(amountOutMin.raw.toString()))
        if (tokenIn === 'ETH') {
          call = 'swapExactETHForTokens'
          args = [_amountOutMin, path, address, deadline]
          metadata['value'] = _amountIn
        } else {
          call = tokenOut === 'ETH' ? 'swapExactTokensForETH' : 'swapExactTokensForTokens'
          args = [_amountIn, _amountOutMin, path, address, deadline]
        }
      } else if (exact === 'out') {
        let _amountOut = ethers.utils.hexlify(parseUnits(amountOut.toString(), tokens[tokenOut].decimals))
        let _amountInMax = ethers.utils.hexlify(ethers.BigNumber.from(amountInMax.raw.toString()))
        if (tokenIn === 'ETH') {
          call = 'swapETHForExactTokens'
          args = [_amountOut, path, address, deadline]
          metadata['value'] = _amountInMax
        } else {
          call = tokenOut === 'ETH' ? 'swapTokensForExactETH' : 'swapTokensForExactTokens'
          args = [_amountOut, _amountInMax, path, address, deadline]
        }
      }
      console.log(call, args, metadata)
      let result = await makeCall(call, routerContract, args, metadata)
      console.log(result)
      notification.open({
        message: 'Swap complete ?',
        description:
        <><Text>{`Swapped ${tokenIn} for ${tokenOut}, transaction: `}</Text><Text copyable>{result.hash}</Text></>,
      });
      setSwapping(false)
  } catch (e) {
    console.log(e)
    setSwapping(false)
    notification.open({
      message: 'Swap unsuccessful',
      description:
      `Error: ${e.message}`,
    });
  }
  }

  const showSwapModal = () => {
    setSwapModalVisible(true);
  };

  const handleSwapModalOk = () => {
    setSwapModalVisible(false);
    executeSwap()
  };

  const handleSwapModalCancel = () => {
    setSwapModalVisible(false);
  };

  let insufficientBalance = balanceIn ? parseFloat(formatUnits(balanceIn,tokens[tokenIn].decimals)) < amountIn : null
  let inputIsToken = tokenIn !== 'ETH'
  let insufficientAllowance = !inputIsToken ? false : routerAllowance ? parseFloat(formatUnits(routerAllowance,tokens[tokenIn].decimals)) < amountIn : null
  let formattedBalanceIn = balanceIn?parseFloat(formatUnits(balanceIn,tokens[tokenIn].decimals)).toPrecision(6):null
  let formattedBalanceOut = balanceOut?parseFloat(formatUnits(balanceOut,tokens[tokenOut].decimals)).toPrecision(6):null

  let metaIn = tokens && tokenList && tokenIn ? tokenList.filter(function (t) {
    return t.address === tokens[tokenIn].address
  })[0] : null
  let metaOut = tokens && tokenList && tokenOut ? tokenList.filter(function (t) {
    return t.address === tokens[tokenOut].address
    })[0] : null

  const cleanIpfsURI = (uri) => {
    try {
    return (uri).replace('ipfs://','https://ipfs.io/ipfs/')
  } catch(e) {
    console.log(e, uri)
    return uri
  }
  }

  let logoIn = metaIn?cleanIpfsURI(metaIn.logoURI):null
  let logoOut = metaOut?cleanIpfsURI(metaOut.logoURI):null

  let rawPrice = trades&&trades[0]?trades[0].executionPrice:null
  let price = rawPrice?rawPrice.toSignificant(7):null
  let priceDescription = rawPrice ? (invertPrice ? `${(rawPrice.invert()).toSignificant(7)} ${tokenIn} per ${tokenOut}` : `${price} ${tokenOut} per ${tokenIn}`) : null

  let priceWidget = (
    <Space>
    <Text type="secondary">{priceDescription}</Text>
    <Button type="text" onClick={() => {setInvertPrice(!invertPrice)}}><RetweetOutlined /></Button>
    </Space>
  )

  let swapModal = (
    <Modal title="Confirm swap" visible={swapModalVisible} onOk={handleSwapModalOk} onCancel={handleSwapModalCancel}>
      <Row><Space><img src={logoIn} alt={tokenIn} width='30'/>{amountIn}{tokenIn}</Space></Row>
      <Row justify='center' align='middle' style={{width:30}}><span>↓</span></Row>
      <Row><Space><img src={logoOut} alt={tokenOut} width='30'/>{amountOut}{tokenOut}</Space></Row>
      <Divider/>
      <Row>{priceWidget}</Row>
      <Row>{trades&&((amountOutMin && exact==='in') || (amountInMax && exact==='out'))?(exact==='in'?`Output is estimated. You will receive at least ${amountOutMin.toSignificant(6)} ${tokenOut} or the transaction will revert.`:`Input is estimated. You will sell at most ${amountInMax.toSignificant(6)} ${tokenIn} or the transaction will revert.`):null}</Row>
    </Modal>
  )

  return (
    <Card title={<Space><img src="https://ipfs.io/ipfs/QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg" width='40' alt='uniswapLogo'/><Typography>Uniswapper</Typography></Space>} extra={<Button type="text" onClick={() => {setSettingsVisible(true)}}><SettingOutlined /></Button>}>
    <Space direction="vertical">
    <Row justify="center" align="middle">
    <Card size="small" type="inner" title={`From${exact==='out' && tokenIn && tokenOut?' (estimate)':''}`} extra={<><img src={logoIn} alt={tokenIn} width='30'/><Button type="link" onClick={() => {
      setAmountOut()
      setAmountIn(formatUnits(balanceIn,tokens[tokenIn].decimals))
      setAmountOutMin()
      setAmountInMax()
      setExact('in')
    }}>{formattedBalanceIn}</Button></>} style={{ width: 400, textAlign: 'left' }}>
      <InputNumber style={{width: '160px'}} min={0} size={'large'} value={amountIn} onChange={(e) => {
        setAmountOut()
        setTrades()
        setAmountIn(e)
        setExact('in')
      }}/>
      <Select showSearch value={tokenIn} style={{width: '120px'}} size={'large'} bordered={false} defaultValue={defaultToken} onChange={(value) => {
        console.log(value)
        if(value===tokenOut) {
          console.log('switch!', tokenIn)
          setTokenOut(tokenIn)
          setAmountOut(amountIn)
          setBalanceOut(balanceIn)
        }
        setTokenIn(value)
        setTrades()
        setAmountIn()
        setExact('out')
        setBalanceIn()
      }} filterOption={(input, option) =>
      option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
      } optionFilterProp="children">
      {tokenList.map(token => (
        <Option key={token.symbol} value={token.symbol}>{token.symbol}</Option>
      ))}
      </Select>
    </Card>
    </Row>
    <Row justify="center" align="middle">
      <Tooltip title={route.join("->")}><span>↓</span></Tooltip>
    </Row>
    <Row justify="center" align="middle">
    <Card size="small" type="inner" title={`To${exact==='in' && tokenIn && tokenOut?' (estimate)':''}`} extra={<><img src={logoOut} width='30' alt={tokenOut}/><Button type="text">{formattedBalanceOut}</Button></>} style={{ width: 400, textAlign: 'left' }}>
      <InputNumber style={{width: '160px'}} size={'large'} min={0} value={amountOut} onChange={(e) => {
        setAmountOut(e)
        setAmountIn()
        setTrades()
        setExact('out')
      }}/>
      <Select showSearch value={tokenOut} style={{width: '120px'}} size={'large'} bordered={false} onChange={(value) => {
        console.log(value, tokenIn, tokenOut)
        if(value===tokenIn) {
          console.log('switch!', tokenOut)
          setTokenIn(tokenOut)
          setAmountIn(amountOut)
          setBalanceIn(balanceOut)
        }
        setTokenOut(value)
        setExact('in')
        setAmountOut()
        setTrades()
        setBalanceOut()
      }} filterOption={(input, option) =>
      option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
      } optionFilterProp="children">
      {tokenList.map(token => (
        <Option key={token.symbol} value={token.symbol}>{token.symbol}</Option>
      ))}
      </Select>
    </Card>
    </Row>
    <Row justify="center" align="middle">
      {priceDescription?priceWidget:null}
    </Row>
    <Row justify="center" align="middle">
    <Space>
      {inputIsToken?<Button size="large" loading={approving} disabled={!insufficientAllowance} onClick={approveRouter}>{(!insufficientAllowance&&amountIn&&amountOut)?'Approved':'Approve'}</Button>:null}
      <Button size="large" loading={swapping} disabled={insufficientAllowance || insufficientBalance || !amountIn || !amountOut} onClick={showSwapModal}>{insufficientBalance?'Insufficient balance':'Swap!'}</Button>
      {swapModal}
    </Space>
    </Row>
    </Space>
    <Drawer visible={settingsVisible} onClose={() => { setSettingsVisible(false) }} width={500}>
    <Descriptions title="Details" column={1} style={{textAlign: 'left'}}>
      <Descriptions.Item label="blockNumber">{blockNumber}</Descriptions.Item>
      <Descriptions.Item label="routerAllowance"><Space>{routerAllowance?formatUnits(routerAllowance,tokens[tokenIn].decimals):null}{routerAllowance>0?<Button onClick={removeRouterAllowance}>Remove Allowance</Button>:null}</Space></Descriptions.Item>
      <Descriptions.Item label="route">{route.join("->")}</Descriptions.Item>
      <Descriptions.Item label="exact">{exact}</Descriptions.Item>
      <Descriptions.Item label="bestPrice">{trades ? (trades.length > 0 ? trades[0].executionPrice.toSignificant(6) : null) : null}</Descriptions.Item>
      <Descriptions.Item label="nextMidPrice">{trades ? (trades.length > 0 ? trades[0].nextMidPrice.toSignificant(6) : null) : null}</Descriptions.Item>
      <Descriptions.Item label="priceImpact">{trades ? (trades.length > 0 ? trades[0].priceImpact.toSignificant(6) : null) : null}</Descriptions.Item>
      <Descriptions.Item label="slippageTolerance">{<InputNumber
        defaultValue={defaultSlippage}
        min={0}
        max={100}
        precision={2}
        formatter={value => `${value}%`}
        parser={value => value.replace('%', '')}
        onChange={(value) => {
          console.log(value)

         let slippagePercent = new Percent(Math.round(value*100).toString(), "10000")
         setSlippageTolerance(slippagePercent)
       }}
      />}</Descriptions.Item>
      <Descriptions.Item label="amountInMax">{amountInMax?amountInMax.toExact():null}</Descriptions.Item>
      <Descriptions.Item label="amountOutMin">{amountOutMin?amountOutMin.toExact():null}</Descriptions.Item>
      <Descriptions.Item label="timeLimitInSeconds">{<InputNumber
              min={0}
              max={3600}
              defaultValue={defaultTimeLimit}
              onChange={(value) => {
              console.log(value)
              setTimeLimit(value)
             }}
            />}</Descriptions.Item>
    </Descriptions>
    </Drawer>
    </Card>
  )

}
Example #22
Source File: MainLayout.js    From bonded-stablecoin-ui with MIT License 4 votes vote down vote up
MainLayout = ({ children, walletModalVisible, setWalletModalVisibility }) => {
  const { pathname, search, hash } = useLocation();
  const dispatch = useDispatch();
  const [width] = useWindowSize();
  const { t } = useTranslation();
  const [activeMenu, setActiveMenu] = useState(false);
  const {visitedBefore, lang} = useSelector(state => state.settings);
  const loading = useSelector(state => state.active.loading);

  useEffect(() => {
    const unlisten = historyInstance.listen((location, action) => {
      if(!location.pathname.includes("governance")){
        window.scrollTo(0, 0);
      }
      if (action === "PUSH" || action === "POP") {
        ReactGA.pageview(location.pathname);
      }
    });
    ReactGA.pageview(pathname);
    return () => {
      unlisten();
    };
  }, []);

  useEffect(()=>{
    if (search && !visitedBefore){
      const [name, address] = search.slice(1).split("=");
      if (name === "r" && address && obyte.utils.isValidAddress(address)){
        dispatch(addReferrer(address));
      } 
      dispatch(firstVisit());
      if (!hash){
        historyInstance.replace(pathname, { search: undefined })
      } 
    } else if (!visitedBefore){
      dispatch(firstVisit());
    } else if (visitedBefore && search && !hash){
      historyInstance.replace(pathname, { search: undefined })
    }
  }, []);

  const pageIsSingle = pathname.includes("stableplus");

  return (
    <Layout style={{ minHeight: "100vh" }}>
      <Header
        style={{
          background: "#fff",
          paddingLeft: 20,
          paddingRight: 20,
          height: "100%"
        }}
      >
        <Row
          justify={width < 990 ? "space-between" : undefined}
          align="middle"
        >
          <NavLink to={lang !== "en" ? `/${lang}`: "/"} className={styles.navLink}>
            <img className={styles.logo} src={logo} alt="Bonded stablecoins" />

            {width > 440 && <div style={{ paddingLeft: 10 }}>
              <span>Bonded stablecoins</span>
              <sup style={{ fontSize: 8 }}>Beta</sup>
            </div>}
          </NavLink>
        {!pageIsSingle && <>
          {width >= 990 ? (
            <MainMenu pathname={pathname} width={width} mode="horizontal" />
          ) : (
            <div style={{ display: "flex", alignItems: "center" }}>
              <Drawer
                title={
                  <span>
                    Bonded stablecoins <sup style={{ fontSize: 10 }}>Beta</sup>
                  </span>
                }
                placement="left"
                closable={true}
                onClose={() => setActiveMenu(false)}
                visible={activeMenu}
                bodyStyle={{ padding: 0, overflowX: "hidden" }}
              >
                <MainMenu
                  pathname={pathname}
                  onClose={() => setActiveMenu(false)}
                  mode="vertical"
                />
                <div style={{ paddingLeft: 7 }}><SocialIcons size="short" gaLabel="Mobile menu" /></div>
              </Drawer>
              
              {width < 990 && width >= 320 && pathname !== "/" && (
                <WalletOutlined
                  onClick={() => setWalletModalVisibility(true)}
                  className={styles.iconWallet}
                  style={{ marginLeft: "auto" }}
                />
              )}
              <Button onClick={() => setActiveMenu(true)}>{t("main_menu.menu", "Menu")}</Button>
              <div style={{ width: 70, marginLeft: "auto" }}><SelectLanguage /></div>
            </div>
          )}

          {width >= 990 && pathname !== "/" && !langs.find((lang) => "/" + lang.name === pathname) && (
            <div style={{ marginLeft: "auto", display: "flex"}}>
              <SelectWallet />
              <div style={{ width: 70, marginLeft: "auto" }}><SelectLanguage /></div>
            </div>
          )}
        </>}
          {(((pathname === "/" || langs.find((lang) => "/" + lang.name === pathname)) && width >= 990) || pageIsSingle) && <div style={{ width: 70, marginLeft: "auto" }}><SelectLanguage /></div>}
        </Row>
      </Header>

      <Content
        className={styles.content}
        style={
          pathname === "/" || pageIsSingle || langs.find((lang) => "/" + lang.name === pathname) || width < 1240
            ? { padding: 0 }
            : { padding: "20px 20px" }
        }
      >
        <SelectWalletModal
          visible={walletModalVisible}
          onCancel={() => setWalletModalVisibility(false)}
        />
        <Route path="/:lang?/trade/:address?/:tab?" exact>
          <SelectStablecoin />
          {!loading && <Statistics windowWidth={width} />}
        </Route>
        {children !== undefined && children !== null && (
          <div style={{ background: "#fff", padding: 20 }}>
            {children}
          </div>
        )}
      </Content>
      <Footer>
        <SocialIcons centered gaLabel="Footer" />
      </Footer>
    </Layout>
  );
}
Example #23
Source File: index.jsx    From react-sendbird-messenger with GNU General Public License v3.0 4 votes vote down vote up
export function MyMenu({
    closable = false,
    visible = false,
    onClose = () => {},
    handleLogout = () => {},
}) {
    const { isDark, toggleDark } = useDark()
    const { language, changeLanguage } = useI18n()
    const { t } = useTranslation()

    const handleLanguageChange = (value) => {
        changeLanguage(value)
    }

    const handleLogoutButton = () => {
        onClose()
        handleLogout()
    }

    return (
        <Fragment>
            <Drawer
                title={t('src.screens.dashboard.Settings')}
                placement="left"
                closable={closable}
                onClose={onClose}
                visible={visible}
            >
                <Menu
                    style={{
                        borderRight: 'none',
                    }}
                >
                    <Menu.Item
                        style={{
                            backgroundColor: 'transparent',
                        }}
                    >
                        {t('src.screens.dashboard.Profile')}
                    </Menu.Item>
                    <Menu.Item
                        style={{
                            display: 'flex',
                            justifyContent: 'space-between',
                            alignItems: 'center',
                            backgroundColor: 'transparent',
                        }}
                    >
                        {t('src.screens.dashboard.Language')}
                        <div id="my-language">
                            <Select
                                defaultValue={language}
                                style={{
                                    width: 60,
                                    textAlign: 'right',
                                }}
                                bordered={false}
                                showArrow={false}
                                onChange={handleLanguageChange}
                            >
                                <Option value="en">EN</Option>
                                <Option value="vi">VI</Option>
                            </Select>
                        </div>
                    </Menu.Item>
                    <Menu.Item
                        style={{
                            display: 'flex',
                            justifyContent: 'space-between',
                            alignItems: 'center',
                            backgroundColor: 'transparent',
                        }}
                    >
                        {t('src.screens.dashboard.DM')}
                        <Switch
                            size="small"
                            checked={isDark}
                            onClick={toggleDark}
                        />
                    </Menu.Item>
                    <Divider />
                    <Menu.Item
                        style={{
                            backgroundColor: 'transparent',
                        }}
                        onClick={handleLogoutButton}
                    >
                        {t('src.screens.dashboard.LO')}
                    </Menu.Item>
                </Menu>
            </Drawer>
        </Fragment>
    )
}
Example #24
Source File: ViewTicket.js    From Peppermint with GNU General Public License v3.0 4 votes vote down vote up
ViewTicket = (props) => {
  const [visible, setVisible] = useState(false);
  const [issue, setIssue] = useState(props.ticket.issue);
  const [note, setNote] = useState(props.ticket.note);
  const [name, setName] = useState(props.ticket.name);
  const [email, setEmail] = useState(props.ticket.email);
  const [number, setNumber] = useState(props.ticket.number);

  const { TextArea } = Input;

  const { completeTicket } = useContext(GlobalContext);

  const showDrawer = () => {
    setVisible(true);
  };

  const onClose = async () => {
    setVisible(false);
    await update();
  };

  const update = async () => {
    await fetch(`/api/v1/tickets/update`, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + localStorage.getItem("jwt"),
      },
      body: JSON.stringify({
        id: props.ticket._id,
        issue,
        note,
        name,
        email,
        number,
      }),
    }).then((res) => res.json());
  };

  return (
    <div>
      <Button
        type="text"
        size="small"
        key={0}
        onClick={() => {
          showDrawer();
        }}
      >
        View Ticket
      </Button>
      <Drawer
        className="my-drawer"
        placement="right"
        onClose={onClose}
        visible={visible}
        width={600}
      >
        <h2>Client: {props.ticket.client.name}</h2>
        <Space size="middle">
          <Transfer ticket={props.ticket} />
          <Popconfirm
            title="Are you sure you want to complete?"
            onConfirm={() => {
              completeTicket(props.ticket._id);
            }}
          >
            <Button>Complete</Button>
          </Popconfirm>
          <AddInfo client={props.ticket} />
        </Space>
        <Divider />
        <Row>
          <Space>
            <h6>Issue status : {props.ticket.status}</h6>
            <Divider type="vertical" />
            
          </Space>
        </Row>
        <Row>
          <TextArea
            rows={6}
            defaultValue={props.ticket.issue}
            style={{ width: "45%" }}
            placeholder="Issue goes here ..."
            onChange={(e) => setIssue(e.target.value)}
          />
          <TextArea
            defaultValue={props.ticket.note}
            style={{ width: "45%", float: "right", marginLeft: 25 }}
            placeholder="Job notes goes here ..."
            onChange={(e) => setNote(e.target.value)}
          />
        </Row>
        <Divider />
        <h4>Contact Details</h4>
        <h5>
          Contact Name:{" "}
          <Input
            defaultValue={props.ticket.name}
            style={{ width: 250, float: "right" }}
            onChange={(e) => setName(e.target.value)}
          />
        </h5>
        <h5>
          Email:{" "}
          <Input
            defaultValue={props.ticket.email}
            style={{ width: 250, float: "right" }}
            onChange={(e) => setEmail(e.target.value)}
          />
        </h5>
        <h5>
          Number:{" "}
          <Input
            defaultValue={props.ticket.number}
            style={{ width: 250, float: "right" }}
            onChange={(e) => setNumber(e.target.value)}
          />
        </h5>
        <Divider />
        <h4>Time Logged to Ticket</h4>
        <TicketTime ticket={props.ticket} />
      </Drawer>
    </div>
  );
}
Example #25
Source File: nodeAddDrawer.js    From AgileTC with Apache License 2.0 4 votes vote down vote up
NoteAddDrawer = (props) => {
  const { visible, minder, onCancel } = props;
  const [list, setList] = useState([{ id: Date.now() }]); // 因子list
  const [selectVal, setVal] = useState('pariwise');

  // input发上变化
  const inputChange = useCallback((value, id, key) => {
    const newList = list;
    newList.find((item) => item.id === id)[key] = value;
    setList([...newList]);
  });
  // 删除
  const deleteList = (id) => {
    setList(list.filter((item) => item.id !== id));
  };
  // 上放下拉发生变化
  const handleChange = (value) => setVal(value);
  // 确认
  const submit = () => {
    let newList = {};
    list.map((item) => {
      newList[item.key] = item.value;
      return item;
    });
    window.ws.sendMessage('case_design_event', {method:selectVal, nodeId: minder.getSelectedNodes()[0].data.id, message: JSON.stringify(newList)}
      // `4|${selectVal}|${minder.getSelectedNodes()[0].data.id}|${JSON.stringify(newList)}`
    );
    onCancel();
  };

  return (
    <Drawer
      title={`${minder.getSelectedNodes()[0].data.text}`}
      placement="right"
      className="agiletc-note-drawer"
      maskClosable={false}
      onClose={onCancel}
      visible={visible}
      width="500"
    >
      <Row gutter={[0, 20]}>
        <Col span={5} style={{ lineHeight: '32px' }}>
          方法选择:
        </Col>
        <Col span={19}>
          <Select value={selectVal} onChange={handleChange} style={{ width: '100%' }}>
            <Option value="pariwise">pariwise</Option>
          </Select>
        </Col>
      </Row>

      {list.map((item, i) => (
        <Row gutter={[16, 16]} key={item.id}>
          <Col span={8}>
            <Input
              value={item.key}
              placeholder="请输入因子"
              onChange={(e) => inputChange(e.target.value, item.id, 'key')}
            />
          </Col>
          <Col span={list.length > 1 ? 14 : 16}>
            <Input
              value={item.value}
              placeholder="请输入因子取值并以“,”分割"
              onChange={(e) => inputChange(e.target.value, item.id, 'value')}
            />
          </Col>
          {list.length > 1 && (
            <Col span={2} style={{ color: 'red', marginTop: 5 }}>
              <Popconfirm
                title="确认删除?"
                placement="topRight"
                onConfirm={() => deleteList(item.id)}
                onCancel={(e) => console.log(e)}
                okText="确定"
                cancelText="取消"
              >
                <Icon type="delete" />
              </Popconfirm>
            </Col>
          )}
        </Row>
      ))}
      <div style={{ margin: '20px 0 70px' }}>
        <Tooltip
          placement="top"
          title={list.every((item) => item.key && item.value) ? null : '填写完整后方可继续添加'}
        >
          <Button
            type="dashed"
            block
            disabled={!list.every((item) => item.key && item.value)}
            onClick={() => setList([...list, { id: Date.now() }])}
          >
            添加
          </Button>
        </Tooltip>
      </div>
      <div
        style={{
          position: 'absolute',
          right: 0,
          bottom: 0,
          width: '100%',
          borderTop: '1px solid #e9e9e9',
          padding: '10px 16px',
          background: '#fff',
          textAlign: 'right'
        }}
      >
        <Button onClick={onCancel} style={{ marginRight: 8 }}>
          取消
        </Button>
        <Tooltip
          placement="topRight"
          title={list.every((item) => item.key && item.value) ? null : '填写完整后方可确认'}
        >
          <Button
            onClick={submit}
            type="primary"
            disabled={!list.every((item) => item.key && item.value)}
          >
            确认
          </Button>
        </Tooltip>
      </div>
    </Drawer>
  );
}
Example #26
Source File: EventsList.js    From react-portal with MIT License 4 votes vote down vote up
EventsList = props => {
	const [events, setEvents] = useState([]);
	const [editDrawer, setEditDrawer] = useState(false);
	const [eventId, setEventId] = useState(null);
	const [refresh, toggleRefresh] = useState(false);
	const [isLoading, setIsLoading] = useState(false);
	const [allEvents, setAllEvents] = useState([]);

	useEffect(() => {
		(async () => {
			setIsLoading(true);
			try {
				const { data } = await getEventsService();
				setEvents(data.upcomingEvents);
				setAllEvents(data);
				setIsLoading(false);
			} catch (err) {
				_notification("warning", "Error", err.message);
			}
		})();
	}, [refresh]);

	const handleDelete = async id => {
		try {
			const res = await deleteEventsService(id);
			if (res.message === "success") {
				toggleRefresh(!refresh);
				_notification("success", "Success", "Event Deleted");
			} else {
				_notification("warning", "Error", res.message);
			}
		} catch (err) {
			_notification("error", "Error", err.message);
		}
	};

	const handleAddEvent = () => {
		toggleRefresh(!refresh);
	};

	function cancel(e) {
		console.log(e);
	}

	const handleToggleEventStatus = async eventId => {
		try {
			const res = await toggleRegistrationsService({ eid: eventId });
			if (res.message === "success") {
				toggleRefresh(!refresh);
				_notification("success", "Success", "Event Status Changed");
			} else {
				_notification("warning", "Error", res.message);
			}
		} catch (err) {
			_notification("error", "Error", err.message);
		}
	};

	const handleChangeAttCode = async eventId => {
		try {
			const res = await refreshEventCodeService({ eid: eventId });
			if (res.message === "success") {
				toggleRefresh(!refresh);
				_notification(
					"success",
					"Success",
					"Event Attendance code Changed"
				);
			} else {
				_notification("warning", "Error", res.message);
			}
		} catch (err) {
			_notification("error", "Error", err.message);
		}
	};

	const columns = [
		{
			title: "#",
			dataIndex: "index",
			key: "index"
		},
		{
			title: "Event Name",
			dataIndex: "event_name",
			key: "event_name",
			render: text => (
				<Link
					to="#"
					onClick={() => {
						setEditDrawer(true);
						setEventId(text[1]);
					}}
				>
					{text[0]}
				</Link>
			)
		},
		{
			title: "Venue",
			dataIndex: "venue",
			key: "venue"
		},
		{
			title: "Timings",
			dataIndex: "time",
			key: "time"
		},
		{
			title: "Start Date",
			dataIndex: "startDate",
			key: "startDate"
		},
		{
			title: "End Date",
			dataIndex: "endDate",
			key: "endDate"
		},
		{
			title: "Attendance code",
			dataIndex: "code",
			key: "code",
			render: code => (
				<>
					<Tag color="green" key={code[0]}>
						{code[0]}
					</Tag>
					<Popconfirm
						title="Do you want refresh the event attendance code?"
						onConfirm={() => handleChangeAttCode(code[1])}
						// onCancel={cancel}
						okText="Yes"
						cancelText="No"
					>
						<RedoOutlined />
					</Popconfirm>
				</>
			)
		},
		{
			title: "Status",
			dataIndex: "status",
			key: "status",
			render: status => {
				return (
					<>
						<Tag color="blue" key={status[0]}>
							{status[0] ? "Open" : "Closed"}
						</Tag>
						<Popconfirm
							title="Do you want to toggle the event status?"
							onConfirm={() => handleToggleEventStatus(status[1])}
							onCancel={cancel}
							okText="Yes"
							cancelText="No"
						>
							<RedoOutlined />
						</Popconfirm>
					</>
				);
			}
		},
		{
			title: "Max Registrations",
			dataIndex: "maxRegister",
			key: "maxRegister",
			className: "registrations"
		},
		{
			title: "Total Registrations",
			dataIndex: "totalRegistrations",
			key: "totalRegistrations",
			className: "registrations"
		},
		{
			title: "Total RSVPs",
			dataIndex: "totalRsvps",
			key: "totalRsvps",
			className: "rsvps"
		},
		{
			title: "Registration",
			dataIndex: "reg",
			key: "reg",
			render: reg => {
				let val = reg ? "Required" : "Not required";
				return (
					<Tag color="orange" key={reg}>
						{val}
					</Tag>
				);
			}
		},
		{
			title: "Action",
			key: "action",
			dataIndex: "action",
			render: _id => (
				<span>
					<Link
						to="#"
						onClick={() => {
							setEditDrawer(true);
							setEventId(_id);
						}}
					>
						<EditOutlined style={{ color: "#F4B400" }} />
					</Link>
					<Divider type="vertical" />
					<Popconfirm
						title="Are you sure delete this event?"
						onConfirm={() => handleDelete(_id)}
						onCancel={cancel}
						okText="Yes"
						cancelText="No"
					>
						<DeleteOutlined style={{ color: "#DB4437" }} />
					</Popconfirm>
				</span>
			)
		}
	];

	console.log(events);

	const data = events
		? events.map((event, id) => {
				const {
					_id,
					title,
					venue,
					startDate,
					endDate,
					time,
					code,
					isRegistrationRequired,
					isRegistrationOpened,
					maxRegister,
					registrations,
					rsvps
				} = event;
				return {
					index: ++id,
					key: _id,
					event_name: [title, _id],
					venue,
					time,
					startDate: new Date(startDate).toDateString(),
					endDate: new Date(endDate).toDateString(),
					code: [code, _id],
					status: [isRegistrationOpened, _id],
					reg: isRegistrationRequired,
					action: _id,
					maxRegister,
					totalRegistrations: registrations,
					totalRsvps: rsvps
				};
		  })
		: null;

	const handleUpdateEvent = () => {
		toggleRefresh(!refresh);
		setEditDrawer(false);
	};

	const handleEventTypeChange = val => {
		if (val === "past") {
			setEvents(allEvents.previousEvents);
		} else if (val === "upcoming") {
			setEvents(allEvents.upcomingEvents);
		} else if (val === "running") {
			setEvents(allEvents.runningEvents);
		}
	};

	return (
		<>
			<PageTitle title="Events" bgColor="#DB4437" />

			<div className="table-wrapper-card">
				<EventOptions
					onAddEvent={handleAddEvent}
					onTypeChange={handleEventTypeChange}
				/>
				<Card style={{ padding: 0, width: "100%", overflowX: "auto" }}>
					<Table
						loading={isLoading}
						columns={columns}
						dataSource={data}
					/>
				</Card>
			</div>

			<Drawer
				title="Update Event Information"
				placement="right"
				closable={true}
				width="40%"
				destroyOnClose={true}
				onClose={() => setEditDrawer(false)}
				visible={editDrawer}
			>
				<UpdateEvent
					eventId={eventId}
					onUpdateEvent={handleUpdateEvent}
				/>
			</Drawer>
		</>
	);
}
Example #27
Source File: TopicConsumerGroupOffset.js    From kafka-map with Apache License 2.0 4 votes vote down vote up
render() {

        const columns = [{
            title: 'Partition',
            dataIndex: 'partition',
            key: 'partition',
            defaultSortOrder: 'ascend',
            sorter: (a, b) => a['partition'] - b['partition'],
        }, {
            title: 'Beginning Offset',
            dataIndex: 'beginningOffset',
            key: 'beginningOffset',
            sorter: (a, b) => a['beginningOffset'] - b['beginningOffset'],
        }, {
            title: 'End Offset',
            dataIndex: 'endOffset',
            key: 'endOffset',
            sorter: (a, b) => a['endOffset'] - b['endOffset'],
        }, {
            title: 'Consumer Offset',
            dataIndex: 'consumerOffset',
            key: 'consumerOffset',
            sorter: (a, b) => a['consumerOffset'] - b['consumerOffset'],
        }, {
            title: 'Lag',
            dataIndex: 'lag',
            key: 'lag',
            sorter: (a, b) => a['lag'] - b['lag'],
            render: (lag, record, index) => {
                return record['endOffset'] - record['consumerOffset']
            }
        }, {
            title: 'Operate',
            key: 'action',
            render: (text, record, index) => {
                return (
                    <div>
                        <Button type="link" size='small' onClick={() => {
                            this.setState({
                                resetOffsetVisible: true,
                                selectedRow: record
                            })
                        }}>Reset Offset</Button>
                    </div>
                )
            },
        }];

        return (
            <div>
                <div style={{marginBottom: 20}}>
                    <Row justify="space-around" align="middle" gutter={24}>
                        <Col span={20} key={1}>
                            <Title level={3}><FormattedMessage id="consume-detail" /></Title>
                        </Col>
                        <Col span={4} key={2} style={{textAlign: 'right'}}>
                            <Space>
                                <Tooltip title={<FormattedMessage id="refresh" />}>
                                    <Button icon={<SyncOutlined/>} onClick={() => {
                                        let clusterId = this.state.clusterId;
                                        let topic = this.state.topic;
                                        let groupId = this.state.groupId;
                                        this.loadItems(clusterId, topic, groupId);
                                    }}>

                                    </Button>
                                </Tooltip>
                            </Space>
                        </Col>
                    </Row>
                </div>

                <Table key='table'
                       dataSource={this.state.items}
                       columns={columns}
                       position={'both'}
                       pagination={{
                           showSizeChanger: true,
                           total: this.state.items.length,
                           showTotal: total => <FormattedMessage id="total-items" values={{total}}/>
                       }}
                       loading={this.state.loading}
                />

                <Drawer
                    title={'Partition: ' + this.state.selectedRow['partition']}
                    width={window.innerWidth * 0.3}
                    closable={true}
                    onClose={() => {
                        this.setState({
                            resetOffsetVisible: false
                        })
                    }}
                    visible={this.state.resetOffsetVisible}
                    footer={
                        <div
                            style={{
                                textAlign: 'right',
                            }}
                        >
                            <Button
                                loading={this.state.resetting}
                                onClick={() => {
                                    this.form.current
                                        .validateFields()
                                        .then(async values => {
                                            this.setState({
                                                resetting: true
                                            })
                                            let topic = this.state.topic;
                                            let groupId = this.state.groupId;
                                            let clusterId = this.state.clusterId;

                                            await request.put(`/topics/${topic}/consumerGroups/${groupId}/offset?clusterId=${clusterId}`, values);
                                            this.form.current.resetFields();
                                            this.setState({
                                                resetOffsetVisible: false
                                            })
                                            this.loadItems(clusterId, topic, groupId);
                                        })
                                        .catch(info => {

                                        }).finally(() => this.setState({resetting: false}));
                                }} type="primary">
                                重置
                            </Button>
                        </div>
                    }
                >
                    <Alert message={<FormattedMessage id="reset-warning" />} description={<FormattedMessage id="reset-warning-description" />} type="warning" showIcon
                           style={{marginBottom: 16}}/>

                    <Form ref={this.form}>
                        <Form.Item label={<FormattedMessage id="reset-partition" />} name='seek' rules={[{required: true}]}>
                            <Radio.Group onChange={(e) => {
                                let seek = e.target.value;
                                this.setState({
                                    'seek': seek
                                })
                            }}>
                                <Radio value={'end'}><FormattedMessage id="latest" /></Radio>
                                <Radio value={'beginning'}><FormattedMessage id="earliest" /></Radio>
                                <Radio value={'custom'}><FormattedMessage id="customization" /></Radio>
                            </Radio.Group>
                        </Form.Item>

                        {
                            this.state.seek === 'custom' ?
                                <Form.Item label="offset" name='offset' rules={[{required: true}]}>
                                    <InputNumber min={0}/>
                                </Form.Item> : undefined
                        }
                    </Form>
                </Drawer>
            </div>
        );
    }
Example #28
Source File: Access.js    From next-terminal with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {

        const hotKeyMenu = (
            <Menu>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65507', '65513', '65535'])}>Ctrl+Alt+Delete</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65507', '65513', '65288'])}>Ctrl+Alt+Backspace</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65515', '100'])}>Windows+D</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65515', '101'])}>Windows+E</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65515', '114'])}>Windows+R</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65515', '120'])}>Windows+X</Menu.Item>
                <Menu.Item
                    onClick={() => this.sendCombinationKey(['65515'])}>Windows</Menu.Item>
            </Menu>
        );

        const cmdMenuItems = this.state.commands.map(item => {
            return <Tooltip placement="left" title={item['content']} color='blue' key={'t-' + item['id']}>
                <Menu.Item onClick={() => {
                    this.writeCommand(item['content'])
                }} key={'i-' + item['id']}>{item['name']}</Menu.Item>
            </Tooltip>;
        });

        const cmdMenu = (
            <Menu>
                {cmdMenuItems}
            </Menu>
        );

        return (
            <div>

                <div className="container" style={{
                    overflow: this.state.containerOverflow,
                    width: this.state.containerWidth,
                    height: this.state.containerHeight,
                    margin: '0 auto'
                }}>
                    <div id="display"/>
                </div>

                <Draggable>
                    <Affix style={{position: 'absolute', top: 50, right: 50}}>
                        <Button icon={<ExpandOutlined/>} disabled={this.state.clientState !== STATE_CONNECTED}
                                onClick={() => {
                                    this.fullScreen();
                                }}/>
                    </Affix>
                </Draggable>

                {
                    this.state.session['copy'] === '1' || this.state.session['paste'] === '1' ?
                        <Draggable>
                            <Affix style={{position: 'absolute', top: 50, right: 100}}>
                                <Button icon={<CopyOutlined/>} disabled={this.state.clientState !== STATE_CONNECTED}
                                        onClick={() => {
                                            this.setState({
                                                clipboardVisible: true
                                            });
                                        }}/>
                            </Affix>
                        </Draggable> : undefined
                }


                {
                    this.state.protocol === 'vnc' ?
                        <>
                            <Draggable>
                                <Affix style={{position: 'absolute', top: 100, right: 100}}>
                                    <Dropdown overlay={hotKeyMenu} trigger={['click']} placement="bottomLeft">
                                        <Button icon={<WindowsOutlined/>}
                                                disabled={this.state.clientState !== STATE_CONNECTED}/>
                                    </Dropdown>
                                </Affix>
                            </Draggable>
                        </> : undefined
                }

                {
                    this.state.protocol === 'rdp' && this.state.showFileSystem ?
                        <>
                            <Draggable>
                                <Affix style={{position: 'absolute', top: 100, right: 50}}>
                                    <Button icon={<FolderOutlined/>}
                                            disabled={this.state.clientState !== STATE_CONNECTED} onClick={() => {
                                        this.setState({
                                            fileSystemVisible: true,
                                        });
                                    }}/>
                                </Affix>
                            </Draggable>
                        </> : undefined
                }

                {
                    this.state.protocol === 'rdp' ?
                        <>
                            <Draggable>
                                <Affix style={{position: 'absolute', top: 100, right: 100}}>
                                    <Dropdown overlay={hotKeyMenu} trigger={['click']} placement="bottomLeft">
                                        <Button icon={<WindowsOutlined/>}
                                                disabled={this.state.clientState !== STATE_CONNECTED}/>
                                    </Dropdown>
                                </Affix>
                            </Draggable>
                        </> : undefined
                }

                {
                    this.state.protocol === 'ssh' ?
                        <>
                            <Draggable>
                                <Affix style={{position: 'absolute', top: 100, right: 50}}>
                                    <Button icon={<FolderOutlined/>}
                                            disabled={this.state.clientState !== STATE_CONNECTED} onClick={() => {
                                        this.setState({
                                            fileSystemVisible: true,
                                        });
                                    }}/>
                                </Affix>
                            </Draggable>

                            <Draggable>
                                <Affix style={{position: 'absolute', top: 100, right: 100}}>
                                    <Dropdown overlay={cmdMenu} trigger={['click']} placement="bottomLeft">
                                        <Button icon={<CodeOutlined/>}
                                                disabled={this.state.clientState !== STATE_CONNECTED}/>
                                    </Dropdown>
                                </Affix>
                            </Draggable>

                            <Draggable>
                                <Affix style={{
                                    position: 'absolute',
                                    top: 150,
                                    right: 100,
                                    zIndex: this.state.enterBtnIndex
                                }}>
                                    <Button icon={<LineChartOutlined/>} onClick={() => {
                                        this.setState({
                                            statsVisible: true,
                                        });
                                        if (this.statsRef) {
                                            this.statsRef.addInterval();
                                        }
                                    }}/>
                                </Affix>
                            </Draggable>
                        </> : undefined
                }


                <Drawer
                    title={'文件管理'}
                    placement="right"
                    width={window.innerWidth * 0.8}
                    closable={true}
                    onClose={() => {
                        this.focus();
                        this.setState({
                            fileSystemVisible: false
                        });
                    }}
                    visible={this.state.fileSystemVisible}
                >
                    <FileSystem
                        storageId={this.state.sessionId}
                        storageType={'sessions'}
                        upload={this.state.session['upload'] === '1'}
                        download={this.state.session['download'] === '1'}
                        delete={this.state.session['delete'] === '1'}
                        rename={this.state.session['rename'] === '1'}
                        edit={this.state.session['edit'] === '1'}
                        minHeight={window.innerHeight - 103}/>

                </Drawer>

                <Drawer
                    title={'状态信息'}
                    placement="right"
                    width={window.innerWidth * 0.8}
                    closable={true}
                    onClose={() => {
                        this.setState({
                            statsVisible: false,
                        });
                        this.focus();
                        if (this.statsRef) {
                            this.statsRef.delInterval();
                        }
                    }}
                    visible={this.state.statsVisible}
                >
                    <Stats sessionId={this.state.sessionId} onRef={this.onRef}/>
                </Drawer>

                {
                    this.state.clipboardVisible ?
                        <Modal
                            title="剪贴板"
                            maskClosable={false}
                            visible={this.state.clipboardVisible}

                            onOk={() => {
                                this.clipboardFormRef.current
                                    .validateFields()
                                    .then(values => {
                                        let clipboardText = values['clipboard'];

                                        this.sendClipboard({
                                            'data': clipboardText,
                                            'type': 'text/plain'
                                        });

                                        this.setState({
                                            clipboardText: clipboardText,
                                            clipboardVisible: false
                                        });
                                    })
                                    .catch(info => {

                                    });
                            }}
                            confirmLoading={this.state.confirmLoading}
                            onCancel={() => {
                                this.focus();
                                this.setState({
                                    clipboardVisible: false
                                })
                            }}
                        >
                            <Form ref={this.clipboardFormRef} initialValues={{'clipboard': this.state.clipboardText}}>
                                <Form.Item name='clipboard' rules={[{required: false}]}>
                                    <TextArea id='clipboard' rows={10}/>
                                </Form.Item>
                            </Form>
                        </Modal>
                        : undefined
                }

            </div>
        );
    }
Example #29
Source File: index.js    From gobench with Apache License 2.0 4 votes vote down vote up
Menu = ({ dispatch, isMobileMenuOpen, isMobileView, menuLayoutType, leftMenuWidth }) => {
  useEffect(() => {
    // mobile menu touch slide opener
    const unify = e => {
      return e.changedTouches ? e.changedTouches[0] : e
    }
    document.addEventListener(
      'touchstart',
      e => {
        const x = unify(e).clientX
        touchStartPrev = x
        touchStartLocked = x > 70
      },
      { passive: false },
    )
    document.addEventListener(
      'touchmove',
      e => {
        const x = unify(e).clientX
        const prev = touchStartPrev
        if (x - prev > 50 && !touchStartLocked) {
          toggleMobileMenu()
          touchStartLocked = true
        }
      },
      { passive: false },
    )
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  const toggleMobileMenu = () => {
    dispatch({
      type: 'settings/CHANGE_SETTING',
      payload: {
        setting: 'isMobileMenuOpen',
        value: !isMobileMenuOpen,
      },
    })
  }

  const GetMenu = () => {
    if (isMobileView) {
      return (
        <div>
          <div
            className={style.handler}
            onClick={toggleMobileMenu}
            onFocus={e => {
              e.preventDefault()
            }}
            onKeyPress={toggleMobileMenu}
            role="button"
            tabIndex="0"
          >
            <div className={style.handlerIcon} />
          </div>
          <Drawer
            closable={false}
            visible={isMobileMenuOpen}
            placement="left"
            className={style.mobileMenu}
            onClose={toggleMobileMenu}
            maskClosable
            getContainer={null}
            width={leftMenuWidth}
          >
            <MenuLeft />
          </Drawer>
        </div>
      )
    }
    if (menuLayoutType === 'top') {
      return <MenuTop />
    }
    if (menuLayoutType === 'nomenu') {
      return null
    }
    return <MenuLeft />
  }

  return GetMenu()
}