fix admin copy text functions
This commit is contained in:
@@ -660,14 +660,46 @@ function formatDate(date) {
|
|||||||
return new Date(date).toLocaleString();
|
return new Date(date).toLocaleString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy text to clipboard
|
// Copy text to clipboard with fallback for non-secure contexts
|
||||||
function copyToClipboard(text) {
|
function adminCopyToClipboard(text) {
|
||||||
navigator.clipboard.writeText(text).then(() => {
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
showAlert('success', 'Copied to clipboard!');
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
}).catch(err => {
|
showAlert('success', 'Copied to clipboard!');
|
||||||
console.error('Failed to copy text: ', err);
|
}).catch(err => {
|
||||||
|
console.error('Failed to copy text: ', err);
|
||||||
|
fallbackCopyText(text);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fallbackCopyText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fallbackCopyText(text) {
|
||||||
|
const textArea = document.createElement("textarea");
|
||||||
|
textArea.value = text;
|
||||||
|
|
||||||
|
// Ensure textArea is not visible but part of the DOM
|
||||||
|
textArea.style.position = "fixed";
|
||||||
|
textArea.style.left = "-9999px";
|
||||||
|
textArea.style.top = "0";
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
showAlert('success', 'Copied to clipboard!');
|
||||||
|
} else {
|
||||||
|
showAlert('danger', 'Failed to copy to clipboard');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback copy failed: ', err);
|
||||||
showAlert('danger', 'Failed to copy to clipboard');
|
showAlert('danger', 'Failed to copy to clipboard');
|
||||||
});
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(textArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dashboard refresh functionality
|
// Dashboard refresh functionality
|
||||||
@@ -2359,7 +2391,7 @@ function createAccessKeysManagementContent(accessKeys) {
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>${key.access_key}</code>
|
<code>${key.access_key}</code>
|
||||||
<button class="btn btn-sm btn-outline-secondary ms-2" onclick="copyToClipboard('${key.access_key}')">
|
<button class="btn btn-sm btn-outline-secondary ms-2" onclick="adminCopyToClipboard('${key.access_key}')">
|
||||||
<i class="fas fa-copy"></i>
|
<i class="fas fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -2454,7 +2486,7 @@ function showSecretKey(accessKey, secretKey) {
|
|||||||
<label class="form-label"><strong>Access Key:</strong></label>
|
<label class="form-label"><strong>Access Key:</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" value="${accessKey}" readonly>
|
<input type="text" class="form-control" value="${accessKey}" readonly>
|
||||||
<button class="btn btn-outline-secondary" onclick="copyToClipboard('${accessKey}')">
|
<button class="btn btn-outline-secondary" onclick="adminCopyToClipboard('${accessKey}')">
|
||||||
<i class="fas fa-copy"></i>
|
<i class="fas fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -2463,7 +2495,7 @@ function showSecretKey(accessKey, secretKey) {
|
|||||||
<label class="form-label"><strong>Secret Key:</strong></label>
|
<label class="form-label"><strong>Secret Key:</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" value="${secretKey}" readonly>
|
<input type="text" class="form-control" value="${secretKey}" readonly>
|
||||||
<button class="btn btn-outline-secondary" onclick="copyToClipboard('${secretKey}')">
|
<button class="btn btn-outline-secondary" onclick="adminCopyToClipboard('${secretKey}')">
|
||||||
<i class="fas fa-copy"></i>
|
<i class="fas fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -2487,7 +2519,7 @@ function showNewAccessKeyModal(accessKeyData) {
|
|||||||
<label class="form-label"><strong>Access Key:</strong></label>
|
<label class="form-label"><strong>Access Key:</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" value="${accessKeyData.access_key}" readonly>
|
<input type="text" class="form-control" value="${accessKeyData.access_key}" readonly>
|
||||||
<button class="btn btn-outline-secondary" onclick="copyToClipboard('${accessKeyData.access_key}')">
|
<button class="btn btn-outline-secondary" onclick="adminCopyToClipboard('${accessKeyData.access_key}')">
|
||||||
<i class="fas fa-copy"></i>
|
<i class="fas fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -2496,7 +2528,7 @@ function showNewAccessKeyModal(accessKeyData) {
|
|||||||
<label class="form-label"><strong>Secret Key:</strong></label>
|
<label class="form-label"><strong>Secret Key:</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" value="${accessKeyData.secret_key}" readonly>
|
<input type="text" class="form-control" value="${accessKeyData.secret_key}" readonly>
|
||||||
<button class="btn btn-outline-secondary" onclick="copyToClipboard('${accessKeyData.secret_key}')">
|
<button class="btn btn-outline-secondary" onclick="adminCopyToClipboard('${accessKeyData.secret_key}')">
|
||||||
<i class="fas fa-copy"></i>
|
<i class="fas fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ templ ServiceAccounts(data dash.ServiceAccountsData) {
|
|||||||
<label class="form-label fw-bold">AWS_ACCESS_KEY_ID</label>
|
<label class="form-label fw-bold">AWS_ACCESS_KEY_ID</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control font-monospace" id="displayAccessKey" readonly>
|
<input type="text" class="form-control font-monospace" id="displayAccessKey" readonly>
|
||||||
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard(event, 'displayAccessKey')">
|
<button class="btn btn-outline-secondary" type="button" onclick="copyCredentialToClipboard(this, 'displayAccessKey')">
|
||||||
<i class="fas fa-copy"></i> Copy
|
<i class="fas fa-copy"></i> Copy
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -280,7 +280,7 @@ templ ServiceAccounts(data dash.ServiceAccountsData) {
|
|||||||
<label class="form-label fw-bold">AWS_SECRET_ACCESS_KEY</label>
|
<label class="form-label fw-bold">AWS_SECRET_ACCESS_KEY</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control font-monospace" id="displaySecretKey" readonly>
|
<input type="text" class="form-control font-monospace" id="displaySecretKey" readonly>
|
||||||
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard(event, 'displaySecretKey')">
|
<button class="btn btn-outline-secondary" type="button" onclick="copyCredentialToClipboard(this, 'displaySecretKey')">
|
||||||
<i class="fas fa-copy"></i> Copy
|
<i class="fas fa-copy"></i> Copy
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -474,27 +474,25 @@ templ ServiceAccounts(data dash.ServiceAccountsData) {
|
|||||||
setTimeout(() => window.location.reload(), 500);
|
setTimeout(() => window.location.reload(), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyToClipboard(event, elementId) {
|
function copyCredentialToClipboard(button, elementId) {
|
||||||
const element = document.getElementById(elementId);
|
const element = document.getElementById(elementId);
|
||||||
|
const textToCopy = element.value;
|
||||||
|
|
||||||
// Use modern Clipboard API if available
|
// Use modern Clipboard API if available
|
||||||
if (navigator.clipboard) {
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
navigator.clipboard.writeText(element.value).then(() => {
|
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||||
// Success feedback could be added here
|
showSuccessMessage('Copied to clipboard!');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.warn('Clipboard API failed:', err);
|
console.warn('Clipboard API failed:', err);
|
||||||
// Fallback
|
// Fallback
|
||||||
element.select();
|
fallbackCopyTextToClipboard(element);
|
||||||
document.execCommand('copy');
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Fallback for older browsers
|
// Fallback for older browsers or non-secure contexts
|
||||||
element.select();
|
fallbackCopyTextToClipboard(element);
|
||||||
document.execCommand('copy');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visual feedback
|
// Visual feedback
|
||||||
const button = event.target.closest('button');
|
|
||||||
const originalHTML = button.innerHTML;
|
const originalHTML = button.innerHTML;
|
||||||
|
|
||||||
button.innerHTML = '<i class="fas fa-check"></i>';
|
button.innerHTML = '<i class="fas fa-check"></i>';
|
||||||
@@ -508,6 +506,26 @@ templ ServiceAccounts(data dash.ServiceAccountsData) {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fallbackCopyTextToClipboard(element) {
|
||||||
|
element.select();
|
||||||
|
element.setSelectionRange(0, 99999); // For mobile devices
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
showSuccessMessage('Copied to clipboard!');
|
||||||
|
} else {
|
||||||
|
showErrorMessage('Failed to copy to clipboard');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback copy failed:', err);
|
||||||
|
showErrorMessage('Failed to copy to clipboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear selection
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function createSADetailsContent(sa) {
|
function createSADetailsContent(sa) {
|
||||||
// Create DOM elements safely to prevent XSS
|
// Create DOM elements safely to prevent XSS
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user