mirror of
https://github.com/stellarshenson/stellars-jupyterhub-ds.git
synced 2026-03-08 06:00:29 +00:00
feat: add loading spinner during credentials fetch
This commit is contained in:
@@ -87,3 +87,9 @@ This journal tracks substantive work on documents, diagrams, and documentation c
|
||||
|
||||
28. **Task - Fix admin template URL handling**: Fixed fetch interceptor and nav links in templates_enhanced<br>
|
||||
**Result**: Fixed `isUserCreation` check in admin.html to strip query params (`?_xsrf=...`) before checking if URL ends with `api/users` - React admin adds XSRF token as query param which broke the endpoint detection. Fixed double "hub" prefix in page.html nav links - changed `{{ base_url }}hub/authorize` to `{{ base_url }}authorize` and `{{ base_url }}hub/change-password` to `{{ base_url }}change-password` since base_url already includes `/hub/`
|
||||
|
||||
29. **Task - Fix credentials API route conflict**: Changed credentials endpoint from `/api/users/credentials` to `/api/admin/credentials`<br>
|
||||
**Result**: JupyterHub's built-in `/api/users/*` handler was catching requests before custom handler, returning "Invalid JSON keys" error. Changed route in jupyterhub_config.py, admin.html, and custom_handlers.py docstring
|
||||
|
||||
30. **Task - Credentials modal UX improvements**: Enhanced modal layout, scrolling, and loading feedback<br>
|
||||
**Result**: Moved Copy/Download buttons to top of modal body. Added scrollable container (max-height 300px) for long user lists. Removed `<code>` styling for plain text display. Added loading spinner modal shown between user creation and credentials display. Improved Makefile version output format to show "Current version" and "New version" lines
|
||||
|
||||
@@ -51,6 +51,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Spinner Modal -->
|
||||
<div class="modal fade" id="loading-modal" tabindex="-1" role="dialog" data-bs-backdrop="static" data-bs-keyboard="false" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body text-center py-4">
|
||||
<div class="spinner-border text-primary mb-3" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<div>Generating credentials...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock main %}
|
||||
|
||||
{% block footer %}
|
||||
@@ -131,6 +145,9 @@
|
||||
console.log('[Admin] Users created:', createdUsers);
|
||||
pendingUsernames.push(...createdUsers);
|
||||
|
||||
// Show loading spinner
|
||||
showLoadingSpinner();
|
||||
|
||||
// Debounce - wait for batch completion then fetch credentials
|
||||
clearTimeout(window._credentialsFetchTimeout);
|
||||
window._credentialsFetchTimeout = setTimeout(() => {
|
||||
@@ -172,14 +189,32 @@
|
||||
}
|
||||
} else {
|
||||
console.error('[Admin] Failed to fetch credentials:', response.status);
|
||||
hideLoadingSpinner();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[Admin] Error fetching credentials:', e);
|
||||
hideLoadingSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
// Loading spinner functions
|
||||
let loadingModal = null;
|
||||
function showLoadingSpinner() {
|
||||
const modalEl = document.getElementById('loading-modal');
|
||||
if (!loadingModal) {
|
||||
loadingModal = new bootstrap.Modal(modalEl);
|
||||
}
|
||||
loadingModal.show();
|
||||
}
|
||||
function hideLoadingSpinner() {
|
||||
if (loadingModal) {
|
||||
loadingModal.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Show modal with credentials
|
||||
function showCredentialsModal(credentials) {
|
||||
hideLoadingSpinner();
|
||||
const tbody = document.getElementById('credentials-body');
|
||||
tbody.innerHTML = '';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user