Add user feedback for exchange configuration
- Show loading state while connecting to exchange - Display success/error messages in the form - Prevent double-submission with disabled button - Add 30-second timeout with error message - Register handler for Exchange_connection_result message - Reload page after successful connection (with delay to show message) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
da9d1fc5ee
commit
4e14463465
|
|
@ -3,6 +3,7 @@ class Exchanges {
|
||||||
this.exchanges = {};
|
this.exchanges = {};
|
||||||
this.balances = {};
|
this.balances = {};
|
||||||
this.connected_exchanges = [];
|
this.connected_exchanges = [];
|
||||||
|
this.isSubmitting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
|
|
@ -12,36 +13,100 @@ class Exchanges {
|
||||||
|
|
||||||
// Extract the text content from each span and store it in the connected_exchanges array
|
// Extract the text content from each span and store it in the connected_exchanges array
|
||||||
this.connected_exchanges = Array.from(spans).map(span => span.textContent.trim());
|
this.connected_exchanges = Array.from(spans).map(span => span.textContent.trim());
|
||||||
|
|
||||||
|
// Register handler for exchange connection results
|
||||||
|
if (window.UI && window.UI.data && window.UI.data.comms) {
|
||||||
|
window.UI.data.comms.on('Exchange_connection_result', this.handleConnectionResult.bind(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status() {
|
status() {
|
||||||
|
// Reset form state when opening
|
||||||
|
this.resetFormState();
|
||||||
document.getElementById('exchanges_config_form').style.display = "grid";
|
document.getElementById('exchanges_config_form').style.display = "grid";
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm() {
|
closeForm() {
|
||||||
|
this.resetFormState();
|
||||||
document.getElementById('exchanges_config_form').style.display = "none";
|
document.getElementById('exchanges_config_form').style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetFormState() {
|
||||||
|
this.isSubmitting = false;
|
||||||
|
const statusEl = document.getElementById('exchange_status');
|
||||||
|
const connectBtn = document.getElementById('exchange_connect_btn');
|
||||||
|
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.style.display = 'none';
|
||||||
|
document.getElementById('exchange_status_text').textContent = '';
|
||||||
|
}
|
||||||
|
if (connectBtn) {
|
||||||
|
connectBtn.disabled = false;
|
||||||
|
connectBtn.textContent = 'Connect';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showStatus(message, type) {
|
||||||
|
const statusEl = document.getElementById('exchange_status');
|
||||||
|
const statusText = document.getElementById('exchange_status_text');
|
||||||
|
|
||||||
|
if (statusEl && statusText) {
|
||||||
|
statusText.textContent = message;
|
||||||
|
statusEl.style.display = 'block';
|
||||||
|
|
||||||
|
// Set color based on type
|
||||||
|
if (type === 'loading') {
|
||||||
|
statusEl.style.color = '#666';
|
||||||
|
statusEl.style.backgroundColor = '#f0f0f0';
|
||||||
|
} else if (type === 'success') {
|
||||||
|
statusEl.style.color = '#155724';
|
||||||
|
statusEl.style.backgroundColor = '#d4edda';
|
||||||
|
} else if (type === 'error') {
|
||||||
|
statusEl.style.color = '#721c24';
|
||||||
|
statusEl.style.backgroundColor = '#f8d7da';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
validateApiKey(data) {
|
validateApiKey(data) {
|
||||||
return !(data === undefined || data === null || data === "");
|
return !(data === undefined || data === null || data === "");
|
||||||
}
|
}
|
||||||
|
|
||||||
postConnection(data) {
|
handleConnectionResult(data) {
|
||||||
|
this.isSubmitting = false;
|
||||||
|
const connectBtn = document.getElementById('exchange_connect_btn');
|
||||||
|
|
||||||
|
if (connectBtn) {
|
||||||
|
connectBtn.disabled = false;
|
||||||
|
connectBtn.textContent = 'Connect';
|
||||||
|
}
|
||||||
|
|
||||||
if (data.status === 'success') {
|
if (data.status === 'success') {
|
||||||
// Trigger a page reload
|
this.showStatus('Exchange connected successfully! Reloading...', 'success');
|
||||||
location.reload();
|
// Reload after a brief delay so user sees the success message
|
||||||
}
|
setTimeout(() => {
|
||||||
else if (data.status === 'already_connected') {
|
location.reload();
|
||||||
alert(data.message);
|
}, 1500);
|
||||||
}
|
} else if (data.status === 'already_connected') {
|
||||||
else if (data.status === 'failure') {
|
this.showStatus(data.message || 'Exchange is already connected.', 'error');
|
||||||
alert(data.message);
|
} else if (data.status === 'failure' || data.status === 'error') {
|
||||||
|
this.showStatus(data.message || 'Failed to connect exchange.', 'error');
|
||||||
|
} else {
|
||||||
|
this.showStatus(data.message || 'Unknown response from server.', 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy handler for backwards compatibility
|
||||||
|
postConnection(data) {
|
||||||
|
this.handleConnectionResult(data);
|
||||||
|
}
|
||||||
|
|
||||||
submitApi() {
|
submitApi() {
|
||||||
|
// Prevent double submission
|
||||||
|
if (this.isSubmitting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Collect the data to submit.
|
// Collect the data to submit.
|
||||||
let exchange = document.getElementById('c_exchanges').value;
|
let exchange = document.getElementById('c_exchanges').value;
|
||||||
let user = window.UI.data.user_name;
|
let user = window.UI.data.user_name;
|
||||||
|
|
@ -59,16 +124,33 @@ class Exchanges {
|
||||||
keys = {}; // Clear keys for public exchanges
|
keys = {}; // Clear keys for public exchanges
|
||||||
} else if (!isKeyValid || !isSecretKeyValid) {
|
} else if (!isKeyValid || !isSecretKeyValid) {
|
||||||
// Validate keys for non-public exchanges
|
// Validate keys for non-public exchanges
|
||||||
alert('Enter a valid API key and secret key to register.');
|
this.showStatus('Please enter a valid API key and secret key.', 'error');
|
||||||
return; // Exit early if validation fails
|
return; // Exit early if validation fails
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the data if validation passes or no validation is required.
|
// Show loading state
|
||||||
|
this.isSubmitting = true;
|
||||||
|
const connectBtn = document.getElementById('exchange_connect_btn');
|
||||||
|
if (connectBtn) {
|
||||||
|
connectBtn.disabled = true;
|
||||||
|
connectBtn.textContent = 'Connecting...';
|
||||||
|
}
|
||||||
|
this.showStatus('Connecting to exchange...', 'loading');
|
||||||
|
|
||||||
|
// Send the data
|
||||||
let payload = { 'user': user, 'exch': exchange, 'keys': keys };
|
let payload = { 'user': user, 'exch': exchange, 'keys': keys };
|
||||||
window.UI.data.comms.sendToApp("config_exchange", payload);
|
window.UI.data.comms.sendToApp("config_exchange", payload);
|
||||||
this.closeForm();
|
|
||||||
|
|
||||||
// Refreshes the current page
|
// Set a timeout in case we don't get a response
|
||||||
// setTimeout(function() { location.reload(); }, 200);
|
setTimeout(() => {
|
||||||
|
if (this.isSubmitting) {
|
||||||
|
this.isSubmitting = false;
|
||||||
|
if (connectBtn) {
|
||||||
|
connectBtn.disabled = false;
|
||||||
|
connectBtn.textContent = 'Connect';
|
||||||
|
}
|
||||||
|
this.showStatus('Connection timed out. Please try again.', 'error');
|
||||||
|
}
|
||||||
|
}, 30000); // 30 second timeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,15 @@
|
||||||
<label for="api_secret_key" style="grid-column: 1; grid-row: 4;">API SECRET KEY:</label>
|
<label for="api_secret_key" style="grid-column: 1; grid-row: 4;">API SECRET KEY:</label>
|
||||||
<input name="api_secret_key" id="api_secret_key" style="grid-column: 2 / span 3; grid-row: 4;">
|
<input name="api_secret_key" id="api_secret_key" style="grid-column: 2 / span 3; grid-row: 4;">
|
||||||
|
|
||||||
|
<!-- Status message area (row 6/8) -->
|
||||||
|
<div id="exchange_status" style="grid-column: 1 / span 4; grid-row: 6; text-align: center; padding: 10px; display: none;">
|
||||||
|
<span id="exchange_status_text"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- buttons (row 8/8)-->
|
<!-- buttons (row 8/8)-->
|
||||||
<div style="grid-column: 1 / span 4; grid-row: 8;">
|
<div style="grid-column: 1 / span 4; grid-row: 8;">
|
||||||
<button type="button" class="btn cancel" onclick="UI.exchanges.closeForm()">Close</button>
|
<button type="button" class="btn cancel" onclick="UI.exchanges.closeForm()">Close</button>
|
||||||
<button type="button" class="btn next" onclick="UI.exchanges.submitApi()">Connect</button>
|
<button type="button" id="exchange_connect_btn" class="btn next" onclick="UI.exchanges.submitApi()">Connect</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div><!----End panel 1--------->
|
</div><!----End panel 1--------->
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue