var start = null; var end = null; var tags = new Set(); var highlight = null; // add a cell to the given row, put link to event(id) with given content function addCell(row,content,id){ var a = document.createElement('a'); if (content){ a.onclick = e => showOverlay('/static/event?id='+id); a.innerHTML = content; } row.insertCell().appendChild(a); } // add a row to the table, fill with event data from json function addRow(json){ var table = element('eventlist'); var row = table.insertRow(1); row.id = json.id; if (json.tags){ var tagList = json.tags.join(' '); row.setAttribute('class',tagList); } //addCell(row,json.id,json.id); addCell(row,json.start,json.id); addCell(row,json.title,json.id); addCell(row,json.location,json.id); row.appendChild(createTags(json.tags)); } function createNewEvent(){ var s = ''; var url = location.href; console.log(url); var pos = url.indexOf("?"); if (pos>0) { s = url.substring(pos); url = url.substring(0,pos); console.log({url:url,search:s}); } location.href = url+'static/edit'+s; } function createTags(tagList){ var td = document.createElement('td'); tagList.forEach(val => { var btn = document.createElement('button'); btn.onclick = e => toggleTag(val); btn.appendChild(document.createTextNode(val)); td.appendChild(btn); td.appendChild(document.createTextNode(' ')); }); return td; } // fetch events in the time range, then call handleEvents function fetchEvents(start, end){ var path = '/api/events/json'; if (start) { path += '?start='+start; if (end) path+= '&end='+end; } fetch(path).then(handleEvents); } function fetchLastMonth(){ var startDate = new Date(Date.parse(start+'-01')); var month = startDate.getMonth() +1; var year = startDate.getFullYear(); month -= 1; if (month < 1) { year--; month+=12; } end = start; start = year + '-' + (month<10 ? '0' : '') + month; fetchEvents(start,end); } function fetchLastYear(){ var startDate = new Date(Date.parse(start+'-01')); var month = startDate.getMonth() +1; var year = startDate.getFullYear(); if (month <= 1) year --; month = 1; start = year + '-' + (month<10 ? '0' : '') + month; fetchEvents(start,end); } // add the events fetched with the latest request to the table async function handleEvents(response){ if (response.ok){ var json = await response.json(); json.forEach(addRow); updateTagVisibility(); if (highlight){ var row = element(highlight); if (row) { row.classList.add('highlight'); row.scrollIntoView({behavior: 'smooth',block: 'center'}); } } } } // called when page is loaded function loadCurrentEvents(){ let params = new URLSearchParams(location.search); highlight = params.get('id'); var tagString = params.get('tags'); if (tagString){ tagString.split(',').forEach(t => { tags.add(t.trim()); }); } if (start == null){ var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1; start = year + '-' + (month < 10 ? '0' : '') + month; fetchEvents(start,end); } } function openIcal(){ var url = location.href; var query = location.search; var params = new URLSearchParams(query); var tags = params.get('tags'); var pos = url.indexOf('?'); if (pos>1) url = url.substring(0,pos); if (!url.endsWith('/')) url += '/'; url += 'api/events/ical'+query; var elem = create('a'); elem.setAttribute('href',url); elem.setAttribute('download',(tags?tags.replace(',','+'):'calendar')+'.ics'); elem.click(); } // shows the given url in an overlayed iframe function showOverlay(url){ var div = element('overlay'); div.innerHTML = ''; var iframe = document.createElement('iframe'); iframe.src = url; div.appendChild(iframe); div.style.display = 'block'; div.onclick = e => div.style.display = 'none'; var closeBtn = document.createElement('div'); closeBtn.id = 'close_overlay'; closeBtn.innerHTML = '✖'; closeBtn.title = 'close overlay'; div.appendChild(closeBtn); } // adds or removes tag from set, updates shown tags function toggleTag(tag){ if (tags.has(tag)){ tags.delete(tag); } else { tags.add(tag); } updateUrl(); updateTagVisibility(); } // creates a button for each tag in tags set function updateTagVisibility(){ var selection = document.getElementById('tag_selection'); selection.innerHTML = 'Selected Tags: '; selection.style.display = tags.size > 0 ? 'block' : 'none'; tags.forEach(tag => { var btn = document.createElement('button'); btn.onclick = e => toggleTag(tag); btn.innerHTML = tag; selection.appendChild(btn); selection.appendChild(document.createTextNode(' ')); }); var table = document.getElementById('eventlist'); for (var tr of table.getElementsByTagName('tr')){ var classes = tr.getAttribute('class'); if (classes =='head') continue; var all = true; tags.forEach(tag => { if (classes.indexOf(tag)<0) all = false; }); tr.style.display = all ? 'table-row' : 'none'; } } function updateUrl(){ var url = location.href; var pos = url.indexOf('?'); if (pos>0) url = url.substring(0,pos); var params = []; if (highlight) params.push('id='+highlight); if (start) params.push('start='+start); var tagString = Array.from(tags).join(','); if (tagString) params.push('tags='+tagString); var query = params.join('&'); if (query) url += '?'+query; window.history.pushState(null,"",url); }