mirror of
https://github.com/openziti/zrok.git
synced 2025-06-20 17:58:50 +02:00
copy to clipboard, hopefully done to a much better standard (#724)
This commit is contained in:
parent
1af626d2c4
commit
ec39625b44
@ -6,9 +6,10 @@ import SecretToggle from "./SecretToggle.tsx";
|
|||||||
import useApiConsoleStore from "./model/store.ts";
|
import useApiConsoleStore from "./model/store.ts";
|
||||||
import PasswordIcon from "@mui/icons-material/Password";
|
import PasswordIcon from "@mui/icons-material/Password";
|
||||||
import TokenIcon from "@mui/icons-material/Key";
|
import TokenIcon from "@mui/icons-material/Key";
|
||||||
import {useState} from "react";
|
import React, {useState} from "react";
|
||||||
import AccountPasswordChangeModal from "./AccountPasswordChangeModal.tsx";
|
import AccountPasswordChangeModal from "./AccountPasswordChangeModal.tsx";
|
||||||
import RegenerateAccountTokenModal from "./RegenerateAccountTokenModal.tsx";
|
import RegenerateAccountTokenModal from "./RegenerateAccountTokenModal.tsx";
|
||||||
|
import ClipboardText from "./ClipboardText.tsx";
|
||||||
|
|
||||||
interface AccountPanelProps {
|
interface AccountPanelProps {
|
||||||
account: Node;
|
account: Node;
|
||||||
@ -32,7 +33,7 @@ const AccountPanel = ({ account }: AccountPanelProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const customProps = {
|
const customProps = {
|
||||||
token: row => <SecretToggle secret={row.value} />
|
token: row => <Grid2 container><SecretToggle secret={row.value} /><ClipboardText text={row.value} /></Grid2>
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = {
|
const label = {
|
||||||
|
35
ui100/src/ClipboardText.tsx
Normal file
35
ui100/src/ClipboardText.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {Button, Popover, Typography} from "@mui/material";
|
||||||
|
|
||||||
|
interface ClipboardTextProps {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ClipboardText = ({ text }: ClipboardTextProps) => {
|
||||||
|
const [copied, setCopied] = useState<boolean>(false);
|
||||||
|
const [color, setColor] = useState<string>("black");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(copied) {
|
||||||
|
setColor("red");
|
||||||
|
} else {
|
||||||
|
setColor("black");
|
||||||
|
}
|
||||||
|
}, [copied]);
|
||||||
|
|
||||||
|
const copy = async () => {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={copy} sx={{ minWidth: "30px" }} style={{ color: color }} ><ContentCopyIcon /></Button>
|
||||||
|
<Popover anchorOrigin={{ vertical: "top", horizontal: "right" }} open={copied}><Typography sx={{ p: 2 }}>Copied!</Typography></Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ClipboardText;
|
@ -4,6 +4,7 @@ import {modalStyle} from "./styling/theme.ts";
|
|||||||
import {Box, Button, Checkbox, FormControlLabel, Grid2, Modal, Typography} from "@mui/material";
|
import {Box, Button, Checkbox, FormControlLabel, Grid2, Modal, Typography} from "@mui/material";
|
||||||
import {getAccountApi, getMetadataApi} from "./model/api.ts";
|
import {getAccountApi, getMetadataApi} from "./model/api.ts";
|
||||||
import useApiConsoleStore from "./model/store.ts";
|
import useApiConsoleStore from "./model/store.ts";
|
||||||
|
import ClipboardText from "./ClipboardText.tsx";
|
||||||
|
|
||||||
interface RegenerateAccountTokenModalProps {
|
interface RegenerateAccountTokenModalProps {
|
||||||
close: () => void;
|
close: () => void;
|
||||||
@ -43,7 +44,7 @@ const RegenerateAccountTokenModal = ({ close, isOpen, user }: RegenerateAccountT
|
|||||||
localStorage.setItem("user", JSON.stringify(newUser));
|
localStorage.setItem("user", JSON.stringify(newUser));
|
||||||
document.dispatchEvent(new Event("userUpdated"));
|
document.dispatchEvent(new Event("userUpdated"));
|
||||||
setSuccessMessage(<><Grid2 container sx={{ flexGrow: 1 }} alignItems="center">
|
setSuccessMessage(<><Grid2 container sx={{ flexGrow: 1 }} alignItems="center">
|
||||||
<Typography variant="h6" sx={{ mt: 2, p: 1 }}>Your new account token is: <code>{d.token}</code></Typography>
|
<Typography variant="h6" sx={{ mt: 2, p: 1 }}>Your new account token is: <code>{d.token}</code> <ClipboardText text={String(d.token)} /></Typography>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
|
<Grid2 container sx={{ flexGrow: 1, p: 1 }} alignItems="center">
|
||||||
<Button type="primary" variant="contained" onClick={reload}>Reload API Console</Button>
|
<Button type="primary" variant="contained" onClick={reload}>Reload API Console</Button>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import ShowIcon from "@mui/icons-material/Visibility";
|
import HideIcon from "@mui/icons-material/Visibility";
|
||||||
import HideIcon from "@mui/icons-material/VisibilityOff";
|
import ShowIcon from "@mui/icons-material/VisibilityOff";
|
||||||
import {Grid2} from "@mui/material";
|
import {Grid2} from "@mui/material";
|
||||||
|
|
||||||
interface SecretToggleProps {
|
interface SecretToggleProps {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user