@ant-design/icons#ArrowDownOutlined JavaScript Examples
The following examples show how to use
@ant-design/icons#ArrowDownOutlined.
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: OverallIndicator.js From website with MIT License | 6 votes |
OverallIndicator = ({ className, metrics }) => {
return (
<div className={'overall-indicator ' + className}>
{metrics.map(
({ label, value, arrow = { direction: 'up', type: 'success ' } }) => (
<OverallItem
key={JSON.stringify({ label, value })}
arrow={arrow}
className='overall-indicator__item'
>
<p className='value'>
{format(value)}{' '}
{arrow.direction === 'up' ? (
<ArrowUpOutlined />
) : (
<ArrowDownOutlined />
)}
</p>
<h3 className='title'>{label}</h3>
</OverallItem>
)
)}
</div>
);
}
Example #2
Source File: AiSample.js From network-rc with Apache License 2.0 | 6 votes |
aiAction = {
left: {
icon: <ArrowLeftOutlined />,
name: "左转弯",
action: { speed: 1, direction: 1 },
label: 0,
},
right: {
icon: <ArrowRightOutlined />,
name: "右转弯",
action: { speed: 1, direction: -1 },
label: 1,
},
forward: {
icon: <ArrowUpOutlined />,
name: "前进",
action: { speed: 1, direction: 0 },
label: 2,
},
back: {
icon: <ArrowDownOutlined />,
action: { speed: -1, direction: 0 },
name: "后退",
label: 3,
},
stop: {
icon: <PauseOutlined />,
action: { speed: 0, direction: 0 },
name: "停止",
label: 4,
},
}
Example #3
Source File: card.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/statistic', module).add('card', () =>
<div className="site-statistic-demo-card">
<Row gutter={16}>
<Col span={12}>
<Card>
<Statistic
title="Active"
value={11.28}
precision={2}
valueStyle={{ color: '#3f8600' }}
prefix={<ArrowUpOutlined />}
suffix="%"
/>
</Card>
</Col>
<Col span={12}>
<Card>
<Statistic
title="Idle"
value={9.3}
precision={2}
valueStyle={{ color: '#cf1322' }}
prefix={<ArrowDownOutlined />}
suffix="%"
/>
</Card>
</Col>
</Row>
</div>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Display statistic data in Card.</p></>) } });
Example #4
Source File: ExchangeForm.js From bonded-stablecoin-ui with MIT License | 4 votes |
ExchangeForm = () => {
const { exchanges_recepient, formInit, referrer } = useSelector(
(state) => state.settings
);
const dispatch = useDispatch();
const { t } = useTranslation();
const params = useParams();
const [width] = useWindowSize();
const { data, loaded } = useSelector((state) => state.list);
const [activeCurrency, setActiveCurrency] = useState("btc");
const [amountCurrency, setAmountCurrency] = useState(0.1);
const [index, setIndex] = useState(0);
const [isCreated, setIsCreated] = useState(false);
const [amountToken, setAmountToken] = useState(undefined);
let tokens = getTokens(data);
const [activeTokenAdr, setActiveTokenAdr] = useState(
config.TESTNET ? "2SEBEEDTEC7LTDVZ765MGQXJW33GSRUD" : "VLKI3XMMX5YULOBA6ZXBXDPI6TXF6V3D"
);
const [oraclePrice, setOraclePrice] = useState(undefined);
const [inited, setInited] = useState(false);
const [recipient, setRecipient] = useState(
exchanges_recepient
? { value: exchanges_recepient, valid: true }
: {
value: undefined,
valid: undefined,
}
);
const provider = activeCurrency && (config.oswapccCurrencies.includes(activeCurrency.toUpperCase()) ? "oswapcc" : "simpleswap");
useEffect(() => {
const id = setInterval(() => setIndex((i) => i + 1), 1000 * 60 * 5);
return () => {
clearInterval(id);
};
}, []);
useEffect(() => {
if (loaded) {
if (params.address) {
setAmountCurrency(formInit?.amountCurrency || "0.1");
setActiveCurrency(formInit?.currentCurrency || "btc");
setActiveTokenAdr(params.address);
} else {
// if (formInit?.currentCurrency === "gbyte") {
// setAmountToken(formInit?.amountToken);
// setActiveCurrency("gbyte");
// setActiveTokenAdr(formInit.currentToken);
// } else if (formInit?.currentCurrency !== undefined) {
// setActiveCurrency(formInit.currentCurrency);
if (formInit?.amountCurrency && formInit?.currentToken) {
setAmountCurrency(formInit.amountCurrency);
setActiveTokenAdr(formInit.currentToken);
}
// setActiveTokenAdr(formInit.currentToken);
// }
}
setInited(true);
}
}, [loaded]);
const buyForGbyteRef = useRef(null);
const buyRef = useRef(null);
const currentTokenData = activeTokenAdr ? data[activeTokenAdr] : undefined;
const reservePrice = useGetReservePrice(currentTokenData && currentTokenData.params.reserve_asset);
useEffect(() => {
(async () => {
if (currentTokenData && inited) {
const { bonded_state, params } = currentTokenData;
const price = await getOraclePrice(bonded_state, params);
setOraclePrice(price);
}
})();
}, [currentTokenData, setOraclePrice, inited]);
// const allCurrencies = useGetCurrency();
const ranges = useGetRanges(activeCurrency);
const exchangeRates = useGetRate(activeCurrency, index, provider === "oswapcc" ? amountCurrency : 1, inited);
const compensation = useGetCompensation(
amountCurrency,
activeCurrency,
exchangeRates
);
const handleAmountCurrency = (ev) => {
const value = ev.target.value;
const reg = /^[0-9.]+$/;
if (
(~(value + "").indexOf(".") ? (value + "").split(".")[1].length : 0) <= 9
) {
if (reg.test(String(value)) || value === "") {
setAmountCurrency(value);
}
}
};
const handleAmountTokens = (ev, decimals) => {
const value = ev.target.value;
const reg = /^[0-9.]+$/;
if (
!currentTokenData ||
(~(value + "").indexOf(".") ? (value + "").split(".")[1].length : 0) <=
decimals
) {
if (reg.test(String(value)) || value === "") {
setAmountToken(value);
}
}
};
useEffect(() => {
(async () => {
if (!currentTokenData) return undefined;
const { bonded_state, params, fund } = currentTokenData;
const result =
currentTokenData &&
oraclePrice &&
oraclePrice !== undefined &&
!isEmpty(bonded_state) &&
$get_exchange_result({
tokens1: 0,
tokens2: amountToken * 10 ** params.decimals2,
params: params,
vars: bonded_state,
oracle_price: oraclePrice,
timestamp: Math.floor(Date.now() / 1000),
reservePrice,
isV2: !!fund
});
if (result && activeCurrency === "gbyte" && inited) {
setAmountCurrency(((result.reserve_needed * 1.01) / 1e9).toFixed(9));
}
})();
}, [
amountToken,
currentTokenData,
activeCurrency,
exchangeRates,
oraclePrice,
]);
useEffect(() => {
const newData = {
currentToken: activeTokenAdr,
amountToken,
currentCurrency: activeCurrency,
amountCurrency: amountCurrency,
};
if (
JSON.stringify(newData) !== JSON.stringify(formInit) &&
inited
) {
dispatch(updateExchangesForm(newData));
}
}, [activeTokenAdr, amountToken, activeCurrency, amountCurrency]);
useEffect(() => {
if (!currentTokenData) return undefined;
const { bonded_state, params, fund } = currentTokenData;
const result =
bonded_state &&
params &&
oraclePrice &&
activeCurrency !== "gbyte" &&
$get_exchange_result({
tokens1: 0,
tokens2: 0,
params: params,
vars: bonded_state,
oracle_price: oraclePrice,
timestamp: Math.floor(Date.now() / 1000),
reservePrice,
isV2: !!fund
});
if (result && activeCurrency !== "gbyte" && inited) {
const expectT2 =
(1 / result.target_p2) *
(Number(amountCurrency) * Number(exchangeRates) + (compensation || 0));
setAmountToken(expectT2.toFixed(params.decimals2));
}
}, [
amountCurrency,
currentTokenData,
activeCurrency,
exchangeRates,
compensation,
oraclePrice
]);
const handleClickExchange = () => {
createExchange({
address: recipient.value,
currency_from: activeCurrency,
asset: currentTokenData.asset_2,
symbol: currentTokenData.symbol,
amount_currency: amountCurrency,
amount_token: amountToken,
active_currency: activeCurrency,
recipient,
curve_address: activeTokenAdr,
ref: referrer,
after: ({ isError, clear = true }) => {
if (!isError) {
message.success(t("buy.exchange_success", "The exchange was successfully added to the list and is waiting for payment"));
dispatch(addExchangeRecipient(recipient.value));
} else {
message.error(t("buy.exchange_error", "An error occurred, please try again later"));
}
ReactGA.event({
category: "Stablecoin",
action: "Buy interest tokens for currency",
});
if (!isError || (isError && clear)) {
setAmountCurrency(amountCurrency);
setAmountToken(undefined);
}
setIsCreated(false);
},
});
};
const handleChange = (value) => {
if (obyte.utils.isValidAddress(value)) {
setRecipient({ value, valid: true });
} else {
setRecipient({ value, valid: false });
}
};
useEffect(() => {
if (inited && activeCurrency !== "gbyte") {
setAmountToken(undefined);
}
}, [activeCurrency]);
const getResult = () =>
$get_exchange_result({
tokens1: 0,
tokens2: amountToken * 10 ** currentTokenData.params.decimals2,
params: currentTokenData.params,
vars: currentTokenData.bonded_state,
oracle_price: oraclePrice,
timestamp: Math.floor(Date.now() / 1000),
reservePrice,
isV2: currentTokenData.fund
});
if (!inited) return <Spin />;
return (
<div>
{exchangeRates === null && activeCurrency !== "gbyte" && <Alert
message={t("buy.exchange_warning", "{{currency}}-to-GBYTE exchange service is currently unavailable, please pay with another currency or try again later.", { currency: String(activeCurrency).toUpperCase() })}
type="warning"
style={{ marginTop: 10 }}
/>}
<Row style={{ marginBottom: 20, marginTop: 50 }}>
<Col lg={{ span: 9, offset: 2 }} xs={{ span: 24, offset: 0 }} md={{ span: 16, offset: 4 }}>
<div style={{ marginBottom: 5 }}>
<Text type="secondary">
<Trans i18nKey="buy.you_send">
You <b>send</b>
</Trans>
</Text>
</div>
<Input.Group compact>
<Input
style={{ width: "50%" }}
size="large"
placeholder={`${t("buy.amount", "Amount")} ${ranges && ranges.min ? "Min. " + ranges.min : ""
} ${ranges && ranges.max ? " Max. " + ranges.max : ""}`}
onChange={handleAmountCurrency}
value={isNaN(amountCurrency) ? undefined : amountCurrency}
disabled={activeCurrency === "gbyte" || isCreated}
onKeyPress={(ev) => {
if (ev.key === "Enter") {
if (activeCurrency === "gbyte") {
buyForGbyteRef.current.click();
} else {
buyRef.current.click();
}
}
}}
/>
<Select
style={{ width: "50%" }}
size="large"
showSearch
placeholder={t("buy.currency_to_pay", "Currency to pay")}
onChange={(c) => {
setActiveCurrency(c);
}}
disabled={true} //isCreated
value={activeCurrency}
>
{/* <Select.OptGroup label={t("buy.popular_cryptocurrencies", "Popular cryptocurrencies")}> */}
{/* <Select.Option value="gbyte" key="c-gbyte">
GBYTE
</Select.Option> */}
{popularCurrencies.filter(
(c) => 1 // allCurrencies.includes(c)
).sort().map((c) => (
<Select.Option key={"c-" + c} value={c}>
<BtcLogo width="1em" height="1em" style={{ marginRight: 3, marginBottom: -1.5 }} /> {c.toUpperCase()}
</Select.Option>
))}
{/* </Select.OptGroup> */}
{/* <Select.OptGroup label={t("buy.others", "Others")}>
{allCurrencies.filter(
(c) => !popularCurrencies.includes(c)
).sort().map((c) => (
<Select.Option key={"c-" + c} value={c}>
{c.toUpperCase()}
</Select.Option>
))}{" "}
</Select.OptGroup> */}
</Select>
</Input.Group>
{/* {activeCurrency && activeCurrency !== "gbyte" && (
<span style={{ fontSize: 10 }}>
{t("buy.better_rate", "You get a better rate if you pay in GBYTE")}
</span>
)} */}
</Col>
<Col lg={{ span: 2, offset: 0 }} xs={{ span: 24, offset: 0 }} md={{ span: 24, offset: 0 }}>
<div
style={{
marginTop: width < 990 ? 10 : 27,
textAlign: "center",
height: 38,
boxSizing: "border-box",
fontSize: "1.5em",
}}
>
{width < 990 ? <ArrowDownOutlined /> : <ArrowRightOutlined />}
</div>
</Col>
<Col lg={{ span: 9, offset: 0 }} xs={{ span: 24, offset: 0 }} md={{ span: 16, offset: 4 }}>
{!amountCurrency ||
(amountToken && compensation !== undefined) ||
activeCurrency === "gbyte" ? (
<>
<div style={{ marginBottom: 5 }}>
<Text type="secondary">
<Trans i18nKey="buy.you_get">
You <b>get</b>
</Trans>
</Text>
</div>
<Input.Group compact>
<Input
style={{ width: width > 500 ? "50%" : "100%" }}
size="large"
suffix={
(exchangeRates || activeCurrency === "gbyte") &&
reservePrice &&
amountCurrency &&
oraclePrice &&
amountToken ? (
<span style={{ color: "#ccc" }}>
≈{" "}
{activeCurrency === "gbyte"
? getResult().amountTokens2InCurrency.toFixed(2)
: (
Number(amountCurrency) *
exchangeRates *
reservePrice
).toFixed(2)}{" "}
USD
</span>
) : (
<span />
)
}
placeholder={t("buy.amount", "Amount")}
prefix={activeCurrency !== "gbyte" ? "≈" : ""}
value={isNaN(amountToken) ? undefined : amountToken}
onChange={(ev) =>
handleAmountTokens(
ev,
currentTokenData && currentTokenData.params.decimals2
)
}
disabled={activeCurrency !== "gbyte" || isCreated}
onKeyPress={(ev) => {
if (ev.key === "Enter") {
if (activeCurrency === "gbyte") {
if (!isNaN(amountToken) && !(Number(amountToken) === 0)) {
buyForGbyteRef.current.click();
}
} else {
buyRef.current.click();
}
}
}}
/>
<Select
style={{ width: width > 500 ? "50%" : "100%" }}
size="large"
showSearch
disabled={isCreated}
optionFilterProp="children"
placeholder={t("buy.will_receive", "The token you will receive")}
onChange={(c) => setActiveTokenAdr(c)}
value={activeTokenAdr}
>
{tokens.map((t) => (
<Select.Option key={"t-" + t.asset} value={t.address}>
<CoinIcon width="1em" style={{ marginRight: 5, marginBottom: -1.5 }} height="1em" type={2} pegged={t.pegged} /> {t.symbol || t.asset}{" "}
{" (" +
Decimal.mul(t.interest_rate, 100).toNumber() +
"% interest)"}
</Select.Option>
))}
</Select>
</Input.Group>
{activeCurrency !== "gbyte" && currentTokenData && (
<>
<Text type="secondary">
<Trans i18nKey="buy.first_exchanged" activeCurrency={activeCurrency} symbol={currentTokenData.symbol || currentTokenData.asset_2.slice(0, 5) + "..."}>
Your <span style={{ textTransform: "uppercase" }}>{{ activeCurrency }}</span>{" "}
will be first exchanged for GBYTE, then GBYTE converted to {" "}
{{
symbol: currentTokenData.symbol ||
currentTokenData.asset_2.slice(0, 5) + "..."
}}.{" "}
<span style={{ textTransform: "uppercase" }}>
{{ activeCurrency }}
</span>{" "}
to GBYTE exchange is performed by{" "}
<a
href={provider === "oswapcc" ? "https://www.oswap.cc" : "https://simpleswap.io/"}
target="_blank"
rel="noopener"
>
{{ providerName: provider === "oswapcc" ? "oswap.cc" : "simpleswap.io" }}
</a>.
</Trans>
</Text>
{amountCurrency &&
(typeof compensation === "number" ? (
<div>
<Text type="secondary">
{t("buy.compensates", "Obyte compensates part of the exchange fees.")}
</Text>
</div>
) : (
<div style={{ marginTop: 5 }}>
<Text type="secondary">
{t("buy.compensates_depleted", "Obyte compensates part of the exchange fees but today's quota is already depleted and the quoted price includes the full fees. To get a better rate, try again after the quota resets at midnight UTC or buy with GBYTE now.")}
</Text>
</div>
))}
</>
)}
<Row>
{activeCurrency !== "gbyte" && (
<Form.Item
hasFeedback
style={{ width: "100%", marginTop: 20 }}
extra={
<span>
<Trans i18nKey="buy.install">
<a
href="https://obyte.org/#download"
target="_blank"
rel="noopener"
onClick={
() => {
ReactGA.event({
category: "Stablecoin",
action: "Install wallet (buy for other currency)",
label: activeCurrency
})
}
}>Install Obyte wallet</a> if you don't have one yet, and copy/paste your address here.
</Trans>
</span>
}
validateStatus={
recipient.valid !== undefined
? recipient.valid
? "success"
: "error"
: undefined
}
>
<Input
size="large"
disabled={isCreated}
value={recipient.value}
placeholder="Your Obyte wallet address"
onChange={(ev) => handleChange(ev.target.value)}
/>
</Form.Item>
)}
</Row>
</>
) : (
<Row justify="center" align="middle">
{(amountCurrency < ranges.min) ? <Result status="error" subTitle="Please check the amount to be sent BTC" /> : <Spin size="large" style={{ padding: 25 }} />}
{/* {!exchangeRates ? <Result status="warning" /> : */}
{/* <Spin size="large" style={{ padding: 25 }} /> */}
</Row>
)}
</Col>
</Row>
{activeCurrency === "gbyte" ? (
<>
<Row justify="center" style={{ marginTop: 40 }}>
<QRButton
type="primary"
size="large"
disabled={
isNaN(amountToken) ||
!Number(amountToken) ||
!amountCurrency ||
amountCurrency === "" ||
Number(amountCurrency) === 0
}
key="btn-buy-gbyte"
onClick={() =>
ReactGA.event({
category: "Stablecoin",
action: "Buy interest tokens for gbyte",
})
}
ref={buyForGbyteRef}
href={
currentTokenData &&
amountCurrency &&
generateLink(
Number(Number(amountCurrency).toFixed(9) * 1e9).toFixed(0),
{
tokens2:
amountToken * 10 ** currentTokenData.params.decimals2,
ref: referrer
},
undefined,
activeTokenAdr
)
}
>
{t("buy.buy", "Buy")}
</QRButton>
</Row>
{amountCurrency &&
amountCurrency !== "" &&
Number(amountCurrency) !== 0 ? (
<div style={{ textAlign: "center" }}>
<Text type="secondary" style={{ fontSize: 10 }}>
{t("buy.volatility", "1% was added to protect against price volatility, you'll get this amount back if the prices don't change.")}
</Text>
<Text type="secondary" style={{ fontSize: 14, display: "block" }}>
<Trans i18nKey="buy.open_wallet">
Clicking "Buy" will open your Obyte wallet. <a
href="https://obyte.org/#download"
target="_blank"
rel="noopener"
onClick={
() => {
ReactGA.event({
category: "Stablecoin",
action: "Install wallet (buy for GBYTE)",
label: "GBYTE"
})
}
}>Install</a> it if you don't have one yet.
</Trans>
</Text>
</div>
) : null}
</>
) : (
<>
<Row justify="center">
<Button
type="primary"
size="large"
ref={buyRef}
loading={isCreated || ranges.min === undefined}
key="btn-buy-currency"
disabled={
!recipient.valid ||
!amountCurrency ||
!amountToken ||
compensation === undefined ||
ranges === undefined ||
ranges.min === undefined ||
Number(ranges.min) > amountCurrency
}
onClick={() => {
setIsCreated(true);
handleClickExchange();
}}
>
{t("buy.buy", "Buy")}
</Button>
</Row>
{activeCurrency &&
ranges &&
ranges.min &&
Number(ranges.min) > amountCurrency ? (
<div style={{ textAlign: "center" }}>
<Text type="secondary" style={{ fontSize: 12, color: "red" }}>
<Trans i18nKey="buy.min" activeCurrency={String(activeCurrency).toUpperCase()} min={ranges.min}>
Sorry, the minimum {{ activeCurrency: String(activeCurrency).toUpperCase() }} amount is {{ min: ranges.min }}. Please increase the {{ activeCurrency: String(activeCurrency).toUpperCase() }} amount.
</Trans>
</Text>
</div>
) : null}
</>
)}
<div style={{ fontSize: 16, textAlign: "center", padding: 10 }}>
<Trans i18nKey="buy.buying_v2">
For buying stable tokens (OUSD, OBIT, etc), fund tokens (SFUSD, SFGB, etc), and redemption, go to the{" "}
<Link to="/trade">trading page</Link>.
</Trans>
</div>
</div>
);
}
Example #5
Source File: index.js From ant-simple-pro with MIT License | 4 votes |
User = memo(function User() {
const columns = [
{
key: 'index',
align: 'center',
title: '序号',
render: (text, record, index) => `${index + 1}`,
},
{
align: 'center',
title: 'id',
dataIndex: 'id',
key: 'id',
},
{
align: 'center',
title: 'email',
dataIndex: 'email',
key: 'email',
},
{
align: 'center',
title: '名称',
dataIndex: 'username',
key: 'username',
render: (text) => <NoData data={text} />
},
{
align: 'center',
title: '介绍',
dataIndex: 'introduct',
key: 'introduct',
render: (text) => <NoData data={text} />
},
{
align: 'center',
title: '头像',
dataIndex: 'iconUrl',
key: 'iconUrl',
render: (text) => (
<>
{text.length ? <Image src={text} alt="头像" style={{ cursor: 'pointer' }} width={50} height={50} /> : <NoData data={text} />}
</>
)
},
{
align: 'center',
title: '操作',
render: (text, record) => (
<>
<a onClick={() => handle(record)}>编辑</a>
</>
),
}
];
const tools = new Tools();
const [editData, setEditData] = useSetState({ visible: false, detailData: {} });
const { Search } = Input;
const [username, setUsername] = useState(undefined);
const selectNumOfDoneTodos = createSelector( // 只计算,给的数据,其他的数据不会重新计算
[(state) => state.user, (state) => state.other],
(user, other) => [user.getUserList, other.loading]
);
const dispatch = useDispatch(); // 这里取代connect里面的dispatch
const [getUserList, loading] = useSelector(selectNumOfDoneTodos); // 获取redux里面的数据,这里取代了connect函数
const initFetch = useCallback((username) => dispatch({ type: SAGA_GET_USER_LIST, payload: { username } }), [dispatch]);
useEffect(() => {
initFetch(username)
}, [initFetch, username])
const downFile = async () => {
let res = await xlsxFileDown();
if (res.code === requestCode.successCode) {
let delBuffer = Buffer.from(res.data, "binary");
const blob = new Blob([delBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
let url = window.URL.createObjectURL(blob);
tools.createALabel(url);
}
}
const datas = {
btnGrounp: [{
component: <Search
enterButton
placeholder="请输入用户名"
onSearch={(value) => setUsername(value ? value : undefined)}
style={{ width: 200 }}
allowClear
/>
}],
iconGrounp: [
{
component: (<Tooltip title='下载' placement="bottom">
<ArrowDownOutlined className='svg-fontSize' onClick={downFile} />
</Tooltip>)
}
],
tableProps: { columns, dataSource: getUserList },
receive: () => initFetch(username),
loading
}
const handle = (detailData) => {
setEditData({
visible: true, detailData: Object.assign({}, detailData, {
iconUrl: detailData.iconUrl.length ? detailData.iconUrl.split(',').map((item) => ({ uid: Math.random() * 100, url: item, response: { code: requestCode.successCode, data: { url: item } } })) : []
})
});
}
return (
<>
<LayoutTableComponent {...datas}>
<UserSearch setUsername={setUsername} />
</LayoutTableComponent>
<EditComponent {...editData} onCancel={() => setEditData({ visible: false })} sucessCallback={() => initFetch(username)} />
</>
)
})
Example #6
Source File: MainWindow.js From ikago-web with MIT License | 4 votes |
render() {
return (
<Layout>
<Header className="header">
<a className="header-a" href="https://github.com/zhxie/ikago">
<img className="header-icon" src={logo} alt="icon" />
</a>
<p className="header-title">{this.state.name}</p>
<p className="header-subtitle">{this.state.version}</p>
</Header>
<Content className="content">
<Row gutter={16}>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card className="content-card" hoverable>
<Statistic
prefix={(() => {
if (this.state.active) {
return <CheckOutlined />;
} else if (this.state.inactive) {
return <WarningOutlined />;
} else {
return <LoadingOutlined />;
}
})()}
title="Status"
value={(() => {
if (this.state.active) {
return 'Active';
} else if (this.state.inactive) {
return 'Inactive';
} else {
return 'Connecting';
}
})()}
valueStyle={{
color: (() => {
if (!this.state.inactive) {
return '#000';
} else {
return '#cf1322';
}
})()
}}
/>
</Card>
</Col>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card className="content-card" hoverable>
<Statistic
precision={2}
prefix={<ClockCircleOutlined />}
title="Operation Time"
value={this.convertTime(this.state.time)}
/>
</Card>
</Col>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card
hoverable
onClick={() => {
this.setState({
showTotal: !this.state.showTotal
});
}}
>
<Statistic
precision={1}
prefix={<ArrowUpOutlined />}
suffix={(() => {
if (this.state.showTotal) {
return this.mapSizeUnit(this.state.outboundSizeTotal);
} else {
return this.mapSizeUnit(this.state.outboundSize) + '/s';
}
})()}
title="Outbound"
value={(() => {
if (this.state.showTotal) {
return this.convertSize(this.state.outboundSizeTotal);
} else {
return this.convertSize(this.state.outboundSize);
}
})()}
/>
</Card>
</Col>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card
hoverable
onClick={() => {
this.setState({
showTotal: !this.state.showTotal
});
}}
>
<Statistic
precision={1}
prefix={<ArrowDownOutlined />}
suffix={(() => {
if (this.state.showTotal) {
return this.mapSizeUnit(this.state.inboundSizeTotal);
} else {
return this.mapSizeUnit(this.state.inboundSize) + '/s';
}
})()}
title="Inbound"
value={(() => {
if (this.state.showTotal) {
return this.convertSize(this.state.inboundSizeTotal);
} else {
return this.convertSize(this.state.inboundSize);
}
})()}
/>
</Card>
</Col>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card className="content-card" hoverable>
<Statistic
prefix={<HourglassOutlined />}
suffix={this.state.ping < 0 ? '' : 'ms'}
title="Delay"
value={(() => {
if (this.state.ping === -1) {
return 'N/A';
} else if (this.state.ping === -2) {
return 'Timeout';
} else {
return this.state.ping;
}
})()}
valueStyle={{
color: (() => {
if (this.state.ping === -2) {
return '#cf1322';
} else if (this.state.ping >= 100) {
return '#faad14';
} else {
return '#000';
}
})()
}}
/>
</Card>
</Col>
<Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
<Card
hoverable
onClick={() => {
this.setState({
configure: true
});
}}
>
<Statistic prefix={<SettingOutlined />} title="Configure" value={this.convertPath(this.state.path)} />
</Card>
<ConfigurationForm
visible={this.state.configure}
onOk={(values) => {
localStorage.setItem('path', values.path);
localStorage.setItem('showTotal', values.showTotal ? 'true' : 'false');
this.setState({
configure: false,
path: values.path,
showTotal: values.showTotal,
active: this.state.path !== values.path ? false : this.state.active,
inactive: this.state.path !== values.path ? false : this.state.inactive
});
}}
onCancel={() => {
this.setState({
configure: false
});
}}
initialValues={{ path: this.state.path, showTotal: this.state.showTotal }}
/>
</Col>
</Row>
<Row gutter={16}>
<Col className="content-col-table" sm={24} md={24} lg={12}>
<Table dataSource={this.mapNodes(this.state.local)} pagination={false} size="middle">
<Column title="Source" key="source" align="left" render={this.showNode} />
<Column title="Outbound" key="outboundSize" align="center" render={this.showOutbound} width={200} />
<Column title="Inbound" key="inboundSize" align="center" render={this.showInbound} width={200} />
</Table>
</Col>
<Col className="content-col-table" sm={24} md={24} lg={12}>
<Table dataSource={this.mapNodes(this.state.remote)} pagination={false} size="middle">
<Column title="Destination" key="source" align="left" render={this.showNode} />
<Column title="Outbound" key="outboundSize" align="center" render={this.showOutbound} width={200} />
<Column title="Inbound" key="inboundSize" align="center" render={this.showInbound} width={200} />
</Table>
</Col>
</Row>
</Content>
</Layout>
);
}