cleanup
This commit is contained in:
@@ -39,6 +39,10 @@ const ApiTokensSection = ({
|
||||
const [newTokenExpires, setNewTokenExpires] = useState('');
|
||||
const [newTokenCapabilitySetId, setNewTokenCapabilitySetId] = useState('');
|
||||
const [formError, setFormError] = useState(null);
|
||||
const supportsClipboardWrite = typeof navigator !== 'undefined'
|
||||
&& Boolean(navigator?.clipboard?.writeText);
|
||||
const [canCopyToken, setCanCopyToken] = useState(supportsClipboardWrite);
|
||||
const [copyFeedback, setCopyFeedback] = useState(null);
|
||||
|
||||
const capabilitySetOptions = useMemo(
|
||||
() => capabilitySets.map((set) => ({
|
||||
@@ -110,19 +114,44 @@ const ApiTokensSection = ({
|
||||
onRefreshCapabilities?.();
|
||||
}, [onRefresh, onRefreshCapabilities, onRefreshCapabilitySets]);
|
||||
|
||||
const handleCopyToken = useCallback(() => {
|
||||
if (!createdToken) {
|
||||
const handleCopyToken = useCallback(async () => {
|
||||
if (!createdToken || !canCopyToken) {
|
||||
return;
|
||||
}
|
||||
if (navigator?.clipboard?.writeText) {
|
||||
navigator.clipboard.writeText(createdToken).catch(() => {});
|
||||
|
||||
const showSuccess = () =>
|
||||
setCopyFeedback({ type: 'success', message: 'Token copied to clipboard.' });
|
||||
const showFailure = () =>
|
||||
setCopyFeedback({
|
||||
type: 'error',
|
||||
message:
|
||||
'Copy failed. Your browser may require HTTPS access; please select the token manually.',
|
||||
});
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(createdToken);
|
||||
showSuccess();
|
||||
return;
|
||||
} catch (error) {
|
||||
// Some browsers expose writeText but still reject outside secure context
|
||||
setCanCopyToken(false);
|
||||
}
|
||||
}, [createdToken]);
|
||||
|
||||
showFailure();
|
||||
}, [createdToken, canCopyToken]);
|
||||
|
||||
const handleDismissSecret = useCallback(() => {
|
||||
setCopyFeedback(null);
|
||||
onDismissCreatedToken?.();
|
||||
}, [onDismissCreatedToken]);
|
||||
|
||||
useEffect(() => {
|
||||
setCopyFeedback(null);
|
||||
if (typeof navigator !== 'undefined') {
|
||||
setCanCopyToken(Boolean(navigator?.clipboard?.writeText));
|
||||
}
|
||||
}, [createdToken]);
|
||||
|
||||
const handleNewCapabilitySetChange = useCallback((event) => {
|
||||
setFormError(null);
|
||||
setNewTokenCapabilitySetId(event.target.value);
|
||||
@@ -215,13 +244,20 @@ const ApiTokensSection = ({
|
||||
</p>
|
||||
<pre className="token-display">{createdToken}</pre>
|
||||
<div className="settings-notice__actions">
|
||||
<button type="button" className="secondary" onClick={handleCopyToken}>
|
||||
Copy token
|
||||
</button>
|
||||
{canCopyToken ? (
|
||||
<button type="button" className="secondary" onClick={handleCopyToken}>
|
||||
Copy token
|
||||
</button>
|
||||
) : null}
|
||||
<button type="button" onClick={handleDismissSecret}>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
{copyFeedback ? (
|
||||
<p className={copyFeedback.type === 'error' ? 'settings-form__error' : 'settings-status'}>
|
||||
{copyFeedback.message}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user