Refactor all JS API calls #360 (#375)

* Refactor all JS API calls #360

* Remove unused imports

* Lint JS

* Fix doubled api key

* Formatting

* Added extra logging to distance lookup

* Remove the .editorconfig file in distrib

* shell check fixes

* Remove the .editorconfig file in distrib
This commit is contained in:
Nabeel S
2019-08-30 08:08:00 -04:00
committed by GitHub
parent e62e4a865d
commit 0d1f38cf85
39 changed files with 1397 additions and 745 deletions

18
.editorconfig Normal file
View File

@@ -0,0 +1,18 @@
#
root = true
[*.js]
indent_style = space
indent_size = 2
[*.php]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
# Matches the exact files either package.json or .travis.yml
[{package.json, .travis.yml}]
indent_style = space
indent_size = 2

View File

@@ -2,13 +2,16 @@
"extends": "airbnb", "extends": "airbnb",
"env": { "env": {
"es6": true, "es6": true,
"mocha": true "browser": true
}, },
"parserOptions": { "parserOptions": {
"ecmaVersion": 8 "ecmaVersion": 8
}, },
"rules": { "rules": {
"camelcase": 0, "camelcase": 0,
"no-console": 0,
"func-names": 0,
"prefer-object-spread": 0,
"no-param-reassign": [ "no-param-reassign": [
2, 2,
{ {

View File

@@ -14,7 +14,7 @@ if [ "$TRAVIS" = "true" ]; then
exit 0; exit 0;
fi; fi;
BASE_VERSION=`php artisan phpvms:version --base-only` BASE_VERSION=$(php artisan phpvms:version --base-only)
PKG_NAME=${BASE_VERSION}-${TRAVIS_BRANCH} PKG_NAME=${BASE_VERSION}-${TRAVIS_BRANCH}
fi fi
@@ -23,7 +23,7 @@ if [ "$TRAVIS" = "true" ]; then
echo "Writing $TAR_NAME" echo "Writing $TAR_NAME"
php artisan phpvms:version --write > VERSION php artisan phpvms:version --write > VERSION
VERSION=`cat VERSION` VERSION=$(cat VERSION)
echo "Version: $VERSION" echo "Version: $VERSION"
echo "Cleaning files" echo "Cleaning files"
@@ -59,6 +59,7 @@ if [ "$TRAVIS" = "true" ]; then
tests tests
_ide_helper.php _ide_helper.php
.dpl .dpl
.editorconfig
.eslintignore .eslintignore
.eslintrc .eslintrc
.php_cs .php_cs

View File

@@ -181,6 +181,7 @@ class PirepController extends Controller
Log::info('aircraft', $aircraft->toArray()); Log::info('aircraft', $aircraft->toArray());
return view('admin.pireps.fares', [ return view('admin.pireps.fares', [
'pirep' => null,
'aircraft' => $aircraft, 'aircraft' => $aircraft,
'read_only' => false, 'read_only' => false,
]); ]);

View File

@@ -73,8 +73,8 @@ class AcarsController extends Controller
$pireps = $this->acarsRepo->getPositions(setting('acars.live_time')); $pireps = $this->acarsRepo->getPositions(setting('acars.live_time'));
$positions = $this->geoSvc->getFeatureForLiveFlights($pireps); $positions = $this->geoSvc->getFeatureForLiveFlights($pireps);
return response(json_encode($positions), 200, [ return response()->json([
'Content-type' => 'application/json', 'data' => $positions,
]); ]);
} }
@@ -84,15 +84,15 @@ class AcarsController extends Controller
* @param $pirep_id * @param $pirep_id
* @param Request $request * @param Request $request
* *
* @return \Illuminate\Contracts\Routing\ResponseFactory * @return \Illuminate\Http\JsonResponse
*/ */
public function acars_geojson($pirep_id, Request $request) public function acars_geojson($pirep_id, Request $request)
{ {
$pirep = Pirep::find($pirep_id); $pirep = Pirep::find($pirep_id);
$geodata = $this->geoSvc->getFeatureFromAcars($pirep); $geodata = $this->geoSvc->getFeatureFromAcars($pirep);
return response(\json_encode($geodata), 200, [ return response()->json([
'Content-Type' => 'application/json', 'data' => $geodata,
]); ]);
} }

View File

@@ -505,6 +505,7 @@ class PirepController extends Controller
public function route_get($id, Request $request) public function route_get($id, Request $request)
{ {
$pirep = Pirep::find($id); $pirep = Pirep::find($id);
return AcarsRouteResource::collection(Acars::where([ return AcarsRouteResource::collection(Acars::where([
'pirep_id' => $id, 'pirep_id' => $id,
'type' => AcarsType::ROUTE, 'type' => AcarsType::ROUTE,

View File

@@ -4,9 +4,6 @@ namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection; use Illuminate\Http\Resources\Json\ResourceCollection;
/**
* Class PirepFieldCollection
*/
class PirepFieldCollection extends ResourceCollection class PirepFieldCollection extends ResourceCollection
{ {
public function toArray($request) public function toArray($request)

View File

@@ -47,6 +47,12 @@
}, },
"devDependencies": { "devDependencies": {
"copy-webpack-plugin": "^4.6.0", "copy-webpack-plugin": "^4.6.0",
"eslint": "^6.2.2",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"tailwindcss": "^0.5.3", "tailwindcss": "^0.5.3",
"webpack-bundle-analyzer": "^3.3", "webpack-bundle-analyzer": "^3.3",
"webpack-dev-server": "^3.1.11" "webpack-dev-server": "^3.1.11"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,9 @@
{ {
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=4ef5a26ff476bb0a9fcf", "/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=96bf382a8107b3fa5495",
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=c4987da93365a82d32b6", "/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=c4987da93365a82d32b6",
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=da87041e81048759bd41", "/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=da87041e81048759bd41",
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=918b9ff17affe36bab4c", "/assets/admin/js/app.js": "/assets/admin/js/app.js?id=09af8d2b342688a72153",
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=964075bbd7379552bc05", "/assets/installer/js/app.js": "/assets/installer/js/app.js?id=db625369782c7597e139",
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56", "/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56",
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56", "/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56",
"/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a", "/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a",

View File

@@ -1,4 +1,5 @@
'use strict';
import request from '../request';
/** /**
* Lookup an airport from the server * Lookup an airport from the server
@@ -6,12 +7,12 @@
* @param {String} icao * @param {String} icao
*/ */
export default async (icao) => { export default async (icao) => {
let params = { const params = {
method: 'GET', method: 'GET',
url: '/api/airports/' + icao + '/lookup', url: `/api/airports/${icao}/lookup`,
}; };
const response = await axios(params); const response = await request(params);
console.log('lookup raw response: ', response); console.log('lookup raw response: ', response);
return response.data; return response.data;
}; };

View File

@@ -3,10 +3,10 @@
*/ */
require('./../bootstrap'); import airport_lookup from './airport_lookup';
import calculate_distance from './calculate_distance';
import airport_lookup from "./airport_lookup"; require('./../bootstrap');
import calculate_distance from "./calculate_distance";
window.phpvms.airport_lookup = airport_lookup; window.phpvms.airport_lookup = airport_lookup;
window.phpvms.calculate_distance = calculate_distance; window.phpvms.calculate_distance = calculate_distance;

View File

@@ -1,3 +1,6 @@
import request from '../request';
/** /**
* Lookup an airport from the server * Lookup an airport from the server
* *
@@ -5,12 +8,12 @@
* @param {String} toICAO * @param {String} toICAO
*/ */
export default async (fromICAO, toICAO) => { export default async (fromICAO, toICAO) => {
let params = { const params = {
method: 'GET', method: 'GET',
url: '/api/airports/' + fromICAO + '/distance/' + toICAO, url: `/api/airports/${fromICAO}/distance/${toICAO}`,
}; };
const response = await axios(params); const response = await request(params);
console.log('distance raw response: ', response); console.log('distance raw response: ', response);
return response.data; return response.data;
}; };

View File

@@ -2,49 +2,19 @@
* Bootstrap any Javascript libraries required * Bootstrap any Javascript libraries required
*/ */
import Storage from './storage';
import config from './config';
import request from './request';
window.axios = require('axios'); window.axios = require('axios');
import Storage from "./storage";
/** /**
* Container for phpVMS specific functions * Container for phpVMS specific functions
*/ */
window.phpvms = { window.phpvms = {
config: {}, config,
request,
Storage, Storage,
}; };
/**
* Configure Axios with both the csrf token and the API key
*/
const base_url = document.head.querySelector('meta[name="base-url"]');
if(base_url) {
console.log(`baseURL=${base_url.content}`);
window.phpvms.config.base_url = base_url.content;
window.axios.default.baseURL = base_url.content;
}
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
const token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.phpvms.config.csrf_token = token.content;
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token')
}
const api_key = document.head.querySelector('meta[name="api-key"]');
if (api_key) {
window.axios.defaults.headers.common['x-api-key'] = api_key.content;
window.phpvms.config.user_api_key = api_key.content;
window.PHPVMS_USER_API_KEY = api_key.content
} else {
window.phpvms.config.user_api_key = false;
window.PHPVMS_USER_API_KEY = false;
console.error('API Key not found!')
}
require('./common'); require('./common');

View File

@@ -1,6 +1,3 @@
/**
*
*/
const rivets = require('rivets'); const rivets = require('rivets');
@@ -11,7 +8,7 @@ const rivets = require('rivets');
* @returns {*} * @returns {*}
*/ */
rivets.formatters.prepend = function (value, prepend) { rivets.formatters.prepend = function (value, prepend) {
return prepend + value return prepend + value;
}; };
/** /**
@@ -19,10 +16,10 @@ rivets.formatters.prepend = function (value, prepend) {
* @param value * @param value
* @returns {string} * @returns {string}
*/ */
rivets.formatters.time_hm = function(value) { rivets.formatters.time_hm = function (value) {
const hours = Math.floor(value / 60); const hours = Math.floor(value / 60);
const mins = value % 60; const mins = value % 60;
return hours + 'h ' + mins + 'm'; return `${hours}h ${mins}m`;
}; };
/** /**
@@ -31,9 +28,7 @@ rivets.formatters.time_hm = function(value) {
* @param len * @param len
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.gt = (value, len) => { rivets.formatters.gt = (value, len) => value.length > len;
return value.length > len;
};
/** /**
* *
@@ -41,9 +36,7 @@ rivets.formatters.gt = (value, len) => {
* @param len * @param len
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.lt = (value, len) => { rivets.formatters.lt = (value, len) => value.length < len;
return value.length < len;
};
/** /**
* *
@@ -51,6 +44,4 @@ rivets.formatters.lt = (value, len) => {
* @param len * @param len
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.eq = (value, len) => { rivets.formatters.eq = (value, len) => value.length > len;
return value.length > len;
};

10
resources/js/config.js Normal file
View File

@@ -0,0 +1,10 @@
const base_url = document.head.querySelector('meta[name="base-url"]');
const token = document.head.querySelector('meta[name="csrf-token"]');
const api_key = document.head.querySelector('meta[name="api-key"]');
export default {
api_key: api_key.content || '',
base_url: base_url.content || '',
csrf_token: token.content || '',
};

View File

@@ -1,11 +1,12 @@
// Import the bids functionality
import { addBid, removeBid } from './bids';
require('./../bootstrap'); require('./../bootstrap');
// Import the bids functionality
import {addBid, removeBid} from './bids';
window.phpvms.bids = { window.phpvms.bids = {
addBid, addBid,
removeBid, removeBid,
}; };
// Import the mapping function // Import the mapping function

View File

@@ -1,4 +1,5 @@
'use strict';
import request from '../request';
/** /**
* Add a bid to a flight * Add a bid to a flight
@@ -8,16 +9,16 @@
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function addBid(flight_id) { export async function addBid(flight_id) {
const params = { const params = {
method: 'POST', method: 'POST',
url: '/api/user/bids', url: '/api/user/bids',
data: { data: {
'_method': 'POST', _method: 'POST',
'flight_id': flight_id flight_id,
} },
}; };
return axios(params); return request(params);
} }
/** /**
@@ -28,14 +29,14 @@ export async function addBid(flight_id) {
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function removeBid(flight_id) { export async function removeBid(flight_id) {
const params = { const params = {
method: 'POST', method: 'POST',
url: '/api/user/bids', url: '/api/user/bids',
data: { data: {
'_method': 'DELETE', _method: 'DELETE',
'flight_id': flight_id flight_id,
} },
}; };
return axios(params); return request(params);
} }

View File

@@ -1,16 +1,16 @@
import draw_base_map from './base_map';
import { addWMSLayer } from './helpers';
const leaflet = require('leaflet'); const leaflet = require('leaflet');
import draw_base_map from './base_map'
import { addWMSLayer } from './helpers';
/** /**
* Render a map with the airspace, etc around a given set of coords * Render a map with the airspace, etc around a given set of coords
* e.g, the airport map * e.g, the airport map
* @param opts * @param {Object} _opts
*/ */
export default (opts) => { export default (_opts) => {
opts = Object.assign({ const opts = Object.assign({
render_elem: 'map', render_elem: 'map',
overlay_elem: '', overlay_elem: '',
lat: 0, lat: 0,
@@ -22,12 +22,12 @@ export default (opts) => {
// Passed from the config/maps.php file // Passed from the config/maps.php file
metar_wms: { metar_wms: {
url: '', url: '',
params: {} params: {},
}, },
}, opts); }, _opts);
let map = draw_base_map(opts); const map = draw_base_map(opts);
const coords = [opts.lat, opts.lon]; const coords = [opts.lat, opts.lon];
console.log('Applying coords', coords); console.log('Applying coords', coords);
@@ -36,8 +36,8 @@ export default (opts) => {
leaflet.marker(coords).addTo(map).bindPopup(opts.marker_popup); leaflet.marker(coords).addTo(map).bindPopup(opts.marker_popup);
} }
if(opts.metar_wms.url !== '') { if (opts.metar_wms.url !== '') {
addWMSLayer(map, opts.metar_wms); addWMSLayer(map, opts.metar_wms);
} }
return map; return map;

View File

@@ -1,62 +1,62 @@
//
const leaflet = require('leaflet'); const leaflet = require('leaflet');
require('leaflet-providers'); require('leaflet-providers');
export default (opts) => { export default (_opts) => {
const opts = Object.assign({
render_elem: 'map',
center: [29.98139, -95.33374],
zoom: 5,
maxZoom: 10,
layers: [],
set_marker: false,
providers: [
'Esri.WorldStreetMap',
],
tile_layers: [],
}, _opts);
opts = Object.assign({ /*
render_elem: 'map', let feature_groups = [];
center: [29.98139, -95.33374], const openaip_airspace_labels = new leaflet.TileLayer.WMS(
zoom: 5, "http://{s}.tile.maps.openaip.net/geowebcache/service/wms", {
maxZoom: 10, maxZoom: 14,
layers: [], minZoom: 12,
set_marker: false, layers: 'openaip_approved_airspaces_labels',
providers: [ tileSize: 1024,
'Esri.WorldStreetMap', detectRetina: true,
], subdomains: '12',
tile_layers: [], format: 'image/png',
}, opts); transparent: true
});
/* openaip_airspace_labels.addTo(map); */
let feature_groups = [];
const openaip_airspace_labels = new leaflet.TileLayer.WMS(
"http://{s}.tile.maps.openaip.net/geowebcache/service/wms", {
maxZoom: 14,
minZoom: 12,
layers: 'openaip_approved_airspaces_labels',
tileSize: 1024,
detectRetina: true,
subdomains: '12',
format: 'image/png',
transparent: true
});
openaip_airspace_labels.addTo(map);*/ /*
const openaip_cached_basemap = new leaflet.TileLayer("http://{s}.tile.maps.openaip.net/geowebcache/service/tms/1.0.0/openaip_basemap@EPSG%3A900913@png/{z}/{x}/{y}.png", {
maxZoom: 14,
minZoom: 4,
tms: true,
detectRetina: true,
subdomains: '12',
format: 'image/png',
transparent: true
});
/*const openaip_cached_basemap = new leaflet.TileLayer("http://{s}.tile.maps.openaip.net/geowebcache/service/tms/1.0.0/openaip_basemap@EPSG%3A900913@png/{z}/{x}/{y}.png", { feature_groups.push(openaip_cached_basemap);
maxZoom: 14, */
minZoom: 4,
tms: true,
detectRetina: true,
subdomains: '12',
format: 'image/png',
transparent: true
});
feature_groups.push(openaip_cached_basemap); const map = leaflet.map('map', {
*/ // layers: [openaip_basemap_phys_osm],
center: opts.center,
zoom: opts.zoom,
scrollWheelZoom: false,
});
let map = leaflet.map('map', { // eslint-disable-next-line no-unused-vars
//layers: [openaip_basemap_phys_osm], opts.providers.forEach((p, idx) => {
center: opts.center, leaflet.tileLayer.provider(p).addTo(map);
zoom: opts.zoom, });
scrollWheelZoom: false,
});
for(const i in opts.providers) { return map;
leaflet.tileLayer.provider(opts.providers[i]).addTo(map);
}
return map;
}; };

View File

@@ -1,4 +1,3 @@
export let export const PLAN_ROUTE_COLOR = '#043758';
PLAN_ROUTE_COLOR = '#043758', export const ACTUAL_ROUTE_COLOR = '#067ec1';
ACTUAL_ROUTE_COLOR = '#067ec1', export const CIRCLE_COLOR = '#056093';
CIRCLE_COLOR = '#056093';

View File

@@ -11,25 +11,24 @@ const leaflet = require('leaflet');
* @param opts * @param opts
*/ */
export function addWMSLayer(map, opts) { export function addWMSLayer(map, opts) {
if (opts.url === '') {
return null;
}
if(opts.url === '') { opts.params = Object.assign({
return; format: 'image/png',
} transparent: true,
maxZoom: 14,
minZoom: 4,
}, opts.params);
opts.params = Object.assign({ const mlayer = leaflet.tileLayer.wms(
format: 'image/png', opts.url, opts.params,
transparent: true, );
maxZoom: 14,
minZoom: 4,
}, opts.params);
const mlayer = leaflet.tileLayer.wms( mlayer.addTo(map);
opts.url, opts.params
);
mlayer.addTo(map); return mlayer;
return mlayer;
} }
/** /**
@@ -38,10 +37,10 @@ export function addWMSLayer(map, opts) {
* @param layer * @param layer
*/ */
export function showFeaturePopup(feature, layer) { export function showFeaturePopup(feature, layer) {
let popup_html = ''; let popup_html = '';
if (feature.properties && feature.properties.popup) { if (feature.properties && feature.properties.popup) {
popup_html += feature.properties.popup popup_html += feature.properties.popup;
} }
layer.bindPopup(popup_html) layer.bindPopup(popup_html);
} }

View File

@@ -2,16 +2,17 @@
* All of the functionality required for maps * All of the functionality required for maps
*/ */
window.L = require('leaflet'); import render_airspace_map from './airspace_map';
import render_live_map from './live_map';
import render_route_map from './route_map';
require('Leaflet.Geodesic'); require('Leaflet.Geodesic');
require('leaflet-rotatedmarker'); require('leaflet-rotatedmarker');
import render_airspace_map from './airspace_map' window.L = require('leaflet');
import render_live_map from './live_map'
import render_route_map from './route_map'
export { export {
render_airspace_map, render_airspace_map,
render_live_map, render_live_map,
render_route_map, render_route_map,
} };

View File

@@ -1,216 +1,185 @@
//
const geolib = require('geolib'); import draw_base_map from './base_map';
import { ACTUAL_ROUTE_COLOR } from './config';
import request from '../request';
// const geolib = require('geolib');
const leaflet = require('leaflet'); const leaflet = require('leaflet');
const rivets = require('rivets'); const rivets = require('rivets');
import draw_base_map from './base_map'
import { ACTUAL_ROUTE_COLOR } from './config'
/** /**
* Render the live map * Render the live map
* @param opts * @param _opts
* @private * @private
*/ */
export default (opts) => { export default (_opts) => {
const opts = Object.assign({
center: [29.98139, -95.33374],
refresh_interval: 10, // seconds
zoom: 5,
update_uri: '/api/acars',
pirep_uri: '/api/pireps/{id}',
pirep_link_uri: '/pireps/{id}',
positions: null,
render_elem: 'map',
aircraft_icon: '/assets/img/acars/aircraft.png',
units: 'nmi',
}, _opts);
opts = Object.assign({ const map = draw_base_map(opts);
center: [29.98139, -95.33374], const aircraftIcon = leaflet.icon({
zoom: 5, iconUrl: opts.aircraft_icon,
update_uri: '/api/acars', iconSize: [42, 42],
pirep_uri: '/api/pireps/{id}', iconAnchor: [21, 21],
pirep_link_uri: '/pireps/{id}', });
positions: null,
render_elem: 'map',
aircraft_icon: '/assets/img/acars/aircraft.png',
units: 'nmi',
}, opts);
const map = draw_base_map(opts); /**
const aircraftIcon = leaflet.icon({ * Hold the markers
iconUrl: opts.aircraft_icon, * @type {{}}
iconSize: [42, 42], */
iconAnchor: [21, 21], const markers_list = {};
let pannedToCenter = false;
let layerFlights = null;
let layerSelFlight = null;
let layerSelFlightFeature = null;
let layerSelFlightLayer = null;
const liveMapController = {
pirep: {},
pireps: [],
has_data: false,
controller: {
/**
* Focus on a specific marker
* @param e
* @param model
*/
focusMarker: (e, model) => {
if (!(model.pirep.id in markers_list)) {
console.log('marker not found in list');
return;
}
const marker = markers_list[model.pirep.id];
onFlightClick(marker[0], marker[1]);
},
},
};
rivets.bind($('#map-info-box'), liveMapController);
rivets.bind($('#live_flights'), liveMapController);
const drawRoute = (feature, layer, route) => {
console.log('drawRoute');
if (layerSelFlight !== null) {
map.removeLayer(layerSelFlight);
}
layerSelFlight = leaflet.geodesic([], {
weight: 5,
opacity: 0.9,
color: ACTUAL_ROUTE_COLOR,
wrap: false,
}).addTo(map);
layerSelFlight.geoJson(route.line);
layerSelFlightFeature = feature;
layerSelFlightLayer = layer;
// Center on it, but only do it once, in case the map is moved
if (!pannedToCenter) {
map.panTo({
lat: route.position.lat,
lng: route.position.lon,
});
pannedToCenter = true;
}
};
/**
* When a flight is clicked on, show the path, etc for that flight
* @param feature
* @param layer
*/
const onFlightClick = (feature, layer) => {
const pirep_uri = opts.pirep_uri.replace('{id}', feature.properties.pirep_id);
const geojson_uri = `${opts.pirep_uri.replace('{id}', feature.properties.pirep_id)}/acars/geojson`;
/*
* Run these in parallel:
* 1. Get information about the PIREP and populate the bottom box/container
* 2. Draw out the flight route
*/
request(pirep_uri).then((response) => {
const pirep = response.data.data;
console.log(pirep);
liveMapController.pirep = pirep;
}); });
/** request(geojson_uri).then((response) => {
* Hold the markers const route = response.data.data;
* @type {{}} console.log(route);
*/
let markers_list = {};
let pannedToCenter = false; drawRoute(feature, layer, route);
});
};
let layerFlights = null; const updateMap = () => {
let layerSelFlight = null; const pirep_uri = opts.pirep_uri.replace('{id}', '');
let layerSelFlightFeature = null;
let layerSelFlightLayer = null;
let layerSelArr = null;
let layerSelDep = null;
/** request(pirep_uri).then((response) => {
* Controller for two-way bindings const pireps = response.data.data;
* @type {{focusMarker: focusMarker}} liveMapController.pireps = pireps;
*/ liveMapController.has_data = pireps.length > 0;
const mapController = { });
/**
* Focus on a specific marker
* @param e
* @param model
*/
focusMarker: (e, model) => {
if(!(model.pirep.id in markers_list)) {
console.log('marker not found in list');
return;
}
const marker = markers_list[model.pirep.id]; request({ url: opts.update_uri }).then((response) => {
onFlightClick(marker[0], marker[1]); const flightGeoJson = response.data.data;
if (layerFlights !== null) {
layerFlights.clearLayers();
}
layerFlights = leaflet.geoJSON(flightGeoJson, {
onEachFeature: (feature, layer) => {
layer.on({
// eslint-disable-next-line no-unused-vars
click: (e) => {
pannedToCenter = false;
liveMapController.controller.onFlightClick(feature, layer);
},
});
let popup_html = '';
if (feature.properties && (feature.properties.popup !== '' && feature.properties.popup !== undefined)) {
popup_html += feature.properties.popup;
layer.bindPopup(popup_html);
}
// add to the list
markers_list[feature.properties.pirep_id] = [feature, layer];
}, },
}; pointToLayer(feature, latlon) {
return leaflet.marker(latlon, {
icon: aircraftIcon,
rotationAngle: feature.properties.heading,
});
},
});
const r_map_view = rivets.bind($('#map-info-box'), {pirep: {}, controller: mapController}); layerFlights.addTo(map);
const r_table_view = rivets.bind($('#live_flights'), {pireps: [], controller: mapController});
/** // Reload the clicked-flight information
* When a flight is clicked on, show the path, etc for that flight if (layerSelFlight !== null) {
* @param feature liveMapController.controller.onFlightClick(layerSelFlightFeature, layerSelFlightLayer);
* @param layer }
*/ });
const onFlightClick = (feature, layer) => { };
const pirep_uri = opts.pirep_uri.replace('{id}', feature.properties.pirep_id); updateMap();
const geojson_uri = opts.pirep_uri.replace('{id}', feature.properties.pirep_id) + "/acars/geojson"; setInterval(updateMap, opts.refresh_interval * 1000);
const pirep_info = $.ajax({
url: pirep_uri,
dataType: 'json',
error: console.log
});
const flight_route = $.ajax({
url: geojson_uri,
dataType: 'json',
error: console.log
});
// Load up the PIREP info
$.when(flight_route).done((rte) => {
if (layerSelFlight !== null) {
map.removeLayer(layerSelFlight);
//map.removeLayer(layerSelArr);
//map.removeLayer(layerSelDep);
}
layerSelFlight = leaflet.geodesic([], {
weight: 5,
opacity: 0.9,
color: ACTUAL_ROUTE_COLOR,
wrap: false,
}).addTo(map);
layerSelFlight.geoJson(rte.line);
layerSelFlightFeature = feature;
layerSelFlightLayer = layer;
/*const dptIcon = leaflet.divIcon({
html: '<div class="map-info-label"><h5>' + rte.airports.d.icao + '</h5></div>'
});
layerSelDep = leaflet.marker([rte.airports.d.lat, rte.airports.d.lon], {icon:dptIcon}).addTo(map);
*/
// Center on it, but only do it once, in case the map is moved
if(!pannedToCenter) {
// find center
const c = geolib.getCenter([
{latitude: rte.airports.a.lat, longitude: rte.airports.a.lon},
{latitude: rte.airports.d.lat, longitude: rte.airports.d.lon},
]);
//map.panTo({lat: c.latitude, lng: c.longitude});
map.panTo({lat: rte.position.lat, lng: rte.position.lon});
pannedToCenter = true;
}
});
//
// When the PIREP info is done loading, show the bottom bar
//
$.when(pirep_info).done(pirep => {
r_map_view.update({pirep:pirep.data});
$('#map-info-box').show();
});
};
const updateMap = () => {
console.log('reloading flights from acars...');
/**
* 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,
dataType: 'json',
error: console.log
});
$.when(flights).done(flightGeoJson => {
if (layerFlights !== null) {
layerFlights.clearLayers()
}
layerFlights = leaflet.geoJSON(flightGeoJson, {
onEachFeature: (feature, layer) => {
layer.on({
click: (e) => {
pannedToCenter = false;
onFlightClick(feature, layer)
}
});
let popup_html = '';
if (feature.properties && (feature.properties.popup !== '' && feature.properties.popup !== undefined)) {
popup_html += feature.properties.popup;
layer.bindPopup(popup_html);
}
// add to the list
markers_list[feature.properties.pirep_id] = [feature, layer];
},
pointToLayer: function (feature, latlon) {
return leaflet.marker(latlon, {
icon: aircraftIcon,
rotationAngle: feature.properties.heading
})
}
});
layerFlights.addTo(map);
// Reload the clicked-flight information
if (layerSelFlight !== null) {
onFlightClick(layerSelFlightFeature, layerSelFlightLayer)
}
});
$.when(pireps).done(pireps => {
r_table_view.update({
pireps: pireps.data,
has_data: (pireps.data.length > 0),
});
});
};
updateMap();
setInterval(updateMap, 10000)
}; };

View File

@@ -1,22 +1,24 @@
import draw_base_map from './base_map';
import { addWMSLayer } from './helpers';
import request from '../request';
import { ACTUAL_ROUTE_COLOR, CIRCLE_COLOR, PLAN_ROUTE_COLOR } from './config';
const leaflet = require('leaflet'); const leaflet = require('leaflet');
import draw_base_map from './base_map'
import {addWMSLayer} from './helpers';
import {ACTUAL_ROUTE_COLOR, CIRCLE_COLOR, PLAN_ROUTE_COLOR} from './config'
/** /**
* Show some popup text when a feature is clicked on * Show some popup text when a feature is clicked on
* @param feature * @param feature
* @param layer * @param layer
*/ */
export const onFeaturePointClick = (feature, layer) => { export const onFeaturePointClick = (feature, layer) => {
let popup_html = ''; let popup_html = '';
if (feature.properties && feature.properties.popup) { if (feature.properties && feature.properties.popup) {
popup_html += feature.properties.popup popup_html += feature.properties.popup;
} }
layer.bindPopup(popup_html) layer.bindPopup(popup_html);
}; };
/** /**
@@ -25,143 +27,134 @@ export const onFeaturePointClick = (feature, layer) => {
* @param latlng * @param latlng
* @returns {*} * @returns {*}
*/ */
export const pointToLayer = (feature, latlng) => { export const pointToLayer = (feature, latlng) => leaflet.circleMarker(latlng, {
return leaflet.circleMarker(latlng, { radius: 5,
radius: 5, fillColor: CIRCLE_COLOR,
fillColor: CIRCLE_COLOR, color: '#000',
color: '#000', weight: 1,
weight: 1, opacity: 1,
opacity: 1, fillOpacity: 0.8,
fillOpacity: 0.8 });
})
}
/** /**
* *
* @param opts * @param _opts
* @private * @private
*/ */
export default (opts) => { export default (_opts) => {
const opts = Object.assign({
route_points: null,
planned_route_line: null,
actual_route_points: null,
actual_route_line: null,
render_elem: 'map',
live_map: false,
aircraft_icon: '/assets/img/acars/aircraft.png',
refresh_interval: 10,
metar_wms: {
url: '',
params: {},
},
}, _opts);
opts = Object.assign({ const aircraftIcon = leaflet.icon({
iconUrl: opts.aircraft_icon,
iconSize: [42, 42],
iconAnchor: [21, 21],
});
route_points: null, const map = draw_base_map(opts);
planned_route_line: null, let layerLiveFlight;
actual_route_points: null,
actual_route_line: null,
render_elem: 'map',
live_map: false,
aircraft_icon: '/assets/img/acars/aircraft.png',
metar_wms: {
url: '',
params: {}
},
}, opts);
const aircraftIcon = leaflet.icon({ if (opts.metar_wms.url !== '') {
iconUrl: opts.aircraft_icon, addWMSLayer(map, opts.metar_wms);
iconSize: [42, 42], }
iconAnchor: [21, 21],
const plannedRouteLayer = leaflet.geodesic([], {
weight: 4,
opacity: 0.9,
color: PLAN_ROUTE_COLOR,
steps: 50,
wrap: false,
}).addTo(map);
plannedRouteLayer.geoJson(opts.planned_route_line);
try {
map.fitBounds(plannedRouteLayer.getBounds());
} catch (e) {
console.log(e);
}
// Draw the route points after
if (opts.route_points !== null) {
const route_points = leaflet.geoJSON(opts.route_points, {
onEachFeature: onFeaturePointClick,
pointToLayer,
style: {
color: PLAN_ROUTE_COLOR,
weight: 3,
opacity: 0.65,
},
}); });
let map = draw_base_map(opts); route_points.addTo(map);
let layerLiveFlight; }
if (opts.metar_wms.url !== '') { /**
addWMSLayer(map, opts.metar_wms);
}
let geodesicLayer = leaflet.geodesic([], {
weight: 4,
opacity: 0.9,
color: PLAN_ROUTE_COLOR,
steps: 50,
wrap: false,
}).addTo(map);
geodesicLayer.geoJson(opts.planned_route_line);
try {
map.fitBounds(geodesicLayer.getBounds())
} catch (e) {
console.log(e)
}
// Draw the route points after
if (opts.route_points !== null) {
let route_points = leaflet.geoJSON(opts.route_points, {
onEachFeature: onFeaturePointClick,
pointToLayer: pointToLayer,
style: {
'color': PLAN_ROUTE_COLOR,
'weight': 3,
'opacity': 0.65,
},
});
route_points.addTo(map);
}
/**
* draw the actual route * draw the actual route
*/ */
if (opts.actual_route_line !== null && opts.actual_route_line.features.length > 0) { if (opts.actual_route_line !== null && opts.actual_route_line.features.length > 0) {
let geodesicLayer = leaflet.geodesic([], { const actualRouteLayer = leaflet.geodesic([], {
weight: 3, weight: 3,
opacity: 0.9, opacity: 0.9,
color: ACTUAL_ROUTE_COLOR, color: ACTUAL_ROUTE_COLOR,
steps: 50, steps: 50,
wrap: false, wrap: false,
}).addTo(map); }).addTo(map);
geodesicLayer.geoJson(opts.actual_route_line); actualRouteLayer.geoJson(opts.actual_route_line);
try { try {
map.fitBounds(geodesicLayer.getBounds()) map.fitBounds(actualRouteLayer.getBounds());
} catch (e) { } catch (e) {
console.log(e) console.log(e);
}
} }
}
if (opts.actual_route_points !== null && opts.actual_route_points.features.length > 0) { if (opts.actual_route_points !== null && opts.actual_route_points.features.length > 0) {
let route_points = leaflet.geoJSON(opts.actual_route_points, { const route_points = leaflet.geoJSON(opts.actual_route_points, {
onEachFeature: onFeaturePointClick, onEachFeature: onFeaturePointClick,
pointToLayer: pointToLayer, pointToLayer,
style: { style: {
'color': ACTUAL_ROUTE_COLOR, color: ACTUAL_ROUTE_COLOR,
'weight': 3, weight: 3,
'opacity': 0.65, opacity: 0.65,
}, },
}); });
route_points.addTo(map) route_points.addTo(map);
} }
/** /**
* *
*/ */
const liveFlight = () => { const liveFlight = () => {
const uri = opts.pirep_uri; request({ url: opts.pirep_uri }).then((response) => {
const live_route = $.ajax({ const routeJson = response.data.data;
url: uri, layerLiveFlight = leaflet.geoJSON(routeJson, {
dataType: 'json', pointToLayer(feature, latlon) {
error: console.log return leaflet.marker(latlon, {
}); icon: aircraftIcon,
rotationAngle: feature.properties.heading,
});
},
});
$.when(live_route).done((routeJson) => { layerLiveFlight.addTo(map);
layerLiveFlight = leaflet.geoJSON(routeJson, { });
pointToLayer: function (feature, latlon) { };
return leaflet.marker(latlon, {
icon: aircraftIcon,
rotationAngle: feature.properties.heading
})
}
});
layerLiveFlight.addTo(map) setInterval(liveFlight, opts.refresh_interval * 1000);
});
};
setInterval(liveFlight, 10000);
}; };

29
resources/js/request.js Normal file
View File

@@ -0,0 +1,29 @@
import config from './config';
const axios = require('axios');
/**
* Run an API request, with some common options
*
* @param {Object|String} _opts Axios request options, or pass a URL
* @param {String} _opts.url
*/
export default async (_opts) => {
if (typeof _opts === 'string' || _opts instanceof String) {
// eslint-disable-next-line no-param-reassign
_opts = {
url: _opts,
};
}
const opts = Object.assign({}, {
baseURL: config.base_url,
headers: {
'X-API-KEY': config.api_key,
'X-CSRF-TOKEN': config.csrf_token,
},
}, _opts);
return axios.request(opts);
};

View File

@@ -1,77 +1,76 @@
'use strict';
/** /**
* Simple browser storage interface * Simple browser storage interface
*/ */
export default class Storage { export default class Storage {
constructor(name, default_value) { constructor(name, default_value) {
this.name = name; this.name = name;
// Read the object from storage; if it doesn't exist, set // Read the object from storage; if it doesn't exist, set
// it to the default value // it to the default value
const st = window.localStorage.getItem(this.name); const st = window.localStorage.getItem(this.name);
if (!st) { if (!st) {
console.log('Nothing found in storage, starting from default'); console.log('Nothing found in storage, starting from default');
this.data = default_value; this.data = default_value;
} else { } else {
console.log('Found in storage: ', st); console.log('Found in storage: ', st);
this.data = JSON.parse(st); this.data = JSON.parse(st);
}
} }
}
/** /**
* Save to local storage * Save to local storage
*/ */
save() { save() {
window.localStorage.setItem(this.name, JSON.stringify(this.data)); window.localStorage.setItem(this.name, JSON.stringify(this.data));
} }
/** /**
* Return a list from a given key * Return a list from a given key
* *
* @param {String} key * @param {String} key
* *
* @returns {Array|*} * @returns {Array|*}
*/ */
getList(key) { getList(key) {
if (!(key in this.data)) { if (!(key in this.data)) {
return []; return [];
}
return this.data[key];
} }
/** return this.data[key];
}
/**
* Add `value` to a given `key` * Add `value` to a given `key`
* *
* @param {string} key * @param {string} key
* @param {*} value * @param {*} value
*/ */
addToList(key, value) { addToList(key, value) {
if (!(key in this.data)) { if (!(key in this.data)) {
this.data[key] = []; this.data[key] = [];
}
const index = this.data[key].indexOf(value);
if (index === -1) {
this.data[key].push(value);
}
} }
/** const index = this.data[key].indexOf(value);
if (index === -1) {
this.data[key].push(value);
}
}
/**
* Remove `value` from the given `key` * Remove `value` from the given `key`
* *
* @param {String} key * @param {String} key
* @param {*} value * @param {*} value
*/ */
removeFromList(key, value) { removeFromList(key, value) {
if (!(key in this.data)) { if (!(key in this.data)) {
return; return;
}
const index = this.data[key].indexOf(value);
if (index !== -1) {
this.data[key].splice(index, 1);
}
} }
const index = this.data[key].indexOf(value);
if (index !== -1) {
this.data[key].splice(index, 1);
}
}
} }

View File

@@ -1,7 +1,6 @@
@section('scripts') @section('scripts')
<script> <script>
function setEditable() { function setEditable() {
const token = $('meta[name="csrf-token"]').attr('content'); const token = $('meta[name="csrf-token"]').attr('content');
const api_key = $('meta[name="api-key"]').attr('content'); const api_key = $('meta[name="api-key"]').attr('content');

View File

@@ -54,7 +54,6 @@ function setEditable() {
} }
$(document).ready(function() { $(document).ready(function() {
const api_key = $('meta[name="api-key"]').attr('content'); const api_key = $('meta[name="api-key"]').attr('content');
const csrf_token = $('meta[name="csrf-token"]').attr('content'); const csrf_token = $('meta[name="csrf-token"]').attr('content');

View File

@@ -13,7 +13,6 @@ const changeParamDescription = (award_class) => {
}; };
$(document).ready(() => { $(document).ready(() => {
const select_id = "select#award_class_select"; const select_id = "select#award_class_select";
console.log('award descriptions', award_descriptions); console.log('award descriptions', award_descriptions);
$(select_id).change((e) => { $(select_id).change((e) => {

View File

@@ -30,8 +30,7 @@ const setEditable = () =>
}); });
}; };
const setFieldsEditable = () => const setFieldsEditable = () => {
{
const api_key = $('meta[name="api-key"]').attr('content'); const api_key = $('meta[name="api-key"]').attr('content');
const csrf_token = $('meta[name="csrf-token"]').attr('content'); const csrf_token = $('meta[name="csrf-token"]').attr('content');
@@ -59,11 +58,10 @@ const setFieldsEditable = () =>
}; };
$(document).ready(function () { $(document).ready(function () {
$("select#days_of_week").select2();
$("select#days_of_week").select2(); setEditable();
setFieldsEditable();
setEditable();
setFieldsEditable();
const start_date_picker = new Pikaday({ const start_date_picker = new Pikaday({
field: document.getElementById('start_date'), field: document.getElementById('start_date'),
@@ -75,47 +73,49 @@ $(document).ready(function () {
minDate: new Date(), minDate: new Date(),
}); });
$(document).on('submit', 'form.pjax_flight_fields', function (event) { $(document).on('submit', 'form.pjax_flight_fields', function (event) {
event.preventDefault(); event.preventDefault();
$.pjax.submit(event, '#flight_fields_wrapper', {push: false}); $.pjax.submit(event, '#flight_fields_wrapper', {push: false});
}); });
$(document).on('submit', 'form.pjax_subfleet_form', function (event) { $(document).on('submit', 'form.pjax_subfleet_form', function (event) {
event.preventDefault(); event.preventDefault();
$.pjax.submit(event, '#subfleet_flight_wrapper', {push: false}); $.pjax.submit(event, '#subfleet_flight_wrapper', {push: false});
}); });
$(document).on('submit', 'form.pjax_fares_form', function (event) { $(document).on('submit', 'form.pjax_fares_form', function (event) {
event.preventDefault(); event.preventDefault();
$.pjax.submit(event, '#flight_fares_wrapper', {push: false}); $.pjax.submit(event, '#flight_fares_wrapper', {push: false});
}); });
$(document).on('pjax:complete', function () { $(document).on('pjax:complete', function () {
initPlugins(); initPlugins();
setEditable(); setEditable();
setFieldsEditable(); setFieldsEditable();
}); });
$('a.airport_distance_lookup').click(async function (e) { $('a.airport_distance_lookup').click(async function (e) {
e.preventDefault(); e.preventDefault();
const fromIcao = $("select#dpt_airport_id option:selected").val(); const fromIcao = $("select#dpt_airport_id option:selected").val();
const toIcao = $("select#arr_airport_id option:selected").val(); const toIcao = $("select#arr_airport_id option:selected").val();
if (fromIcao === '' || toIcao === '') { console.log('fromIcao="' + fromIcao + '", toIcao="' + toIcao + '"');
return;
}
console.log(`Calculating from ${fromIcao} to ${toIcao}`); if (fromIcao === '' || toIcao === '') {
let response; return;
}
try { console.log(`Calculating from ${fromIcao} to ${toIcao}`);
response = await phpvms.calculate_distance(fromIcao, toIcao); let response;
} catch (e) {
console.log('Error calculating distance:', e);
return;
}
$("#distance").val(response.data.distance.nmi); try {
}); response = await phpvms.calculate_distance(fromIcao, toIcao);
} catch (e) {
console.log('Error calculating distance:', e);
return;
}
$("#distance").val(response.data.distance.nmi);
});
}); });
</script> </script>
@endsection @endsection

View File

@@ -11,7 +11,7 @@
<td>{{ $fare->name }} ({{ $fare->code }})</td> <td>{{ $fare->name }} ({{ $fare->code }})</td>
<td> <td>
<div class="form-group"> <div class="form-group">
@if($pirep->read_only) @if(isset($pirep) && $pirep->read_only)
<p>{{ $pirep->{'fare_'.$fare->id} }}</p> <p>{{ $pirep->{'fare_'.$fare->id} }}</p>
{{ Form::hidden('fare_'.$fare->id) }} {{ Form::hidden('fare_'.$fare->id) }}
@else @else
@@ -19,7 +19,7 @@
'class' => 'form-control', 'class' => 'form-control',
'min' => 0, 'min' => 0,
'step' => '0.01', 'step' => '0.01',
'readonly' => $pirep->read_only]) }} ]) }}
@endif @endif
</div> </div>
</td> </td>

View File

@@ -1,53 +1,29 @@
@section('scripts') @section('scripts')
<script> <script>
const changeStatus = (values, fn) => { const changeStatus = async (values, fn) => {
const api_key = $('meta[name="api-key"]').attr('content');
const token = $('meta[name="csrf-token"]').attr('content');
console.log('Changing PIREP ' + values.pirep_id + ' to state ' + values.new_status); console.log('Changing PIREP ' + values.pirep_id + ' to state ' + values.new_status);
$.ajax({ const opts = {
method: 'POST',
url: '{{url('/admin/pireps')}}/' + values.pirep_id + '/status', url: '{{url('/admin/pireps')}}/' + values.pirep_id + '/status',
data: values, data: values,
type: 'POST', };
headers: {
'x-api-key': api_key, const response = await phpvms.request(opts);
'X-CSRF-TOKEN': token, fn(response.data);
},
success: function (data) {
fn(data);
}
});
}; };
$(document).ready(() => { $(document).ready(() => {
const api_key = $('meta[name="api-key"]').attr('content');
const token = $('meta[name="csrf-token"]').attr('content');
const select_id = "select#aircraft_select"; const select_id = "select#aircraft_select";
const destContainer = $('#fares_container'); const destContainer = $('#fares_container');
$(select_id).change((e) => { $(select_id).change(async (e) => {
const aircraft_id = $(select_id + " option:selected").val(); const aircraft_id = $(select_id + " option:selected").val();
console.log('aircraft select change: ', aircraft_id); console.log('aircraft select change: ', aircraft_id);
$.ajax({ const response = await phpvms.request("{{ url('/admin/pireps/fares') }}?aircraft_id=" + aircraft_id);
url: "{{ url('/admin/pireps/fares') }}?aircraft_id=" + aircraft_id, console.log('returned new fares', response.data);
type: 'GET', destContainer.html(response.data);
headers: {
'x-api-key': api_key,
'X-CSRF-TOKEN': token,
},
success: (data) => {
console.log('returned new fares', data);
destContainer.html(data);
},
error: () => {
destContainer.html('');
}
});
}); });
$(document).on('submit', 'form.pjax_form', (event) => { $(document).on('submit', 'form.pjax_form', (event) => {
@@ -62,23 +38,19 @@ $(document).ready(() => {
/** /**
* Recalculate finances button is clicked * Recalculate finances button is clicked
*/ */
$('button#recalculate-finances').on('click', (event) => { $('button#recalculate-finances').on('click', async (event) => {
event.preventDefault(); event.preventDefault();
console.log('Sending recalculate finances request'); console.log('Sending recalculate finances request');
const pirep_id = $(event.currentTarget).attr('data-pirep-id'); const pirep_id = $(event.currentTarget).attr('data-pirep-id');
$.ajax({ const opts = {
method: 'POST',
url: '{{url('/api/pireps')}}/' + pirep_id + '/finances/recalculate', url: '{{url('/api/pireps')}}/' + pirep_id + '/finances/recalculate',
type: 'POST', };
headers: {
'x-api-key': api_key, const response = await phpvms.request(opts);
'X-CSRF-TOKEN': token, console.log(response.data);
}, location.reload();
success: (data) => {
console.log(data);
location.reload();
}
});
}); });
$(document).on('submit', 'form.pirep_submit_status', (event) => { $(document).on('submit', 'form.pirep_submit_status', (event) => {

View File

@@ -3,14 +3,12 @@
const select_id = "select#aircraft_select"; const select_id = "select#aircraft_select";
const destContainer = $('#fares_container'); const destContainer = $('#fares_container');
$(select_id).change((e) => { $(select_id).change(e => {
const aircraft_id = $(select_id + ' option:selected').val(); const aircraft_id = $(select_id + ' option:selected').val();
const url = '{{ url('/pireps/fares') }}?aircraft_id=' + aircraft_id; const url = '/pireps/fares?aircraft_id=' + aircraft_id;
console.log('aircraft select change: ', aircraft_id); console.log('aircraft select change: ', aircraft_id);
axios.get(url).then(response => { phpvms.request(url).then(response => {
console.log('returned new fares', response);
destContainer.html(response.data); destContainer.html(response.data);
}); });
}); });

View File

@@ -29,6 +29,7 @@
A couple of places (like the distance) use both to output the correct bindings. A couple of places (like the distance) use both to output the correct bindings.
--}} --}}
<div id="map-info-box" class="map-info-box" <div id="map-info-box" class="map-info-box"
rv-show="pirep"
style="width: {{ $config['width'] }};"> style="width: {{ $config['width'] }};">
<div style="float: left; width: 50%;"> <div style="float: left; width: 50%;">
<h3 style="margin: 0" id="map_flight_id"> <h3 style="margin: 0" id="map_flight_id">
@@ -112,9 +113,6 @@ and being mindful of the rivets bindings
phpvms.map.render_live_map({ phpvms.map.render_live_map({
center: ['{{ $center[0] }}', '{{ $center[1] }}'], center: ['{{ $center[0] }}', '{{ $center[1] }}'],
zoom: '{{ $zoom }}', zoom: '{{ $zoom }}',
update_uri: '{!! url('/api/acars') !!}',
pirep_uri: '{!! url('/api/pireps/{id}') !!}',
pirep_link_uri: '{!! url('/pireps/{id}') !!}',
aircraft_icon: '{!! public_asset('/assets/img/acars/aircraft.png') !!}', aircraft_icon: '{!! public_asset('/assets/img/acars/aircraft.png') !!}',
units: '{{ setting('units.distance') }}', units: '{{ setting('units.distance') }}',
}); });

View File

@@ -2,6 +2,8 @@
const mix = require('laravel-mix'); const mix = require('laravel-mix');
mix.disableNotifications();
/** /**
* COPY ASSETS * COPY ASSETS
* Copy required assets * Copy required assets

675
yarn.lock

File diff suppressed because it is too large Load Diff