Playing with cockpit-project.org.
| <head> | |
| <title>O A C I D S</title> | |
| <meta charset="utf-8"> | |
| <link href="../base1/cockpit.css" type="text/css" rel="stylesheet"> | |
| <link href="./oacids.css" type="text/css" rel="stylesheet"> | |
| <script src="../base1/jquery.js"></script> | |
| <script src="../base1/cockpit.js"></script> | |
| </head> | |
| <body> | |
| <div class="container-fluid"> | |
| <h2>Status</h2> | |
| </div> | |
| <div class="container-fluid"> | |
| <table id="ActivityEvents" class="listing"> | |
| <thead> | |
| <tr> | |
| <td colspan="2"> | |
| <h3>Current activity</h3> | |
| </td> | |
| </tr> | |
| </thead> | |
| <tbody id="EventTimeline"> | |
| </tbody> | |
| <tbody id="TimelineEnd" class="EventEnd "> | |
| <tr> | |
| <td> | |
| <div class="timeline timeline-end"> | |
| <i class="fa fa-caret-up timeline-point timeline-md"></i> | |
| <div class="listing-panel listing-maybe"> | |
| <div class="listing-head"> | |
| <div class="listing-actions"> | |
| <button class="btn btn-default">Do</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| <tbody class="oacidsEvent EventScheduled skeleton nominal" data-trigger-expected=""> | |
| <tr> | |
| <td> | |
| <div class="timeline timeline-end"> | |
| <span class="point-future wrapper"> | |
| <i class="fa fa-circle timeline-point timeline-md"></i> | |
| </span> | |
| <span class="point-failure timeline-point pficon pficon-warning-triangle-o"></span> | |
| <span class="point-success wrapper"> | |
| <i class="fa fa-check-circle-o timeline-point timeline-lg active"></i> | |
| </span> | |
| <div class="point-pending timeline-point timeline-md"> | |
| <div class="spinner"></div> | |
| </div> | |
| <div class="listing-panel listing-maybe"> | |
| <div class="listing-head"> | |
| <div class="listing-actions"> | |
| <button class="cancel btn btn-primary">Cancel</button> | |
| </div> | |
| <h3 class="v name">fedora-atomic: 24.2</h3> | |
| <div class="listing-status"> | |
| <span class="v Status">Available</span> | |
| </div> | |
| <ul class="nav nav-tabs nav-tabs-pf"> | |
| <li><a href="#">Tree</a></li> | |
| <li class="active"><a href="#">Packages</a></li> | |
| </ul> | |
| </div> | |
| <div class="listing-error alert" ng-if="error"> | |
| <span class="pficon pficon-warning-triangle-o"></span> | |
| There was an error | |
| </div> | |
| <div class="listing-body"> | |
| <div class="row"> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Expected</dt> | |
| <dd class="v expected">fedora-atomic</dd> | |
| <dt>id</dt> | |
| <dd class="v id">24.2</dd> | |
| <dt>Rrule</dt> | |
| <dd class="v rrule" title="2015-09-26 15:33">3 days ago</dd> | |
| </dl> | |
| </div> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Reference</dt> | |
| <dd class="v obj">10 packages</dd> | |
| <!-- | |
| <dt>Removals</dt> | |
| <dd>3 packages</dd> | |
| <dt>Changes</dt> | |
| <dd>18 packages</dd> | |
| --> | |
| </dl> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| <tbody class="EventMaybe skeleton"> | |
| <tr> | |
| <td> | |
| <div class="timeline"> | |
| <i class="fa fa-circle timeline-point"></i> | |
| <div class="listing-panel"> | |
| <div class="listing-head"> | |
| <div class="listing-actions"> | |
| <button class="btn btn-primary">Update and reboot</button> | |
| </div> | |
| <h3>fedora-atomic: 24.2</h3> | |
| <div class="listing-status"> | |
| Available | |
| </div> | |
| <ul class="nav nav-tabs nav-tabs-pf"> | |
| <li><a href="#">Tree</a></li> | |
| <li class="active"><a href="#">Packages</a></li> | |
| </ul> | |
| </div> | |
| <div class="listing-error alert" ng-if="error"> | |
| <span class="pficon pficon-warning-triangle-o"></span> | |
| There was an error | |
| </div> | |
| <div class="listing-body"> | |
| <div class="row"> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Operating System</dt> | |
| <dd>fedora-atomic</dd> | |
| <dt>Revision Number</dt> | |
| <dd>24.2</dd> | |
| <dt>Released</dt> | |
| <dd title="2015-09-26 15:33">3 days ago</dd> | |
| </dl> | |
| </div> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Additions</dt> | |
| <dd>10 packages</dd> | |
| <dt>Removals</dt> | |
| <dd>3 packages</dd> | |
| <dt>Changes</dt> | |
| <dd>18 packages</dd> | |
| </dl> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| <tbody class="active EventCurrent skeleton"> | |
| <tr> | |
| <td> | |
| <div class="timeline"> | |
| <i class="fa fa-check-circle-o timeline-point timeline-lg active"></i> | |
| <div class="listing-panel"> | |
| <div class="listing-head"> | |
| <div class="listing-actions"> | |
| </div> | |
| <div class="listing-status"> | |
| Installed | |
| </div> | |
| <h3>fedora-atomic: 24.1</h3> | |
| <ul class="nav nav-tabs nav-tabs-pf"> | |
| <li class="active"><a href="#">Tree</a></li> | |
| <li><a href="#">Packages</a></li> | |
| </ul> | |
| </div> | |
| <div class="listing-body"> | |
| <div class="row"> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Operating System</dt> | |
| <dd>fedora-atomic</dd> | |
| <dt>Revision Number</dt> | |
| <dd>24.1</dd> | |
| <dt>Released</dt> | |
| <dd title="2015-08-29 15:33">1 month ago</dd> | |
| </dl> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| <tbody class="EventPending skeleton"> | |
| <tr> | |
| <td> | |
| <div class="timeline"> | |
| <div class="timeline-point timeline-md"> | |
| <div class="spinner"></div> | |
| </div> | |
| <div class="listing-panel"> | |
| <div class="listing-head"> | |
| <div class="listing-actions"> | |
| </div> | |
| <div class="listing-status"> | |
| Downloading manifests 85% | |
| </div> | |
| <h3>fedora-atomic: 24.0</h3> | |
| <ul class="nav nav-tabs nav-tabs-pf"> | |
| <li class="active"><a href="#">Tree</a></li> | |
| <li><a href="#">Packages</a></li> | |
| </ul> | |
| </div> | |
| <div class="listing-body"> | |
| <div class="row"> | |
| <div class="col-sm-6"> | |
| <dl> | |
| <dt>Operating System</dt> | |
| <dd>fedora-atomic</dd> | |
| <dt>Revision Number</dt> | |
| <dd>24.1</dd> | |
| <dt>Released</dt> | |
| <dd title="2015-08-29 15:33">1 month ago</dd> | |
| </dl> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="container-fluid"> | |
| <table class="cockpit-form-table"> | |
| <tr> | |
| <td><label class="control-label" for="address">URL</label></td> | |
| <td><input class="form-control" id="address" value="8.8.8.8"></td> | |
| </tr> | |
| <tr> | |
| <td><button class="btn btn-default btn-primary" id="ping">Ping</button></td> | |
| <td><button class="btn btn-default btn-danger" disabled id="stop">Stop</button></td> | |
| </tr> | |
| </table> | |
| <p> | |
| <pre id="output" style="display: none;"> | |
| </pre> | |
| </p> | |
| <p id="failure" class="warning" style="display: none"></p> | |
| </div> | |
| <script src="./oacids.js"></script> | |
| <script> | |
| var proc = null; | |
| $(document).ready(function ( ) { | |
| console.log("fofoo bar"); | |
| }); | |
| $("#ping").on("click", function() { | |
| var output = $("#output"); | |
| output.text(""); | |
| output.show(); | |
| if (proc) | |
| proc.close("terminated"); | |
| $("#failure").empty(); | |
| var cmd = [ "ping", $("#address").val() ]; | |
| proc = cockpit.spawn(cmd, { "err": "out" }). | |
| stream(function(data) { | |
| output.append(document.createTextNode(data)); | |
| }). | |
| fail(function(ex) { | |
| $("#failure").show(). | |
| text(ex.toString()); | |
| }); | |
| $("#stop").prop("disabled", false); | |
| }); | |
| $("#stop").on("click", function() { | |
| $(this).prop("disabled", true); | |
| if (proc) | |
| proc.close("terminated"); | |
| proc = null; | |
| }); | |
| </script> | |
| </body> | |
| </html> | |
| { | |
| "version": 0, | |
| "dashboard": { | |
| "index": { | |
| "label": "O A C I D S" | |
| } | |
| }, | |
| "content-security-policy": "default-src 'self' 'unsafe-inline' 'unsafe-eval'" | |
| } |
| #ActivityEvents TBODY.nominal .listing-error { | |
| display: none; | |
| } | |
| #ActivityEvents TBODY.errors .listing-error { | |
| display: block; | |
| } | |
| #ActivityEvents .skeleton { | |
| display: none; | |
| } | |
| .oacidsEvent.nominal .point-future { | |
| display: inline; | |
| } | |
| .oacidsEvent.nominal .point-success, | |
| .oacidsEvent.nominal .point-failure, | |
| .oacidsEvent.nominal .point-pending { | |
| display: none; | |
| } | |
| .oacidsEvent.pending .point-pending { | |
| display: block; | |
| } | |
| .oacidsEvent.pending .point-success, | |
| .oacidsEvent.pending .listing-error.alert, | |
| .oacidsEvent.pending .point-future { | |
| display: none; | |
| } | |
| .oacidsEvent.success .point-success, | |
| .oacidsEvent.success.finished SPAN.point-success, | |
| .oacidsEvent.success.gone .point-success { | |
| display: inline; | |
| } | |
| .oacidsEvent.success .listing-error.alert, | |
| .oacidsEvent.gone.success .listing-error.alert, | |
| .oacidsEvent.success .point-failure { | |
| display: none; | |
| } | |
| .oacidsEvent.finished .point-pending, | |
| .oacidsEvent.finished .point-future { | |
| display: none; | |
| } | |
| .oacidsEvent.gone .point-success, | |
| .oacidsEvent.gone .point-pending, | |
| .oacidsEvent.finished.error .point-success { | |
| display: none; | |
| } | |
| .oacidsEvent.finished.error .point-failure { | |
| display: inline; | |
| } | |
| /* | |
| display: inline; | |
| display: block; | |
| display: none; | |
| .point-future | |
| .point-success | |
| .point-pending | |
| */ |
| // function openaps ( ) { return this; } | |
| jQuery.fn.reverse = function() { | |
| return this.pushStack(this.get().reverse(), arguments); | |
| }; | |
| var openaps = { }; | |
| openaps.BUS = 'org.openaps'; | |
| var SERVICE_IFACE = 'org.openaps.Service'; | |
| openaps.IFACE = { | |
| Service: SERVICE_IFACE | |
| , Instance: SERVICE_IFACE + '.Instance' | |
| , Heartbeat: SERVICE_IFACE + '.Instance.Heartbeat' | |
| , Do: SERVICE_IFACE + '.Do' | |
| , Scheduler: SERVICE_IFACE + '.Scheduler' | |
| , Trigger: SERVICE_IFACE + '.Trigger' | |
| }; | |
| var PATH = '/org/openaps/Services'; | |
| openaps.PATHS = { | |
| Service: PATH | |
| , Do: PATH + '/Do' | |
| , Heartbeat: PATH + '/Heartbeat' | |
| , Instance: PATH + '/Instance' | |
| , Scheduler: PATH + '/Scheduler' | |
| }; | |
| function update_event (dom, props) { | |
| } | |
| function create_event (cfg, path ) { | |
| var clone = cfg.clones.Scheduled.clone(true); | |
| // console.log('adding', clone, cfg.events.find("#TimelineEnd")); | |
| var trigger = openaps.dbus.proxy(openaps.IFACE.Trigger, path).wait(function ( ) { | |
| console.log("UPDATING TRIGGER", trigger.data.name, trigger.data.Status, trigger.data, path); | |
| clone.prop('data-trigger-expected', trigger.data.expected); | |
| clone.data('trigger-expected', trigger.data.expected); | |
| clone.find('H4').text(trigger.data.name); | |
| for (var field in this.data) { | |
| var selector = '.v.' + field; | |
| clone.find(selector).each(function ( ) { | |
| var target = $(this); | |
| target.filter('P, SPAN, DIV, H1, H2, H3, H4, H5, H6, SPAN, TT, DD').text(trigger.data[field]); | |
| }); | |
| } | |
| var prior = cfg.Activity.find('TBODY.EventScheduled').not('.skeleton'); | |
| // console.log("PRIOR", prior, prior.length, prior.is("TBODY")); | |
| if (prior.is("TBODY")) { | |
| var insertion = prior.filter(function (i, elem) { | |
| var $this = $(this); | |
| var expected = $this.data('trigger-expected'); | |
| if (expected >= trigger.data.expected) { | |
| return true; | |
| } | |
| return false; | |
| }); | |
| if (insertion && insertion.is('TBODY')) { | |
| var last = insertion.filter(":last"); | |
| last.after(clone); | |
| } else { | |
| prior.filter(":first").before(clone); | |
| } | |
| } else { | |
| cfg.Activity.find('#TimelineEnd').after(clone); | |
| } | |
| $(trigger).on('signal', function (ch, signal, args) { | |
| console.log("UPDATING TRIGGER", trigger.data.name, trigger.data.Status, trigger.data); | |
| // clone.filter('.EventScheduled').removeClass('nominal').toggleClass('pending', trigger.data.Status == 'Running'); | |
| clone.find('.timeline-end').toggleClass('timeline-end', trigger.data.Status == 'Armed'); | |
| switch (trigger.data.Status) { | |
| case 'Armed': | |
| clone.addClass('nominal').removeClass('pending'); | |
| break; | |
| case 'Running': | |
| clone.removeClass('EventScheduled'); | |
| clone.find('.listing-actions .cancel').prop('disabled', true); | |
| clone.removeClass('nominal').toggleClass('pending', true); | |
| clone.find('.listing-maybe').removeClass('listing-maybe'); | |
| break; | |
| case 'Fired': | |
| case 'Fire': | |
| case 'Fire': | |
| clone.removeClass('nominal').addClass('pending'); | |
| clone.find('.timeline-end').removeClass('timeline-end'); | |
| clone.find('.timeline-point').removeClass('timeline-end'); | |
| break; | |
| case 'Error': | |
| clone.removeClass('pending').addClass('error finished errors'); | |
| break; | |
| case 'Success': | |
| clone.removeClass('pending').addClass('active finished success'); | |
| break; | |
| case 'Done': | |
| case 'Finish': | |
| clone.removeClass('pending').addClass('finished'); | |
| break; | |
| case 'Remove': | |
| case 'Gone': | |
| clone.removeClass('pending').addClass('gone finished'); | |
| setTimeout(function ( ) { | |
| $(trigger).off('signal'); | |
| }, 5000); | |
| // clone.find('') | |
| // <i class="fa fa-question timeline-point"></i> | |
| break; | |
| default: | |
| break; | |
| } | |
| for (var field in trigger.data) { | |
| var selector = '.v.' + field; | |
| clone.find(selector).each(function ( ) { | |
| var target = $(this); | |
| target.filter('P, SPAN, DIV, H1, H2, H3, H4, H5, H6, SPAN, TT, DD').text(trigger.data[field]); | |
| }); | |
| } | |
| }); | |
| // console.log('TRIGGER', this.valid, this.data); | |
| }); | |
| } | |
| function update_timeline (ev, path, prop_spec) { | |
| console.log(ev.type, prop_spec); | |
| switch (ev.type) { | |
| case 'InterfacesAdded': | |
| var cfg = ev.data; | |
| create_event(cfg, path); | |
| break; | |
| case 'InterfacesRemoved': | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| $(document).ready(function ( ) { | |
| var cfg = { | |
| Activity: $('#ActivityEvents') | |
| , events: $('#EventTimeline') | |
| , clones: { | |
| End: $('#TimelineEnd').clone(true).removeClass('skeleton') | |
| , Scheduled: $('#ActivityEvents .EventScheduled').clone(true).removeClass('skeleton') | |
| , Maybe: $('#ActivityEvents .EventMaybe').clone(true).removeClass('skeleton') | |
| , Current: $('#ActivityEvents .EventCurrent').clone(true).removeClass('skeleton') | |
| , Pending: $('#ActivityEvents .EventPending').clone(true).removeClass('skeleton') | |
| } | |
| }; | |
| // cfg.Activity.tablesorter( ); | |
| cfg.Activity.trigger('update'); | |
| // var bus = cockpit.dbus(openaps.BUS, { bus: "session" }); | |
| var bus = cockpit.dbus(openaps.BUS); | |
| openaps.dbus = bus; | |
| // $(bus).on('notify', console.log.bind(console, 'NOTIFY XYXYX')); | |
| // $(bus).on('signal', console.log.bind(console, 'SIGNAL XYXYX')); | |
| // var mgr = bus.proxy('org.freedesktop.DBus.Properties', openaps.PATHS.Service); | |
| var mgr = bus.proxy('org.freedesktop.DBus.ObjectManager', openaps.PATHS.Instance); | |
| mgr.call('GetManagedObjects').always(function (managed) { | |
| console.log('got managed', managed); | |
| openaps.instance = managed; | |
| }); | |
| // openaps.dbus = mgr; | |
| var root = bus.proxy('org.freedesktop.DBus.ObjectManager', openaps.PATHS.Service); | |
| root.call('GetManagedObjects').always(function (managed) { | |
| console.log('got root managed', managed); | |
| openaps.root = managed[0]; | |
| for (var path in managed[0]) { | |
| // console.log('path', path); | |
| var objs = openaps.root[path]; | |
| for (var iface in objs) { | |
| var fields = objs[iface]; | |
| var name = iface.split('.').pop( ); | |
| // console.log('new name', name, path, name); | |
| if (Object.keys(fields).length > 0) { | |
| console.log(iface, path, Object.keys(fields)); | |
| openaps[name] = bus.proxy(iface, path); | |
| } | |
| } | |
| } | |
| /* | |
| var Do = bus.proxy(openaps.IFACE.Do, openaps.PATHS.Do); | |
| openaps.Do = Do; | |
| openaps.Scheduler = bus.proxy(openaps.IFACE.Scheduler, openaps.PATHS.Scheduler); | |
| */ | |
| console.log(openaps); | |
| $(openaps.Do).on("Phase", cfg, function (ev, status, props) { | |
| console.log("DO", ev.type, status, props.name.v, props); | |
| }); | |
| $([openaps.Scheduler, openaps.Heartbeat, openaps.Instance]).on("signal", function (ev, signal) { | |
| console.log('signal', ev.type, signal); | |
| }); | |
| $([openaps.Scheduler, openaps.Heartbeat, openaps.Instance]).on("Trigger Phase Fire", function (ev, signal) { | |
| console.log('signal', ev.type, signal, arguments); | |
| }); | |
| $(openaps.Scheduler).on("changed added removed Trigger Phase", function (ev, signal, path) { | |
| console.log('Scheduler XYYX', ev.type, signal, path, [].slice.call(arguments, 2)); | |
| }); | |
| // $(openaps.Do).on("signal", function (ev) { console.log('Do signal', ev.type, arguments); }); | |
| console.log("Scheduler", "1111", openaps.Scheduler, openaps.Scheduler.valid, openaps.IFACE.Scheduler, openaps.PATHS.Scheduler); | |
| $(openaps.Scheduler.as('org.freedesktop.DBus.ObjectManager')).on("InterfacesAdded InterfacesRemoved", cfg, function (ev, signal) { | |
| console.log('Scheduler MGR', ev.type, ev.data, signal, arguments); | |
| }); | |
| $(openaps.Scheduler.as('org.freedesktop.DBus.ObjectManager')).on("InterfacesAdded InterfacesRemoved", cfg, update_timeline); | |
| openaps.Scheduler.as('org.freedesktop.DBus.ObjectManager').call("GetManagedObjects").always(function (scheduled) { | |
| scheduled = scheduled.pop( ); | |
| // console.log("FIRST SCHEDULES", scheduled); | |
| var i = 0; | |
| for (var path in scheduled) { | |
| i++; | |
| function later (p) { | |
| function step ( ) { | |
| create_event(cfg, p); | |
| } | |
| return step; | |
| } | |
| setTimeout(later(path), i * 100); | |
| } | |
| }); | |
| }); | |
| var heartbeat = bus.proxy(openaps.IFACE.Heartbeat, openaps.PATHS.Heartbeat); | |
| openaps.heartbeat = heartbeat; | |
| $(openaps.heartbeat).on("Heartbeat", cfg, function (ev) { | |
| console.log('Heartbeat', arguments); | |
| var last = ev.data.Activity.find('TBODY.EventScheduled:last'); | |
| var sentinel = ev.data.Activity.find('#TimelineEnd').remove( ); | |
| last.after(sentinel); | |
| }); | |
| /* | |
| */ | |
| }); | |
| if (!window.openaps) { | |
| window.openaps = openaps; | |
| } |
bewest
commented
Feb 14, 2016

Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment




