From 3274cb35dc8fbc1ebe6e82af3b0545eaf75fc627 Mon Sep 17 00:00:00 2001 From: seanlu99 Date: Thu, 11 Jul 2019 18:33:21 -0700 Subject: [PATCH] Issue #107 - Condensed playback component and moved it to lower navigation bar --- ait/gui/__init__.py | 8 +- ait/gui/static/css/ait/gui/Playback.css | 21 +-- ait/gui/static/index.html | 2 +- ait/gui/static/js/ait/gui/Playback.js | 182 +++++++++++------------- 4 files changed, 104 insertions(+), 109 deletions(-) diff --git a/ait/gui/__init__.py b/ait/gui/__init__.py index 7bc5ab86..e852fe4b 100644 --- a/ait/gui/__init__.py +++ b/ait/gui/__init__.py @@ -25,7 +25,7 @@ from ait.core import api, cmd, db, dmc, evr, limits, log, notify, pcap, tlm, gds, util from ait.core.server.plugin import Plugin import copy -from datetime import datetime +from datetime import datetime, timedelta from Queue import Queue class Session (object): @@ -1035,9 +1035,13 @@ def handle(): # Add start time and end time to ranges point_query = 'SELECT * FROM "{}"'.format(packet_name) points = list(dbconn.query(point_query).get_points()) - start_time = points[0]['time'] + start_time = points[0]['time'][:19] + 'Z' ranges[i].append(start_time) end_time = points[len(points) - 1]['time'] + dt = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S.%fZ') + if dt.microsecond != 0: + dt += timedelta(0, 1) + end_time = dt.strftime('%Y-%m-%dT%H:%M:%SZ') ranges[i].append(end_time) return json.dumps(ranges) diff --git a/ait/gui/static/css/ait/gui/Playback.css b/ait/gui/static/css/ait/gui/Playback.css index c4da348e..3a132030 100644 --- a/ait/gui/static/css/ait/gui/Playback.css +++ b/ait/gui/static/css/ait/gui/Playback.css @@ -1,30 +1,31 @@ -.timeline { - width: 80%; - position: relative; - margin: 50px 10% 50px 10%; +ait-playback { + display: block; + height: 300px; } -.slider { - width: 100%; +ait-playback .timeline { + width: 80%; + position: relative; + margin: 100px 10% 50px 10%; } -.timeline-start { +ait-playback .timeline-start { position: absolute; top: 20px; } -.timeline-end { +ait-playback .timeline-end { position: absolute; top: 20px; right: 0px; } -.timeline-current { +ait-playback .timeline-current { position: absolute; top: 40px; } -@keyframes move-dot { +ait-playback @keyframes move-dot { from {left: 0;} to {left: 100%;} } \ No newline at end of file diff --git a/ait/gui/static/index.html b/ait/gui/static/index.html index 9836e573..7868b1d9 100644 --- a/ait/gui/static/index.html +++ b/ait/gui/static/index.html @@ -156,7 +156,6 @@

1553 HS Currents

The current time

- @@ -194,6 +193,7 @@

The current time

