function advancedSearch() { return { gopen: false, bopen: false, dopen: false, copen: false, loading: false, submitDisabled: true, g: {}, b: {}, d: {}, c: {}, tagName(type, id) { if (type === 'b') { return this.b.find(i => i.id == id).label; } else if (type === 'c') { return this.c.find(i => i.id == id).code; } else if (type === 'g') { try { return this.g.find(i => i.id == id).label; } catch(err) { return; } } else if (type === 'd') { try { return this.d.find(i => i.id == id).code; } catch (err) { return; } } }, gid: null, bid: [], did: null, cid: [], date: {}, search() { generateRequest(this.did, this.cid, this.date.from, this.date.to, this.bid); }, // Triggers when an entry is selected from any of the dropdowns selectEntry(element, entry) { const selType = element.id.split('-')[1]; console.debug(selType); if (selType === 'group') { element.parentElement.querySelectorAll('a').forEach(el => el.classList.remove('is-active')); element.classList.add('is-active'); // update variables; this.bid = []; this.gid = entry; this.gopen = false; } else if (selType === 'body') { // toggle element.classList.toggle('is-active'); // update variables; this.bid.indexOf(entry) === -1 ? this.bid.push(entry) : this.bid = this.bid.filter(function(id) { return id !== entry}); this.bopen = false; // add tag } else if (selType === 'desc') { // highlight element.parentElement.querySelectorAll('a').forEach(el => el.classList.remove('is-active')); element.classList.add('is-active'); // update variables; this.cid = []; this.did = entry; console.debug(this.did); this.dopen = false; } else if (selType === 'crit') { // toggle element.classList.toggle('is-active'); // update variables; this.cid.indexOf(entry) === -1 ? this.cid.push(entry) : this.cid = this.cid.filter(function(id) { return id !== entry}); this.copen = false; // add tag } this.submitDisabled = !(this.bid.length > 0 && this.cid.length > 0); }, getDropdownData(dropdown) { this.loading = true; let url = BASE_URL; switch(dropdown) { case 'g': url += '/interface/dropdowns/watergroups'; break; case 'b': url += '/interface/dropdowns/waterbodies?group_id=' + this.gid; break; case 'd': url += '/interface/dropdowns/descriptors?body_id=' + this.bid; break; case 'c': url += '/interface/dropdowns/criterias?desc_id=' + this.did; break; } fetch(url) .then(res => res.json()) .then(data => { this.isLoading = false; eval('this.' + dropdown + '=data'); console.debug(data); }); }, loadCal() { const calendars = bulmaCalendar.attach('[type=date]', {dateFormat: 'dd/MM/yyyy', isRange: true, minDate: '01/01/1990'}); // Loop on each calendar initialized calendars.forEach(calendar => { calendar.on('save', data => { this.date = { from: calendar.startDate.toLocaleDateString(), to: calendar.endDate.toLocaleDateString() } }); }); } }; } function makeRequestsGrid() { window.requestsGrid = new gridjs.Grid({ columns: ['UUID', 'Criterias', { name: 'Requested At', }, { name: 'Status', }, { name: 'Actions', formatter: (cell, row) => { if (cell == 'f') { return ""; } return gridjs.h('button', { className: 'py-2 mb-4 px-4 border rounded-md text-white bg-blue-600', onClick: () => downloadOneFile(row.cells[0].data) }, 'Download'); } }], search: false, server: { url: BASE_URL + '/actions/requests/', then: data => data.map(reqs => [reqs.uuid, reqs.criterias, reqs.requested_at, reqs.status, reqs.downloadable]) } }).render(document.getElementById('grid-requests')); setInterval(function() { requestsGrid.forceRender(); }, 20000); } function refreshRequestGrid() { requestsGrid.forceRender(); } function downloadOneFile(fileUUID) { const url = BASE_URL + '/actions/data/download?uuid=' + fileUUID; fetch(url,{ "credentials": "include", "headers": { "Accept": "application/zip", "Accept-Language": "en-US,en;q=0.5", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Pragma": "no-cache", "Cache-Control": "no-cache" }, "method": "GET", "mode": "cors"} ) .then(res => { return res.blob(); }) .then(data => { var a = document.createElement("a"); a.href = window.URL.createObjectURL(data); a.download = fileUUID; a.click(); }); } /** * Submit a request to the server and returns the entry inserted * @param {number} desc * @param {number} crit * @return {json} */ function generateRequest(desc, crit, from, to, bodyId=null) { console.debug('requesting data'); const url = BASE_URL + `/actions/data/search?bodyId=${bodyId}&dateFrom=${from}&dateTo=${to}&critId=${crit}`; fetch(url) .then(res => { return res.json(); }).then(data => { db.requests.add({ uuid: data.uuid, parameters: data.parameters, status: data.status }).then(d => { alert('Request complete. Check the request tab'); requestsGrid.forceRender(); }); }); } /** * Function to request data for a specific entity such as station or cruise * @param {number} desc - The descriptor id * @param {number} crit - The criteria id * @param {string} from - The start date for which the data is to be requested * @param {string} to - The end date for which the data is to be requested * @param {string} entityGroup - The entity group (e.g. cruise station, argo, wfd station) * @param {string} entityId - The entity feature id (e.g. station id) * @return {null} */ function requestEntityData(desc, crit, from, to, entityGroup, entityId) { const url = BASE_URL + `/actions/data/search?entityGroup=${entityGroup}&entityId=${entityId}&dateFrom=${from}&dateTo=${to}&critId=${crit}`; fetch(url) .then(res => { return res.json(); }).then(data => { db.requests.add({ uuid: data.uuid, parameters: data.parameters, status: data.status }).then(d => { alert('Request complete. Check the request tab'); requestsGrid.forceRender(); }); }); } /** * Function to request data for a specific entity that has an external source * @param {number} desc - The descriptor id * @param {number} crit - The criteria id * @param {string} from - The start date for which the data is to be requested * @param {string} to - The end date for which the data is to be requested * @param {string} entityGroup - The entity group (e.g. cruise station, argo, wfd station) * @param {string} entityId - The entity feature id (e.g. station id) * @return {null} */ function requestExternalData(desc, crit, from, to, entityGroup, entityId) { console.debug('requesting external data'); const url = BASE_URL + `/src/data/request_external_data.php?entityGroup=${entityGroup}&entityId=${entityId}&dateFrom=${from}&dateTo=${to}&critId=${crit}`; fetch(url) .then(res => { return res.blob(); }).then(data => { const url = window.URL.createObjectURL(data); const a = document.createElement('a'); a.href = url; a.download = `external_data-${entityId}.json`; a.click(); }); } function clearRequests() { let url = BASE_URL + `/actions/requests/`; if (confirm('Clear requests list?')) { fetch(url, { method: 'DELETE' }) .then(response => { if (response.ok) requestsGrid.forceRender(); }); } else { console.log('Cancel'); } } function moreInfo() { return { entityGroup: selectedEntityGroup, entityId: selectedEntityId || Alpine.store('entity').id, dopen: false, copen: false, loading: false, isGrid: Alpine.store('entity').hasOwnProperty('cellcode'), d: {}, c: {}, tagName(type, id) { if (id == null) return; if (type === 'd') { return this.d.find(i => i.id == id).code; } else if (type === 'c') { return this.c.find(i => i.id == id).code; } }, did: null, cid: [], date: {}, search() { this.drawDataChart(); // check if entity has an external source if (this.$store.entity.hasOwnProperty('ctStationCode')) { requestExternalData(this.did, this.cid, this.date.from, this.date.to, this.entityGroup, this.entityId); } else { requestEntityData(this.did, this.cid, this.date.from, this.date.to, this.entityGroup, this.entityId); } }, selectEntry(element, entry) { console.debug(element.text.substr(0, element.text.indexOf(' '))); if (element.id.split('-')[1] === 'desc') { // highlight element.parentElement.querySelectorAll('a').forEach(el => el.classList.remove('is-active')); element.classList.add('is-active'); // update variables; this.cid = []; this.did = entry; this.dopen = false; } else if (element.id.split('-')[1] === 'crit') { // toggle element.classList.toggle('is-active'); // update variables; this.cid.indexOf(entry) === -1 ? this.cid.push(entry) : this.cid = this.cid.filter(function(id) { return id !== entry}); this.copen = false; // add tag } }, getDropdownData(dropdown) { this.loading = true; let url = BASE_URL; let gridCode; if (this.isGrid) { gridCode = Alpine.store('entity').cellcode.substr(0,4); } switch(dropdown) { case 'd': url += '/interface/descriptor_dropdown.php?entityid=' + this.entityId + '&cellcode=' + gridCode; break; case 'c': url += '/interface/criteria_dropdown.php?descriptor_id=' + this.did + '&cellcode=' + gridCode; break; } fetch(url) .then(res => res.json()) .then(data => { this.isLoading = false; eval('this.' + dropdown + '=data'); }); }, loadCal() { const calendars = bulmaCalendar.attach('[type=date]', {dateFormat: 'dd/MM/yyyy', isRange: true}); // Loop on each calendar initialized calendars.forEach(calendar => { calendar.on('save', data => { this.date = { from: calendar.startDate.toLocaleDateString(), to: calendar.endDate.toLocaleDateString() } }); }); }, populateFeatureGrid(grid) { const features = Alpine.store('entity'); console.debug(features); const featureCols = Object.getOwnPropertyNames(Alpine.store('entity')).filter(name => aliasMap.has(name)); const featureVals = featureCols.map(col => {return {feature: aliasMap.get(col), value: features[col]}}); console.debug(featureVals); new gridjs.Grid({ data: featureVals }).render(grid); }, drawDataChart() { if (this.entityGroup != 'POSEIDON') return; const url = `/data/external/POSEIDON/${Alpine.store('entity').tspr}_${Alpine.store('entity').type}_${Alpine.store('entity').pid}`; fetch(url) .then(res => res.json()) .then(data => { this.isLoading = false; console.debug(data); }); const config = { type: 'line', data: data, options: { responsive: true, plugins: { legend: { position: 'top', }, title: { display: true, text: 'Chart.js Line Chart' } } }, }; } }; } function mruInfo() { return { dopen: false, copen: false, loading: false, d: {}, c: {}, tagName(type, id) { if (id == null) return; if (type === 'd') { return this.d.find(i => i.id == id).code; } else if (type === 'c') { return this.c.find(i => i.id == id).code; } }, bid: Alpine.store('mru').objectid, did: null, cid: [], date: {}, search() { generateRequest(this.did, this.cid, this.date.from, this.date.to, this.bid); }, selectEntry(element, entry) { console.debug(element.text.substr(0, element.text.indexOf(' '))); if (element.id.split('-')[1] === 'desc') { // highlight element.parentElement.querySelectorAll('a').forEach(el => el.classList.remove('is-active')); element.classList.add('is-active'); // update variables; this.cid = []; this.did = entry; this.dopen = false; } else if (element.id.split('-')[1] === 'crit') { // toggle element.classList.toggle('is-active'); // update variables; this.cid.indexOf(entry) === -1 ? this.cid.push(entry) : this.cid = this.cid.filter(function(id) { return id !== entry}); this.copen = false; // add tag } }, getDropdownData(dropdown) { this.loading = true; let url = BASE_URL; switch(dropdown) { case 'd': url += '/interface/descriptor_dropdown.php?bodyid=' + this.bid; break; case 'c': url += '/interface/criteria_dropdown.php?descriptor_id=' + this.did; break; } fetch(url) .then(res => res.json()) .then(data => { this.isLoading = false; eval('this.' + dropdown + '=data'); }); }, loadCal() { const calendars = bulmaCalendar.attach('[type=date]', {dateFormat: 'dd/MM/yyyy', isRange: true}); // Loop on each calendar initialized calendars.forEach(calendar => { calendar.on('save', data => { this.date = { from: calendar.startDate.toLocaleDateString(), to: calendar.endDate.toLocaleDateString() } }); }); }, populateFeatureGrid(grid) { console.debug(grid); const features = Alpine.store('mru'); const featureCols = Object.getOwnPropertyNames(Alpine.store('mru')).filter(name => aliasMap.has(name)); const featureVals = featureCols.map(col => {return {feature: aliasMap.get(col), value: features[col]}}); console.debug(featureVals); new gridjs.Grid({ data: featureVals }).render(grid); } }; }