(function() { 'use strict'; // AJ Query var $ = window.$; var $$ = window.$$; var state = { account: { schedules: [] } }; var $grantTpl; var $devTpl; var $updateTpl; var $headerTpl; var $webhookTpl; var $webhookHeaderTpl; function pad(i) { i = String(i); while (i.length < 2) { i = '0' + i; } return i; } function run() { $headerTpl = $('.js-new-webhook .js-header').outerHTML; $webhookHeaderTpl = $('.js-schedule .js-webhook .js-header').outerHTML; $('.js-schedule .js-webhooks .js-headers').innerHTML = ''; $webhookTpl = $('.js-schedule .js-webhook').outerHTML; $('.js-schedule .js-webhooks').innerHTML = ''; // after blanking all inner templates $devTpl = $('.js-schedule').outerHTML; var $form = $('.js-new-schedule'); // Pick a date and time on an even number // between 10 and 15 minutes in the future var d = new Date(Date.now() + 10 * 60 * 1000); var minutes = d.getMinutes() + (5 - (d.getMinutes() % 5)) - d.getMinutes(); d = new Date(d.valueOf() + minutes * 60 * 1000); $('.js-date', $form).value = d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()); $('.js-time', $form).value = pad(d.getHours()) + ':' + pad(d.getMinutes()); $('.js-url', $form).value = 'https://enfqtbjh5ghw.x.pipedream.net'; console.log('hello'); $('body').addEventListener('click', function(ev) { if (ev.target.matches('.js-new-header')) { newWebhookHeader(ev.target); } else if (ev.target.matches('.js-rm-header')) { rmWebhookHeader(ev.target); } else if (ev.target.matches('.js-delete') && ev.target.closest('.js-webhook')) { deleteWebhook(ev.target.closest('.js-webhook')); } else { return; } ev.preventDefault(); ev.stopPropagation(); }); $('body').addEventListener('change', function(ev) { var $hook = ev.target.closest('.js-new-webhook'); if (ev.target.matches('.js-url') && $hook) { if (!$('.js-comment', $hook).value) { $('.js-comment', $hook).value = ev.target.value.replace(/https:\/\//, '').replace(/\/.*/, ''); } } }); $('body').addEventListener('submit', function(ev) { if (ev.target.matches('.js-new-schedule')) { newSchedule(ev.target); } else if (ev.target.matches('.js-schedules-list')) { doLogin(); } else if (ev.target.matches('.js-schedules-new')) { scheduleTask(); } else { return; } ev.preventDefault(); ev.stopPropagation(); }); } function newSchedule() { var $hook = $('.js-new-schedule'); //var deviceId = $hook.closest('.js-new-schedule').querySelector('.js-id').value; var schedule = { date: $('.js-date', $hook).value, time: $('.js-time', $hook).value, tz: $('.js-tz', $hook).value, webhooks: [] }; var hook = { comment: $('.js-comment', $hook).value, method: $('.js-method', $hook).value, url: $('.js-url', $hook).value, headers: {} }; schedule.webhooks.push(hook); console.log('schedule:', schedule); $$('.js-header', $hook).forEach(function($head) { var key = $('.js-key', $head).value; var val = $('.js-value', $head).value; if (key && val) { hook.headers[key] = val; } }); hook.body = $('.js-body-template', $hook).value; // TODO update on template change and show preview var opts = { method: 'POST', headers: { Accept: 'application/json', Authorization: getToken(), 'Content-Type': 'application/json' }, body: JSON.stringify(schedule), cors: true }; /* state.account.devices .filter(function(d) { return d.accessToken == deviceId; })[0] .webhooks.push(hook); displayAccount(state.account); return; */ window.fetch('/api/v0/schedules', opts).then(function(resp) { return resp .json() .then(function(data) { if (!data.date || !data.webhooks) { console.error(data); throw new Error('something bad happened'); } state.account.schedules.push(resp.data); displayAccount(state.account); }) .catch(function(e) { window.alert(e.message); }); }); } function newWebhookHeader($newHeader) { var $hs = $newHeader.closest('.js-headers'); var $h = $newHeader.closest('.js-header'); var $div = document.createElement('div'); $div.innerHTML = $headerTpl; $hs.append($('.js-header', $div)); $newHeader.hidden = true; $('.js-rm-header', $h).hidden = false; $('.js-key', $h).required = 'required'; $('.js-value', $h).required = 'required'; } function rmWebhookHeader($rmHeader) { var $h = $rmHeader.closest('.js-header'); $h.parentElement.removeChild($h); } function deleteWebhook($hook) { var deviceId = $hook.closest('.js-schedule').querySelector('.js-id').value; var id = $('.js-id', $hook).innerText; var opts = { method: 'DELETE', headers: { Accept: 'application/json', Authorization: getToken() }, cors: true }; window.fetch('/api/iot/devices/' + deviceId + '/webhooks/' + id, opts).then(function(resp) { return resp.json().then(function(result) { if (!result.webhook) { console.error(result); window.alert('something went wrong: ' + JSON.stringify(result)); return; } var index = -1; var dev = state.account.devices.filter(function(d, i) { return d.accessToken == deviceId; })[0]; dev.webhooks.some(function(g, i) { if (g.id === id) { index = i; return true; } }); if (index > -1) { dev.webhooks.splice(index, 1); displayAccount(state.account); } }); }); } function displayAccount(data) { state.account = data; console.log('[debug] Display Account:'); console.log(data); var $devs = $('.js-schedules'); $devs.innerHTML = ''; data.schedules.forEach(function(d) { var $dev = $.create($devTpl); $('.js-id', $dev).value = d.id; $('.js-date', $dev).value = d.date; $('.js-time', $dev).value = d.time; $('.js-tz', $dev).value = d.tz; d.webhooks.forEach(function(h) { console.log('webhook', h); var $hook = $.create($webhookTpl); $('.js-id', $hook).innerText = h.id; $('.js-comment', $hook).innerText = h.comment; $('.js-method', $hook).innerText = h.method; $('.js-url', $hook).innerText = h.url; Object.keys(h.headers || {}).forEach(function(k) { var $header = $.create($webhookHeaderTpl); var v = h.headers[k]; $('.js-key', $header).innerText = k; $('.js-value', $header).innerText = v; $('.js-headers', $hook).innerHTML += $header.innerHTML; }); $('.js-body-template', $hook).innerText = h.body || ''; $('.js-webhooks', $dev).innerHTML += $hook.innerHTML; }); $devs.appendChild($dev); }); } console.info('[tzdb] requesting'); window.fetch('./tzdb.json').then(function(resp) { return resp.json().then(function(tzdb) { console.info('[tzdb] received'); var tz = Intl.DateTimeFormat().resolvedOptions().timeZone; var options = $$('.js-tz option'); var valOpt = options[0].outerHTML; // UTC //var spaceOpt = options[1].outerHTML; // ---- var innerHTML = $('.js-new-schedule .js-tz').innerHTML; /* innerHTML = '' + spaceOpt + innerHTML.replace(/>UTC/, '>    UTC'); */ //$('.js-tz').innerHTML += spaceOpt; //$('.js-tz').innerHTML += valOpt.replace(/UTC/g, 'custom'); Object.keys(tzdb) .sort() .forEach(function(k) { var parts = k.split(' '); //var sep = '── ' + parts[0]; var sep = parts[0]; if (parts[0] !== parts[1]) { sep += ' / ' + parts[1] + ' (DST)'; } //innerHTML += ''; innerHTML += ''; var areas = tzdb[k]; areas.forEach(function(_tz) { if (tz !== _tz) { innerHTML += valOpt.replace(/UTC/g, _tz); } else { innerHTML += ''; } }); innerHTML += ''; }); $('.js-new-schedule .js-tz').innerHTML = innerHTML; console.info('[tzdb] loaded'); run(); }); }); var allSchedules = []; function getToken() { return JSON.parse(localStorage.getItem('session')).access_token; } function doLogin() { localStorage.setItem( 'session', JSON.stringify({ access_token: $('.js-auth-token').value }) ); $('.js-schedules-list').hidden = true; return window .fetch('/api/v0/schedules', { headers: { Authorization: getToken() } }) .then(function(resp) { return resp .clone() .json() .then(function(schedules) { console.log('schedules'); console.log(schedules); allSchedules = schedules; renderSchedules(schedules); state.account.schedules = schedules; displayAccount(state.account); $('.js-account').hidden = false; }) .catch(function(e) { console.error("Didn't parse JSON:"); console.error(e); console.log(resp); $('.js-schedules-list').hidden = false; window.alert(resp.status + ': ' + resp.statusText); return resp.text().then(function(text) { window.alert(text); }); }); }) .catch(function(e) { console.error('Request Error'); console.error(e); window.alert('Network error. Are you online?'); }); } function renderSchedules(schedules) { document.querySelector('.js-schedules-output').innerText = JSON.stringify(schedules, null, 2); } function scheduleTask() { return window .fetch('/api/v0/schedules/new', { method: 'POST', headers: { Authorization: getToken(), 'Content-Type': 'application/json' }, body: JSON.stringify(task) }) .then(function(resp) { return resp.json().then(function(schedule) { console.log('New Schedule:', schedule); allSchedules.push(schedule); renderSchedules(allSchedules); }); }); } console.log('whatever'); $('.js-auth-token').value = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //window.addEventListener('load', run); })();