diff --git a/network-poc/static/index.html b/network-poc/static/index.html
index a5e74c7..e8ba4c8 100644
--- a/network-poc/static/index.html
+++ b/network-poc/static/index.html
@@ -1105,10 +1105,11 @@
-
@@ -1982,13 +1983,105 @@
return false;
}
+ // Dropdown-autocompletionin tila
+ const dropdown = document.getElementById('term-dropdown');
+ let dropdownItems = [];
+ let dropdownIdx = -1;
+ let dropdownPrefix = ''; // Inputin alku joka säilyy valinnan yhteydessä
+
+ function getCandidates(val) {
+ const words = val.trimEnd().split(/\s+/);
+ for (let depth = words.length; depth >= 1; depth--) {
+ const prefix = words.slice(0, depth).join(' ');
+ const partial = words[depth] || '';
+ // Esimerkkipromptit
+ if (kpnExamples[prefix] && !partial) {
+ return { items: kpnExamples[prefix], prefix: prefix + ' ' };
+ }
+ // Komennot
+ const candidates = kpnCommands[prefix];
+ if (candidates) {
+ const matches = partial ? candidates.filter(c => c.startsWith(partial)) : candidates;
+ if (matches.length > 0) {
+ return { items: matches, prefix: prefix + ' ' };
+ }
+ }
+ }
+ if (!val.trim()) return { items: kpnCommands['kpn'] || [], prefix: 'kpn ' };
+ return { items: [], prefix: val };
+ }
+
+ function showDropdown(items, prefix) {
+ if (!dropdown || items.length === 0) { hideDropdown(); return; }
+ dropdownItems = items;
+ dropdownPrefix = prefix;
+ dropdownIdx = -1;
+ dropdown.innerHTML = items.map((item, i) =>
+ `${esc(item)}
`
+ ).join('');
+ dropdown.style.display = 'block';
+
+ // Klikkaus-handlerit
+ dropdown.querySelectorAll('.term-dd-item').forEach(el => {
+ el.addEventListener('mouseenter', () => highlightDropdown(parseInt(el.dataset.idx)));
+ el.addEventListener('click', () => { selectDropdown(); termInput.focus(); });
+ });
+ }
+
+ function hideDropdown() {
+ if (dropdown) { dropdown.style.display = 'none'; dropdown.innerHTML = ''; }
+ dropdownItems = [];
+ dropdownIdx = -1;
+ }
+
+ function highlightDropdown(idx) {
+ dropdownIdx = idx;
+ dropdown.querySelectorAll('.term-dd-item').forEach((el, i) => {
+ el.style.background = i === idx ? '#30363d' : 'transparent';
+ el.style.color = i === idx ? '#58a6ff' : '#c9d1d9';
+ });
+ // Varmistetaan näkyvyys
+ const active = dropdown.children[idx];
+ if (active) active.scrollIntoView({ block: 'nearest' });
+ }
+
+ function selectDropdown() {
+ if (dropdownIdx >= 0 && dropdownIdx < dropdownItems.length) {
+ termInput.value = dropdownPrefix + dropdownItems[dropdownIdx] + (dropdownItems[dropdownIdx].startsWith('"') ? '' : ' ');
+ }
+ hideDropdown();
+ }
+
termInput?.addEventListener('keydown', (e) => {
+ // Dropdown auki: nuolet navigoi, Enter/Tab valitsee, Esc sulkee
+ if (dropdown && dropdown.style.display === 'block') {
+ if (e.key === 'ArrowDown') {
+ e.preventDefault();
+ highlightDropdown(Math.min(dropdownIdx + 1, dropdownItems.length - 1));
+ return;
+ }
+ if (e.key === 'ArrowUp') {
+ e.preventDefault();
+ highlightDropdown(Math.max(dropdownIdx - 1, 0));
+ return;
+ }
+ if ((e.key === 'Enter' || e.key === 'Tab') && dropdownIdx >= 0) {
+ e.preventDefault();
+ selectDropdown();
+ return;
+ }
+ if (e.key === 'Escape') {
+ e.preventDefault();
+ hideDropdown();
+ return;
+ }
+ }
+
if (e.key === 'Tab' && e.shiftKey) {
- // Shift-TAB: poista viimeinen sana (tai lainausmerkkien sisältö)
e.preventDefault();
+ hideDropdown();
const val = termInput.value.trimEnd();
if (!val) return;
- // Jos päättyy lainausmerkkeihin, poista koko lainattu osa
const quoteMatch = val.match(/^(.+\s)".*"?$|^(.+\s)'.*'?$/);
if (quoteMatch) {
termInput.value = (quoteMatch[1] || quoteMatch[2]).trimEnd() + ' ';
@@ -1998,18 +2091,26 @@
}
} else if (e.key === 'Tab') {
e.preventDefault();
- tabComplete(termInput);
+ // Näytä dropdown tai täydennä jos vain yksi vaihtoehto
+ const { items, prefix } = getCandidates(termInput.value);
+ if (items.length === 1) {
+ termInput.value = prefix + items[0] + (items[0].startsWith('"') ? '' : ' ');
+ hideDropdown();
+ } else if (items.length > 1) {
+ showDropdown(items, prefix);
+ }
} else if (e.key === 'Enter') {
+ hideDropdown();
const cmd = termInput.value.trim();
if (cmd) termExec(cmd);
termInput.value = '';
- } else if (e.key === 'ArrowUp') {
+ } else if (e.key === 'ArrowUp' && !dropdown?.style.display?.includes('block')) {
e.preventDefault();
if (termHistIdx < termHistory.length - 1) {
termHistIdx++;
termInput.value = termHistory[termHistIdx];
}
- } else if (e.key === 'ArrowDown') {
+ } else if (e.key === 'ArrowDown' && !dropdown?.style.display?.includes('block')) {
e.preventDefault();
if (termHistIdx > 0) {
termHistIdx--;
@@ -2021,6 +2122,11 @@
}
});
+ // Suljetaan dropdown kun klikataan muualle
+ document.addEventListener('click', (e) => {
+ if (!termInput?.contains(e.target) && !dropdown?.contains(e.target)) hideDropdown();
+ });
+
// Klikkaa terminaalipaneelia → fokusoi input
termPanel?.addEventListener('click', () => termInput?.focus());