Compare commits

...
Author SHA1 Message Date
snyk-bot b60251e7b8 fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-AXIOS-1579269
2021-09-06 01:31:47 +00:00
B.Fatih KOZandNabeel S 6eef246b6a Improve Map features (GeoJson) (#1290)
* Update GeoService.php

Replace double name usage with more valuable info

* Update GeoService.php

Changed `GS` with `Spd` 'cause it may be IAS or GS according to the phase of the flight.

Co-authored-by: Nabeel S <nabeelio@users.noreply.github.com>
2021-08-30 13:00:27 -04:00
B.Fatih KOZandNabeel S fc8ca69729 Fix Private Profile fields not being editable (#1289)
* Update ProfileController.php

* Update UserRepository.php

* Update UserRepository.php

Co-authored-by: Nabeel S <nabeelio@users.noreply.github.com>
2021-08-30 12:55:33 -04:00
B.Fatih KOZ 57277c558d Fix Fare not properly set in controller (#1291)
* Update FareService.php

* Update PirepController.php

Move the logic to controller as requested

* Update FareService.php

Reverting back the service changes as requested

* StyleFix
2021-08-30 12:50:04 -04:00
B.Fatih KOZ b0f52ed1d0 Remove SimBrief with Bid (#1283)
* Update BidService.php

* Update BidService.php

Delete directly ;)
2021-08-13 14:39:18 -04:00
Khendal d64e674c21 Update pirep_card.blade.php (#1282)
Added Pilot name in card to know who have submitted the pirep.
2021-08-13 11:51:52 -04:00
B.Fatih KOZ 40c911ff17 Add web middleware to laravel-widgets (#1281)
Title says it all ... Added web middleware to laravel-widgets config so the widget auto-reload / auto-refresh options can work with full functionality.
2021-08-12 08:40:41 -04:00
B.Fatih KOZ b6abe8dd5b Bid check for flights/show (#1278)
* Update FlightController.php

Add missing $bid to flight/show so when needed Load In Acars button can be placed there too.

* Update show.blade.php

Add Load In Acars button to flight details page (flights/show.blade.php)
2021-08-10 13:23:43 -04:00
Nabeel Shahzad 54c3c8f346 Fix user id check in template 2021-08-09 18:12:48 -04:00
Nabeel S c250fce84b Cast the user ID to int in the sb model (#1277) 2021-08-09 13:54:40 -04:00
Nabeel S 4125cdd373 Launch ACARS link on the simbrief page #1272 (#1276) 2021-08-09 12:01:27 -04:00
Nabeel S 6eb883de73 Dependency updates (#1274)
* Dependency updates

* Downgrade league/commonmark to 1.6
2021-08-08 11:48:45 -04:00
Nabeel Shahzad 49528c9644 Remove tar-to-zip dep 2021-08-07 12:58:31 -04:00
Nabeel Shahzad 4475813a12 remove dotfiles again 2021-08-07 12:51:13 -04:00
Nabeel Shahzad 681e39650b Try to fix dots in tar 2021-08-07 12:24:15 -04:00
Nabeel Shahzad bbbe8a8bd3 remove base dir 2021-08-07 12:16:16 -04:00
Nabeel Shahzad 0acab21712 Fix cd 2021-08-07 11:54:33 -04:00
Nabeel Shahzad a17840d690 Another zip fix attempt 2021-08-07 11:46:43 -04:00
Nabeel Shahzad fe87f21599 Restrict zip to current dir 2021-08-07 11:37:26 -04:00
Nabeel Shahzad 2756c34702 Try fixing zip 2021-08-07 11:34:06 -04:00
Nabeel S 564f9ec06e Add ability to launch acars for flight/bid #1272 (#1273)
* Add ability to launch acars for flight/bid #1272

* Check for module active/inactive status

* Just some formatting
2021-08-06 14:53:04 -04:00
Nabeel S 95e1df619e Trap exception/check for module existing on disk #1211 (#1271)
* Trap exception/check for module existing on disk #1211

* Style fixes
2021-08-06 13:30:24 -04:00
B.Fatih KOZandNabeel Shahzad 4a04d73d08 Update DownloadController.php (#1267)
* Update DownloadController.php

* StyleFix

* Another StyleFix !

* Update DownloadController.php

* Last StyleFix and Update

* Apply StyleCI fix

Co-authored-by: Nabeel Shahzad <nabeel@nabeel.sh>
2021-08-02 14:43:38 -04:00
Nabeel S 88a8ffe48a Check for blank values on import and omit them (#1266)
* Check for blank values on import and omit them

* Add paused status to the pirep changed
2021-07-22 15:56:03 -04:00
Nabeel Shahzad 78d3c6b577 Fix where for paused 2021-07-22 12:47:55 -04:00
Nabeel S f42a41286d Add a 'paused' state (#1265)
* Add a 'paused' state

* Check paused status
2021-07-22 11:59:52 -04:00
Nabeel S f8ded4e410 Update dependencies (#1262)
* Update dependencies

* Rebuild assets with updated deps
2021-07-21 10:43:36 -04:00
B.Fatih KOZ 6304f3cab4 Fix PirepService (#1261)
`$fv['name']` should be used instead of `$fv->name` due to the nature of source data.

Fixes #1260
2021-07-16 13:24:31 -04:00
Nabeel Shahzad 4eb73ab5f3 Update 3rd party services config 2021-07-13 14:38:42 -04:00
Nabeel Shahzad 2af72d137d Have emails go into the logs by default, make note to users to change that #1259 2021-07-12 17:18:28 -04:00
Nabeel Shahzad f68e068f87 Use MAIL_MAILER #1259 2021-07-12 13:50:36 -04:00
Nabeel Shahzad 89f9706520 Include all dotfiles in zip 2021-07-12 12:47:24 -04:00
Nabeel Shahzad cde6fb314b Add footer requirement into license explicitly 2021-06-20 09:07:13 -04:00
Nabeel Shahzad 1a944f320c Make the license extra clear 2021-06-19 15:58:56 -04:00
Nabeel Shahzad d7ad2bdd11 Fix PIREP rejected message #1246 2021-06-18 13:21:59 -04:00
Nabeel Shahzad 24fca650f8 Use old notification handler for admin notifications 2021-06-18 11:33:02 -04:00
Nabeel S 35359b8646 Create endpoint to load bid by ID (#1248)
* Create endpoint to load bid by ID

* Fix endpoint
2021-06-17 19:42:56 -04:00
B.Fatih KOZ b6a2fe405d Update AcarsRepository (#1245)
* Update AcarsRepository.php

Use `where` instead of `whereDate` , as you know whereDate only checks the date, it skips the time part completely, thus not providing correct live pireps collection.

* Switch from created_at to updated_at

Also remove the UTC conversion 'cause `updated_at` field is not being populated with UTC values.
2021-06-14 07:05:28 -04:00
Nabeel Shahzad bd9c429cfc Don't force status to airborne 2021-06-13 15:28:57 -04:00
Nabeel Shahzad b18f1bbe6c Fix paginate on airlines 2021-06-11 09:40:42 -04:00
Andrew Roberts a5a21fb2fd Fix missing colon on ./vendor volume (#1243)
docker up throwing error due to missing colon on the ./vendor folder
2021-06-11 08:46:37 -04:00
77 changed files with 11536 additions and 24737 deletions
+10 -2
View File
@@ -70,14 +70,22 @@ mkdir -p storage/framework/views
cd /tmp
echo "Current directory contents"
ls -al $BASE_DIR
echo "Parent directory contents"
ls -al $BASE_DIR/../
tar -czf $TAR_NAME -C $BASE_DIR .
echo "Calling find"
find $BASE_DIR/../ -type d -maxdepth 2
tar -czf $TAR_NAME -C $BASE_DIR --xform 's:^\./::' . [--show-transformed-names|--show-stored-names]
sha256sum $TAR_NAME >"$TAR_NAME.sha256"
cd $BASE_DIR;
zip -r $ZIP_NAME *
zip -r $ZIP_NAME ./
sha256sum $ZIP_NAME >"$ZIP_NAME.sha256"
mv $ZIP_NAME /tmp
mv "$ZIP_NAME.sha256" /tmp
-2
View File
@@ -116,7 +116,6 @@ jobs:
- name: 'Install Release Dependencies'
run: |
rm -rf vendor
sudo npm i tar-to-zip -g
composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/*
@@ -179,7 +178,6 @@ jobs:
- name: 'Install Release Dependencies'
run: |
rm -rf vendor
sudo npm i tar-to-zip -g
composer install --no-dev --prefer-dist --no-interaction --verbose
sudo chmod +x ./.github/scripts/*
+3 -2
View File
@@ -1,5 +1,3 @@
BSD 3-Clause License
Copyright (c) 2017, phpvms - http://www.phpvms.net
All rights reserved.
@@ -17,6 +15,9 @@ modification, are permitted provided that the following conditions are met:
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
* A "powered by phpvms" is required in page footers, unless the license has
purchased to omit it.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-9
View File
@@ -82,10 +82,6 @@ test:
phpcs:
@vendor/bin/php-cs-fixer fix --config=.php_cs -v --diff --diff-format=udiff --dry-run
#.PHONY: phpstan
#phpstan:
# vendor/bin/phpstan analyse -c phpstan.neon -v --level 2 app
.PHONY: replay-acars
replay-acars:
#@php artisan phpvms:replay AAL10,AAL3113,BAW172,DAL988,FIN6,MSR986 --manual
@@ -95,11 +91,6 @@ replay-acars:
sass-watch:
sass --watch public/assets/admin/sass/paper-dashboard.scss:public/assets/admin/css/paper-dashboard.css
.PHONY: schema
schema:
#php artisan infyom:scaffold Aircraft --fieldsFile=database/schema/aircraft.json
echo ""
.PHONY: deploy-package
deploy-package:
./.travis/deploy_script.sh
+5
View File
@@ -170,6 +170,11 @@ class ImportExport
}
foreach ($split_values as $value) {
$value = trim($value);
if ($value === '') {
continue;
}
// This isn't in the query string format, so it's
// just a straight key-value pair set
if (strpos($value, '?') === false) {
+5 -1
View File
@@ -5,6 +5,7 @@ namespace App\Cron\Hourly;
use App\Contracts\Listener;
use App\Events\CronHourly;
use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus;
use App\Models\Pirep;
use App\Services\PirepService;
use Carbon\Carbon;
@@ -38,7 +39,10 @@ class DeletePireps extends Listener
protected function deletePireps(int $expire_time_hours, int $state)
{
$dt = Carbon::now('UTC')->subHours($expire_time_hours);
$pireps = Pirep::where('created_at', '<', $dt)->where(['state' => $state])->get();
$pireps = Pirep::where('created_at', '<', $dt)
->where(['state' => $state])
->where('status', '<>', PirepStatus::PAUSED)
->get();
/** @var PirepService $pirepSvc */
$pirepSvc = app(PirepService::class);
@@ -32,6 +32,7 @@ class RemoveExpiredLiveFlights extends Listener
$pireps = Pirep::where('updated_at', '<', $date)
->where('state', PirepState::IN_PROGRESS)
->get();
foreach ($pireps as $pirep) {
event(new PirepCancelled($pirep));
Log::info('Cron: Deleting Expired Live PIREP id='.$pirep->id.', state='.PirepState::label($pirep->state));
@@ -9,6 +9,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
class ModulesController extends Controller
@@ -29,6 +30,7 @@ class ModulesController extends Controller
{
$modules = $this->moduleSvc->getAllModules();
$new_modules = $this->moduleSvc->scan();
return view('admin.modules.index', [
'modules' => $modules,
'new_modules' => $new_modules,
@@ -97,7 +99,14 @@ class ModulesController extends Controller
*/
public function enable(Request $request)
{
$this->moduleSvc->addModule($request->input('name'));
$moduleName = $request->input('name');
try {
$this->moduleSvc->addModule($moduleName);
} catch (\Exception $e) {
Log::error('Error activating module '.$moduleName);
}
return redirect(route('admin.modules.index'));
}
@@ -9,6 +9,7 @@ use App\Models\Enums\PirepSource;
use App\Models\Enums\PirepState;
use App\Models\Pirep;
use App\Models\PirepComment;
use App\Models\PirepFare;
use App\Repositories\AircraftRepository;
use App\Repositories\AirlineRepository;
use App\Repositories\AirportRepository;
@@ -151,10 +152,10 @@ class PirepController extends Controller
$count = $request->input($field_name);
}
$fares[] = [
$fares[] = new PirepFare([
'fare_id' => $fare->id,
'count' => $count,
];
]);
}
$this->fareSvc->saveForPirep($pirep, $fares);
+2 -2
View File
@@ -193,9 +193,9 @@ class AcarsController extends Controller
}
// Change the PIREP status if it's as SCHEDULED before
if ($pirep->status === PirepStatus::INITIATED) {
/*if ($pirep->status === PirepStatus::INITIATED) {
$pirep->status = PirepStatus::AIRBORNE;
}
}*/
$pirep->save();
@@ -30,9 +30,9 @@ class AirlineController extends Controller
*/
public function index(Request $request)
{
$airports = $this->airlineRepo->whereOrder(['active' => true], 'name')->get();
$airlines = $this->airlineRepo->whereOrder(['active' => true], 'name')->paginate();
return AirlineResource::collection($airports);
return AirlineResource::collection($airlines);
}
/**
@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Api;
use App\Contracts\Controller;
use App\Exceptions\Unauthorized;
use App\Exceptions\UserNotFound;
use App\Http\Resources\Bid as BidResource;
use App\Http\Resources\Pirep as PirepResource;
@@ -144,6 +145,28 @@ class UserController extends Controller
return BidResource::collection($bids);
}
/**
* Get a particular bid for a user
*
* @param $bid_id
* @param \Illuminate\Http\Request $request
*
* @return \App\Http\Resources\Bid
*/
public function get_bid($bid_id, Request $request)
{
/** @var \App\Models\User $user */
$user = Auth::user();
// Return the current bid
$bid = $this->bidSvc->getBid($user, $bid_id);
if ($bid->user_id !== $user->id) {
throw new Unauthorized(new \Exception('Bid not not belong to authenticated user'));
}
return new BidResource($bid);
}
/**
* Return the fleet that this user is allowed to
*
@@ -41,22 +41,25 @@ class DownloadController extends Controller
$klass = new $class();
$obj = $klass->find($id);
$category = explode('\\', $class);
$category = end($category);
// Check if the object is there first
if (isset($obj)) {
$category = explode('\\', $class);
$category = end($category);
if ($category == 'Aircraft' && $airlines > 1) {
$group_name = $category.' > '.$obj->subfleet->airline->name.' '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Aircraft') {
$group_name = $category.' > '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Airport') {
$group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')';
} elseif ($category == 'Subfleet' && $airlines > 1) {
$group_name = $category.' > '.$obj->airline->name.' '.$obj->name;
} else {
$group_name = $category.' > '.$obj->name;
if ($category == 'Aircraft' && $airlines > 1) {
$group_name = $category.' > '.$obj->subfleet->airline->name.' '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Aircraft') {
$group_name = $category.' > '.$obj->icao.' '.$obj->registration;
} elseif ($category == 'Airport') {
$group_name = $category.' > '.$obj->icao.' : '.$obj->name.' ('.$obj->country.')';
} elseif ($category == 'Subfleet' && $airlines > 1) {
$group_name = $category.' > '.$obj->airline->name.' '.$obj->name;
} else {
$group_name = $category.' > '.$obj->name;
}
$regrouped_files[$group_name] = $files;
}
$regrouped_files[$group_name] = $files;
}
ksort($regrouped_files, SORT_STRING);
@@ -13,6 +13,7 @@ use App\Repositories\FlightRepository;
use App\Repositories\SubfleetRepository;
use App\Repositories\UserRepository;
use App\Services\GeoService;
use App\Services\ModuleService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@@ -25,6 +26,7 @@ class FlightController extends Controller
private $airlineRepo;
private $airportRepo;
private $flightRepo;
private $moduleSvc;
private $subfleetRepo;
private $geoSvc;
private $userRepo;
@@ -34,6 +36,7 @@ class FlightController extends Controller
* @param AirportRepository $airportRepo
* @param FlightRepository $flightRepo
* @param GeoService $geoSvc
* @param ModuleService $moduleSvc
* @param SubfleetRepository $subfleetRepo
* @param UserRepository $userRepo
*/
@@ -42,6 +45,7 @@ class FlightController extends Controller
AirportRepository $airportRepo,
FlightRepository $flightRepo,
GeoService $geoSvc,
ModuleService $moduleSvc,
SubfleetRepository $subfleetRepo,
UserRepository $userRepo
) {
@@ -49,6 +53,7 @@ class FlightController extends Controller
$this->airportRepo = $airportRepo;
$this->flightRepo = $flightRepo;
$this->geoSvc = $geoSvc;
$this->moduleSvc = $moduleSvc;
$this->subfleetRepo = $subfleetRepo;
$this->userRepo = $userRepo;
}
@@ -108,7 +113,12 @@ class FlightController extends Controller
// Get only used Flight Types for the search form
// And filter according to settings
$usedtypes = Flight::select('flight_type')->where($where)->groupby('flight_type')->orderby('flight_type', 'asc')->get();
$usedtypes = Flight::select('flight_type')
->where($where)
->groupby('flight_type')
->orderby('flight_type')
->get();
// Build collection with type codes and labels
$flight_types = collect('', '');
foreach ($usedtypes as $ftype) {
@@ -123,12 +133,20 @@ class FlightController extends Controller
'simbrief' => function ($query) use ($user) {
$query->where('user_id', $user->id);
}, ])
->orderBy('flight_number', 'asc')
->orderBy('route_leg', 'asc')
->orderBy('flight_number')
->orderBy('route_leg')
->paginate();
$saved_flights = Bid::where('user_id', Auth::id())
->pluck('flight_id')->toArray();
$saved_flights = [];
$bids = Bid::where('user_id', Auth::id())->get();
foreach ($bids as $bid) {
if (!$bid->flight) {
$bid->delete();
continue;
}
$saved_flights[$bid->flight_id] = $bid->id;
}
return view('flights.index', [
'user' => $user,
@@ -145,6 +163,7 @@ class FlightController extends Controller
'subfleet_id' => $request->input('subfleet_id'),
'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
@@ -171,7 +190,7 @@ class FlightController extends Controller
}
$flights->add($bid->flight);
$saved_flights[] = $bid->flight->id;
$saved_flights[$bid->flight_id] = $bid->id;
}
return view('flights.bids', [
@@ -183,6 +202,7 @@ class FlightController extends Controller
'subfleets' => $this->subfleetRepo->selectBoxList(true),
'simbrief' => !empty(setting('simbrief.api_key')),
'simbrief_bids' => setting('simbrief.only_bids'),
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
@@ -203,9 +223,14 @@ class FlightController extends Controller
$map_features = $this->geoSvc->flightGeoJson($flight);
// See if the user has a bid for this flight
$bid = Bid::where(['user_id' => Auth::id(), 'flight_id' => $flight->id])->first();
return view('flights.show', [
'flight' => $flight,
'map_features' => $map_features,
'bid' => $bid,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
}
@@ -123,7 +123,7 @@ class ProfileController extends Controller
$airlines = $this->airlineRepo->selectBoxList();
$airports = $this->airportRepo->selectBoxList(false, setting('pilots.home_hubs_only'));
$userFields = $this->userRepo->getUserFields($user, true);
$userFields = $this->userRepo->getUserFields($user);
return view('profile.edit', [
'user' => $user,
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Frontend;
use App\Exceptions\AssetNotFound;
use App\Models\Aircraft;
use App\Models\Bid;
use App\Models\Enums\AircraftState;
use App\Models\Enums\AircraftStatus;
use App\Models\Enums\FareType;
@@ -14,6 +15,7 @@ use App\Models\SimBrief;
use App\Models\User;
use App\Repositories\FlightRepository;
use App\Services\FareService;
use App\Services\ModuleService;
use App\Services\SimBriefService;
use App\Services\UserService;
use Exception;
@@ -24,17 +26,20 @@ class SimBriefController
{
private $fareSvc;
private $flightRepo;
private $moduleSvc;
private $simBriefSvc;
private $userSvc;
public function __construct(
FareService $fareSvc,
FlightRepository $flightRepo,
ModuleService $moduleSvc,
SimBriefService $simBriefSvc,
UserService $userSvc
) {
$this->fareSvc = $fareSvc;
$this->flightRepo = $flightRepo;
$this->moduleSvc = $moduleSvc;
$this->simBriefSvc = $simBriefSvc;
$this->userSvc = $userSvc;
}
@@ -106,6 +111,7 @@ class SimBriefController
if (setting('simbrief.block_aircraft')) {
// Build a list of aircraft_id's being used for active sb packs
$sb_aircraft = SimBrief::whereNotNull('flight_id')->pluck('aircraft_id');
// Filter aircraft list to non used/blocked ones
$aircrafts = $aircrafts->whereNotIn('id', $sb_aircraft);
}
@@ -225,7 +231,7 @@ class SimBriefController
// Show the main simbrief form
return view('flights.simbrief_form', [
'user' => Auth::user(),
'user' => $user,
'flight' => $flight,
'aircraft' => $aircraft,
'pax_weight' => $pax_weight,
@@ -253,7 +259,11 @@ class SimBriefController
*/
public function briefing($id)
{
$simbrief = SimBrief::find($id);
/** @var User $user */
$user = Auth::user();
/** @var SimBrief $simbrief */
$simbrief = SimBrief::with(['flight'])->find($id);
if (!$simbrief) {
flash()->error('SimBrief briefing not found');
return redirect(route('frontend.flights.index'));
@@ -266,11 +276,18 @@ class SimBriefController
$equipment = substr($str, $wc + 1, $tr - 2);
$transponder = substr($str, $tr + 1);
// See if a bid exists for this flight
$bid = Bid::where(['user_id' => $user->id, 'flight_id' => $simbrief->flight_id])->first();
return view('flights.simbrief_briefing', [
'simbrief' => $simbrief,
'wakecat' => $wakecat,
'equipment' => $equipment,
'transponder' => $transponder,
'user' => $user,
'simbrief' => $simbrief,
'wakecat' => $wakecat,
'equipment' => $equipment,
'transponder' => $transponder,
'bid' => $bid,
'flight' => $simbrief->flight,
'acars_plugin' => $this->moduleSvc->isModuleActive('VMSAcars'),
]);
}
+1 -1
View File
@@ -6,7 +6,7 @@ use App\Contracts\Model;
use Carbon\Carbon;
/**
* @property string user_id
* @property int user_id
* @property string flight_id
* @property Carbon created_at
* @property Carbon updated_at
+2 -3
View File
@@ -4,9 +4,6 @@ namespace App\Models\Enums;
use App\Contracts\Enum;
/**
* Class PirepState
*/
class PirepState extends Enum
{
public const IN_PROGRESS = 0; // flight is ongoing
@@ -16,6 +13,7 @@ class PirepState extends Enum
public const DELETED = 4;
public const DRAFT = 5;
public const REJECTED = 6;
public const PAUSED = 7;
protected static $labels = [
self::IN_PROGRESS => 'pireps.state.in_progress',
@@ -25,5 +23,6 @@ class PirepState extends Enum
self::DELETED => 'pireps.state.deleted',
self::DRAFT => 'pireps.state.draft',
self::REJECTED => 'pireps.state.rejected',
self::PAUSED => 'pireps.state.paused',
];
}
+2
View File
@@ -34,6 +34,7 @@ class PirepStatus extends Enum
public const ARRIVED = 'ONB'; // On block
public const CANCELLED = 'DX';
public const EMERG_DESCENT = 'EMG';
public const PAUSED = 'PSD';
protected static $labels = [
self::INITIATED => 'pireps.status.initialized',
@@ -59,5 +60,6 @@ class PirepStatus extends Enum
self::ARRIVED => 'pireps.status.arrived',
self::CANCELLED => 'pireps.status.cancelled',
self::EMERG_DESCENT => 'pireps.status.emerg_decent',
self::PAUSED => 'pireps.status.paused',
];
}
+11 -11
View File
@@ -195,22 +195,22 @@ class Pirep extends Model
/**
* Create a new PIREP from a SimBrief instance
*
* @param \App\Models\SimBrief $simBrief
* @param \App\Models\SimBrief $simbrief
*
* @return \App\Models\Pirep
*/
public static function fromSimBrief(SimBrief $simBrief): self
public static function fromSimBrief(SimBrief $simbrief): self
{
return new self([
'flight_id' => $simBrief->flight->id,
'airline_id' => $simBrief->flight->airline_id,
'flight_number' => $simBrief->flight->flight_number,
'route_code' => $simBrief->flight->route_code,
'route_leg' => $simBrief->flight->route_leg,
'dpt_airport_id' => $simBrief->flight->dpt_airport_id,
'arr_airport_id' => $simBrief->flight->arr_airport_id,
'route' => $simBrief->xml->getRouteString(),
'level' => $simBrief->xml->getFlightLevel(),
'flight_id' => $simbrief->flight->id,
'airline_id' => $simbrief->flight->airline_id,
'flight_number' => $simbrief->flight->flight_number,
'route_code' => $simbrief->flight->route_code,
'route_leg' => $simbrief->flight->route_leg,
'dpt_airport_id' => $simbrief->flight->dpt_airport_id,
'arr_airport_id' => $simbrief->flight->arr_airport_id,
'route' => $simbrief->xml->getRouteString(),
'level' => $simbrief->xml->getFlightLevel(),
]);
}
+9 -6
View File
@@ -41,6 +41,10 @@ class SimBrief extends Model
'updated_at',
];
protected $casts = [
'user_id' => 'integer',
];
/** @var \App\Models\SimBriefXML Store a cached version of the XML object */
private $xml_instance;
@@ -92,13 +96,12 @@ class SimBrief extends Model
public function flight()
{
if (!empty($this->attributes['flight_id'])) {
return $this->belongsTo(Flight::class, 'flight_id');
}
return $this->belongsTo(Flight::class, 'flight_id');
}
if (!empty($this->attributes['pirep_id'])) {
return $this->belongsTo(Pirep::class, 'pirep_id');
}
public function pirep()
{
return $this->belongsTo(Pirep::class, 'pirep_id');
}
public function user()
@@ -44,6 +44,7 @@ class PirepStatusChanged extends Notification implements ShouldQueue
PirepStatus::LANDED => 'has landed',
PirepStatus::ARRIVED => 'has arrived',
PirepStatus::CANCELLED => 'is cancelled',
PirepStatus::PAUSED => 'is paused',
PirepStatus::EMERG_DESCENT => 'in emergency descent',
];
@@ -58,8 +58,8 @@ class NotificationEventsHandler extends Listener
}
try {
$this->notifyUser($user, $notification);
// Notification::send([$user], $notification);
// $this->notifyUser($user, $notification);
Notification::send([$user], $notification);
} catch (Exception $e) {
Log::emergency('Error emailing admin ('.$user->email.'). Error='.$e->getMessage());
}
+4
View File
@@ -584,6 +584,10 @@ class RouteServiceProvider extends ServiceProvider
Route::get('user/fleet', 'UserController@fleet');
Route::get('user/pireps', 'UserController@pireps');
Route::get('bids', 'UserController@bids');
Route::get('bids/{id}', 'UserController@get_bid');
Route::get('user/bids/{id}', 'UserController@get_bid');
Route::get('user/bids', 'UserController@bids');
Route::put('user/bids', 'UserController@bids');
Route::post('user/bids', 'UserController@bids');
+3 -3
View File
@@ -69,11 +69,11 @@ class AcarsRepository extends Repository
->where(['state' => PirepState::IN_PROGRESS]);
if ($live_time !== null && $live_time > 0) {
$st = Carbon::now('UTC')->subHours($live_time);
$q = $q->whereDate('created_at', '>=', $st);
$st = Carbon::now()->subHours($live_time);
$q = $q->where('updated_at', '>=', $st);
}
$q = $q->orderBy('created_at', 'desc');
$q = $q->orderBy('updated_at', 'desc');
return $q->get();
}
+7 -2
View File
@@ -36,9 +36,14 @@ class UserRepository extends Repository
*
* @return \App\Models\UserField[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection
*/
public function getUserFields(User $user, $only_public_fields = true): Collection
public function getUserFields(User $user, $only_public_fields = null): Collection
{
$fields = UserField::where(['private' => !$only_public_fields])->get();
if (is_bool($only_public_fields)) {
$fields = UserField::where(['private' => !$only_public_fields])->get();
} else {
$fields = UserField::get();
}
return $fields->map(function ($field, $_) use ($user) {
foreach ($user->fields as $userFieldValue) {
if ($userFieldValue->field->slug === $field->slug) {
+26 -5
View File
@@ -8,6 +8,7 @@ use App\Exceptions\UserBidLimit;
use App\Models\Bid;
use App\Models\Flight;
use App\Models\Pirep;
use App\Models\SimBrief;
use App\Models\User;
use Illuminate\Support\Facades\Log;
@@ -30,12 +31,24 @@ class BidService extends Service
*
* @param $bid_id
*
* @return \App\Models\Bid|\Illuminate\Database\Eloquent\Model|tests/ImporterTest.php:521object|null
* @return \App\Models\Bid|\Illuminate\Database\Eloquent\Model|object|null
*/
public function getBid($bid_id)
public function getBid(User $user, $bid_id): Bid
{
return Bid::with(['flight', 'flight.simbrief'])
->where(['id' => $bid_id])->first();
$with = [
'flight',
'flight.fares',
'flight.simbrief' => function ($query) use ($user) {
$query->where('user_id', $user->id);
},
'flight.simbrief.aircraft',
'flight.simbrief.aircraft.subfleet',
'flight.subfleets',
'flight.subfleets.aircraft',
'flight.subfleets.fares',
];
return Bid::with($with)->where(['id' => $bid_id])->first();
}
/**
@@ -132,7 +145,7 @@ class BidService extends Service
$flight->has_bid = true;
$flight->save();
return $this->getBid($bid->id);
return $this->getBid($user, $bid->id);
}
/**
@@ -152,6 +165,14 @@ class BidService extends Service
$bid->forceDelete();
}
// Remove SimBrief OFP when removing the bid if it is not flown
if (setting('simbrief.only_bids')) {
$simbrief = SimBrief::where([
'user_id' => $user->id,
'flight_id' => $flight->id,
])->whereNull('pirep_id')->delete();
}
// Only flip the flag if there are no bids left for this flight
$bid_count = Bid::where(['flight_id' => $flight->id])->count();
if ($bid_count === 0) {
+3 -3
View File
@@ -309,7 +309,7 @@ class GeoService extends Service
foreach ($all_route_points as $point) {
$route->addPoint($point->lat, $point->lon, [
'name' => $point->name,
'popup' => $point->name.' ('.$point->name.')',
'popup' => $point->name.' ('.$point->lat.', '.$point->lon.')',
'icon' => '',
]);
}
@@ -351,7 +351,7 @@ class GeoService extends Service
foreach ($planned_route as $point) {
$planned->addPoint($point->lat, $point->lon, [
'name' => $point->name,
'popup' => $point->name.' ('.$point->name.')',
'popup' => $point->name.' ('.$point->lat.', '.$point->lon.')',
]);
}
@@ -369,7 +369,7 @@ class GeoService extends Service
$actual->addPoint($point->lat, $point->lon, [
'pirep_id' => $pirep->id,
'name' => $point->altitude,
'popup' => 'GS: '.$point->gs.'<br />Alt: '.$point->altitude,
'popup' => 'Spd: '.$point->gs.' kts<br />Alt: '.$point->altitude.' ft<br />Pos: '.$point->lat.', '.$point->lon,
]);
}
@@ -212,6 +212,11 @@ class FlightImporter extends ImportExport
$count = 0;
$subfleets = $this->parseMultiColumnValues($col);
foreach ($subfleets as $subfleet_type) {
$subfleet_type = trim($subfleet_type);
if (empty($subfleet_type)) {
continue;
}
$subfleet = Subfleet::firstOrCreate(
['type' => $subfleet_type],
['name' => $subfleet_type]
+1 -1
View File
@@ -33,7 +33,7 @@ class ConfigService extends Service
'DB_EMULATE_PREPARES' => false,
'CACHE_DRIVER' => 'array',
'CACHE_PREFIX' => '',
'MAIL_DRIVER' => 'mail',
'MAIL_DRIVER' => 'log',
'MAIL_HOST' => '',
'MAIL_PORT' => 587,
'MAIL_ENCRYPTION' => '',
+50 -10
View File
@@ -88,13 +88,56 @@ class ModuleService extends Service
}
/**
* Get All modules from Database
* Get all of the modules from database but make sure they also exist on disk
*
* @return object
*/
public function getAllModules(): object
public function getAllModules(): array
{
return Module::all();
$modules = [];
$moduleList = Module::all();
/** @var Module $module */
foreach ($moduleList as $module) {
/** @var \Nwidart\Modules\Module $moduleInstance */
$moduleInstance = \Nwidart\Modules\Facades\Module::find($module->name);
if (empty($moduleInstance)) {
continue;
}
if (file_exists($moduleInstance->getPath())) {
$modules[] = $module;
}
}
return $modules;
}
/**
* Determine if a module is active - also checks that the module exists properly
*
* @param string $name
*
* @return bool
*/
public function isModuleActive(string $name): bool
{
$module = Module::where('name', $name)->first();
if (empty($module)) {
return false;
}
/** @var \Nwidart\Modules\Module $moduleInstance */
$moduleInstance = \Nwidart\Modules\Facades\Module::find($module->name);
if (empty($moduleInstance)) {
return false;
}
if (!file_exists($moduleInstance->getPath())) {
return false;
}
return $moduleInstance->isEnabled();
}
/**
@@ -102,9 +145,9 @@ class ModuleService extends Service
*
* @param $id
*
* @return object
* @return Module
*/
public function getModule($id): object
public function getModule($id): Module
{
return Module::find($id);
}
@@ -148,22 +191,20 @@ class ModuleService extends Service
*/
public function installModule(UploadedFile $file): FlashNotifier
{
$file_ext = $file->getClientOriginalExtension();
$file_ext = strtolower($file->getClientOriginalExtension());
$allowed_extensions = ['zip', 'tar', 'gz'];
if (!in_array($file_ext, $allowed_extensions, true)) {
throw new ModuleInvalidFileType();
}
$module = null;
$new_dir = rand();
File::makeDirectory(
storage_path('app/tmp/modules/'.$new_dir),
0777,
true
);
$temp_ext_folder = storage_path('app/tmp/modules/'.$new_dir);
$temp = storage_path('app/tmp/modules/'.$new_dir);
@@ -219,7 +260,6 @@ class ModuleService extends Service
}
File::moveDirectory($temp, $toCopy);
File::deleteDirectory($temp_ext_folder);
try {
+2 -2
View File
@@ -574,8 +574,8 @@ class PirepService extends Service
foreach ($field_values as $fv) {
PirepFieldValue::updateOrCreate(
['pirep_id' => $pirep_id, 'name' => $fv->name],
['value' => $fv->value, 'source' => $fv->source]
['pirep_id' => $pirep_id, 'name' => $fv['name']],
['value' => $fv['value'], 'source' => $fv['source']]
);
}
}
+1
View File
@@ -41,6 +41,7 @@
"laravel/helpers": "^1.4",
"laravelcollective/html": "~6.2.0",
"jeremykendall/php-domain-parser": "~5.7.2",
"league/commonmark": "~1.6",
"league/csv": "9.2.*",
"league/geotools": "0.8.*",
"league/iso3166": "^3.0.0",
Generated
+581 -447
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -8,7 +8,7 @@ return [
/*
* Set Ajax widget middleware
*/
'route_middleware' => [],
'route_middleware' => ['web'],
'widget_stub' => 'resources/stubs/widgets/widget.stub',
'widget_plain_stub' => 'resources/stubs/widgets/widget_plain.stub',
+3 -17
View File
@@ -1,21 +1,7 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill",
| "ses", "sparkpost", "log"
|
*/
'default' => env('MAIL_DRIVER', 'smtp'),
'default' => env('MAIL_MAILER', 'smtp'),
'mailers' => [
'smtp' => [
'transport' => 'smtp',
@@ -28,7 +14,7 @@ return [
],
'ses' => [
'transport' => 'seapp/Contracts/Command.php:105s',
'transport' => 'ses',
],
'mailgun' => [
@@ -46,7 +32,7 @@ return [
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
'channel' => env('MAIL_LOG_CHANNEL', 'stack'),
],
'array' => [
+13 -21
View File
@@ -1,7 +1,5 @@
<?php
use App\Models\User;
return [
/*
|--------------------------------------------------------------------------
@@ -9,31 +7,25 @@ return [
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
];
+1 -1
View File
@@ -26,7 +26,7 @@ services:
- ./composer-lock.json:/var/www/composer-lock.json
- ./env.php:/var/www/env.php
- ./resources/docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf
- ./vendor/var/www/vendor
- ./vendor:/var/www/vendor
depends_on:
- mysql
- redis
+10527 -11554
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -13,7 +13,7 @@
"@turf/center": "^6.0.1",
"acorn": "^7.4.1",
"animate.css": "~3.6",
"axios": "^0.21.1",
"axios": "^0.21.3",
"bootstrap": "~4.3",
"bootstrap-sass": "^3.4.1",
"bootstrap3": "npm:bootstrap@~3.4",
@@ -27,14 +27,14 @@
"jquery": "^3.5.1",
"jquery-pjax": "~2.0",
"js-yaml": "^3.14.0",
"laravel-mix": "^5.0.7",
"laravel-mix": "^6.0.25",
"leaflet": "^1.3.4",
"leaflet-ajax": "2.1.0",
"leaflet-providers": "1.0.*",
"leaflet-rotatedmarker": "^0.2.0",
"leaflet.geodesic": "^2.5.2",
"lodash": ">=4.17.19",
"marked": "^1.2.2",
"marked": "^2.1.3",
"minimist": "^1.2.2",
"moment": "^2.29.1",
"paper-dashboard": "^1.1.0",
@@ -44,14 +44,14 @@
"popper.js": "^1.15.0",
"rivets": "^0.9.6",
"select2": "^4.0.13",
"ssri": "^5.3.0",
"ssri": "^8.0.1",
"tar": ">=4.4.2",
"webpack": "^4.44.2",
"webpack": "^5.45.1",
"webpack-cli": "^3.3.12",
"x-editable": "1.5.1"
},
"devDependencies": {
"copy-webpack-plugin": "^4.6.0",
"copy-webpack-plugin": "^9.0.1",
"eslint": "^6.2.2",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
@@ -63,6 +63,6 @@
"tailwindcss": "^0.5.3",
"vue-template-compiler": "^2.6.12",
"webpack-bundle-analyzer": "^3.9.0",
"webpack-dev-server": "^3.1.11"
"webpack-dev-server": "^1.16.5"
}
}
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
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
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
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
+1 -10881
View File
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
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
File diff suppressed because one or more lines are too long
+1 -38
View File
@@ -1,38 +1 @@
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
*/
CKEDITOR.editorConfig = function( config ) {
// Define changes to default configuration here.
// For complete reference see:
// https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html
// The toolbar groups arrangement, optimized for two toolbar rows.
config.toolbarGroups = [
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
// Remove some buttons provided by the standard plugins, which are
// not needed in the Standard(s) toolbar.
config.removeButtons = 'Underline,Subscript,Superscript';
// Set the most common block elements.
config.format_tags = 'p;h1;h2;h3;pre';
// Simplify the dialog windows.
config.removeDialogTabs = 'image:advanced;link:advanced';
};
CKEDITOR.editorConfig=function(e){e.toolbarGroups=[{name:"clipboard",groups:["clipboard","undo"]},{name:"editing",groups:["find","selection","spellchecker"]},{name:"links"},{name:"insert"},{name:"forms"},{name:"tools"},{name:"document",groups:["mode","document","doctools"]},{name:"others"},"/",{name:"basicstyles",groups:["basicstyles","cleanup"]},{name:"paragraph",groups:["list","indent","blocks","align","bidi"]},{name:"styles"},{name:"colors"},{name:"about"}],e.removeButtons="Underline,Subscript,Superscript",e.format_tags="p;h1;h2;h3;pre",e.removeDialogTabs="image:advanced;link:advanced"};
+1 -208
View File
@@ -1,208 +1 @@
/*
Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
body
{
/* Font */
/* Emoji fonts are added to visualise them nicely in Internet Explorer. */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 12px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent. */
background-color: #fff;
margin: 20px;
}
.cke_editable
{
font-size: 13px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* Preserved spaces for list items with text direction different than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
outline: solid 1px #ccc;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
/* Widget Styles */
.code-featured
{
border: 5px solid red;
}
.math-featured
{
padding: 20px;
box-shadow: 0 0 2px rgba(200, 0, 0, 1);
background-color: rgba(255, 0, 0, 0.05);
margin: 10px;
}
.image-clean
{
border: 0;
background: none;
padding: 0;
}
.image-clean > figcaption
{
font-size: .9em;
text-align: right;
}
.image-grayscale
{
background-color: white;
color: #666;
}
.image-grayscale img, img.image-grayscale
{
filter: grayscale(100%);
}
.embed-240p
{
max-width: 426px;
max-height: 240px;
margin:0 auto;
}
.embed-360p
{
max-width: 640px;
max-height: 360px;
margin:0 auto;
}
.embed-480p
{
max-width: 854px;
max-height: 480px;
margin:0 auto;
}
.embed-720p
{
max-width: 1280px;
max-height: 720px;
margin:0 auto;
}
.embed-1080p
{
max-width: 1920px;
max-height: 1080px;
margin:0 auto;
}
body{font-family:sans-serif,Arial,Verdana,"Trebuchet MS","Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:12px;color:#333;background-color:#fff;margin:20px}.cke_editable{font-size:13px;line-height:1.6;word-wrap:break-word}blockquote{font-style:italic;font-family:Georgia,Times,"Times New Roman",serif;padding:2px 0;border-style:solid;border-color:#ccc;border-width:0}.cke_contents_ltr blockquote{padding-left:20px;padding-right:8px;border-left-width:5px}.cke_contents_rtl blockquote{padding-left:8px;padding-right:20px;border-right-width:5px}a{color:#0782c1}dl,ol,ul{padding:0 40px}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.2}hr{border:0;border-top:1px solid #ccc}img.right{border:1px solid #ccc;float:right;margin-left:15px;padding:5px}img.left{border:1px solid #ccc;float:left;margin-right:15px;padding:5px}pre{white-space:pre-wrap;word-wrap:break-word;-moz-tab-size:4;tab-size:4}.marker{background-color:#ff0}span[lang]{font-style:italic}figure{text-align:center;outline:solid 1px #ccc;background:rgba(0,0,0,.05);padding:10px;margin:10px 20px;display:inline-block}figure>figcaption{text-align:center;display:block}a>img{padding:1px;margin:1px;border:none;outline:1px solid #0782C1}.code-featured{border:5px solid red}.math-featured{padding:20px;box-shadow:0 0 2px #c80000;background-color:rgba(255,0,0,.05);margin:10px}.image-clean{border:0;background:0 0;padding:0}.image-clean>figcaption{font-size:.9em;text-align:right}.image-grayscale{background-color:#fff;color:#666}.image-grayscale img,img.image-grayscale{filter:grayscale(100%)}.embed-240p{max-width:426px;max-height:240px;margin:0 auto}.embed-360p{max-width:640px;max-height:360px;margin:0 auto}.embed-480p{max-width:854px;max-height:480px;margin:0 auto}.embed-720p{max-width:1280px;max-height:720px;margin:0 auto}.embed-1080p{max-width:1920px;max-height:1080px;margin:0 auto}
+1 -137
View File
@@ -1,137 +1 @@
/**
* Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
// This file contains style definitions that can be used by CKEditor plugins.
//
// The most common use for it is the "stylescombo" plugin which shows the Styles drop-down
// list containing all styles in the editor toolbar. Other plugins, like
// the "div" plugin, use a subset of the styles for their features.
//
// If you do not have plugins that depend on this file in your editor build, you can simply
// ignore it. Otherwise it is strongly recommended to customize this file to match your
// website requirements and design properly.
//
// For more information refer to: https://ckeditor.com/docs/ckeditor4/latest/guide/dev_styles.html#style-rules
CKEDITOR.stylesSet.add( 'default', [
/* Block styles */
// These styles are already available in the "Format" drop-down list ("format" plugin),
// so they are not needed here by default. You may enable them to avoid
// placing the "Format" combo in the toolbar, maintaining the same features.
/*
{ name: 'Paragraph', element: 'p' },
{ name: 'Heading 1', element: 'h1' },
{ name: 'Heading 2', element: 'h2' },
{ name: 'Heading 3', element: 'h3' },
{ name: 'Heading 4', element: 'h4' },
{ name: 'Heading 5', element: 'h5' },
{ name: 'Heading 6', element: 'h6' },
{ name: 'Preformatted Text',element: 'pre' },
{ name: 'Address', element: 'address' },
*/
{ name: 'Italic Title', element: 'h2', styles: { 'font-style': 'italic' } },
{ name: 'Subtitle', element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },
{
name: 'Special Container',
element: 'div',
styles: {
padding: '5px 10px',
background: '#eee',
border: '1px solid #ccc'
}
},
/* Inline styles */
// These are core styles available as toolbar buttons. You may opt enabling
// some of them in the Styles drop-down list, removing them from the toolbar.
// (This requires the "stylescombo" plugin.)
/*
{ name: 'Strong', element: 'strong', overrides: 'b' },
{ name: 'Emphasis', element: 'em' , overrides: 'i' },
{ name: 'Underline', element: 'u' },
{ name: 'Strikethrough', element: 'strike' },
{ name: 'Subscript', element: 'sub' },
{ name: 'Superscript', element: 'sup' },
*/
{ name: 'Marker', element: 'span', attributes: { 'class': 'marker' } },
{ name: 'Big', element: 'big' },
{ name: 'Small', element: 'small' },
{ name: 'Typewriter', element: 'tt' },
{ name: 'Computer Code', element: 'code' },
{ name: 'Keyboard Phrase', element: 'kbd' },
{ name: 'Sample Text', element: 'samp' },
{ name: 'Variable', element: 'var' },
{ name: 'Deleted Text', element: 'del' },
{ name: 'Inserted Text', element: 'ins' },
{ name: 'Cited Work', element: 'cite' },
{ name: 'Inline Quotation', element: 'q' },
{ name: 'Language: RTL', element: 'span', attributes: { 'dir': 'rtl' } },
{ name: 'Language: LTR', element: 'span', attributes: { 'dir': 'ltr' } },
/* Object styles */
{
name: 'Styled Image (left)',
element: 'img',
attributes: { 'class': 'left' }
},
{
name: 'Styled Image (right)',
element: 'img',
attributes: { 'class': 'right' }
},
{
name: 'Compact Table',
element: 'table',
attributes: {
cellpadding: '5',
cellspacing: '0',
border: '1',
bordercolor: '#ccc'
},
styles: {
'border-collapse': 'collapse'
}
},
{ name: 'Borderless Table', element: 'table', styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },
{ name: 'Square Bulleted List', element: 'ul', styles: { 'list-style-type': 'square' } },
/* Widget styles */
{ name: 'Clean Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-clean' } },
{ name: 'Grayscale Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-grayscale' } },
{ name: 'Featured Snippet', type: 'widget', widget: 'codeSnippet', attributes: { 'class': 'code-featured' } },
{ name: 'Featured Formula', type: 'widget', widget: 'mathjax', attributes: { 'class': 'math-featured' } },
{ name: '240p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-240p' }, group: 'size' },
{ name: '360p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-360p' }, group: 'size' },
{ name: '480p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-480p' }, group: 'size' },
{ name: '720p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-720p' }, group: 'size' },
{ name: '1080p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-1080p' }, group: 'size' },
// Adding space after the style name is an intended workaround. For now, there
// is no option to create two styles with the same name for different widget types. See https://dev.ckeditor.com/ticket/16664.
{ name: '240p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-240p' }, group: 'size' },
{ name: '360p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-360p' }, group: 'size' },
{ name: '480p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-480p' }, group: 'size' },
{ name: '720p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-720p' }, group: 'size' },
{ name: '1080p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-1080p' }, group: 'size' }
] );
CKEDITOR.stylesSet.add("default",[{name:"Italic Title",element:"h2",styles:{"font-style":"italic"}},{name:"Subtitle",element:"h3",styles:{color:"#aaa","font-style":"italic"}},{name:"Special Container",element:"div",styles:{padding:"5px 10px",background:"#eee",border:"1px solid #ccc"}},{name:"Marker",element:"span",attributes:{class:"marker"}},{name:"Big",element:"big"},{name:"Small",element:"small"},{name:"Typewriter",element:"tt"},{name:"Computer Code",element:"code"},{name:"Keyboard Phrase",element:"kbd"},{name:"Sample Text",element:"samp"},{name:"Variable",element:"var"},{name:"Deleted Text",element:"del"},{name:"Inserted Text",element:"ins"},{name:"Cited Work",element:"cite"},{name:"Inline Quotation",element:"q"},{name:"Language: RTL",element:"span",attributes:{dir:"rtl"}},{name:"Language: LTR",element:"span",attributes:{dir:"ltr"}},{name:"Styled Image (left)",element:"img",attributes:{class:"left"}},{name:"Styled Image (right)",element:"img",attributes:{class:"right"}},{name:"Compact Table",element:"table",attributes:{cellpadding:"5",cellspacing:"0",border:"1",bordercolor:"#ccc"},styles:{"border-collapse":"collapse"}},{name:"Borderless Table",element:"table",styles:{"border-style":"hidden","background-color":"#E6E6FA"}},{name:"Square Bulleted List",element:"ul",styles:{"list-style-type":"square"}},{name:"Clean Image",type:"widget",widget:"image",attributes:{class:"image-clean"}},{name:"Grayscale Image",type:"widget",widget:"image",attributes:{class:"image-grayscale"}},{name:"Featured Snippet",type:"widget",widget:"codeSnippet",attributes:{class:"code-featured"}},{name:"Featured Formula",type:"widget",widget:"mathjax",attributes:{class:"math-featured"}},{name:"240p",type:"widget",widget:"embedSemantic",attributes:{class:"embed-240p"},group:"size"},{name:"360p",type:"widget",widget:"embedSemantic",attributes:{class:"embed-360p"},group:"size"},{name:"480p",type:"widget",widget:"embedSemantic",attributes:{class:"embed-480p"},group:"size"},{name:"720p",type:"widget",widget:"embedSemantic",attributes:{class:"embed-720p"},group:"size"},{name:"1080p",type:"widget",widget:"embedSemantic",attributes:{class:"embed-1080p"},group:"size"},{name:"240p ",type:"widget",widget:"embed",attributes:{class:"embed-240p"},group:"size"},{name:"360p ",type:"widget",widget:"embed",attributes:{class:"embed-360p"},group:"size"},{name:"480p ",type:"widget",widget:"embed",attributes:{class:"embed-480p"},group:"size"},{name:"720p ",type:"widget",widget:"embed",attributes:{class:"embed-720p"},group:"size"},{name:"1080p ",type:"widget",widget:"embed",attributes:{class:"embed-1080p"},group:"size"}]);
+22 -12
View File
@@ -1,25 +1,35 @@
{
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=c6f09efd67f43399c980",
"/assets/admin/js/app.js.map": "/assets/admin/js/app.js.map?id=d7cf2fb613c6991e3725",
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=cd0e1cc7897d01d2b2c8",
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=4e7a6eff0f7ee6e041a4",
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=71ff475a10f4f7af711c",
"/assets/frontend/js/app.js.map": "/assets/frontend/js/app.js.map?id=354cbdecd6ca9a777054",
"/assets/frontend/css/now-ui-kit.css.map": "/assets/frontend/css/now-ui-kit.css.map?id=e5c9b2a4e9d0a7678653",
"/assets/admin/css/vendor.min.css.map": "/assets/admin/css/vendor.min.css.map?id=ef71a09a5b9fa35df9a9",
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=4ebdf2b99afe39ca2dc3",
"/assets/installer/js/app.js.map": "/assets/installer/js/app.js.map?id=03bfe28bb64a23033bec",
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=b4f2e97d5ad74fbbb8c1",
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=83f3226250dcffc124b0",
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=b3b38b9ffe987af4c1e7",
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=bdbd85be3fb1f0381fc2",
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=c40e60a13efd077c7c02",
"/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/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a",
"/assets/admin/img/loading.gif": "/assets/admin/img/loading.gif?id=1e2db432947c2dca1b9f",
"/assets/global/js/jquery.js": "/assets/global/js/jquery.js?id=2849239b95f5a9a2aea3",
"/assets/global/css/images/layers-2x.png": "/assets/global/css/images/layers-2x.png?id=f905cd0e87fcdde8969b",
"/assets/global/css/images/layers.png": "/assets/global/css/images/layers.png?id=3d61d49c98ea3572cae4",
"/assets/global/css/images/marker-icon-2x.png": "/assets/global/css/images/marker-icon-2x.png?id=da330e712dc6fc8c7d58",
"/assets/global/css/images/marker-icon.png": "/assets/global/css/images/marker-icon.png?id=1045a925825f69b0a874",
"/assets/global/css/images/marker-shadow.png": "/assets/global/css/images/marker-shadow.png?id=43ccefc930d47f2e3a17",
"/assets/admin/css/blue.png": "/assets/admin/css/blue.png?id=39437a6200d8066a49d4",
"/assets/admin/css/blue@2x.png": "/assets/admin/css/blue@2x.png?id=127d7cfbb176dc559854",
"/assets/frontend/js/vendor.js": "/assets/frontend/js/vendor.js?id=3ab539b466b46ef2ed84",
"/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=4e79a5c8b0241493191b",
"/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=568fd06f4beaec54aa13",
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=edb4f99fb0b0998555c1",
"/assets/installer/css/vendor.css": "/assets/installer/css/vendor.css?id=a60c0e373bba3e7cd76b",
"/assets/vendor/ckeditor4/CHANGES.md": "/assets/vendor/ckeditor4/CHANGES.md?id=f6aecaa34a4f047b698b",
"/assets/vendor/ckeditor4/LICENSE.md": "/assets/vendor/ckeditor4/LICENSE.md?id=bdd7b1a5211ef8687a2b",
"/assets/vendor/ckeditor4/README.md": "/assets/vendor/ckeditor4/README.md?id=54b2071da0fd5125556d",
"/assets/vendor/ckeditor4/bower.json": "/assets/vendor/ckeditor4/bower.json?id=a6d6f831706863d6df7a",
"/assets/vendor/ckeditor4/ckeditor.js": "/assets/vendor/ckeditor4/ckeditor.js?id=aa81f7b2b2ddb8c4e0dd",
"/assets/vendor/ckeditor4/composer.json": "/assets/vendor/ckeditor4/composer.json?id=7d18ab5f522c8ecf3892",
"/assets/vendor/ckeditor4/config.js": "/assets/vendor/ckeditor4/config.js?id=dbc65722e8c3bae5b43b",
"/assets/vendor/ckeditor4/contents.css": "/assets/vendor/ckeditor4/contents.css?id=471be63a33e8ce099801",
"/assets/vendor/ckeditor4/package.json": "/assets/vendor/ckeditor4/package.json?id=4c783954edc3a50b72fc",
"/assets/vendor/ckeditor4/styles.js": "/assets/vendor/ckeditor4/styles.js?id=f5d57c2be704fbecec57",
"/assets/installer/css/vendor.css": "/assets/installer/css/vendor.css?id=29cfe641b34ad0c7ed19",
"/assets/installer/js/vendor.js": "/assets/installer/js/vendor.js?id=4398fa9f7340f95a1107",
"/assets/global/js/vendor.js": "/assets/global/js/vendor.js?id=bb691042c0629f4af9f5",
"/assets/global/css/vendor.css": "/assets/global/css/vendor.css?id=e01e86f8033ae9836957"
+2
View File
@@ -43,6 +43,7 @@ return [
'cancelled' => 'Abgebrochen',
'deleted' => 'Gelöscht',
'draft' => 'Entwurf',
'paused' => 'Angehalten',
],
'status' => [
'initialized' => 'Erstellt',
@@ -66,5 +67,6 @@ return [
'arrived' => 'Angekommen',
'cancelled' => 'Abgebrochen',
'emerg_decent' => 'Notfall dezent',
'paused' => 'Angehalten',
],
];
+2
View File
@@ -43,6 +43,7 @@ return [
'cancelled' => 'Cancelled',
'deleted' => 'Deleted',
'draft' => 'Draft',
'paused' => 'Paused',
],
'status' => [
'initialized' => 'Initiated',
@@ -66,5 +67,6 @@ return [
'arrived' => 'Arrived',
'cancelled' => 'Cancelled',
'emerg_decent' => 'Emergency decent',
'paused' => 'Paused',
],
];
+2
View File
@@ -43,6 +43,7 @@ return [
'cancelled' => 'Cancelado',
'deleted' => 'Eliminado',
'draft' => 'Borrador',
'paused' => 'Pausado',
],
'status' => [
'initialized' => 'Iniciado',
@@ -66,5 +67,6 @@ return [
'arrived' => 'Llegó',
'cancelled' => 'Cancelado',
'emerg_decent' => 'Descenso de emergencía',
'paused' => 'Pausado',
],
];
+2
View File
@@ -44,6 +44,7 @@ return [
'cancelled' => 'Cancellato',
'deleted' => 'Eliminato',
'draft' => 'Bozza',
'paused' => 'In pausa',
],
'status' => [
'initialized' => 'Iniziato',
@@ -67,5 +68,6 @@ return [
'arrived' => 'Arrivato',
'cancelled' => 'Cancellato',
'emerg_decent' => 'Discesa di Emergenza',
'paused' => 'In pausa',
],
];
+2
View File
@@ -43,6 +43,7 @@ return [
'cancelled' => 'Cancelado',
'deleted' => 'Deletado',
'draft' => 'Esboçado',
'paused' => 'Em pausa',
],
'status' => [
'initialized' => 'Iniciada',
@@ -66,5 +67,6 @@ return [
'arrived' => 'Chegou',
'cancelled' => 'Cancelado',
'emerg_decent' => 'Descida de emergência',
'paused' => 'Em pausa',
],
];
+1 -1
View File
@@ -49,7 +49,7 @@ CACHE_PREFIX='$CACHE_PREFIX$'
# If you're using SMTP, I recommend setting the QUEUE_DRIVER to 'database'
# https://docs.phpvms.net/config/optimizing#queue-driver
MAIL_DRIVER=$MAIL_DRIVER$
MAIL_MAILER=$MAIL_DRIVER$
MAIL_FROM_NAME='$MAIL_FROM_NAME$'
MAIL_FROM_ADDRESS='$MAIL_FROM_ADDRESS$'
MAIL_HOST=$MAIL_HOST$
@@ -17,6 +17,11 @@
<div class="row">
<div class="col-sm-6">
<div>
<span class="description">
<b>Pilot</b>&nbsp;{{ $pirep->user->name }}&nbsp;
</span>
</div>
<div>
<span class="description">
<b>DEP</b>&nbsp;{{ $pirep->dpt_airport_id }}&nbsp;
<b>ARR</b>&nbsp;{{ $pirep->arr_airport_id }}&nbsp;
@@ -64,8 +64,9 @@
<div class="container">
<div class="copyright">
{{--
Please keep the copyright message somewhere, as-per the LICENSE file
Thanks!!
This "powered by phpVMS" must be kept visible. as-per the the license
If you want to remove the attribution, a license can be purchased
https://docs.phpvms.net/#license
--}}
powered by <a href="http://www.phpvms.net" target="_blank">phpvms</a>
</div>
@@ -6,7 +6,14 @@
<div class="col-8">
<div class="row">
<div class="col-12">
<h2>{{ $flight->ident }}</h2>
<h2>
{{ $flight->ident }}
@if ($acars_plugin && $bid)
<a href="vmsacars:bid/{{$bid->id}}" class="btn btn-info btn-sm float-right">Load in vmsACARS</a>
@elseif ($acars_plugin)
<a href="vmsacars:flight/{{$flight->id}}" class="btn btn-info btn-sm float-right">Load in vmsACARS</a>
@endif
</h2>
</div>
</div>
<div class="row">
@@ -7,26 +7,39 @@
<h2>{{ $simbrief->xml->general->icao_airline }}{{ $simbrief->xml->general->flight_number }}
: {{ $simbrief->xml->origin->icao_code }} to {{ $simbrief->xml->destination->icao_code }}</h2>
</div>
<div class="col-sm-2">
<div class="col">
@if (empty($simbrief->pirep_id))
<a class="btn btn-outline-info pull-right btn-lg"
style="margin-top: -10px; margin-bottom: 5px"
href="{{ url(route('frontend.simbrief.prefile', [$simbrief->id])) }}">Prefile PIREP</a>
@endif
</div>
<div class="col-sm-2">
@if (!empty($simbrief->xml->params->static_id) && Auth::id() == $simbrief->user_id)
<a class="btn btn-secondary pull-right btn-lg"
@if (!empty($simbrief->xml->params->static_id) && $user->id === $simbrief->user_id)
<div class="col">
<a class="btn btn-secondary btn-lg"
style="margin-top: -10px; margin-bottom: 5px"
href="#"
data-toggle="modal" data-target="#OFP_Edit">Edit OFP</a>
@endif
</div>
<div class="col-sm-2">
<a class="btn btn-primary pull-right btn-lg"
@endif
<div class="col">
<a class="btn btn-primary btn-lg"
style="margin-top: -10px; margin-bottom: 5px"
href="{{ url(route('frontend.simbrief.generate_new', [$simbrief->id])) }}">Generate New OFP</a>
</div>
<div class="col">
@if ($acars_plugin)
@if ($bid)
<a href="vmsacars:bid/{{$bid->id}}"
style="margin-top: -10px; margin-bottom: 5px"
class="btn btn-info btn-lg">Load in vmsACARS</a>
@else
<a href="vmsacars:flight/{{$flight->id}}"
style="margin-top: -10px; margin-bottom: 5px"
class="btn btn-info btn-lg">Load in vmsACARS</a>
@endif
@endif
</div>
</div>
<div class="row">
@@ -307,7 +320,7 @@
</div>
<div class="modal-footer text-right p-1">
<a
class="btn btn-success btn-sm m-1 p-1"
class="btn btn-success btn-sm m-1 p-1"
href="{{ route('frontend.simbrief.update_ofp') }}?ofp_id={{ $simbrief->id }}&flight_id={{ $simbrief->flight_id }}&aircraft_id={{ $simbrief->aircraft_id }}&sb_userid={{ $simbrief->xml->params->user_id }}&sb_static_id={{ $simbrief->xml->params->static_id }}">
Download Updated OFP & Close
</a>
@@ -22,9 +22,9 @@
"x-saved-class" is the class to add/remove if the bid exists or not
If you change it, remember to change it in the in-array line as well
--}}
@if (!setting('pilots.only_flights_from_current') || $flight->dpt_airport_id == Auth::user()->current_airport->icao)
@if (!setting('pilots.only_flights_from_current') || $flight->dpt_airport_id == $user->current_airport->icao)
<button class="btn btn-round btn-icon btn-icon-mini save_flight
{{ in_array($flight->id, $saved, true) ? 'btn-info':'' }}"
{{ isset($saved[$flight->id]) ? 'btn-info':'' }}"
x-id="{{ $flight->id }}"
x-saved-class="btn-info"
type="button"
@@ -39,16 +39,12 @@
{{--<table class="table-condensed"></table>--}}
<span class="title">{{ strtoupper(__('flights.dep')) }}&nbsp;</span>
{{ optional($flight->dpt_airport)->name ?? $flight->dpt_airport_id }}
(<a href="{{route('frontend.airports.show', [
'id' => $flight->dpt_airport_id
])}}">{{$flight->dpt_airport_id}}</a>)
(<a href="{{route('frontend.airports.show', ['id' => $flight->dpt_airport_id])}}">{{$flight->dpt_airport_id}}</a>)
@if($flight->dpt_time), {{ $flight->dpt_time }}@endif
<br/>
<span class="title">{{ strtoupper(__('flights.arr')) }}&nbsp;</span>
{{ optional($flight->arr_airport)->name ?? $flight->arr_airport_id }}
(<a href="{{route('frontend.airports.show', [
'id' => $flight->arr_airport_id
])}}">{{$flight->arr_airport_id}}</a>)
(<a href="{{route('frontend.airports.show', ['id' => $flight->arr_airport_id])}}">{{$flight->arr_airport_id}}</a>)
@if($flight->arr_time), {{ $flight->arr_time }}@endif
<br/>
@if(filled($flight->callsign))
@@ -76,6 +72,13 @@
</div>
<div class="row">
<div class="col-sm-12 text-right">
@if ($acars_plugin)
@if (isset($saved[$flight->id]))
<a href="vmsacars:bid/{{ $saved[$flight->id] }}" class="btn btn-sm btn-outline-primary">Load in vmsACARS</a>
@else
<a href="vmsacars:flight/{{ $flight->id }}" class="btn btn-sm btn-outline-primary">Load in vmsACARS</a>
@endif
@endif
<!-- Simbrief enabled -->
@if ($simbrief !== false)
<!-- If this flight has a briefing, show the link to view it-->
@@ -86,7 +89,7 @@
</a>
@else
<!-- Show button if the bids-only is disable, or if bids-only is enabled, they've saved it -->
@if ($simbrief_bids === false || ($simbrief_bids === true && in_array($flight->id, $saved, true)))
@if ($simbrief_bids === false || ($simbrief_bids === true && isset($saved[$flight->id])))
<a href="{{ route('frontend.simbrief.generate') }}?flight_id={{ $flight->id }}"
class="btn btn-sm btn-outline-primary">
Create Simbrief Flight Plan
@@ -94,7 +97,6 @@
@endif
@endif
@endif
<a href="{{ route('frontend.pireps.create') }}?flight_id={{ $flight->id }}"
class="btn btn-sm btn-outline-info">
{{ __('pireps.newpirep') }}
@@ -1,5 +1,5 @@
@component('mail::message')
# PIREP Accepted!
# PIREP Rejected!
Your PIREP has been rejected
+10
View File
@@ -185,6 +185,8 @@ class BidTest extends TestCase
{
$this->user = factory(User::class)->create();
$user2 = factory(User::class)->create();
/** @var \App\Models\Flight $flight */
$flight = $this->addFlight($this->user);
$uri = '/api/user/bids';
@@ -194,6 +196,14 @@ class BidTest extends TestCase
$body = $body->json('data');
$this->assertEquals($body['flight_id'], $flight->id);
$this->assertNotEmpty($body['flight']);
$res = $this->get('/api/bids/'.$body['id']);
$res->assertOk();
$body = $res->json('data');
$this->assertEquals($body['flight_id'], $flight->id);
$this->assertNotEmpty($body['flight']);
// Now try to have the second user bid on it
// Should return a 409 error
+7
View File
@@ -149,6 +149,13 @@ class ImporterTest extends TestCase
'Arrival Gate' => 'C61',
],
],
// Blank values omitted
[
'input' => 'gate; ',
'expected' => [
'gate',
],
],
];
foreach ($tests as $test) {