'use strict'; (function() { window.addEventListener('DOMContentLoaded', (event) => { setupPage(); }); function close_modal(node) { let current = node; while(current.nodeName != 'BACKDROP') { current = current.parentNode; if(current.nodeName === 'HTML') { console.error("can't find modal parent"); return; } } current.parentNode.removeChild(current); } function display_create_form() { const template = document.querySelector('template#create-form') .content.cloneNode(true); const form = template.querySelector('form'); form.addEventListener('submit', (event) => { event.preventDefault(); const id = crypto.randomUUID(); const name = form.name.value; if(!name) { return; } const description = form.description.value.trim(); make_api_request('POST', '/configs/' + id + '/create', {'name': name, 'description': description}) .then((response) => {display_configs(id)}) .then((response) => {close_modal(form)}) .catch((exception) => { console.error('creation failed for: '+id, exception); }); }); display_modal(template); } function display_configs(...config_ids) { const configs_parent = document.querySelector('configs'); const dlprefix = 'data:text/plain;charset:utf-8,'; config_ids.forEach((config_id) => { const template = document.querySelector('template#display-config') .content.cloneNode(true); const config = template.querySelector('config'); make_api_request('GET', '/configs/' + config_id) .then((data) => { config.id = 'config-' + config_id; config.querySelector('name').textContent = data.name; config.querySelector('date').textContent = data.created; config.querySelector('description').textContent = data.description; config.querySelector('data').textContent = data.data; config.querySelector('qrcode').replaceWith( QRCode({msg: data.data, dim: 280, pad: 0, ecl: 'M'})); const link = config.querySelector('.conffile'); link.setAttribute('href', dlprefix + encodeURIComponent(data.data)); link.setAttribute('download', data.name + '.conf'); config.querySelector('button.edit') .addEventListener('click', (event) => { display_edit_form(config_id, data); }); config.querySelector('button.download') .addEventListener('click', (event) => { link.click(); }); }); const old = configs_parent.querySelector('#config-'+config_id); if(old) { old.replaceWith(template); } else { configs_parent.appendChild(template); } }); } function display_edit_form(config_id, config) { const template = document.querySelector('template#update-form') .content.cloneNode(true); const form = template.querySelector('form'); form.name.value = config.name; form.description.value = config.description; form.addEventListener('submit', (event) => { event.preventDefault(); }); const save_button = form.querySelector('button.save'); save_button.addEventListener('click', (event) => { make_api_request('POST', '/configs/' + config_id + '/update', {'name': form.name.value, 'description': form.description.value.trim()}) .then((response) => {display_configs(config_id)}) .then((response) => {close_modal(form)}) .catch((exception) => { console.error('update failed for: '+config_id, exception); }); }); const delete_button = form.querySelector('button.delete'); delete_button.addEventListener('click', (event) => { if(!window.confirm('Are you sure you want to delete this client?')) { return; } make_api_request('POST', '/configs/' + config_id + '/delete') .then((response) => { document.querySelector('#config-'+config_id).remove(); }) .then((response) => {close_modal(form)}) .catch((exception) => { console.error('deletion failed for: '+config_id, exception); }); }); display_modal(template); } function display_modal(fragment) { const modal = document.querySelector('template#modal') .content.cloneNode(true); modal.querySelector('wrapper').appendChild(fragment); const backdrop = modal.querySelector('backdrop'); const cancel = modal.querySelector('button.cancel'); backdrop.addEventListener('click', (event) => { if(event.target === backdrop || event.target === cancel) { close_modal(backdrop); } }); document.querySelector('body').appendChild(modal); } function getCookies() { var out = new Object(); const cookies = document.cookie.split('; '); cookies.forEach((cookie) => { const temp = cookie.split('='); const name = temp[0]; const value = temp.slice(1).join('='); out[name] = value; }); return out; } function login() { const current_path = window.location.pathname; return window.location.replace('/api/login?return=' + current_path); } async function make_api_request(method, path, body) { const data = {'method': method, 'headers': {'Content-Type': 'application/json'}}; if(method != 'GET') { data['body'] = JSON.stringify(body); } const request = new Request('/api' + path, data); const response = await fetch(request); if(response.status === 403) { console.log('doing login'); login(); } return response.json(); } async function setupPage(route) { const configs = await make_api_request('GET', '/configs/'); const cookies = getCookies(); document.querySelector('user#banner-userid') .textContent = cookies['username']; document.querySelector('button#create-config') .addEventListener('click', (event) => { display_create_form(); }); await display_configs(...configs); } })();