Skip to content

Commit

Permalink
updated innsida-search to show search results
Browse files Browse the repository at this point in the history
  • Loading branch information
on committed Mar 3, 2026
1 parent 03187fd commit bb9073d
Showing 1 changed file with 207 additions and 21 deletions.
228 changes: 207 additions & 21 deletions scripts/innsida-search/innsida-search.user.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// ==UserScript==
// @name Innsida - Quick Search
// @namespace https://git.ntnu.no/M365-Drift/MonkeyMagic/
// @version 1.2.1
// @description `Ctrl` + `Shift` + `F` to search on Innsida
// @version 2.1.0
// @description `Ctrl` + `Shift` + `F` to search on Innsida with real-time results
// @author Øyvind Nilsen (on@ntnu.no)
// @match https://innsida.ntnu.no/*
// @grant none
Expand All @@ -15,26 +15,48 @@
(function() {
'use strict';

let currentSelection = 0; // 0 = input box, 1+ = menu items
let currentSelection = 0;
let menuItems = [];
let links = [];
let searchResults = [];
let searchMode = false;
let searchDebounceTimeout;
let abortController;

// Language support
const translations = {
en: {
searchPlaceholder: 'Search Innsida...',
mineNotFound: 'Mine div not found, using default links',
linksFound: 'Found {count} links in "mine" section'
linksFound: 'Found {count} links in "mine" section',
searching: 'Searching...',
noResults: 'No results found',
quickLinks: 'Quick Links',
searchResults: 'Search Results',
typeToSearch: 'Type to search...',
enterToSearchAll: 'Press Enter to see all results'
},
nb: {
searchPlaceholder: 'Søk på Innsida...',
mineNotFound: 'Mine-div ikke funnet, bruker standardlenker',
linksFound: 'Fant {count} lenker i "mine"-seksjonen'
linksFound: 'Fant {count} lenker i "mine"-seksjonen',
searching: 'Søker...',
noResults: 'Ingen resultater funnet',
quickLinks: 'Hurtiglenker',
searchResults: 'Søkeresultater',
typeToSearch: 'Skriv for å søke...',
enterToSearchAll: 'Trykk Enter for å se alle resultater'
},
nn: {
searchPlaceholder: 'Søk på Innsida...',
mineNotFound: 'Mine-div ikkje funne, brukar standardlenkjer',
linksFound: 'Fann {count} lenkjer i "mine"-seksjonen'
linksFound: 'Fann {count} lenkjer i "mine"-seksjonen',
searching: 'Søkjer...',
noResults: 'Ingen resultat funne',
quickLinks: 'Hurtiglenkjer',
searchResults: 'Søkjeresultat',
typeToSearch: 'Skriv for å søkje...',
enterToSearchAll: 'Trykk Enter for å sjå alle resultat'
}
};

Expand Down Expand Up @@ -68,23 +90,26 @@
container.style.borderRadius = '8px';
container.style.padding = '20px';
container.style.boxShadow = '0 4px 20px rgba(0,0,0,0.3)';
container.style.minWidth = '300px';
container.style.minWidth = '400px';
container.style.maxHeight = '80vh';
container.style.overflowY = 'auto';

// Create and style the input box
const inputBox = document.createElement('input');
inputBox.type = 'text';
inputBox.style.width = '100%';
inputBox.style.padding = '10px';
inputBox.style.padding = '12px';
inputBox.style.fontSize = '16px';
inputBox.style.border = '2px solid #007acc';
inputBox.style.borderRadius = '4px';
inputBox.style.marginBottom = '10px';
inputBox.style.outline = 'none';
inputBox.style.boxSizing = 'border-box';

// Create menu container
const menu = document.createElement('div');
menu.style.maxHeight = '500px';
menu.style.overflowY = 'auto';

container.appendChild(inputBox);
container.appendChild(menu);
Expand Down Expand Up @@ -126,38 +151,180 @@
];
}