+ diff --git a/ait/gui/static/js/ait/gui/Playback.js b/ait/gui/static/js/ait/gui/Playback.js index b51b2f05..1e228878 100644 --- a/ait/gui/static/js/ait/gui/Playback.js +++ b/ait/gui/static/js/ait/gui/Playback.js @@ -32,20 +32,15 @@ const Playback = { view(vnode) { - let range = [ - m('h3', 'Time ranges available in database'), - m('ul', - this._range.map(function(i) { - return m('li', [m('div', 'Telemetry packet: ' + i[0]), - m('div', 'Start time: ' + i[1]), - m('div', 'End time: ' + i[2])] - ) - }) - ) - ] + let range = m('div', {class: 'form-group'}, [ + m('label', 'Time ranges available'), + this._range.map(function(i) { + return m('div', i[0] + ': ' + i[1] + ' to ' + i[2]) + }) + ]) - let packets = m('div', {class: 'form-group'}, [ - m('label', 'Telemetry packet'), + let packets = m('div', {class: 'form-group col-xs-3'}, [ + m('label', 'Telemetry packet:'), m('select', { class: 'form-control', name: 'packet', @@ -53,95 +48,41 @@ const Playback = { [m('option', { disabled: 'disabled', selected: 'selected' - }, 'Select an option ...')].concat( - map(this._range, (k) => { - return m('option', {value: k[0]}, k[0]) + }, 'Select an option')].concat( + map(this._range, (i) => { + return m('option', {value: i[0]}, i[0]) }) ) - ), - m('p', {class: 'help-block'}, 'Telemetry packet from database') + ) ]) if (this._validation_errors['packet']) { packets.attrs.className += ' has-error' } - let startTime = m('div', {class: 'form-group'}, [ - m('label', 'Start time'), - m('input', {class: 'form-control', placeholder: 'Start time YYYY-MM-DDTHH:MM:SSZ', name: 'startTime'}), - m('p', {class: 'help-block'}, 'Start time for data query. Expected format: YYYY-MM-DDTHH:MM:SSZ') + let startTime = m('div', {class: 'form-group col-xs-3'}, [ + m('label', 'Start time:'), + m('input', {class: 'form-control', placeholder: 'YYYY-MM-DDTHH:MM:SSZ', name: 'startTime'}) ]) if (this._validation_errors['startTime']) { startTime.attrs.className += ' has-error' } - let endTime = m('div', {class: 'form-group'}, [ - m('label', 'End time'), - m('input', {class: 'form-control', placeholder: 'End time YYYY-MM-DDTHH:MM:SSZ', name: 'endTime'}), - m('p', {class: 'help-block'}, 'End time for data query. Expected format: YYYY-MM-DDTHH:MM:SSZ') + let endTime = m('div', {class: 'form-group col-xs-3'}, [ + m('label', 'End time:'), + m('input', {class: 'form-control', placeholder: 'YYYY-MM-DDTHH:MM:SSZ', name: 'endTime'}) ]) if (this._validation_errors['endTime']) { endTime.attrs.className += ' has-error' } - let queryBtn = m('button', - {class: 'btn btn-success pull-right', type: 'submit', id: 'playback-query'}, 'Query') - - let timeline = - m('div', {class:'timeline', style:'display:none'}, - [ - this._slider, - m('div', {class:'timeline-start'}, this._start_time), - m('div', {class:'timeline-end'}, this._end_time), - this._current_time, - ]) - - let playBtn = - m('button', - {class: 'btn btn-success pull-right', - onclick: (e) => { - this.start_slider(vnode, this._end_time) - }, - style: 'display:none', - id: 'playback-control' - }, 'Play' - ) - - let pauseBtn = - m('button', - {class: 'btn btn-success pull-right', - onclick: (e) => { - this.stop_slider() - }, - style: 'display:none', - id: 'playback-control' - }, 'Pause' - ) - - let abortBtn = - m('button', - {class: 'btn btn-success pull-right', - onclick: (e) => { - vnode.dom.getElementsByClassName('timeline')[0].style.display = 'none' - this.stop_slider() - - let buttons = vnode.dom.getElementsByClassName('btn btn-success pull-right') - for (let i = 0; i < buttons.length; ++i) { - if (buttons[i].id == 'playback-control') - buttons[i].style.display = 'none' - if (buttons[i].id == 'playback-query') - buttons[i].style.display = 'block' - } - m.request({ - url: '/playback/abort', - method: 'PUT' - }) - }, - style: 'display:none', - id: 'playback-control' - }, 'Abort' - ) + let queryBtn = m('div', {class: 'form-group col-xs-3'}, [ + m('div', {style: 'height: 25px'}), + m('button', {class: 'btn btn-success', type: 'submit'}, 'Query') + ] + ) let form = m('form', { + class: 'form-row', onsubmit: (e) => { e.preventDefault() let form = e.currentTarget @@ -184,24 +125,73 @@ const Playback = { vnode.dom.getElementsByClassName('timeline')[0].style.display = 'block' this._current_time = m('div', {class: 'timeline-current'}, 'Current time: ' + this._start_time) + vnode.dom.getElementsByClassName('btn btn-success')[0].style.display = 'none' let buttons = vnode.dom.getElementsByClassName('btn btn-success pull-right') for (let i = 0; i < buttons.length; ++i) { - if (buttons[i].id == 'playback-control') - buttons[i].style.display = 'block' - if (buttons[i].id == 'playback-query') - buttons[i].style.display = 'none' + buttons[i].style.display = 'block' } - }, - }, [ - m('h3', 'Query data from database'), - packets, - startTime, - endTime, - queryBtn, - ]) + }}, [ + packets, + startTime, + endTime, + queryBtn, + ] + ) + + let timeline = + m('div', {class:'timeline', style:'display:none'}, + [ + this._slider, + m('div', {class:'timeline-start'}, this._start_time), + m('div', {class:'timeline-end'}, this._end_time), + this._current_time, + ]) + + let playBtn = + m('button', + {class: 'btn btn-success pull-right', + onclick: (e) => { + this.start_slider(vnode, this._end_time) + }, + style: 'display:none' + }, 'Play' + ) + + let pauseBtn = + m('button', + {class: 'btn btn-success pull-right', + onclick: (e) => { + this.stop_slider() + }, + style: 'display:none' + }, 'Pause' + ) + + let abortBtn = + m('button', + {class: 'btn btn-success pull-right', + onclick: (e) => { + this.stop_slider() + vnode.dom.getElementsByClassName('timeline')[0].style.display = 'none' + vnode.dom.getElementsByClassName('btn btn-success')[0].style.display = 'inline-block' + let buttons = vnode.dom.getElementsByClassName('btn btn-success pull-right') + for (let i = 0; i < buttons.length; ++i) { + buttons[i].style.display = 'none' + } + + m.request({ + url: '/playback/abort', + method: 'PUT' + }) + }, + style: 'display:none' + }, 'Abort' + ) + + let controls = [abortBtn, pauseBtn, playBtn] return m('ait-playback', vnode.attrs, [ - range, form, timeline, abortBtn, pauseBtn, playBtn + range, form, timeline, controls ]) },