mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-06-16 14:28:14 +00:00
Re-implement copy to clipboard (DevAddr, EUI and AES keys).
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import { Input, Select, Button, Space, Form } from "antd";
|
import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd";
|
||||||
import { ReloadOutlined } from "@ant-design/icons";
|
import { ReloadOutlined, CopyOutlined } from "@ant-design/icons";
|
||||||
import {Buffer} from "buffer";
|
import {Buffer} from "buffer";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -104,7 +104,58 @@ class AesKeyInput extends Component<IProps, IState> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
copyToClipboard = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join("").toUpperCase())
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboardHexArray = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join(", ").toUpperCase().replace(/[A-Fa-f0-9]{2}/g, "0x$&"))
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const copyMenu = <Menu items={[
|
||||||
|
{
|
||||||
|
key: "1",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboard}>HEX string</Button>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "2",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboardHexArray}>HEX array</Button>,
|
||||||
|
},
|
||||||
|
]} />;
|
||||||
|
|
||||||
const addon = (
|
const addon = (
|
||||||
<Space size="large">
|
<Space size="large">
|
||||||
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
||||||
@ -114,6 +165,11 @@ class AesKeyInput extends Component<IProps, IState> {
|
|||||||
<Button type="text" size="small" shape="circle" onClick={this.generateRandom}>
|
<Button type="text" size="small" shape="circle" onClick={this.generateRandom}>
|
||||||
<ReloadOutlined />
|
<ReloadOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Dropdown overlay={copyMenu}>
|
||||||
|
<Button type="text" size="small">
|
||||||
|
<CopyOutlined />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import { Input, Select, Button, Space, Form } from "antd";
|
import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd";
|
||||||
import { ReloadOutlined } from "@ant-design/icons";
|
import { ReloadOutlined, CopyOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
import { GetRandomDevAddrRequest, GetRandomDevAddrResponse } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
|
import { GetRandomDevAddrRequest, GetRandomDevAddrResponse } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
|
||||||
|
|
||||||
@ -107,7 +107,60 @@ class DevAddrInput extends Component<IProps, IState> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
copyToClipboard = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join("").toUpperCase())
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboardHexArray = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join(", ").toUpperCase().replace(/[A-Fa-f0-9]{2}/g, "0x$&"))
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const copyMenu = <Menu items={[
|
||||||
|
{
|
||||||
|
key: "1",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboard}>HEX string</Button>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "2",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboardHexArray}>HEX array</Button>,
|
||||||
|
},
|
||||||
|
]} />;
|
||||||
|
|
||||||
const addon = (
|
const addon = (
|
||||||
<Space size="large">
|
<Space size="large">
|
||||||
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
||||||
@ -117,6 +170,11 @@ class DevAddrInput extends Component<IProps, IState> {
|
|||||||
<Button type="text" size="small" shape="circle" onClick={this.generateRandom}>
|
<Button type="text" size="small" shape="circle" onClick={this.generateRandom}>
|
||||||
<ReloadOutlined />
|
<ReloadOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Dropdown overlay={copyMenu}>
|
||||||
|
<Button type="text" size="small">
|
||||||
|
<CopyOutlined />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import { Input, Select, Button, Space, Form } from "antd";
|
import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd";
|
||||||
import { ReloadOutlined } from "@ant-design/icons";
|
import { ReloadOutlined, CopyOutlined } from "@ant-design/icons";
|
||||||
import {Buffer} from "buffer";
|
import {Buffer} from "buffer";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -103,16 +103,72 @@ class EuiInput extends Component<IProps, IState> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
copyToClipboard = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join("").toUpperCase())
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboardHexArray = () => {
|
||||||
|
const bytes = this.state.value.match(/[A-Fa-f0-9]{2}/g);
|
||||||
|
|
||||||
|
if (bytes !== null && navigator.clipboard !== undefined) {
|
||||||
|
navigator.clipboard.writeText(bytes.join(", ").toUpperCase().replace(/[A-Fa-f0-9]{2}/g, "0x$&"))
|
||||||
|
.then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
notification.error({
|
||||||
|
message: "Error",
|
||||||
|
description: e,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const copyMenu = <Menu items={[
|
||||||
|
{
|
||||||
|
key: "1",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboard}>HEX string</Button>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "2",
|
||||||
|
label: <Button type="text" onClick={this.copyToClipboardHexArray}>HEX array</Button>,
|
||||||
|
},
|
||||||
|
]} />;
|
||||||
|
|
||||||
const addon = (
|
const addon = (
|
||||||
<Space size="large">
|
<Space size="large">
|
||||||
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
<Select value={this.state.byteOrder} onChange={this.onByteOrderSelect}>
|
||||||
<Select.Option value="msb">MSB</Select.Option>
|
<Select.Option value="msb">MSB</Select.Option>
|
||||||
<Select.Option value="lsb">LSB</Select.Option>
|
<Select.Option value="lsb">LSB</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
<Button type="text" size="small" shape="circle" onClick={this.generateRandom}>
|
<Button type="text" size="small" onClick={this.generateRandom}>
|
||||||
<ReloadOutlined />
|
<ReloadOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Dropdown overlay={copyMenu}>
|
||||||
|
<Button type="text" size="small">
|
||||||
|
<CopyOutlined />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user