function createMenu() {
// Fetch search results from Innsida API
async function fetchSearchResults(query) {
if (!query || query.length < 2) {
return [];
}

// Abort previous request if still in progress
if (abortController) {
abortController.abort();
}
abortController = new AbortController();

try {
// The actual Innsida search API endpoint
const url = `/api/search-api/query?site=innsida&q=${encodeURIComponent(query)}&pageSize=8&pageNr=1`;

console.log(`Fetching search results from: ${url}`);

const response = await fetch(url, { signal: abortController.signal });

if (!response.ok) {
console.log('Search API error:', response.status);
return [];
}

const data = await response.json();
console.log('Search results received:', {
numFound: data.numFound,
docsCount: data.docs?.length || 0,
sampleDoc: data.docs?.[0]
});

// Parse results from the 'docs' array
if (data.docs && Array.isArray(data.docs)) {
return data.docs.map(doc => ({
text: doc.title || doc.name || '',
url: doc.url || '',
description: doc.description || doc.teaser || '',
type: doc.type || 'document'
})).filter(r => r.text && r.url);
}

return [];
} catch (error) {
if (error.name !== 'AbortError') {
console.log('Search error:', error.message);
}
return [];
}
}

function createMenuItems(results) {
// Clear existing menu
menu.innerHTML = '';
menuItems = [];

// Load links from "mine" div only
links = loadLinksFromMine();
if (results.length === 0 && searchMode) {
const noResultsDiv = document.createElement('div');
noResultsDiv.textContent = t('noResults');
noResultsDiv.style.padding = '12px';
noResultsDiv.style.color = '#999';
noResultsDiv.style.textAlign = 'center';
noResultsDiv.style.fontStyle = 'italic';
menu.appendChild(noResultsDiv);
return;
}

links.forEach((link, index) => {
// Add section headers and items
results.forEach((item) => {
const menuItem = document.createElement('div');
menuItem.textContent = link.text;
menuItem.style.padding = '8px 12px';
menuItem.style.padding = '10px 12px';
menuItem.style.cursor = 'pointer';
menuItem.style.borderRadius = '4px';
menuItem.style.marginBottom = '2px';
menuItem.style.marginBottom = '4px';
menuItem.style.backgroundColor = '#f5f5f5';
menuItem.style.border = '1px solid transparent';
menuItem.style.whiteSpace = 'nowrap';
menuItem.style.overflow = 'hidden';
menuItem.style.textOverflow = 'ellipsis';
menuItem.dataset.url = link.url;
menuItem.title = link.url; // Show full URL on hover
menuItem.style.transition = 'background-color 0.2s';
menuItem.dataset.url = item.url;

const titleDiv = document.createElement('div');
titleDiv.textContent = item.text;
titleDiv.style.fontWeight = '500';
titleDiv.style.whiteSpace = 'nowrap';
titleDiv.style.overflow = 'hidden';
titleDiv.style.textOverflow = 'ellipsis';
menuItem.appendChild(titleDiv);

if (item.description) {
const descDiv = document.createElement('div');
descDiv.textContent = item.description;
descDiv.style.fontSize = '12px';
descDiv.style.color = '#666';
descDiv.style.marginTop = '2px';
descDiv.style.whiteSpace = 'nowrap';
descDiv.style.overflow = 'hidden';
descDiv.style.textOverflow = 'ellipsis';
menuItem.appendChild(descDiv);
}

menuItem.title = item.url;

menuItem.addEventListener('click', function() {
window.location.href = link.url;
window.location.href = item.url;
});

menuItem.addEventListener('mouseenter', function() {
currentSelection = menuItems.indexOf(menuItem) + 1;
updateSelection();
});

menu.appendChild(menuItem);
menuItems.push(menuItem);
});
}

function createMenu() {
// Load and display quick links
links = loadLinksFromMine();
createMenuItems(links);
searchMode = false;
}

async function updateSearchResults(query) {
if (!query || query.length < 2) {
createMenuItems(links);
searchMode = false;
return;
}

searchMode = true;
currentSelection = 0;

// Show searching state
menu.innerHTML = '';
const searchingDiv = document.createElement('div');
searchingDiv.textContent = t('searching');
searchingDiv.style.padding = '12px';
searchingDiv.style.color = '#999';
searchingDiv.style.textAlign = 'center';
menu.appendChild(searchingDiv);

const results = await fetchSearchResults(query);

if (results.length > 0) {
createMenuItems(results);
searchResults = results;
} else {
// Show no results or fallback message
menu.innerHTML = '';
const noResultsDiv = document.createElement('div');
if (searchResults.length === 0) {
// Try pressing Enter to search on full Innsida search page
const infoDiv = document.createElement('div');
infoDiv.textContent = t('noResults');
infoDiv.style.padding = '12px';
infoDiv.style.color = '#999';
infoDiv.style.textAlign = 'center';
infoDiv.style.fontSize = '12px';
infoDiv.style.marginBottom = '8px';
menu.appendChild(infoDiv);

const hintDiv = document.createElement('div');
hintDiv.textContent = t('enterToSearchAll');
hintDiv.style.padding = '8px';
hintDiv.style.color = '#aaa';
hintDiv.style.textAlign = 'center';
hintDiv.style.fontSize = '11px';
hintDiv.style.fontStyle = 'italic';
menu.appendChild(hintDiv);
}
}
updateSelection();
}

function updateSelection() {
// Reset all styles
inputBox.style.borderColor = '#007acc';
Expand Down Expand Up @@ -187,7 +354,11 @@
container.style.display = 'none';
inputBox.value = '';
currentSelection = 0;
searchMode = false;
updateSelection();
if (abortController) {
abortController.abort();
}
}

function showContainer() {
Expand All @@ -208,6 +379,21 @@
}
});

// Real-time search on input
inputBox.addEventListener('input', function(event) {
const query = event.target.value.trim();

// Clear existing debounce timeout
if (searchDebounceTimeout) {
clearTimeout(searchDebounceTimeout);
}

// Debounce search requests (300ms delay)
searchDebounceTimeout = setTimeout(() => {
updateSearchResults(query);
}, 300);
});

// Handle navigation and actions
document.addEventListener('keydown', function(event) {
// Only handle keys when container is visible
Expand Down

0 comments on commit bb9073d

Please sign in to comment.