Toggle credentials in instance detail view
This commit is contained in:
parent
69a0c5bd5d
commit
461565cdd4
2 changed files with 96 additions and 3 deletions
|
|
@ -220,8 +220,17 @@
|
||||||
{% if instance.connection_credentials %}
|
{% if instance.connection_credentials %}
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h4>{% translate "Connection Credentials" %}</h4>
|
<h4 class="mb-0">{% translate "Connection Credentials" %}</h4>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-secondary"
|
||||||
|
id="toggle-credentials-btn"
|
||||||
|
data-show-text="{% translate "Show All" %}"
|
||||||
|
data-hide-text="{% translate "Hide All" %}"
|
||||||
|
onclick="toggleAllCredentials()">
|
||||||
|
<i class="bi bi-eye me-1"></i>
|
||||||
|
<span id="toggle-credentials-text">{% translate "Show All" %}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
|
|
@ -230,6 +239,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% translate "Name" %}</th>
|
<th>{% translate "Name" %}</th>
|
||||||
<th>{% translate "Value" %}</th>
|
<th>{% translate "Value" %}</th>
|
||||||
|
<th style="width: 50px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -240,7 +250,17 @@
|
||||||
{% if key == "error" %}
|
{% if key == "error" %}
|
||||||
<span class="text-danger">{{ value }}</span>
|
<span class="text-danger">{{ value }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<code>{{ value }}</code>
|
<code class="credential-value" data-value="{{ value }}">••••••••••••</code>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
{% if key != "error" %}
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-link p-0 credential-toggle"
|
||||||
|
onclick="toggleCredential(this)"
|
||||||
|
title="{% translate 'Show/Hide' %}">
|
||||||
|
<i class="bi bi-eye"></i>
|
||||||
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -248,6 +268,10 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="text-muted small mt-2">
|
||||||
|
<i class="bi bi-info-circle me-1"></i>
|
||||||
|
{% translate "Click the eye icon to reveal individual credentials, or use 'Show All' to reveal all at once." %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -286,6 +310,7 @@
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<script src="{% static 'js/local-time.js' %}"></script>
|
<script src="{% static 'js/local-time.js' %}"></script>
|
||||||
|
<script src="{% static 'js/credentials.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
// Initialize Bootstrap popovers for help text
|
// Initialize Bootstrap popovers for help text
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
|
||||||
68
src/servala/static/js/credentials.js
Normal file
68
src/servala/static/js/credentials.js
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
const CREDENTIAL_MASK = '••••••••••••';
|
||||||
|
|
||||||
|
function toggleCredential(button) {
|
||||||
|
const row = button.closest('tr');
|
||||||
|
const codeEl = row.querySelector('.credential-value');
|
||||||
|
const icon = button.querySelector('i');
|
||||||
|
|
||||||
|
if (!codeEl) return;
|
||||||
|
|
||||||
|
const isHidden = codeEl.textContent === CREDENTIAL_MASK;
|
||||||
|
|
||||||
|
if (isHidden) {
|
||||||
|
codeEl.textContent = codeEl.getAttribute('data-value');
|
||||||
|
icon.classList.remove('bi-eye');
|
||||||
|
icon.classList.add('bi-eye-slash');
|
||||||
|
} else {
|
||||||
|
codeEl.textContent = CREDENTIAL_MASK;
|
||||||
|
icon.classList.remove('bi-eye-slash');
|
||||||
|
icon.classList.add('bi-eye');
|
||||||
|
}
|
||||||
|
|
||||||
|
updateShowAllButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAllCredentials() {
|
||||||
|
const credentials = document.querySelectorAll('.credential-value');
|
||||||
|
const anyHidden = Array.from(credentials).some(el => el.textContent === CREDENTIAL_MASK);
|
||||||
|
|
||||||
|
credentials.forEach(function (codeEl) {
|
||||||
|
const row = codeEl.closest('tr');
|
||||||
|
const button = row.querySelector('.credential-toggle');
|
||||||
|
const icon = button ? button.querySelector('i') : null;
|
||||||
|
|
||||||
|
if (anyHidden) {
|
||||||
|
codeEl.textContent = codeEl.getAttribute('data-value');
|
||||||
|
if (icon) {
|
||||||
|
icon.classList.remove('bi-eye');
|
||||||
|
icon.classList.add('bi-eye-slash');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
codeEl.textContent = CREDENTIAL_MASK;
|
||||||
|
if (icon) {
|
||||||
|
icon.classList.remove('bi-eye-slash');
|
||||||
|
icon.classList.add('bi-eye');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateShowAllButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateShowAllButton() {
|
||||||
|
const credentials = document.querySelectorAll('.credential-value');
|
||||||
|
const anyHidden = Array.from(credentials).some(el => el.textContent === CREDENTIAL_MASK);
|
||||||
|
const toggleBtn = document.getElementById('toggle-credentials-btn');
|
||||||
|
const toggleText = document.getElementById('toggle-credentials-text');
|
||||||
|
const toggleIcon = toggleBtn ? toggleBtn.querySelector('i') : null;
|
||||||
|
|
||||||
|
if (toggleText && toggleBtn) {
|
||||||
|
const showText = toggleBtn.getAttribute('data-show-text') || 'Show All';
|
||||||
|
const hideText = toggleBtn.getAttribute('data-hide-text') || 'Hide All';
|
||||||
|
toggleText.textContent = anyHidden ? showText : hideText;
|
||||||
|
}
|
||||||
|
if (toggleIcon) {
|
||||||
|
toggleIcon.classList.toggle('bi-eye', anyHidden);
|
||||||
|
toggleIcon.classList.toggle('bi-eye-slash', !anyHidden);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue