update livemap to use rivets.js bindings for data updates
This commit is contained in:
2
resources/js/bootstrap.js
vendored
2
resources/js/bootstrap.js
vendored
@@ -38,3 +38,5 @@ if (api_key) {
|
||||
window.PHPVMS_USER_API_KEY = false;
|
||||
console.error('API Key not found!')
|
||||
}
|
||||
|
||||
require('./common');
|
||||
|
||||
@@ -1,2 +1,56 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
const rivets = require('rivets');
|
||||
|
||||
/**
|
||||
* Generic formatter to prepend
|
||||
* @param value
|
||||
* @param prepend
|
||||
* @returns {*}
|
||||
*/
|
||||
rivets.formatters.prepend = function (value, prepend) {
|
||||
return prepend + value
|
||||
};
|
||||
|
||||
/**
|
||||
* Format minutes into HHh MMm
|
||||
* @param value
|
||||
* @returns {string}
|
||||
*/
|
||||
rivets.formatters.time_hm = function(value) {
|
||||
const hours = Math.floor(value / 60);
|
||||
const mins = value % 60;
|
||||
return hours + 'h ' + mins + 'm';
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
* @returns {boolean}
|
||||
*/
|
||||
rivets.formatters.gt = (value, len) => {
|
||||
return value.length > len;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
* @returns {boolean}
|
||||
*/
|
||||
rivets.formatters.lt = (value, len) => {
|
||||
return value.length < len;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
* @returns {boolean}
|
||||
*/
|
||||
rivets.formatters.eq = (value, len) => {
|
||||
return value.length > len;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const leaflet = require('leaflet');
|
||||
const rivets = require('rivets');
|
||||
|
||||
import draw_base_map from './base_map'
|
||||
import {ACTUAL_ROUTE_COLOR} from './config'
|
||||
@@ -33,6 +34,9 @@ export default (opts) => {
|
||||
let layerSelFlightFeature = null;
|
||||
let layerSelFlightLayer = null;
|
||||
|
||||
const r_map_view = rivets.bind($('#map-info-box'), {pirep: {}});
|
||||
const r_table_view = rivets.bind($('#live_flights'), {pireps: []});
|
||||
|
||||
/**
|
||||
* When a flight is clicked on, show the path, etc for that flight
|
||||
* @param feature
|
||||
@@ -41,7 +45,6 @@ export default (opts) => {
|
||||
const onFlightClick = (feature, layer) => {
|
||||
|
||||
const pirep_uri = opts.pirep_uri.replace('{id}', feature.properties.pirep_id);
|
||||
const link_uri = opts.pirep_link_uri.replace('{id}', feature.properties.pirep_id);
|
||||
const geojson_uri = opts.pirep_uri.replace('{id}', feature.properties.pirep_id) + "/acars/geojson";
|
||||
|
||||
const pirep_info = $.ajax({
|
||||
@@ -83,49 +86,9 @@ export default (opts) => {
|
||||
//
|
||||
// When the PIREP info is done loading, show the bottom bar
|
||||
//
|
||||
$.when(pirep_info).done(pirep => { pirep = pirep.data;
|
||||
|
||||
let dist, planned_dist;
|
||||
if(opts.units === 'nmi') {
|
||||
dist = pirep.distance.nmi;
|
||||
planned_dist = pirep.planned_distance.nmi;
|
||||
} else if(opts.units === 'mi') {
|
||||
dist = pirep.distance.mi;
|
||||
planned_dist = pirep.planned_distance.mi;
|
||||
} else if(opts.units === 'km') {
|
||||
dist = pirep.distance.km;
|
||||
planned_dist = pirep.planned_distance.km;
|
||||
}
|
||||
|
||||
// Parse flight time
|
||||
const hours = Math.floor(pirep.flight_time / 60);
|
||||
const mins = pirep.flight_time % 60;
|
||||
|
||||
$('#map_flight_id').html(
|
||||
'<a href="' + link_uri + '" target="_blank">' +
|
||||
pirep.airline.icao + pirep.flight_number +
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$('#map_flight_info').text(
|
||||
pirep.dpt_airport.name + ' (' + pirep.dpt_airport.icao + ') to ' +
|
||||
pirep.arr_airport.name + ' (' + pirep.arr_airport.icao + ')'
|
||||
);
|
||||
|
||||
$('#map_flight_stats_middle').html(
|
||||
'Status: <strong>' + pirep.status_text + '</strong><br />' +
|
||||
'Flight Time: <strong>' + hours + 'h ' + mins + 'm</strong><br />' +
|
||||
'Distance: <strong>' + dist + '</strong> / ' + planned_dist + opts.units + '<br />'
|
||||
);
|
||||
|
||||
// Show flight stat info
|
||||
$('#map_flight_stats_right').html(
|
||||
'Ground Speed: <strong>' + pirep.position.gs + '</strong><br />' +
|
||||
'Altitude: <strong>' + pirep.position.altitude + '</strong><br />' +
|
||||
'Heading: <strong>' + pirep.position.heading + '</strong>'
|
||||
);
|
||||
|
||||
$('#map-info-bar').show();
|
||||
$.when(pirep_info).done(pirep => {
|
||||
r_map_view.update({pirep:pirep.data});
|
||||
$('#map-info-box').show();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -136,6 +99,12 @@ export default (opts) => {
|
||||
/**
|
||||
* AJAX UPDATE
|
||||
*/
|
||||
const pirep_uri = opts.pirep_uri.replace('{id}', '');
|
||||
let pireps = $.ajax({
|
||||
url: pirep_uri,
|
||||
dataType: 'json',
|
||||
error: console.log
|
||||
});
|
||||
|
||||
let flights = $.ajax({
|
||||
url: opts.update_uri,
|
||||
@@ -143,7 +112,7 @@ export default (opts) => {
|
||||
error: console.log
|
||||
});
|
||||
|
||||
$.when(flights).done(function (flightGeoJson) {
|
||||
$.when(flights).done(flightGeoJson => {
|
||||
|
||||
if (layerFlights !== null) {
|
||||
layerFlights.clearLayers()
|
||||
@@ -178,7 +147,14 @@ export default (opts) => {
|
||||
if (layerSelFlight !== null) {
|
||||
onFlightClick(layerSelFlightFeature, layerSelFlightLayer)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$.when(pireps).done(pireps => {
|
||||
r_table_view.update({
|
||||
pireps: pireps.data,
|
||||
has_data: (pireps.data.length > 0),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
updateMap();
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
{{-- Start of the required tags block. Don't remove these or things will break!! --}}
|
||||
<script src="{{ public_asset('/assets/global/js/vendor.js') }}"></script>
|
||||
<script src="{{ public_asset('/assets/frontend/js/app.js') }}"></script>
|
||||
{{--<script src="bower_components/sightglass/index.js"></script>
|
||||
<script src="bower_components/rivets/dist/rivets.min.js"></script>--}}
|
||||
@yield('scripts')
|
||||
{{-- End the required tags block --}}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
If you change it, remember to change it in the in-array line as well
|
||||
--}}
|
||||
<button class="btn btn-round btn-icon btn-icon-mini
|
||||
{{ in_array($flight->id, $saved, true) ? 'btn-info':'' }}
|
||||
save_flight"
|
||||
{{ in_array($flight->id, $saved, true) ? 'btn-info':'' }}
|
||||
save_flight"
|
||||
x-id="{{ $flight->id }}"
|
||||
x-saved-class="btn-info"
|
||||
type="button"
|
||||
|
||||
@@ -2,28 +2,62 @@
|
||||
<div class="col-md-12">
|
||||
<div class="box-body">
|
||||
|
||||
{{--
|
||||
This map uses rivets.js to fill in the updates from the livemap
|
||||
So the single brackets are used by rivets to fill in the values
|
||||
And then the rv-* attributes are data-binds that will automatically
|
||||
update whenever the base model behind it updates:
|
||||
|
||||
http://rivetsjs.com/docs/guide
|
||||
|
||||
Look in resources/js/maps/live_map.js to see where the actual binding
|
||||
and update() call is made
|
||||
--}}
|
||||
<div id="map" style="width: {{ $config['width'] }}; height: {{ $config['height'] }}">
|
||||
<div id="map-info-bar"
|
||||
style="display: none;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
padding: 20px;
|
||||
height: 100px;
|
||||
z-index: 9999;
|
||||
background-color:rgba(232, 232, 232, 0.9);
|
||||
width: {{ $config['width'] }};">
|
||||
<div style="float: left; margin-right: 30px; width: 50%;">
|
||||
<h3 style="margin: 0" id="map_flight_id"></h3>
|
||||
<p id="map_flight_info"></p>
|
||||
|
||||
{{--
|
||||
This is the bottom bar that appears when you click on a flight in the map.
|
||||
You can show any data you want - use a JS debugger to see the value of "pirep",
|
||||
or look up the API documentation for the /api/pirep/{id}/acars call
|
||||
|
||||
It's basically any of the fields from the database and pirep.position.X is any
|
||||
column from the ACARS table - holds the latest position.
|
||||
|
||||
Again, this is updated automatically via the rivets.js bindings, so be mindful
|
||||
when you're editing the { } - single brackets == rivets, double brackets == laravel
|
||||
|
||||
A couple of places (like the distance) use both to output the correct bindings.
|
||||
--}}
|
||||
<div id="map-info-box" class="map-info-box"
|
||||
style="width: {{ $config['width'] }};">
|
||||
<div style="float: left; width: 50%;">
|
||||
<h3 style="margin: 0" id="map_flight_id">
|
||||
<a rv-href="pirep.id | prepend '{{url('/pireps/')}}/'" target="_blank">
|
||||
{ pirep.airline.icao }{ pirep.flight_number }
|
||||
</a>
|
||||
</h3>
|
||||
<p id="map_flight_info">
|
||||
{ pirep.dpt_airport.name } ({ pirep.dpt_airport.icao }) to
|
||||
{ pirep.arr_airport.name } ({ pirep.arr_airport.icao })
|
||||
</p>
|
||||
</div>
|
||||
<div style="float: left; margin-right: 30px;">
|
||||
<p id="map_flight_stats_middle"></p>
|
||||
<div style="float: right; margin-left: 30px; margin-right: 30px;">
|
||||
<p id="map_flight_stats_right">
|
||||
Ground Speed: <span style="font-weight: bold">{ pirep.position.gs }</span><br/>
|
||||
Altitude: <span style="font-weight: bold">{ pirep.position.altitude }</span><br/>
|
||||
Heading: <span style="font-weight: bold">{ pirep.position.heading }</span><br/>
|
||||
</p>
|
||||
</div>
|
||||
<div style="float: left;">
|
||||
<p id="map_flight_stats_right"></p>
|
||||
<div style="float: right; margin-left: 30px;">
|
||||
<p id="map_flight_stats_middle">
|
||||
Status: <span style="font-weight: bold">{ pirep.status_text }</span><br />
|
||||
Flight Time: <span style="font-weight: bold">{ pirep.flight_time | time_hm }</span><br />
|
||||
Distance: <span style="font-weight: bold">{ pirep.position.distance.{{setting('units.distance')}} }</span>
|
||||
/ <span style="font-weight: bold">
|
||||
{ pirep.planned_distance.{{setting('units.distance')}} }</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -31,26 +65,47 @@
|
||||
|
||||
<div class="clearfix" style="padding-top: 25px"></div>
|
||||
|
||||
{{--<div id="flights_table" class="row">
|
||||
{{--
|
||||
This table is also handled/rendered by rivets from the livemap
|
||||
Handles the updates by automatically updating the data in the row.
|
||||
|
||||
Same note applies from above about the data from the PIREP API being available
|
||||
and being mindful of the rivets bindings
|
||||
--}}
|
||||
<div id="live_flights" class="row">
|
||||
<div class="col-md-12">
|
||||
@if(!filled($pireps))
|
||||
<div class="jumbotron text-center">There are no flights</div>
|
||||
@endif
|
||||
<table class="table">
|
||||
@foreach($pireps as $pirep)
|
||||
<tr>
|
||||
<td>{{ $pirep->airline->code }}{{ $pirep->ident }}</td>
|
||||
<td>{{ $pirep->dpt_airport_id }}</td>
|
||||
<td>{{ $pirep->arr_airport_id }}</td>
|
||||
<td>{{ $pirep->aircraft->name }}</td>
|
||||
<td>
|
||||
{{ PirepStatus::label($pirep->status) }}
|
||||
</td>
|
||||
<div rv-hide="has_data" class="jumbotron text-center">There are no flights</div>
|
||||
<table rv-show="has_data" id="live_flights_table" class="table table-striped">
|
||||
<thead>
|
||||
<tr class="text-small header">
|
||||
<td class="text-small">Flight</td>
|
||||
<td class="text-small">Departure</td>
|
||||
<td class="text-small">Arrival</td>
|
||||
<td class="text-small">Aircraft</td>
|
||||
<td class="text-small">Altitude</td>
|
||||
<td class="text-small">GS</td>
|
||||
<td class="text-small">Distance</td>
|
||||
<td class="text-small">Status</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr rv-each-pirep="pireps">
|
||||
<td>{ pirep.airline.code }{ pirep.ident}</td>
|
||||
{{-- Show the full airport name on hover --}}
|
||||
<td><span rv-title="pirep.dpt_airport.name">{ pirep.dpt_airport.icao }</span></td>
|
||||
<td><span rv-title="pirep.arr_airport.name">{ pirep.arr_airport.icao }</span></td>
|
||||
<td>{ pirep.aircraft.name }</td>
|
||||
<td>{ pirep.position.altitude }</td>
|
||||
<td>{ pirep.position.gs }</td>
|
||||
<td>{ pirep.position.distance.{{setting('units.distance')}} } /
|
||||
{ pirep.planned_distance.{{setting('units.distance')}} }
|
||||
</td>
|
||||
<td>{ pirep.status_text }</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>--}}
|
||||
</div>
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user