diff --git a/frontend/src/js/app.js b/frontend/src/js/app.js
index 09280ef..631681a 100644
--- a/frontend/src/js/app.js
+++ b/frontend/src/js/app.js
@@ -510,29 +510,119 @@ class App {
}
/**
- * Prompts the user for a host/port and opens a quick connection.
+ * Opens a quick connect dialog for ad-hoc connections without saving a profile.
*/
async quickConnect() {
- const input = await this._inputPrompt('Quick Connect', 'Enter host[:port]', 'e.g. 192.168.1.1:22');
- if (!input || !input.trim()) return;
+ const createElement = window.NexusTerminal.createElement;
+ const result = await new Promise((resolve) => {
+ const backdrop = createElement('div', 'modal-backdrop');
+ const modal = createElement('div', 'modal modal-sm');
+ modal.innerHTML = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ backdrop.appendChild(modal);
+ document.body.appendChild(backdrop);
+ requestAnimationFrame(() => {
+ backdrop.classList.add('is-visible');
+ modal.classList.add('is-visible');
+ });
- const parts = input.trim().split(':');
- const host = parts[0];
- const port = parts[1] ? parseInt(parts[1], 10) : 22;
- const protocol = this.state.preferences.defaultProtocol || 'ssh';
+ const protocolSelect = modal.querySelector('.qc-protocol');
+ const portInput = modal.querySelector('.qc-port');
+ const usernameGroup = modal.querySelector('.qc-username-group');
+ const hostInput = modal.querySelector('.qc-host');
+
+ // Update port default and username visibility when protocol changes
+ protocolSelect.addEventListener('change', () => {
+ const proto = protocolSelect.value;
+ const defaultPorts = { ssh: 22, telnet: 23, raw: 23 };
+ portInput.value = defaultPorts[proto] || 22;
+ usernameGroup.style.display = proto === 'ssh' ? '' : 'none';
+ });
+
+ const close = (value) => {
+ backdrop.classList.remove('is-visible');
+ modal.classList.remove('is-visible');
+ setTimeout(() => backdrop.remove(), 200);
+ resolve(value);
+ };
+
+ modal.querySelector('.modal-close').addEventListener('click', () => close(null));
+ modal.querySelector('.qc-cancel').addEventListener('click', () => close(null));
+ modal.querySelector('.qc-connect').addEventListener('click', () => {
+ const host = hostInput.value.trim();
+ if (!host) {
+ hostInput.focus();
+ return;
+ }
+ close({
+ protocol: protocolSelect.value,
+ host,
+ port: parseInt(portInput.value, 10) || 22,
+ username: modal.querySelector('.qc-username').value.trim(),
+ });
+ });
+ backdrop.addEventListener('click', (e) => { if (e.target === backdrop) close(null); });
+ hostInput.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') modal.querySelector('.qc-connect').click();
+ if (e.key === 'Escape') close(null);
+ });
+
+ setTimeout(() => hostInput.focus(), 50);
+ });
+
+ if (!result) return;
try {
- const profile = { protocol, host, port, displayName: host, tags: [] };
+ const profile = {
+ protocol: result.protocol,
+ host: result.host,
+ port: result.port,
+ username: result.username || '',
+ displayName: result.host,
+ tags: [],
+ };
const sessionInfo = await window.go.api.Service.ConnectQuick(profile);
this.state.addSession(sessionInfo);
this.tabs.addTab(sessionInfo);
const panelId = `panel-${sessionInfo.id}`;
- if (protocol === 'raw') {
- this.rawViewer.createViewer(sessionInfo.id, panelId, { protocol, raw: {} });
+ if (result.protocol === 'raw') {
+ this.rawViewer.createViewer(sessionInfo.id, panelId, { protocol: 'raw', raw: {} });
} else {
- this.terminals.createTerminal(sessionInfo.id, panelId, { protocol });
+ this.terminals.createTerminal(sessionInfo.id, panelId, { protocol: result.protocol });
}
+
+ this.notifications.info(`Connecting to ${result.host}…`);
} catch (err) {
this.notifications.error('Quick connect failed: ' + err);
}