- New map right "share map" added, closed #927
- Upgraded "[_Select2_](https://select2.org/)" js lib `v4.0.6-rc.1` → `v4.0.13` - Fixed some issues where changed map settings (e.g. "share") do not get updated/stored, closed #889, closed #925 - Moved ajax endpoints for map create/update/delete into `/Api/Rest/` dir - Minor UI improvements for "manual dialog" (fixed pixelated text)
This commit is contained in:
@@ -77,11 +77,11 @@ class AccessController extends Controller {
|
||||
|
||||
/**
|
||||
* broadcast MapModel to clients
|
||||
* @see broadcastMapData()
|
||||
* @param Pathfinder\MapModel $map
|
||||
* @param bool $noCache
|
||||
*/
|
||||
protected function broadcastMap(Pathfinder\MapModel $map) : void {
|
||||
$this->broadcastMapData($this->getFormattedMapData($map));
|
||||
protected function broadcastMap(Pathfinder\MapModel $map, bool $noCache = false) : void {
|
||||
$this->broadcastMapData($this->getFormattedMapData($map, $noCache));
|
||||
}
|
||||
|
||||
|
||||
@@ -99,18 +99,13 @@ class AccessController extends Controller {
|
||||
/**
|
||||
* get formatted Map Data
|
||||
* @param Pathfinder\MapModel $map
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param Pathfinder\MapModel $map
|
||||
* @param bool $noCache
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getFormattedMapData(Pathfinder\MapModel $map) : ?array {
|
||||
protected function getFormattedMapData(Pathfinder\MapModel $map, bool $noCache = false) : ?array {
|
||||
$data = null;
|
||||
try{
|
||||
$mapData = $map->getData();
|
||||
$mapData = $map->getData($noCache);
|
||||
$data = [
|
||||
'config' => $mapData->mapData,
|
||||
'data' => [
|
||||
|
||||
@@ -203,7 +203,7 @@ class Admin extends Controller{
|
||||
// character has access to that corporation -> create/update/delete rights...
|
||||
if($corporationRightsData = (array)$settings['rights']){
|
||||
// get existing corp rights
|
||||
foreach($corporation->getRights(['addInactive' => true]) as $corporationRight){
|
||||
foreach($corporation->getRights($corporation::RIGHTS, ['addInactive' => true]) as $corporationRight){
|
||||
$corporationRightData = $corporationRightsData[$corporationRight->rightId->_id];
|
||||
if(
|
||||
$corporationRightData &&
|
||||
|
||||
@@ -260,11 +260,11 @@ class Map extends Controller\AccessController {
|
||||
|
||||
// get SSO error messages that should be shown immediately ----------------------------------------------------
|
||||
// -> e.g. errors while character switch from previous HTTP requests
|
||||
if($f3->exists(Controller\Ccp\Sso::SESSION_KEY_SSO_ERROR, $message)){
|
||||
if($f3->exists(Controller\Ccp\Sso::SESSION_KEY_SSO_ERROR, $text)){
|
||||
$ssoError = (object) [];
|
||||
$ssoError->type = 'error';
|
||||
$ssoError->title = 'Login failed';
|
||||
$ssoError->message = $message;
|
||||
$ssoError->text = $text;
|
||||
$return->error[] = $ssoError;
|
||||
$f3->clear(Controller\Ccp\Sso::SESSION_KEY_SSO_ERROR);
|
||||
}elseif($validInitData){
|
||||
@@ -392,7 +392,7 @@ class Map extends Controller\AccessController {
|
||||
}else{
|
||||
$maxSystemsError = (object) [];
|
||||
$maxSystemsError->type = 'error';
|
||||
$maxSystemsError->message = 'Map has to many systems (' . $systemCount . ').'
|
||||
$maxSystemsError->text = 'Map has to many systems (' . $systemCount . ').'
|
||||
.' Max system count is ' . $defaultConfig['max_systems'] . ' for ' . $mapType->name . ' maps.';
|
||||
$return->error[] = $maxSystemsError;
|
||||
}
|
||||
@@ -400,20 +400,20 @@ class Map extends Controller\AccessController {
|
||||
// systems || connections missing
|
||||
$missingConfigError = (object) [];
|
||||
$missingConfigError->type = 'error';
|
||||
$missingConfigError->message = 'Map data not valid (systems || connections) missing';
|
||||
$missingConfigError->text = 'Map data not valid (systems || connections) missing';
|
||||
$return->error[] = $missingConfigError;
|
||||
}
|
||||
}else{
|
||||
$unknownMapScope= (object) [];
|
||||
$unknownMapScope->type = 'error';
|
||||
$unknownMapScope->message = 'Map scope unknown!';
|
||||
$unknownMapScope->text = 'Map scope unknown!';
|
||||
$return->error[] = $unknownMapScope;
|
||||
}
|
||||
}else{
|
||||
// map config || systems/connections missing
|
||||
$missingConfigError = (object) [];
|
||||
$missingConfigError->type = 'error';
|
||||
$missingConfigError->message = 'Map data not valid (config || data) missing';
|
||||
$missingConfigError->text = 'Map data not valid (config || data) missing';
|
||||
$return->error[] = $missingConfigError;
|
||||
}
|
||||
|
||||
@@ -422,239 +422,20 @@ class Map extends Controller\AccessController {
|
||||
}else{
|
||||
$unknownMapType = (object) [];
|
||||
$unknownMapType->type = 'error';
|
||||
$unknownMapType->message = 'Map type unknown!';
|
||||
$unknownMapType->text = 'Map type unknown!';
|
||||
$return->error[] = $unknownMapType;
|
||||
}
|
||||
}else{
|
||||
// map data missing
|
||||
$missingDataError = (object) [];
|
||||
$missingDataError->type = 'error';
|
||||
$missingDataError->message = 'Map data missing';
|
||||
$missingDataError->text = 'Map data missing';
|
||||
$return->error[] = $missingDataError;
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* save a new map or update an existing map
|
||||
* @param \Base $f3
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save(\Base $f3){
|
||||
$formData = (array)$f3->get('POST.formData');
|
||||
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
if( isset($formData['id']) ){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
/**
|
||||
* @var $map Pathfinder\MapModel
|
||||
*/
|
||||
$map = Pathfinder\AbstractPathfinderModel::getNew('MapModel');
|
||||
$map->getById( (int)$formData['id'] );
|
||||
|
||||
if(
|
||||
$map->dry() ||
|
||||
$map->hasAccess($activeCharacter)
|
||||
){
|
||||
try{
|
||||
// new map
|
||||
$map->setData($formData);
|
||||
$map = $map->save($activeCharacter);
|
||||
|
||||
$mapDefaultConf = Config::getMapsDefaultConfig();
|
||||
|
||||
// save global map access. Depends on map "type"
|
||||
if($map->isPrivate()){
|
||||
|
||||
// share map between characters -> set access
|
||||
if(isset($formData['mapCharacters'])){
|
||||
// remove character (re-add later)
|
||||
$accessCharacters = array_diff($formData['mapCharacters'], [$activeCharacter->_id]);
|
||||
|
||||
// avoid abuse -> respect share limits
|
||||
$maxShared = max($mapDefaultConf['private']['max_shared'] - 1, 0);
|
||||
$accessCharacters = array_slice($accessCharacters, 0, $maxShared);
|
||||
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
if($accessCharacters){
|
||||
/**
|
||||
* @var $tempCharacter Pathfinder\CharacterModel
|
||||
*/
|
||||
$tempCharacter = Pathfinder\AbstractPathfinderModel::getNew('CharacterModel');
|
||||
|
||||
foreach($accessCharacters as $characterId){
|
||||
$tempCharacter->getById( (int)$characterId );
|
||||
|
||||
if(
|
||||
!$tempCharacter->dry() &&
|
||||
$tempCharacter->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempCharacter);
|
||||
}
|
||||
|
||||
$tempCharacter->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the current character itself should always have access
|
||||
// just in case he removed himself :)
|
||||
$map->setAccess($activeCharacter);
|
||||
}elseif($map->isCorporation()){
|
||||
$corporation = $activeCharacter->getCorporation();
|
||||
|
||||
if($corporation){
|
||||
// the current user has to have a corporation when
|
||||
// working on corporation maps!
|
||||
|
||||
// share map between corporations -> set access
|
||||
if(isset($formData['mapCorporations'])){
|
||||
// remove character corporation (re-add later)
|
||||
$accessCorporations = array_diff($formData['mapCorporations'], [$corporation->_id]);
|
||||
|
||||
// avoid abuse -> respect share limits
|
||||
$maxShared = max($mapDefaultConf['corporation']['max_shared'] - 1, 0);
|
||||
$accessCorporations = array_slice($accessCorporations, 0, $maxShared);
|
||||
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
if($accessCorporations){
|
||||
/**
|
||||
* @var $tempCorporation Pathfinder\CorporationModel
|
||||
*/
|
||||
$tempCorporation = Pathfinder\AbstractPathfinderModel::getNew('CorporationModel');
|
||||
|
||||
foreach($accessCorporations as $corporationId){
|
||||
$tempCorporation->getById( (int)$corporationId );
|
||||
|
||||
if(
|
||||
!$tempCorporation->dry() &&
|
||||
$tempCorporation->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempCorporation);
|
||||
}
|
||||
|
||||
$tempCorporation->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the corporation of the current user should always have access
|
||||
$map->setAccess($corporation);
|
||||
}
|
||||
}elseif($map->isAlliance()){
|
||||
$alliance = $activeCharacter->getAlliance();
|
||||
|
||||
if($alliance){
|
||||
// the current user has to have a alliance when
|
||||
// working on alliance maps!
|
||||
|
||||
// share map between alliances -> set access
|
||||
if(isset($formData['mapAlliances'])){
|
||||
// remove character alliance (re-add later)
|
||||
$accessAlliances = array_diff($formData['mapAlliances'], [$alliance->_id]);
|
||||
|
||||
// avoid abuse -> respect share limits
|
||||
$maxShared = max($mapDefaultConf['alliance']['max_shared'] - 1, 0);
|
||||
$accessAlliances = array_slice($accessAlliances, 0, $maxShared);
|
||||
|
||||
// clear map access. In case something has removed from access list
|
||||
$map->clearAccess();
|
||||
|
||||
if($accessAlliances){
|
||||
/**
|
||||
* @var $tempAlliance Pathfinder\AllianceModel
|
||||
*/
|
||||
$tempAlliance = Pathfinder\AbstractPathfinderModel::getNew('AllianceModel');
|
||||
|
||||
foreach($accessAlliances as $allianceId){
|
||||
$tempAlliance->getById( (int)$allianceId );
|
||||
|
||||
if(
|
||||
!$tempAlliance->dry() &&
|
||||
$tempAlliance->shared == 1 // check if map shared is enabled
|
||||
){
|
||||
$map->setAccess($tempAlliance);
|
||||
}
|
||||
|
||||
$tempAlliance->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the alliance of the current user should always have access
|
||||
$map->setAccess($alliance);
|
||||
}
|
||||
}
|
||||
// reload the same map model (refresh)
|
||||
// this makes sure all data is up2date
|
||||
$map->getById($map->_id, 0);
|
||||
|
||||
// broadcast map Access -> and send map Data
|
||||
$this->broadcastMapAccess($map);
|
||||
|
||||
$return->mapData = $map->getData();
|
||||
}catch(Exception\ValidationException $e){
|
||||
$return->error[] = $e->getError();
|
||||
}
|
||||
}else{
|
||||
// map access denied
|
||||
$captchaError = (object) [];
|
||||
$captchaError->type = 'error';
|
||||
$captchaError->message = 'Access denied';
|
||||
$return->error[] = $captchaError;
|
||||
}
|
||||
}else{
|
||||
// map id field missing
|
||||
$idError = (object) [];
|
||||
$idError->type = 'error';
|
||||
$idError->message = 'Map id missing';
|
||||
$return->error[] = $idError;
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a map and all dependencies
|
||||
* @param \Base $f3
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(\Base $f3){
|
||||
$mapData = (array)$f3->get('POST.mapData');
|
||||
$mapId = (int)$mapData['id'];
|
||||
$return = (object) [];
|
||||
$return->deletedMapIds = [];
|
||||
|
||||
if($mapId){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
/**
|
||||
* @var $map Pathfinder\MapModel
|
||||
*/
|
||||
$map = Pathfinder\AbstractPathfinderModel::getNew('MapModel');
|
||||
$map->getById($mapId);
|
||||
|
||||
if($map->hasAccess($activeCharacter)){
|
||||
$map->setActive(false);
|
||||
$map->save($activeCharacter);
|
||||
$return->deletedMapIds[] = $mapId;
|
||||
|
||||
// broadcast map delete
|
||||
$this->broadcastMapDeleted($mapId);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* broadcast characters with map access rights to WebSocket server
|
||||
* -> if characters with map access found -> broadcast mapData to them
|
||||
@@ -665,7 +446,7 @@ class Map extends Controller\AccessController {
|
||||
$mapAccess = [
|
||||
'id' => $map->_id,
|
||||
'name' => $map->name,
|
||||
'characterIds' => array_map(function ($data){
|
||||
'characterIds' => array_map(function($data){
|
||||
return $data->id;
|
||||
}, $map->getCharactersData())
|
||||
];
|
||||
@@ -673,15 +454,7 @@ class Map extends Controller\AccessController {
|
||||
$this->getF3()->webSocket()->write('mapAccess', $mapAccess);
|
||||
|
||||
// map has (probably) active connections that should receive map Data
|
||||
$this->broadcastMap($map);
|
||||
}
|
||||
|
||||
/**
|
||||
* broadcast map delete information to clients
|
||||
* @param int $mapId
|
||||
*/
|
||||
protected function broadcastMapDeleted(int $mapId){
|
||||
$this->getF3()->webSocket()->write('mapDeleted', $mapId);
|
||||
$this->broadcastMap($map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
239
app/Controller/Api/Rest/Map.php
Normal file
239
app/Controller/Api/Rest/Map.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Exodus 4D
|
||||
* Date: 12.03.2020
|
||||
* Time: 19:30
|
||||
*/
|
||||
|
||||
namespace Exodus4D\Pathfinder\Controller\Api\Rest;
|
||||
|
||||
|
||||
use Exodus4D\Pathfinder\Lib\Config;
|
||||
use Exodus4D\Pathfinder\Model\Pathfinder;
|
||||
|
||||
class Map extends AbstractRestController {
|
||||
|
||||
/**
|
||||
* error message missing character right for map delete
|
||||
*/
|
||||
const ERROR_MAP_DELETE = 'Character %s does not have sufficient rights for map delete';
|
||||
|
||||
/**
|
||||
* @param \Base $f3
|
||||
* @param $test
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function put(\Base $f3, $test){
|
||||
$requestData = $this->getRequestData($f3);
|
||||
|
||||
/**
|
||||
* @var $map Pathfinder\MapModel
|
||||
*/
|
||||
$map = Pathfinder\AbstractPathfinderModel::getNew('MapModel');
|
||||
$mapData = $this->update($map, $requestData)->getData();
|
||||
|
||||
$this->out($mapData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Base $f3
|
||||
* @param $params
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function patch(\Base $f3, $params){
|
||||
$requestData = $this->getRequestData($f3);
|
||||
$mapData = [];
|
||||
|
||||
if($mapId = (int)$params['id']){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
/**
|
||||
* @var $map Pathfinder\MapModel
|
||||
*/
|
||||
$map = Pathfinder\AbstractPathfinderModel::getNew('MapModel');
|
||||
$map->getById($mapId);
|
||||
if($map->hasAccess($activeCharacter)){
|
||||
$mapData = $this->update($map, $requestData)->getData(true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->out($mapData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Base $f3
|
||||
* @param $params
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(\Base $f3, $params){
|
||||
$deletedMapIds = [];
|
||||
|
||||
if($mapId = (int)$params['id']){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
/**
|
||||
* @var $map Pathfinder\MapModel
|
||||
*/
|
||||
$map = Pathfinder\AbstractPathfinderModel::getNew('MapModel');
|
||||
$map->getById($mapId);
|
||||
|
||||
if($map->hasAccess($activeCharacter)){
|
||||
// check if character has delete right for map type
|
||||
$hasRight = true;
|
||||
if($map->isCorporation()){
|
||||
if($corpRight = $activeCharacter->getCorporation()->getRights(['map_delete'])){
|
||||
if($corpRight[0]->get('roleId', true) !== $activeCharacter->get('roleId', true)){
|
||||
$hasRight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($hasRight){
|
||||
$map->setActive(false);
|
||||
$map->save($activeCharacter);
|
||||
$deletedMapIds[] = $mapId;
|
||||
// broadcast map delete
|
||||
$this->broadcastMapDeleted($mapId);
|
||||
}else{
|
||||
$f3->set('HALT', true);
|
||||
$f3->error(401, sprintf(self::ERROR_MAP_DELETE, $activeCharacter->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->out($deletedMapIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Pathfinder\MapModel $map
|
||||
* @param array $mapData
|
||||
* @return Pathfinder\MapModel
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function update(Pathfinder\MapModel $map, array $mapData) : Pathfinder\MapModel {
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$map->setData($mapData);
|
||||
$typeChange = $map->changed('typeId');
|
||||
$map->save($activeCharacter);
|
||||
|
||||
// save global map access. Depends on map "type" --------------------------------------------------------------
|
||||
/**
|
||||
* @param Pathfinder\AbstractPathfinderModel $primaryModel
|
||||
* @param array|null $modelIds
|
||||
* @param int $maxShared
|
||||
* @return int
|
||||
*/
|
||||
$setMapAccess = function(Pathfinder\AbstractPathfinderModel &$primaryModel, ?array $modelIds = [], int $maxShared = 3) use (&$map) : int {
|
||||
$added = 0;
|
||||
$deleted = 0;
|
||||
if(is_array($modelIds)){
|
||||
// remove primaryModel id (-> re-add later)
|
||||
$modelIds = array_diff(array_map('intval', $modelIds), [$primaryModel->_id]);
|
||||
|
||||
// avoid abuse -> respect share limits (-1 is because the primaryModel has also access)
|
||||
$modelIds = array_slice($modelIds, 0, max($maxShared - 1, 0));
|
||||
|
||||
// add the primaryModel id back (again)
|
||||
$modelIds[] = $primaryModel->_id;
|
||||
|
||||
// clear map access for entities that do not match the map "mapType"
|
||||
$deleted += $map->clearAccessByType();
|
||||
|
||||
$compare = $map->compareAccess($modelIds);
|
||||
|
||||
foreach((array)$compare['old'] as $modelId) {
|
||||
$deleted += $map->removeFromAccess($modelId);
|
||||
}
|
||||
|
||||
$modelClass = (new \ReflectionClass($primaryModel))->getShortName();
|
||||
$tempModel = Pathfinder\AbstractPathfinderModel::getNew($modelClass);
|
||||
foreach((array)$compare['new'] as $modelId) {
|
||||
$tempModel->getById($modelId);
|
||||
if(
|
||||
$tempModel->valid() &&
|
||||
(
|
||||
$modelId == $primaryModel->_id || // primary model has always access (regardless of "shared" value)
|
||||
$tempModel->shared == 1 // check if map shared is enabled
|
||||
)
|
||||
){
|
||||
$added += (int)$map->setAccess($tempModel);
|
||||
}
|
||||
|
||||
$tempModel->reset();
|
||||
}
|
||||
}
|
||||
return $added + $deleted;
|
||||
};
|
||||
|
||||
$accessChangeCount = 0;
|
||||
$mapDefaultConf = Config::getMapsDefaultConfig();
|
||||
if($map->isPrivate()){
|
||||
$accessChangeCount = $setMapAccess(
|
||||
$activeCharacter,
|
||||
$typeChange ? [$activeCharacter->_id] : $mapData['mapCharacters'],
|
||||
(int)$mapDefaultConf['private']['max_shared']
|
||||
);
|
||||
}elseif($map->isCorporation()){
|
||||
if($corporation = $activeCharacter->getCorporation()){
|
||||
$accessChangeCount = $setMapAccess(
|
||||
$corporation,
|
||||
$typeChange ? [$corporation->_id] : $mapData['mapCorporations'],
|
||||
(int)$mapDefaultConf['corporation']['max_shared']
|
||||
);
|
||||
}
|
||||
}elseif($map->isAlliance()){
|
||||
if($alliance = $activeCharacter->getAlliance()){
|
||||
$accessChangeCount = $setMapAccess(
|
||||
$alliance,
|
||||
$typeChange ? [$alliance->_id] : $mapData['mapAlliances'],
|
||||
(int)$mapDefaultConf['alliance']['max_shared']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if($accessChangeCount){
|
||||
$map->touch('updated');
|
||||
$map->save($activeCharacter);
|
||||
}
|
||||
|
||||
// reload the same map model (refresh)
|
||||
// this makes sure all data is up2date
|
||||
$map->getById($map->_id, 0);
|
||||
|
||||
// broadcast map Access -> and send map Data
|
||||
$this->broadcastMapAccess($map);
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* broadcast characters with map access rights to WebSocket server
|
||||
* -> if characters with map access found -> broadcast mapData to them
|
||||
* @param Pathfinder\MapModel $map
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function broadcastMapAccess(Pathfinder\MapModel $map){
|
||||
$mapAccess = [
|
||||
'id' => $map->_id,
|
||||
'name' => $map->name,
|
||||
'characterIds' => array_map(function($data){
|
||||
return $data->id;
|
||||
}, $map->getCharactersData())
|
||||
];
|
||||
|
||||
$this->getF3()->webSocket()->write('mapAccess', $mapAccess);
|
||||
|
||||
// map has (probably) active connections that should receive map Data
|
||||
$this->broadcastMap($map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* broadcast map delete information to clients
|
||||
* @param int $mapId
|
||||
*/
|
||||
private function broadcastMapDeleted(int $mapId){
|
||||
$this->getF3()->webSocket()->write('mapDeleted', $mapId);
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class System extends Controller\AccessController {
|
||||
}else{
|
||||
$error = (object) [];
|
||||
$error->type = 'error';
|
||||
$error->message = $response['error'];
|
||||
$error->text = $response['error'];
|
||||
$return->error[] = $error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ class User extends Controller\Controller{
|
||||
}else{
|
||||
$characterError = (object) [];
|
||||
$characterError->type = 'warning';
|
||||
$characterError->message = 'This can happen through "invalid cookies(SSO)", "login restrictions", "ESI problems".';
|
||||
$characterError->text = 'This can happen through "invalid cookies(SSO)", "login restrictions", "ESI problems".';
|
||||
$return->error[] = $characterError;
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ class User extends Controller\Controller{
|
||||
}else{
|
||||
$captchaError = (object) [];
|
||||
$captchaError->type = 'error';
|
||||
$captchaError->message = 'Could not create captcha image';
|
||||
$captchaError->text = 'Could not create captcha image';
|
||||
$return->error[] = $captchaError;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ class User extends Controller\Controller{
|
||||
}else{
|
||||
$error = (object) [];
|
||||
$error->type = 'error';
|
||||
$error->message = $response['error'];
|
||||
$error->text = $response['error'];
|
||||
$return->error[] = $error;
|
||||
}
|
||||
}
|
||||
@@ -289,7 +289,7 @@ class User extends Controller\Controller{
|
||||
// captcha was send but not valid -> return error
|
||||
$captchaError = (object)[];
|
||||
$captchaError->type = 'error';
|
||||
$captchaError->message = 'Captcha does not match';
|
||||
$captchaError->text = 'Captcha does not match';
|
||||
$return->error[] = $captchaError;
|
||||
}
|
||||
}
|
||||
@@ -377,7 +377,7 @@ class User extends Controller\Controller{
|
||||
// captcha not valid -> return error
|
||||
$captchaError = (object) [];
|
||||
$captchaError->type = 'error';
|
||||
$captchaError->message = 'Captcha does not match';
|
||||
$captchaError->text = 'Captcha does not match';
|
||||
$return->error[] = $captchaError;
|
||||
}
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ class Controller {
|
||||
* @param bool $deleteSession
|
||||
* @param bool $deleteLog
|
||||
* @param bool $deleteCookie
|
||||
* @param int $status
|
||||
* @param int $statusCode
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function logoutCharacter(
|
||||
@@ -496,7 +496,7 @@ class Controller {
|
||||
bool $deleteSession = true,
|
||||
bool $deleteLog = true,
|
||||
bool $deleteCookie = false,
|
||||
int $status = self::DEFAULT_STATUS_LOGOUT
|
||||
int $statusCode = self::DEFAULT_STATUS_LOGOUT
|
||||
){
|
||||
$sessionCharacterData = (array)$f3->get(Api\User::SESSION_KEY_CHARACTERS);
|
||||
|
||||
@@ -526,11 +526,11 @@ class Controller {
|
||||
}
|
||||
|
||||
if($f3->get('AJAX')){
|
||||
$f3->status($status);
|
||||
$f3->status($statusCode);
|
||||
|
||||
$return = (object) [];
|
||||
$return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $f3->alias('login');
|
||||
$return->error[] = $this->getErrorObject($status, Config::getMessageFromHTTPStatus($status));
|
||||
$return->error[] = $this->getErrorObject($statusCode, Config::getHttpStatusByCode($statusCode), 'Access denied: User not found');
|
||||
|
||||
echo json_encode($return);
|
||||
}else{
|
||||
@@ -639,18 +639,18 @@ class Controller {
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
* @param string $message
|
||||
* @param string $status
|
||||
* @param string $text
|
||||
* @param null $trace
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function getErrorObject(int $code, string $message = '', string $status = '', $trace = null): \stdClass{
|
||||
protected function getErrorObject(int $code, string $status = '', string $text = '', $trace = null) : \stdClass {
|
||||
$object = (object) [];
|
||||
$object->type = 'error';
|
||||
$object->code = $code;
|
||||
$object->status = empty($status) ? @constant('Base::HTTP_' . $code) : $status;
|
||||
if(!empty($message)){
|
||||
$object->message = $message;
|
||||
if(!empty($text)){
|
||||
$object->text = $text;
|
||||
}
|
||||
if(!empty($trace)){
|
||||
$object->trace = $trace;
|
||||
@@ -660,15 +660,15 @@ class Controller {
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
* @param string $message
|
||||
* @param string $text
|
||||
* @param string $type
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function getNotificationObject(string $title, $message = '', $type = 'danger') : \stdClass {
|
||||
protected function getNotificationObject(string $title, $text = '', $type = 'danger') : \stdClass {
|
||||
$notification = (object) [];
|
||||
$notification->type = in_array($type, self::NOTIFICATION_TYPES) ? $type : 'danger';
|
||||
$notification->title = $title;
|
||||
$notification->message = $message;
|
||||
$notification->text = $text;
|
||||
return $notification;
|
||||
}
|
||||
|
||||
@@ -762,7 +762,7 @@ class Controller {
|
||||
|
||||
if(count($matches) === 2){
|
||||
$error->field = $matches[1][1];
|
||||
$error->message = 'Value "' . $matches[0][1] . '" already exists';
|
||||
$error->text = 'Value "' . $matches[0][1] . '" already exists';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1570,7 +1570,7 @@ class Setup extends Controller {
|
||||
|
||||
// setup tables
|
||||
foreach($this->databases[$dbAlias]['models'] as $modelClass){
|
||||
$checkTables[] = call_user_func($modelClass . '::setup', $db);
|
||||
$checkTables[] = call_user_func(Config::withNamespace($modelClass) . '::setup', $db);
|
||||
}
|
||||
}
|
||||
return $checkTables;
|
||||
|
||||
@@ -49,7 +49,7 @@ class PathfinderException extends \Exception {
|
||||
$error->type = 'error';
|
||||
$error->code = $this->getResponseCode();
|
||||
$error->status = Config::getHttpStatusByCode($this->getResponseCode());
|
||||
$error->message = $this->getMessage();
|
||||
$error->text = $this->getMessage();
|
||||
if(\Base::instance()->get('DEBUG') >= 1){
|
||||
$error->trace = preg_split('/\R/', $this->getTraceAsString()); // no $this->>getTrace() here -> to much data
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class Config extends \Prefab {
|
||||
* custom HTTP status codes
|
||||
*/
|
||||
const
|
||||
HTTP_422='Unprocessable Entity';
|
||||
HTTP_422 = 'Unprocessable Entity';
|
||||
|
||||
/**
|
||||
* all environment data
|
||||
@@ -463,22 +463,6 @@ class Config extends \Prefab {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get custom $message for a a HTTP $status
|
||||
* -> use this in addition to the very general Base::HTTP_XXX labels
|
||||
* @param int $status
|
||||
* @return string
|
||||
*/
|
||||
static function getMessageFromHTTPStatus(int $status) : string {
|
||||
switch($status){
|
||||
case 403:
|
||||
$message = 'Access denied: User not found'; break;
|
||||
default:
|
||||
$message = '';
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* use this function to "validate" the socket connection.
|
||||
* The result will be CACHED for a few seconds!
|
||||
@@ -569,7 +553,7 @@ class Config extends \Prefab {
|
||||
}
|
||||
|
||||
/**
|
||||
* get HTTP status message by HTTP return code
|
||||
* get HTTP status by HTTP return code
|
||||
* -> either from F3 or from self::Config constants
|
||||
* @param int $code
|
||||
* @return string
|
||||
|
||||
@@ -54,21 +54,6 @@ abstract class AbstractPathfinderModel extends AbstractModel {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* set "updated" field to current timestamp
|
||||
* this is useful to mark a row as "changed"
|
||||
*/
|
||||
protected function setUpdated(){
|
||||
if($this->_id > 0){
|
||||
$this->db->exec(
|
||||
["UPDATE " . $this->table . " SET updated=NOW() WHERE id=:id"],
|
||||
[
|
||||
[':id' => $this->_id]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get old and new value from field, in case field is configured with 'activity-log'
|
||||
* @return array
|
||||
|
||||
@@ -91,7 +91,8 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
'map_update',
|
||||
'map_delete',
|
||||
'map_import',
|
||||
'map_export'
|
||||
'map_export',
|
||||
'map_share'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -303,15 +304,16 @@ class CorporationModel extends AbstractPathfinderModel {
|
||||
|
||||
/**
|
||||
* get all corporation rights
|
||||
* @param array $names
|
||||
* @param array $options
|
||||
* @return CorporationRightModel[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getRights($options = []) : array {
|
||||
public function getRights($names = self::RIGHTS, $options = []) : array {
|
||||
$corporationRights = [];
|
||||
// get available rights
|
||||
$right = self::getNew('RightModel');
|
||||
if($rights = $right->find(['active = ? AND name IN (?)', 1, self::RIGHTS])){
|
||||
if($rights = $right->find(['active = ? AND name IN (?)', 1, $names])){
|
||||
// get already stored rights
|
||||
if( !$options['addInactive'] ){
|
||||
$this->filter('corporationRights', ['active = ?', 1]);
|
||||
|
||||
@@ -217,14 +217,13 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
/**
|
||||
* get data
|
||||
* -> this includes system and connection data as well
|
||||
* @return \stdClass
|
||||
* @throws \Exception
|
||||
* @param bool $noCache
|
||||
* @return mixed|object|null
|
||||
* @throws Exception\ConfigException
|
||||
*/
|
||||
public function getData(){
|
||||
public function getData(bool $noCache = false){
|
||||
// check if there is cached data
|
||||
$mapDataAll = $this->getCacheData();
|
||||
|
||||
if(is_null($mapDataAll)){
|
||||
if($noCache || is_null($mapDataAll = $this->getCacheData())){
|
||||
// no cached map data found
|
||||
|
||||
$mapData = (object) [];
|
||||
@@ -702,99 +701,134 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
/**
|
||||
* set map access for an object (character, corporation or alliance)
|
||||
* @param $obj
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setAccess($obj){
|
||||
|
||||
public function setAccess($obj) : bool {
|
||||
$newAccessGranted = false;
|
||||
|
||||
if($obj instanceof CharacterModel){
|
||||
// private map
|
||||
|
||||
// check whether the user has already map access
|
||||
$this->has('mapCharacters', ['active = 1 AND characterId = :characterId', ':characterId' => $obj->id]);
|
||||
$result = $this->findone(['id = :id', ':id' => $this->id]);
|
||||
|
||||
if($result === false){
|
||||
$result = $this->relFindOne('mapCharacters', self::getFilter('characterId', $obj->_id));
|
||||
if(!$result){
|
||||
// grant access for the character
|
||||
$characterMap = self::getNew('CharacterMapModel');
|
||||
$characterMap->characterId = $obj;
|
||||
$characterMap->mapId = $this;
|
||||
$characterMap->save();
|
||||
|
||||
$newAccessGranted = true;
|
||||
if($characterMap->save()){
|
||||
$newAccessGranted = true;
|
||||
}
|
||||
}
|
||||
}elseif($obj instanceof CorporationModel){
|
||||
|
||||
// check whether the corporation already has map access
|
||||
$this->has('mapCorporations', ['active = 1 AND corporationId = :corporationId', ':corporationId' => $obj->id]);
|
||||
$result = $this->findone(['id = :id', ':id' => $this->id]);
|
||||
|
||||
if($result === false){
|
||||
$result = $this->relFindOne('mapCorporations', self::getFilter('corporationId', $obj->_id));
|
||||
if(!$result){
|
||||
// grant access for this corporation
|
||||
$corporationMap = self::getNew('CorporationMapModel');
|
||||
$corporationMap->corporationId = $obj;
|
||||
$corporationMap->mapId = $this;
|
||||
$corporationMap->save();
|
||||
|
||||
$newAccessGranted = true;
|
||||
if($corporationMap->save()){
|
||||
$newAccessGranted = true;
|
||||
}
|
||||
}
|
||||
}elseif($obj instanceof AllianceModel){
|
||||
|
||||
// check whether the alliance already has map access
|
||||
$this->has('mapAlliances', ['active = 1 AND allianceId = :allianceId', ':allianceId' => $obj->id]);
|
||||
$result = $this->findone(['id = :id', ':id' => $this->id]);
|
||||
|
||||
if($result === false){
|
||||
$result = $this->relFindOne('mapAlliances', self::getFilter('allianceId', $obj->_id));
|
||||
if(!$result){
|
||||
$allianceMap = self::getNew('AllianceMapModel');
|
||||
$allianceMap->allianceId = $obj;
|
||||
$allianceMap->mapId = $this;
|
||||
$allianceMap->save();
|
||||
|
||||
$newAccessGranted = true;
|
||||
if($allianceMap->save()){
|
||||
$newAccessGranted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $newAccessGranted;
|
||||
}
|
||||
|
||||
if($newAccessGranted){
|
||||
// mark this map as updated
|
||||
$this->setUpdated();
|
||||
/**
|
||||
* @param $stack
|
||||
* @return array
|
||||
*/
|
||||
public function compareAccess($stack) : array {
|
||||
$result = [];
|
||||
if($this->valid()){
|
||||
if($this->isPrivate()){
|
||||
$result = $this->mapCharacters ? $this->mapCharacters->compare($stack, 'characterId') : ['new' => $stack];
|
||||
}elseif($this->isCorporation()){
|
||||
$result = $this->mapCorporations ? $this->mapCorporations->compare($stack, 'corporationId') : ['new' => $stack];
|
||||
}elseif($this->isAlliance()){
|
||||
$result = $this->mapAlliances ? $this->mapAlliances->compare($stack, 'allianceId') : ['new' => $stack];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return int
|
||||
*/
|
||||
public function removeFromAccess(int $id) : int {
|
||||
$count = 0;
|
||||
if($id && $this->valid()){
|
||||
$result = null;
|
||||
if($this->isPrivate()){
|
||||
$result = $this->relFindOne('mapCharacters', self::getFilter('characterId', $id));
|
||||
}elseif($this->isCorporation()){
|
||||
$result = $this->relFindOne('mapCorporations', self::getFilter('corporationId', $id));
|
||||
}elseif($this->isAlliance()){
|
||||
$result = $this->relFindOne('mapAlliances', self::getFilter('allianceId', $id));
|
||||
}
|
||||
|
||||
if($result && $result->erase()){
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear map access for entities that do not match the map "mapType"
|
||||
* @return int
|
||||
*/
|
||||
public function clearAccessByType() : int {
|
||||
$count = 0;
|
||||
if($this->valid()){
|
||||
if($this->isPrivate()){
|
||||
$count = $this->clearAccess(['corporation', 'alliance']);
|
||||
}elseif($this->isCorporation()){
|
||||
$count = $this->clearAccess(['character', 'alliance']);
|
||||
}elseif($this->isAlliance()){
|
||||
$count = $this->clearAccess(['character', 'corporation']);
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear access for a given type of objects
|
||||
* @param array $clearKeys
|
||||
* @return int
|
||||
*/
|
||||
public function clearAccess($clearKeys = ['character', 'corporation', 'alliance']){
|
||||
public function clearAccess($clearKeys = ['character', 'corporation', 'alliance']) : int {
|
||||
$count = 0;
|
||||
foreach($clearKeys as $key){
|
||||
$field = null;
|
||||
switch($key){
|
||||
case 'character':
|
||||
foreach((array)$this->mapCharacters as $characterMapModel){
|
||||
/**
|
||||
* @var CharacterMapModel $characterMapModel
|
||||
*/
|
||||
$characterMapModel->erase();
|
||||
case 'character': $field = 'mapCharacters'; break;
|
||||
case 'corporation': $field = 'mapCorporations'; break;
|
||||
case 'alliance': $field = 'mapAlliances'; break;
|
||||
}
|
||||
|
||||
if($this->$field){
|
||||
foreach((array)$this->$field as $model){
|
||||
if($model->erase()){
|
||||
$count++;
|
||||
}
|
||||
break;
|
||||
case 'corporation':
|
||||
foreach((array)$this->mapCorporations as $corporationMapModel){
|
||||
/**
|
||||
* @var CorporationMapModel $corporationMapModel
|
||||
*/
|
||||
$corporationMapModel->erase();
|
||||
}
|
||||
break;
|
||||
case 'alliance':
|
||||
foreach((array)$this->mapAlliances as $allianceMapModel){
|
||||
/**
|
||||
* @var AllianceMapModel $allianceMapModel
|
||||
*/
|
||||
$allianceMapModel->erase();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1429,17 +1463,6 @@ class MapModel extends AbstractMapTrackingModel {
|
||||
*/
|
||||
$mapModel = parent::save($characterModel);
|
||||
|
||||
// check if map type has changed and clear access objects
|
||||
if( !$mapModel->dry() ){
|
||||
if( $mapModel->isPrivate() ){
|
||||
$mapModel->clearAccess(['corporation', 'alliance']);
|
||||
}elseif( $mapModel->isCorporation() ){
|
||||
$mapModel->clearAccess(['character', 'alliance']);
|
||||
}elseif( $mapModel->isAlliance() ){
|
||||
$mapModel->clearAccess(['character', 'corporation']);
|
||||
}
|
||||
}
|
||||
|
||||
return $mapModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ class RightModel extends AbstractPathfinderModel {
|
||||
'name' => 'map_export',
|
||||
'label' => 'export',
|
||||
'description' => 'Map export right'
|
||||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'name' => 'map_share',
|
||||
'label' => 'share',
|
||||
'description' => 'Map share right'
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ requirejs.config({
|
||||
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart
|
||||
peityInlineChart: 'lib/jquery.peity.min', // v3.3.0 Inline Chart - http://benpickles.github.io/peity/
|
||||
hoverIntent: 'lib/jquery.hoverIntent.min', // v1.10.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
|
||||
select2: 'lib/select2.min', // v4.0.3 Drop Down customization - https://select2.github.io
|
||||
select2: 'lib/select2.min', // v4.0.13 Drop Down customization - https://select2.github.io
|
||||
validator: 'lib/validator.min', // v0.10.1 Validator for Bootstrap 3 - https://github.com/1000hz/bootstrap-validator
|
||||
lazylinepainter: 'lib/jquery.lazylinepainter-1.5.1.min', // v1.5.1 SVG line animation plugin - http://lazylinepainter.info
|
||||
blueImpGallery: 'lib/blueimp-gallery', // v2.21.3 Image Gallery - https://github.com/blueimp/Gallery
|
||||
|
||||
@@ -38,8 +38,6 @@ define([], () => {
|
||||
updateUserData: '/api/map/updateUserData', // ajax URL - main map user data trigger
|
||||
updateUnloadData: '/api/map/updateUnloadData', // post URL - for my sync onUnload
|
||||
// map API
|
||||
saveMap: '/api/map/save', // ajax URL - save/update map
|
||||
deleteMap: '/api/map/delete', // ajax URL - delete map
|
||||
importMap: '/api/map/import', // ajax URL - import map
|
||||
getMapConnectionData: '/api/map/getConnectionData', // ajax URL - get connection data
|
||||
getMapLogData: '/api/map/getLogData', // ajax URL - get logs data
|
||||
@@ -138,6 +136,18 @@ define([], () => {
|
||||
class: 'fa-hat-wizard',
|
||||
label: 'hat wizard',
|
||||
unicode: ''
|
||||
},{
|
||||
class: 'fa-cross',
|
||||
label: 'cross',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-cannabis',
|
||||
label: 'cannabis',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-spider',
|
||||
label: 'spider',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-plane',
|
||||
label: 'plane',
|
||||
|
||||
@@ -194,7 +194,7 @@ define([
|
||||
currentUserIsHere &&
|
||||
!userWasHere &&
|
||||
Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')) &&
|
||||
Boolean(Util.getObjVal(Util.getCurrentUserData(), 'character.selectLocation'))
|
||||
Boolean(Util.getCurrentCharacterData('selectLocation'))
|
||||
){
|
||||
Util.triggerMenuAction(map.getContainer(), 'SelectSystem', {systemId: system.data('id'), forceSelect: false});
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ define([
|
||||
let mapElement = $(this);
|
||||
let mapOverlay = MapOverlayUtil.getMapOverlay(mapElement, 'local');
|
||||
let currentMapData = Util.getCurrentMapData(mapId);
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
let currentCharacterLog = Util.getCurrentCharacterData('log');
|
||||
let clearLocal = true;
|
||||
|
||||
if(
|
||||
@@ -2891,7 +2891,7 @@ define([
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogSystemId = Util.getObjVal(Util.getCurrentCharacterLog(), 'system.id') || 0;
|
||||
let characterLogSystemId = Util.getObjVal(Util.getCurrentCharacterData('log'), 'system.id') || 0;
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
|
||||
@@ -186,7 +186,7 @@ define([
|
||||
systemData = options.systemData;
|
||||
}else{
|
||||
// ... check for current active system (characterLog) -----------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
let currentCharacterLog = Util.getCurrentCharacterData('log');
|
||||
if(currentCharacterLog !== false){
|
||||
// set system from 'characterLog' data as pre-selected system
|
||||
systemData = Util.getObjVal(currentCharacterLog, 'system');
|
||||
|
||||
@@ -2005,60 +2005,26 @@ define([
|
||||
*/
|
||||
let checkRight = (right, mapConfig) => {
|
||||
let hasAccess = false;
|
||||
let currentUserData = Util.getCurrentUserData();
|
||||
if(currentUserData){
|
||||
// ...there is an active user
|
||||
let currentCharacterData = Util.getObjVal(currentUserData, 'character');
|
||||
if(currentCharacterData){
|
||||
// ... there is an active character
|
||||
let currentCharacterRole = Util.getObjVal(currentCharacterData, 'role');
|
||||
if(currentCharacterRole){
|
||||
// ... active character has a role assigned
|
||||
let mapType = Util.getObjVal(mapConfig, 'type.name');
|
||||
let accessObjectId = Util.getCurrentUserInfo(mapType + 'Id');
|
||||
|
||||
let mapType = Util.getObjVal(mapConfig, 'type.name');
|
||||
let mapAccess = Util.getObjVal(mapConfig, 'access.' + (mapType === 'private' ? 'character' : mapType)) || [];
|
||||
|
||||
// this is either Ally/Corp or Character Id
|
||||
let accessObjectId = Util.getCurrentUserInfo(mapType + 'Id');
|
||||
|
||||
// check whether character has map access
|
||||
let hasMapAccess = mapAccess.some((accessObj) => {
|
||||
return (accessObj.id === accessObjectId);
|
||||
});
|
||||
|
||||
if(hasMapAccess){
|
||||
// ... this should ALWAYS be be true!
|
||||
switch(mapType){
|
||||
case 'private':
|
||||
hasAccess = true;
|
||||
break;
|
||||
case 'corporation':
|
||||
let objectRights = Util.getObjVal(currentCharacterData, mapType + '.rights') || [];
|
||||
|
||||
let objectRight = objectRights.find((objectRight) => {
|
||||
return objectRight.right.name === right;
|
||||
});
|
||||
|
||||
if(objectRight){
|
||||
// ... Ally/Corp has the right we are looking for assigned with a required role
|
||||
if(
|
||||
currentCharacterRole.name === 'SUPER' ||
|
||||
objectRight.role.name === 'MEMBER' ||
|
||||
objectRight.role.name === currentCharacterRole.name
|
||||
){
|
||||
hasAccess = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'alliance':
|
||||
hasAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check whether character has map access
|
||||
let mapAccess = Util.getObjVal(mapConfig, 'access.' + (mapType === 'private' ? 'character' : mapType)) || [];
|
||||
let hasMapAccess = mapAccess.some(accessObj => accessObj.id === accessObjectId);
|
||||
if(hasMapAccess){
|
||||
// ... this should ALWAYS be be true!
|
||||
switch(mapType){
|
||||
case 'private':
|
||||
hasAccess = true;
|
||||
break;
|
||||
case 'corporation':
|
||||
hasAccess = Util.hasRight(right, mapType);
|
||||
break;
|
||||
case 'alliance':
|
||||
hasAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasAccess;
|
||||
};
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@ define([
|
||||
mapIds: mapId ? [mapId] : [],
|
||||
getMapUserData: Util.getSyncType() === 'webSocket' ? 0 : 1,
|
||||
mapTracking: locationToggle ? locationToggle.checked | 0 : 0, // location tracking
|
||||
systemData: Util.getCurrentSystemData(mapId)
|
||||
systemData: mapId ? Util.getCurrentSystemData(mapId) : []
|
||||
};
|
||||
|
||||
if(newSystemPositions){
|
||||
@@ -540,7 +540,8 @@ define([
|
||||
// clear both main update request trigger timer
|
||||
clearUpdateTimeouts();
|
||||
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = `${status} ${jqXHR.status}`;
|
||||
let firstError = error;
|
||||
let errorData = [];
|
||||
let redirect = false; // redirect user to other page e.g. login
|
||||
let reload = true; // reload current page (default: true)
|
||||
@@ -552,6 +553,7 @@ define([
|
||||
responseObj.error &&
|
||||
responseObj.error.length > 0
|
||||
){
|
||||
firstError = responseObj.error[0].status;
|
||||
errorData = responseObj.error;
|
||||
}
|
||||
|
||||
@@ -569,7 +571,7 @@ define([
|
||||
console.error(' ↪ %s Error response: %o', jqXHR.url, errorData);
|
||||
$(document).trigger('pf:shutdown', {
|
||||
status: jqXHR.status,
|
||||
reason: reason,
|
||||
reason: `${reason}: ${firstError}`,
|
||||
error: errorData,
|
||||
redirect: redirect,
|
||||
reload: reload
|
||||
|
||||
@@ -823,17 +823,17 @@ define([
|
||||
});
|
||||
|
||||
// changes in current userData ----------------------------------------------------------------------------
|
||||
documentElement.on('pf:changedUserData', (e, userData, changes) => {
|
||||
documentElement.on('pf:changedUserData', (e, changes) => {
|
||||
// update menu buttons (en/disable)
|
||||
if(changes.characterId){
|
||||
documentElement.trigger('pf:updateMenuOptions', {
|
||||
menuGroup: 'userOptions',
|
||||
payload: Boolean(Util.getObjVal(userData, 'character.id'))
|
||||
payload: Boolean(Util.getCurrentCharacterData('id'))
|
||||
});
|
||||
}
|
||||
|
||||
// update header
|
||||
updateHeaderUserData(userData, changes).then();
|
||||
updateHeaderUserData(changes).then();
|
||||
});
|
||||
|
||||
// shutdown the program -> show dialog --------------------------------------------------------------------
|
||||
@@ -873,7 +873,7 @@ define([
|
||||
// add error information (if available)
|
||||
if(data.error && data.error.length){
|
||||
for(let error of data.error){
|
||||
options.content.textSmaller.push(error.message);
|
||||
options.content.textSmaller.push(error.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,7 +929,7 @@ define([
|
||||
//modalElement.find('form').filter((i, form) => $(form).data('bs.validator')).validator('destroy');
|
||||
|
||||
// destroy all popovers
|
||||
modalElement.find('.' + Util.config.popoverTriggerClass).popover('destroy');
|
||||
modalElement.destroyPopover(true);
|
||||
|
||||
// destroy all Select2
|
||||
modalElement.find('.' + Util.config.select2Class)
|
||||
@@ -1050,18 +1050,17 @@ define([
|
||||
|
||||
/**
|
||||
* update all header elements with current userData
|
||||
* @param userData
|
||||
* @param changes
|
||||
* @returns {Promise<[any, any, any, any, any, any, any, any, any, any]>}
|
||||
* @returns {Promise<[]>}
|
||||
*/
|
||||
let updateHeaderUserData = (userData, changes) => {
|
||||
let updateHeaderUserData = changes => {
|
||||
let updateTasks = [];
|
||||
|
||||
if(changes.characterLogLocation){
|
||||
updateTasks.push(updateMapTrackingToggle(Boolean(Util.getObjVal(userData, 'character.logLocation'))));
|
||||
updateTasks.push(updateMapTrackingToggle(Boolean(Util.getCurrentCharacterData('logLocation'))));
|
||||
}
|
||||
if(changes.charactersIds){
|
||||
updateTasks.push(updateHeaderCharacterSwitch(userData, changes.characterId));
|
||||
updateTasks.push(updateHeaderCharacterSwitch(changes.characterId));
|
||||
}
|
||||
if(
|
||||
changes.characterSystemId ||
|
||||
@@ -1070,7 +1069,7 @@ define([
|
||||
changes.characterStructureId ||
|
||||
changes.characterLogHistory
|
||||
){
|
||||
updateTasks.push(updateHeaderCharacterLocation(userData, changes.characterShipType));
|
||||
updateTasks.push(updateHeaderCharacterLocation(changes.characterShipType));
|
||||
}
|
||||
|
||||
return Promise.all(updateTasks);
|
||||
@@ -1099,22 +1098,21 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* @param userData
|
||||
* @param changedCharacter
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let updateHeaderCharacterSwitch = (userData, changedCharacter) => {
|
||||
let updateHeaderCharacterSwitch = changedCharacter => {
|
||||
let executor = resolve => {
|
||||
let userInfoElement = $('.' + config.headUserCharacterClass);
|
||||
// toggle element
|
||||
animateHeaderElement(userInfoElement, userInfoElement => {
|
||||
if(changedCharacter){
|
||||
// current character changed
|
||||
userInfoElement.find('span').text(Util.getObjVal(userData, 'character.name'));
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('characters', Util.getObjVal(userData, 'character.id')));
|
||||
userInfoElement.find('span').text(Util.getCurrentCharacterData('name'));
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('characters', Util.getCurrentCharacterData('id')));
|
||||
}
|
||||
// init "character switch" popover
|
||||
userInfoElement.initCharacterSwitchPopover(userData);
|
||||
userInfoElement.initCharacterSwitchPopover();
|
||||
|
||||
resolve({
|
||||
action: 'updateHeaderCharacterSwitch',
|
||||
@@ -1127,28 +1125,26 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userData
|
||||
* @param changedShip
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let updateHeaderCharacterLocation = (userData, changedShip) => {
|
||||
let updateHeaderCharacterLocation = changedShip => {
|
||||
let executor = resolve => {
|
||||
let userLocationElement = $('#' + Util.config.headUserLocationId);
|
||||
let breadcrumbHtml = '';
|
||||
let logData = Util.getObjVal(userData, 'character.log');
|
||||
let logData = Util.getCurrentCharacterData('log');
|
||||
let logDataAll = [];
|
||||
|
||||
if(logData){
|
||||
let shipData = Util.getObjVal(userData, 'character.log.ship');
|
||||
let shipData = Util.getObjVal(logData, 'ship');
|
||||
let shipTypeId = Util.getObjVal(shipData, 'typeId') || 0;
|
||||
let shipTypeName = Util.getObjVal(shipData, 'typeName') || '';
|
||||
|
||||
let stationData = Util.getObjVal(userData, 'character.log.station');
|
||||
let stationData = Util.getObjVal(logData, 'station');
|
||||
let stationId = Util.getObjVal(stationData, 'id') || 0;
|
||||
let stationName = Util.getObjVal(stationData, 'name') || '';
|
||||
|
||||
let structureData = Util.getObjVal(userData, 'character.log.structure');
|
||||
let structureData = Util.getObjVal(logData, 'structure');
|
||||
let structureTypeId = Util.getObjVal(structureData, 'type.id') || 0;
|
||||
let structureTypeName = Util.getObjVal(structureData, 'type.name') || '';
|
||||
let structureId = Util.getObjVal(structureData, 'id') || 0;
|
||||
@@ -1157,7 +1153,7 @@ define([
|
||||
logDataAll.push(logData);
|
||||
|
||||
// check for log history data as well
|
||||
let logHistoryData = Util.getObjVal(userData, 'character.logHistory');
|
||||
let logHistoryData = Util.getCurrentCharacterData('logHistory');
|
||||
if(logHistoryData){
|
||||
// check if there are more history log entries than max visual limit
|
||||
if(logHistoryData.length > config.headMaxLocationHistoryBreadcrumbs){
|
||||
|
||||
@@ -53,8 +53,9 @@ define([
|
||||
captchaImageId: config.captchaImageId,
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
ccpImageServer: Init.url.ccpImageServer,
|
||||
roleLabel: Util.getLabelByRole(Util.getObjVal(Util.getCurrentUserData(), 'character.role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect'))
|
||||
roleLabel: Util.getLabelByRole(Util.getCurrentCharacterData('role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')),
|
||||
hasRightCorporationShare: Util.hasRight('map_share', 'corporation')
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
@@ -193,8 +193,8 @@ define([
|
||||
});
|
||||
});
|
||||
|
||||
mapElement.initTooltips();
|
||||
mapElement.hideLoadingAnimation();
|
||||
mapElement.initTooltips({container: '.modal'});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -219,14 +219,6 @@ define([
|
||||
|
||||
systemsElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
systemTable.on('init.dt', function(){
|
||||
systemsElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = systemsElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
let systemsDataTable = systemTable.DataTable({
|
||||
pageLength: 20,
|
||||
paging: true,
|
||||
@@ -514,6 +506,9 @@ define([
|
||||
}
|
||||
],
|
||||
initComplete: function(settings){
|
||||
systemsElement.hideLoadingAnimation();
|
||||
systemsElement.initTooltips({container: '.modal'});
|
||||
|
||||
Counter.initTableCounter(this, ['updated:name']);
|
||||
}
|
||||
});
|
||||
@@ -542,15 +537,6 @@ define([
|
||||
|
||||
connectionsElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
// table init complete
|
||||
connectionTable.on('init.dt', function(){
|
||||
connectionsElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = connectionsElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
// connections table ------------------------------------------------------------------------------------------
|
||||
let connectionDataTable = connectionTable.dataTable({
|
||||
pageLength: 20,
|
||||
@@ -701,6 +687,9 @@ define([
|
||||
}
|
||||
],
|
||||
initComplete: function(settings){
|
||||
connectionsElement.hideLoadingAnimation();
|
||||
connectionsElement.initTooltips({container: '.modal'});
|
||||
|
||||
Counter.initTableCounter(this, ['updated:name']);
|
||||
}
|
||||
});
|
||||
@@ -721,17 +710,6 @@ define([
|
||||
|
||||
usersElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
// table init complete
|
||||
userTable.on('init.dt', function(){
|
||||
usersElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = usersElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: usersElement.parent()
|
||||
});
|
||||
});
|
||||
|
||||
// users table ------------------------------------------------------------------------------------------------
|
||||
// prepare users data for dataTables
|
||||
let currentMapUserData = Util.getCurrentMapUserData( mapData.config.id );
|
||||
@@ -941,7 +919,11 @@ define([
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
initComplete: function(settings){
|
||||
usersElement.hideLoadingAnimation();
|
||||
usersElement.initTooltips({container: '.modal'});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -9,8 +9,9 @@ define([
|
||||
'app/render',
|
||||
'bootbox',
|
||||
'app/map/util',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap) => {
|
||||
'app/module_map',
|
||||
'app/map/overlay/util',
|
||||
], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap, MapOverlayUtil) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -99,144 +100,39 @@ define([
|
||||
'text!templates/form/map.html',
|
||||
'mustache'
|
||||
], (templateMapDialog, templateMapForm, Mustache) => {
|
||||
let selectOption = value => () => (val, render) => {
|
||||
if(render(val) === String(value)){
|
||||
return 'selected';
|
||||
}
|
||||
};
|
||||
|
||||
let dialogTitle = 'Map settings';
|
||||
|
||||
// if there are no maps -> hide settings tab
|
||||
let hideSettingsTab = false;
|
||||
let hideEditTab = false;
|
||||
let hideDownloadTab = false;
|
||||
let hideEditTab = mapData === false;
|
||||
let hideSettingsTab = mapData === false;
|
||||
let hideDownloadTab = mapData === false;
|
||||
|
||||
let hasRightMapCreate = true;
|
||||
let hasRightMapUpdate = true;
|
||||
let hasRightMapExport = true;
|
||||
let hasRightMapImport = true;
|
||||
|
||||
if(mapData === false){
|
||||
hideSettingsTab = true;
|
||||
hideEditTab = true;
|
||||
hideDownloadTab = true;
|
||||
}else{
|
||||
hasRightMapUpdate = MapUtil.checkRight('map_update', mapData.config);
|
||||
hasRightMapExport = MapUtil.checkRight('map_export', mapData.config);
|
||||
hasRightMapImport = MapUtil.checkRight('map_import', mapData.config);
|
||||
}
|
||||
let hasRightMapUpdate = MapUtil ? MapUtil.checkRight('map_update', mapData.config) : true;
|
||||
let hasRightMapExport = MapUtil ? MapUtil.checkRight('map_export', mapData.config) : true;
|
||||
let hasRightMapImport = MapUtil ? MapUtil.checkRight('map_import', mapData.config) : true;
|
||||
let hasRightMapShare = MapUtil ? MapUtil.checkRight('map_share', mapData.config) : true;
|
||||
|
||||
// available map "types" for a new or existing map
|
||||
let mapTypes = MapUtil.getMapTypes(true);
|
||||
|
||||
let mapFormData = {
|
||||
select2Class: Util.config.select2Class,
|
||||
scope: MapUtil.getMapScopes(),
|
||||
type: mapTypes,
|
||||
icon: MapUtil.getMapIcons(),
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
formInfoContainerClass: Util.config.formInfoContainerClass
|
||||
};
|
||||
|
||||
// render "new map" tab content -----------------------------------------------------------------------
|
||||
let mapFormDataNew = $.extend({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapCreate,
|
||||
nameInputId: config.newNameInputId,
|
||||
iconSelectId: config.newIconSelectId,
|
||||
scopeSelectId: config.newScopeSelectId,
|
||||
typeSelectId: config.newTypeSelectId
|
||||
});
|
||||
let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew);
|
||||
|
||||
// render "edit map" tab content ----------------------------------------------------------------------
|
||||
let mapFormDataEdit = $.extend({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapUpdate,
|
||||
nameInputId: config.editNameInputId,
|
||||
iconSelectId: config.editIconSelectId,
|
||||
scopeSelectId: config.editScopeSelectId,
|
||||
typeSelectId: config.editTypeSelectId
|
||||
});
|
||||
let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit);
|
||||
contentEditMap = $(contentEditMap);
|
||||
|
||||
// current map access info
|
||||
let accessCharacter = [];
|
||||
let accessCorporation = [];
|
||||
let accessAlliance = [];
|
||||
let deleteExpiredConnections = true;
|
||||
let deleteEolConnections = true;
|
||||
let persistentAliases = true;
|
||||
let persistentSignatures = true;
|
||||
let trackAbyssalJumps = true;
|
||||
|
||||
let logActivity = true;
|
||||
let logHistory = true;
|
||||
|
||||
let slackWebHookURL = '';
|
||||
let slackUsername = '';
|
||||
let slackIcon = '';
|
||||
let slackChannelHistory = '';
|
||||
let slackChannelRally = '';
|
||||
let slackEnabled = false;
|
||||
let slackHistoryEnabled = false;
|
||||
let slackRallyEnabled = false;
|
||||
let slackSectionShow = false;
|
||||
|
||||
let discordUsername = '';
|
||||
let discordWebHookURLRally = '';
|
||||
let discordWebHookURLHistory = '';
|
||||
let discordEnabled = false;
|
||||
let discordRallyEnabled = false;
|
||||
let discordHistoryEnabled = false;
|
||||
let discordSectionShow = false;
|
||||
|
||||
if(mapData !== false){
|
||||
// set current map information
|
||||
contentEditMap.find('input[name="id"]').val( mapData.config.id );
|
||||
contentEditMap.find('select[name="icon"]').val( mapData.config.icon );
|
||||
contentEditMap.find('input[name="name"]').val( mapData.config.name );
|
||||
contentEditMap.find('select[name="scopeId"]').val( mapData.config.scope.id );
|
||||
contentEditMap.find('select[name="typeId"]').val( mapData.config.type.id );
|
||||
|
||||
accessCharacter = mapData.config.access.character;
|
||||
accessCorporation = mapData.config.access.corporation;
|
||||
accessAlliance = mapData.config.access.alliance;
|
||||
|
||||
deleteExpiredConnections = mapData.config.deleteExpiredConnections;
|
||||
deleteEolConnections = mapData.config.deleteEolConnections;
|
||||
persistentAliases = mapData.config.persistentAliases;
|
||||
persistentSignatures = mapData.config.persistentSignatures;
|
||||
trackAbyssalJumps = mapData.config.trackAbyssalJumps;
|
||||
|
||||
logActivity = mapData.config.logging.activity;
|
||||
logHistory = mapData.config.logging.history;
|
||||
|
||||
slackWebHookURL = mapData.config.logging.slackWebHookURL;
|
||||
slackUsername = mapData.config.logging.slackUsername;
|
||||
slackIcon = mapData.config.logging.slackIcon;
|
||||
slackChannelHistory = mapData.config.logging.slackChannelHistory;
|
||||
slackChannelRally = mapData.config.logging.slackChannelRally;
|
||||
slackEnabled = Boolean(Util.getObjVal(Init, 'slack.status'));
|
||||
slackHistoryEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled'));
|
||||
slackRallyEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled'));
|
||||
slackSectionShow = (slackEnabled && slackWebHookURL.length > 0);
|
||||
|
||||
discordUsername = Util.getObjVal(mapData, 'config.logging.discordUsername');
|
||||
discordWebHookURLRally = Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally');
|
||||
discordWebHookURLHistory = Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory');
|
||||
discordEnabled = Boolean(Util.getObjVal(Init, 'discord.status'));
|
||||
discordRallyEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled'));
|
||||
discordHistoryEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled'));
|
||||
discordSectionShow = (discordEnabled && (discordWebHookURLRally.length > 0 || discordWebHookURLHistory.length > 0));
|
||||
|
||||
// remove "#" from Slack channels
|
||||
slackChannelHistory = slackChannelHistory.indexOf('#') === 0 ? slackChannelHistory.substr(1) : slackChannelHistory;
|
||||
slackChannelRally = slackChannelRally.indexOf('#') === 0 ? slackChannelRally.substr(1) : slackChannelRally;
|
||||
}
|
||||
|
||||
// render main dialog ---------------------------------------------------------------------------------
|
||||
let mapDialogData = {
|
||||
id: config.newMapDialogId,
|
||||
mapData: mapData,
|
||||
type: mapTypes,
|
||||
|
||||
hasRightMapUpdate,
|
||||
hasRightMapExport,
|
||||
hasRightMapImport,
|
||||
hasRightMapShare,
|
||||
|
||||
// message container
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
@@ -253,9 +149,9 @@ define([
|
||||
dialogMapSettingsContainerId: config.dialogMapSettingsContainerId,
|
||||
dialogMapDownloadContainerId: config.dialogMapDownloadContainerId,
|
||||
|
||||
hideEditTab: hideEditTab,
|
||||
hideSettingsTab: hideSettingsTab,
|
||||
hideDownloadTab: hideDownloadTab,
|
||||
hideEditTab,
|
||||
hideSettingsTab,
|
||||
hideDownloadTab,
|
||||
|
||||
// settings tab --------------
|
||||
deleteExpiredConnectionsId : config.deleteExpiredConnectionsId,
|
||||
@@ -263,57 +159,59 @@ define([
|
||||
persistentAliasesId : config.persistentAliasesId,
|
||||
persistentSignaturesId : config.persistentSignaturesId,
|
||||
trackAbyssalJumpsId : config.trackAbyssalJumpsId,
|
||||
deleteExpiredConnections: deleteExpiredConnections,
|
||||
deleteEolConnections: deleteEolConnections,
|
||||
persistentAliases: persistentAliases,
|
||||
persistentSignatures: persistentSignatures,
|
||||
trackAbyssalJumps: trackAbyssalJumps,
|
||||
|
||||
logHistoryId: config.logHistoryId,
|
||||
logActivityId: config.logActivityId,
|
||||
logActivity: logActivity,
|
||||
logHistory: logHistory,
|
||||
|
||||
deleteExpiredConnections: true,
|
||||
deleteEolConnections: true,
|
||||
persistentAliases: true,
|
||||
persistentSignatures: true,
|
||||
trackAbyssalJumps: true,
|
||||
logActivity: true,
|
||||
logHistory: true,
|
||||
|
||||
slackWebHookURLId: config.slackWebHookURLId,
|
||||
slackUsernameId: config.slackUsernameId,
|
||||
slackIconId: config.slackIconId,
|
||||
slackChannelHistoryId: config.slackChannelHistoryId,
|
||||
slackChannelRallyId: config.slackChannelRallyId,
|
||||
slackWebHookURL: slackWebHookURL,
|
||||
slackUsername: slackUsername,
|
||||
slackIcon: slackIcon,
|
||||
slackChannelHistory: slackChannelHistory,
|
||||
slackChannelRally: slackChannelRally,
|
||||
slackEnabled: slackEnabled,
|
||||
slackHistoryEnabled: slackHistoryEnabled,
|
||||
slackRallyEnabled: slackRallyEnabled,
|
||||
slackSectionShow: slackSectionShow,
|
||||
|
||||
slackWebHookURL: '',
|
||||
slackUsername: '',
|
||||
slackIcon: '',
|
||||
slackChannelHistory: '',
|
||||
slackChannelRally: '',
|
||||
slackEnabled: false,
|
||||
slackHistoryEnabled: false,
|
||||
slackRallyEnabled: false,
|
||||
slackSectionShow: false,
|
||||
|
||||
discordUsernameId: config.discordUsernameId,
|
||||
discordWebHookURLRallyId: config.discordWebHookURLRallyId,
|
||||
discordWebHookURLHistoryId: config.discordWebHookURLHistoryId,
|
||||
discordUsername: discordUsername,
|
||||
discordWebHookURLRally: discordWebHookURLRally,
|
||||
discordWebHookURLHistory: discordWebHookURLHistory,
|
||||
discordEnabled: discordEnabled,
|
||||
discordRallyEnabled: discordRallyEnabled,
|
||||
discordHistoryEnabled: discordHistoryEnabled,
|
||||
discordSectionShow: discordSectionShow,
|
||||
|
||||
discordUsername: '',
|
||||
discordWebHookURLRally: '',
|
||||
discordWebHookURLHistory: '',
|
||||
discordEnabled: false,
|
||||
discordRallyEnabled: false,
|
||||
discordHistoryEnabled: false,
|
||||
discordSectionShow: false,
|
||||
|
||||
// map access ----------------
|
||||
characterSelectId: config.characterSelectId,
|
||||
corporationSelectId: config.corporationSelectId,
|
||||
allianceSelectId: config.allianceSelectId,
|
||||
|
||||
// map access objects --------
|
||||
accessCharacter: accessCharacter,
|
||||
accessCorporation: accessCorporation,
|
||||
accessAlliance: accessAlliance,
|
||||
|
||||
// access limitations --------
|
||||
maxCharacter: Init.mapTypes.private.defaultConfig.max_shared,
|
||||
maxCorporation: Init.mapTypes.corporation.defaultConfig.max_shared,
|
||||
maxAlliance: Init.mapTypes.alliance.defaultConfig.max_shared,
|
||||
|
||||
accessCharacter: [],
|
||||
accessCorporation: [],
|
||||
accessAlliance: [],
|
||||
|
||||
// download tab --------------
|
||||
dialogMapExportFormId: config.dialogMapExportFormId,
|
||||
dialogMapImportFormId: config.dialogMapImportFormId,
|
||||
@@ -323,25 +221,100 @@ define([
|
||||
fieldImportId: config.fieldImportId,
|
||||
dialogMapImportInfoId: config.dialogMapImportInfoId,
|
||||
|
||||
hasRightMapUpdate: hasRightMapUpdate,
|
||||
hasRightMapExport: hasRightMapExport,
|
||||
hasRightMapImport: hasRightMapImport,
|
||||
|
||||
formatFilename: function(){
|
||||
// format filename from "map name" (initial)
|
||||
return function(mapName, render){
|
||||
let filename = render(mapName);
|
||||
return formatFilename(filename);
|
||||
};
|
||||
}
|
||||
formatFilename: () => (mapName, render) => formatFilename(render(mapName))
|
||||
};
|
||||
|
||||
if(mapData !== false){
|
||||
Object.assign(mapDialogData, {
|
||||
deleteExpiredConnections: mapData.config.deleteExpiredConnections,
|
||||
deleteEolConnections: mapData.config.deleteEolConnections,
|
||||
persistentAliases: mapData.config.persistentAliases,
|
||||
persistentSignatures: mapData.config.persistentSignatures,
|
||||
trackAbyssalJumps: mapData.config.trackAbyssalJumps,
|
||||
logActivity: mapData.config.logging.activity,
|
||||
logHistory: mapData.config.logging.history,
|
||||
|
||||
slackWebHookURL: mapData.config.logging.slackWebHookURL,
|
||||
slackUsername: mapData.config.logging.slackUsername,
|
||||
slackIcon: mapData.config.logging.slackIcon,
|
||||
slackChannelHistory: mapData.config.logging.slackChannelHistory,
|
||||
slackChannelRally: mapData.config.logging.slackChannelRally,
|
||||
slackEnabled: Boolean(Util.getObjVal(Init, 'slack.status')),
|
||||
|
||||
discordUsername: Util.getObjVal(mapData, 'config.logging.discordUsername'),
|
||||
discordWebHookURLRally: Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally'),
|
||||
discordWebHookURLHistory: Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory'),
|
||||
discordEnabled: Boolean(Util.getObjVal(Init, 'discord.status')),
|
||||
|
||||
accessCharacter: mapData.config.access.character,
|
||||
accessCorporation: mapData.config.access.corporation,
|
||||
accessAlliance: mapData.config.access.alliance
|
||||
});
|
||||
|
||||
Object.assign(mapDialogData, {
|
||||
// remove "#" from Slack channels
|
||||
slackChannelHistory: mapDialogData.slackChannelHistory.indexOf('#') === 0 ? mapDialogData.slackChannelHistory.substr(1) : mapDialogData.slackChannelHistory,
|
||||
slackChannelRally: mapDialogData.slackChannelRally.indexOf('#') === 0 ? mapDialogData.slackChannelRally.substr(1) : mapDialogData.slackChannelRally,
|
||||
|
||||
slackHistoryEnabled: mapDialogData.slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled')),
|
||||
slackRallyEnabled: mapDialogData.slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled')),
|
||||
slackSectionShow: (mapDialogData.slackEnabled && mapDialogData.slackWebHookURL.length > 0),
|
||||
|
||||
discordRallyEnabled: mapDialogData.discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled')),
|
||||
discordHistoryEnabled: mapDialogData.discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled')),
|
||||
discordSectionShow: (mapDialogData.discordEnabled && (mapDialogData.discordWebHookURLRally.length > 0 || mapDialogData.discordWebHookURLHistory.length > 0)),
|
||||
});
|
||||
}
|
||||
|
||||
let contentDialog = Mustache.render(templateMapDialog, mapDialogData);
|
||||
contentDialog = $(contentDialog);
|
||||
|
||||
// set tab content
|
||||
// "new map" + "edit map" tab base --------------------------------------------------------------------
|
||||
let mapFormData = {
|
||||
select2Class: Util.config.select2Class,
|
||||
scope: MapUtil.getMapScopes(),
|
||||
type: mapTypes,
|
||||
icon: MapUtil.getMapIcons(),
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
formInfoContainerClass: Util.config.formInfoContainerClass
|
||||
};
|
||||
|
||||
// render "new map" tab content -----------------------------------------------------------------------
|
||||
let mapFormDataNew = Object.assign({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapCreate,
|
||||
nameInputId: config.newNameInputId,
|
||||
iconSelectId: config.newIconSelectId,
|
||||
scopeSelectId: config.newScopeSelectId,
|
||||
typeSelectId: config.newTypeSelectId,
|
||||
|
||||
mapId: 0,
|
||||
mapIcon: undefined,
|
||||
mapName: undefined,
|
||||
mapScopeId: undefined,
|
||||
mapTypeId: undefined
|
||||
});
|
||||
let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew);
|
||||
$('#' + config.dialogMapNewContainerId, contentDialog).html(contentNewMap);
|
||||
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
|
||||
|
||||
// render "edit map" tab content ----------------------------------------------------------------------
|
||||
if(!hideEditTab){
|
||||
let mapFormDataEdit = Object.assign({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapUpdate,
|
||||
nameInputId: config.editNameInputId,
|
||||
iconSelectId: config.editIconSelectId,
|
||||
scopeSelectId: config.editScopeSelectId,
|
||||
typeSelectId: config.editTypeSelectId,
|
||||
|
||||
mapId: mapData.config.id,
|
||||
mapIcon: selectOption(mapData.config.icon),
|
||||
mapName: mapData.config.name,
|
||||
mapScopeId: selectOption(mapData.config.scope.id),
|
||||
mapTypeId: selectOption(mapData.config.type.id)
|
||||
});
|
||||
let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit);
|
||||
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
|
||||
}
|
||||
|
||||
let mapInfoDialog = bootbox.dialog({
|
||||
title: dialogTitle,
|
||||
@@ -355,7 +328,6 @@ define([
|
||||
label: '<i class="fas fa-check fa-fw"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function(){
|
||||
|
||||
// get the current active form
|
||||
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
|
||||
|
||||
@@ -375,9 +347,7 @@ define([
|
||||
});
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === true){
|
||||
if(form.isValidForm()){
|
||||
// lock dialog
|
||||
let dialogContent = mapInfoDialog.find('.modal-content');
|
||||
dialogContent.showLoadingAnimation();
|
||||
@@ -386,68 +356,36 @@ define([
|
||||
let formData = form.getFormValues();
|
||||
|
||||
// add value prefixes (Slack channels)
|
||||
let tmpVal;
|
||||
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelHistory')) === 'string' && tmpVal.length){
|
||||
formData.slackChannelHistory = '#' + tmpVal;
|
||||
}
|
||||
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelRally')) === 'string' && tmpVal.length){
|
||||
formData.slackChannelRally = '#' + tmpVal;
|
||||
}
|
||||
Object.keys(formData).map((key, index) => {
|
||||
if(['slackChannelHistory', 'slackChannelRally'].includes(key))
|
||||
formData[key] = (formData[key].length ? '#' : '') + formData[key];
|
||||
});
|
||||
|
||||
// checkbox fix -> settings tab
|
||||
if( form.find('#' + config.deleteExpiredConnectionsId).length ){
|
||||
formData.deleteExpiredConnections = formData.hasOwnProperty('deleteExpiredConnections') ? parseInt( formData.deleteExpiredConnections ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.deleteEolConnectionsId).length ){
|
||||
formData.deleteEolConnections = formData.hasOwnProperty('deleteEolConnections') ? parseInt( formData.deleteEolConnections ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.persistentAliasesId).length ){
|
||||
formData.persistentAliases = formData.hasOwnProperty('persistentAliases') ? parseInt( formData.persistentAliases ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.persistentSignaturesId).length ){
|
||||
formData.persistentSignatures = formData.hasOwnProperty('persistentSignatures') ? parseInt( formData.persistentSignatures ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.trackAbyssalJumpsId).length ){
|
||||
formData.trackAbyssalJumps = formData.hasOwnProperty('trackAbyssalJumps') ? parseInt( formData.trackAbyssalJumps ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.logHistoryId).length ){
|
||||
formData.logHistory = formData.hasOwnProperty('logHistory') ? parseInt( formData.logHistory ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.logActivityId).length ){
|
||||
formData.logActivity = formData.hasOwnProperty('logActivity') ? parseInt( formData.logActivity ) : 0;
|
||||
}
|
||||
MapOverlayUtil.getMapOverlay($(mapData.map.getContainer()), 'timer').startMapUpdateCounter();
|
||||
|
||||
let requestData = {formData: formData};
|
||||
let method = formData.id ? 'PATCH' : 'PUT';
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveMap,
|
||||
data: requestData,
|
||||
dataType: 'json'
|
||||
}).done(function(responseData){
|
||||
if(responseData.error.length){
|
||||
form.showFormMessage(responseData.error);
|
||||
}else{
|
||||
// success
|
||||
Util.showNotify({title: dialogTitle, text: 'Map: ' + responseData.mapData.mapData.name, type: 'success'});
|
||||
Util.request(method, 'map', formData.id, formData, {
|
||||
formElement: form // for error form messages
|
||||
}, context => {
|
||||
// always do
|
||||
dialogContent.hideLoadingAnimation();
|
||||
}).then(
|
||||
payload => {
|
||||
let mapData = Util.getObjVal(payload, 'data.mapData');
|
||||
Util.showNotify({title: dialogTitle, text: `Map: ${Util.getObjVal(mapData, 'name')}`, type: 'success'});
|
||||
|
||||
// update map-tab Element
|
||||
let tabLinkEls = Util.getMapTabLinkElements(Util.getMapModule()[0], responseData.mapData.mapData.id);
|
||||
let tabLinkEls = Util.getMapTabLinkElements(Util.getMapModule()[0], Util.getObjVal(mapData, 'id'));
|
||||
if(tabLinkEls.length === 1){
|
||||
ModuleMap.updateTabData(tabLinkEls[0], responseData.mapData.mapData);
|
||||
ModuleMap.updateTabData(tabLinkEls[0], mapData);
|
||||
}
|
||||
|
||||
$(mapInfoDialog).modal('hide');
|
||||
Util.triggerMenuAction(document, 'Close');
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveMap', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
|
||||
}).always(function(){
|
||||
dialogContent.hideLoadingAnimation();
|
||||
});
|
||||
},
|
||||
Util.handleAjaxErrorResponse
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -487,11 +425,11 @@ define([
|
||||
// get current active form(tab)
|
||||
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
|
||||
|
||||
form.showFormMessage([{type: 'info', message: 'Creating new maps or change settings may take a few seconds'}]);
|
||||
form.showFormMessage([{type: 'info', text: 'Creating new maps or change settings may take a few seconds'}]);
|
||||
|
||||
if(mapData === false){
|
||||
// no map data found (probably new user
|
||||
form.showFormMessage([{type: 'warning', message: 'No maps found. Create a new map before you can start'}]);
|
||||
form.showFormMessage([{type: 'warning', text: 'No maps found. Create a new map before you can start'}]);
|
||||
}
|
||||
|
||||
// init "download tab" ============================================================================
|
||||
@@ -573,7 +511,7 @@ define([
|
||||
importData.mapData.push( JSON.parse( readEvent.target.result ) );
|
||||
}catch(error){
|
||||
filesCountFail++;
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'File can not be parsed'}]);
|
||||
importFormElement.showFormMessage([{type: 'error', text: 'File can not be parsed'}]);
|
||||
}
|
||||
|
||||
// start import when all files are parsed
|
||||
@@ -640,7 +578,7 @@ define([
|
||||
}
|
||||
});
|
||||
}else{
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'The File APIs are not fully supported in this browser.'}]);
|
||||
importFormElement.showFormMessage([{type: 'error', text: 'The File APIs are not fully supported in this browser.'}]);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -789,39 +727,32 @@ define([
|
||||
* @param mapData
|
||||
*/
|
||||
$.fn.showDeleteMapDialog = function(mapData){
|
||||
let mapName = mapData.config.name;
|
||||
let mapNameStr = '<span class="txt-color txt-color-danger">' + mapName + '</span>';
|
||||
let mapId = Util.getObjVal(mapData, 'config.id');
|
||||
let mapName = Util.getObjVal(mapData, 'config.name');
|
||||
if(!mapId) return;
|
||||
|
||||
let mapNameStr = `<span class="txt-color txt-color-danger">${mapName}</span>`;
|
||||
|
||||
let mapDeleteDialog = bootbox.confirm({
|
||||
message: 'Delete map "' + mapNameStr + '"?',
|
||||
message: `Delete map "${mapNameStr}"?`,
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: '<i class="fas fa-trash fa-fw"></i> delete map',
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result){
|
||||
callback: result => {
|
||||
if(result){
|
||||
// lock dialog
|
||||
let dialogContent = mapDeleteDialog.find('.modal-content');
|
||||
dialogContent.showLoadingAnimation();
|
||||
|
||||
let data = {mapData: mapData.config};
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.deleteMap,
|
||||
data: data,
|
||||
dataType: 'json'
|
||||
}).done(function(data){
|
||||
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': deleteMap', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
}).always(function(){
|
||||
$(mapDeleteDialog).modal('hide');
|
||||
});
|
||||
Util.request('DELETE', 'map', mapId, {}, {}).then(
|
||||
payload => {
|
||||
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
|
||||
},
|
||||
Util.handleAjaxErrorResponse
|
||||
).finally(() => mapDeleteDialog.modal('hide'));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -830,5 +761,4 @@ define([
|
||||
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
@@ -632,7 +632,7 @@ define([
|
||||
// get current ship data ----------------------------------------------------------
|
||||
massShipCell.parent().toggle(showShip);
|
||||
if(showShip){
|
||||
shipData = Util.getObjVal(Util.getCurrentCharacterLog(), 'ship');
|
||||
shipData = Util.getObjVal(Util.getCurrentCharacterData('log'), 'ship');
|
||||
if(shipData){
|
||||
if(shipData.mass){
|
||||
massShip = parseInt(shipData.mass);
|
||||
|
||||
@@ -807,13 +807,13 @@ define([
|
||||
// -> add a modal button for pre-fill modal with it
|
||||
// -> systemId must match systemId from current character log
|
||||
let currentUserData = Util.getCurrentUserData();
|
||||
let characterStructureId = Util.getCurrentCharacterData('log.structure.id') || 0;
|
||||
let characterStructureName = Util.getCurrentCharacterData('log.structure.name') || '';
|
||||
let characterStructureTypeId = Util.getCurrentCharacterData('log.structure.type.id') || 0;
|
||||
let characterStructureTypeName = Util.getCurrentCharacterData('log.structure.type.name') || '';
|
||||
let isCurrentLocation = false;
|
||||
let characterStructureId = Util.getObjVal(currentUserData, 'character.log.structure.id') || 0;
|
||||
let characterStructureName = Util.getObjVal(currentUserData, 'character.log.structure.name') || '';
|
||||
let characterStructureTypeId = Util.getObjVal(currentUserData, 'character.log.structure.type.id') || 0;
|
||||
let characterStructureTypeName = Util.getObjVal(currentUserData, 'character.log.structure.type.name') || '';
|
||||
|
||||
if(this._systemData.id === Util.getObjVal(currentUserData, 'character.log.system.id')){
|
||||
if(this._systemData.id === Util.getCurrentCharacterData('log.system.id')){
|
||||
isCurrentLocation = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -732,7 +732,7 @@ define([
|
||||
let systemSecClass = this._config.systemSecurityClassPrefix + tempSystemSec.replace('.', '-');
|
||||
|
||||
// check for wormhole
|
||||
let icon = 'fas fa-square';
|
||||
let icon = 'fas fa-square-full';
|
||||
if(isWormholeSystemName(systemName)){
|
||||
icon = 'fas fa-dot-circle';
|
||||
}
|
||||
|
||||
@@ -1243,7 +1243,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
enrichParsedSignatureData(signatureData){
|
||||
let characterData = Util.getObjVal(Util.getCurrentUserData(), 'character');
|
||||
let characterData = Util.getCurrentCharacter();
|
||||
let timestamp = Math.floor((new Date()).getTime() / 1000);
|
||||
|
||||
for(let i = 0; i < signatureData.length; i++){
|
||||
|
||||
207
js/app/util.js
207
js/app/util.js
@@ -259,30 +259,31 @@ define([
|
||||
* @param errors
|
||||
*/
|
||||
$.fn.showFormMessage = function(errors){
|
||||
|
||||
let formElement = $(this);
|
||||
|
||||
let errorMessage = [];
|
||||
let warningMessage = [];
|
||||
let infoMessage = [];
|
||||
for(let i = 0; i < errors.length; i++){
|
||||
if(errors[i].type === 'error'){
|
||||
errorMessage.push( errors[i].message );
|
||||
|
||||
for (let error of errors) {
|
||||
let message = `${error.text}`;
|
||||
if(error.type === 'error'){
|
||||
message = `${error.status} - ${message}`;
|
||||
errorMessage.push(message);
|
||||
|
||||
// mark form field as invalid in case of a validation error
|
||||
if(
|
||||
errors[i].field &&
|
||||
errors[i].field.length > 0
|
||||
error.field &&
|
||||
error.field.length > 0
|
||||
){
|
||||
let formField = formElement.find('[name="' + errors[i].field + '"]');
|
||||
let formField = formElement.find('[name="' + error.field + '"]');
|
||||
let formGroup = formField.parents('.form-group').removeClass('has-success').addClass('has-error');
|
||||
let formHelp = formGroup.find('.help-block').text(errors[i].message);
|
||||
let formHelp = formGroup.find('.help-block').text(error.text);
|
||||
}
|
||||
|
||||
}else if(errors[i].type === 'warning'){
|
||||
warningMessage.push( errors[i].message );
|
||||
}else if(errors[i].type === 'info'){
|
||||
infoMessage.push( errors[i].message );
|
||||
}else if(error.type === 'warning'){
|
||||
warningMessage.push(message);
|
||||
}else if(error.type === 'info'){
|
||||
infoMessage.push(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,10 +596,10 @@ define([
|
||||
|
||||
/**
|
||||
* add character switch popover
|
||||
* @param userData
|
||||
*/
|
||||
$.fn.initCharacterSwitchPopover = function(userData){
|
||||
$.fn.initCharacterSwitchPopover = function(){
|
||||
let elements = $(this);
|
||||
let userData = getCurrentUserData();
|
||||
let eventNamespace = 'hideCharacterPopup';
|
||||
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function(template, Mustache){
|
||||
@@ -1820,14 +1821,16 @@ define([
|
||||
|
||||
// check if userData is valid
|
||||
if(userData && userData.character && userData.characters){
|
||||
// check new vs. old userData for changes
|
||||
let changes = compareUserData(getCurrentUserData(), userData);
|
||||
// check if there is any change
|
||||
if(Object.values(changes).some(val => val)){
|
||||
$(document).trigger('pf:changedUserData', [userData, changes]);
|
||||
}
|
||||
|
||||
Init.currentUserData = userData;
|
||||
isSet = true;
|
||||
|
||||
// check if there is any change
|
||||
if(Object.values(changes).some(val => val)){
|
||||
$(document).trigger('pf:changedUserData', [changes]);
|
||||
}
|
||||
}else{
|
||||
console.error('Could not set userData %o. Missing or malformed obj', userData);
|
||||
}
|
||||
@@ -1836,28 +1839,71 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* get currentUserData from "global" variable
|
||||
* get currentUserData from "global" var
|
||||
* @returns {*}
|
||||
*/
|
||||
let getCurrentUserData = () => {
|
||||
return Init.currentUserData;
|
||||
};
|
||||
|
||||
/**
|
||||
* get currentCharacterData
|
||||
* @see getCurrentUserData
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
let getCurrentCharacter = () => getObjVal(getCurrentUserData(), 'character') || false;
|
||||
|
||||
/**
|
||||
* get data from currentCharacterData (e.g. id)
|
||||
* @see getCurrentCharacter
|
||||
* @param key
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
let getCurrentCharacterData = key => getObjVal(getCurrentCharacter(), key) || false;
|
||||
|
||||
/**
|
||||
* get either active characterID or characterId from initial page load
|
||||
* @returns {number}
|
||||
*/
|
||||
let getCurrentCharacterId = () => {
|
||||
let currentCharacterId = parseInt(getObjVal(getCurrentUserData(), 'character.id')) || 0;
|
||||
|
||||
let currentCharacterId = parseInt(getCurrentCharacterData('id')) || 0;
|
||||
if(!currentCharacterId){
|
||||
// no active character... -> get default characterId from initial page load
|
||||
currentCharacterId = parseInt(document.body.getAttribute('data-character-id'));
|
||||
}
|
||||
|
||||
return currentCharacterId;
|
||||
};
|
||||
|
||||
/**
|
||||
* get information for the current mail user
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
if(currentUserData){
|
||||
// user data is set -> user data will be set AFTER the main init request!
|
||||
let characterData = currentUserData.character;
|
||||
if(characterData){
|
||||
if(option === 'privateId'){
|
||||
userInfo = characterData.id;
|
||||
}
|
||||
|
||||
if(option === 'allianceId' && characterData.alliance){
|
||||
userInfo = characterData.alliance.id;
|
||||
}
|
||||
|
||||
if(option === 'corporationId' && characterData.corporation){
|
||||
userInfo = characterData.corporation.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* compares two userData objects for changes that are relevant
|
||||
* @param oldUserData
|
||||
@@ -1886,6 +1932,29 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* checks if currentCharacter has a role that matches a specific right
|
||||
* @param right
|
||||
* @param objKey
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let hasRight = (right, objKey) => {
|
||||
let hasRight = false;
|
||||
let objectRights = getCurrentCharacterData(`${objKey}.rights`) || [];
|
||||
let objectRight = objectRights.find(objectRight => objectRight.right.name === right);
|
||||
if(objectRight){
|
||||
let characterRole = getCurrentCharacterData('role');
|
||||
if(
|
||||
characterRole.name === 'SUPER' ||
|
||||
objectRight.role.name === 'MEMBER' ||
|
||||
objectRight.role.name === characterRole.name
|
||||
){
|
||||
hasRight = true;
|
||||
}
|
||||
}
|
||||
return hasRight;
|
||||
};
|
||||
|
||||
/**
|
||||
* get a unique ID for each tab
|
||||
* -> store ID in session storage
|
||||
@@ -2021,31 +2090,36 @@ define([
|
||||
* global ajax error handler -> handles .fail() requests
|
||||
* @param payload
|
||||
*/
|
||||
let handleAjaxErrorResponse = (payload) => {
|
||||
let handleAjaxErrorResponse = payload => {
|
||||
// handle only request errors
|
||||
if(payload.action === 'request'){
|
||||
let jqXHR = payload.data.jqXHR;
|
||||
let reason = '';
|
||||
|
||||
if(jqXHR.responseJSON){
|
||||
// ... valid JSON response
|
||||
let response = jqXHR.responseJSON;
|
||||
|
||||
if(response.error && response.error.length > 0){
|
||||
// build error notification reason from errors
|
||||
reason = response.error.map(error => error.message ? error.message : error.status).join('\n');
|
||||
|
||||
// check if errors might belong to a HTML form -> check "context"
|
||||
if(payload.context.formElement){
|
||||
// show form messages e.g. validation errors
|
||||
payload.context.formElement.showFormMessage(response.error);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
reason = 'Invalid JSON response';
|
||||
}
|
||||
showNotify({title: jqXHR.status + ': ' + payload.name, text: reason, type: 'error'});
|
||||
if(payload.action !== 'request'){
|
||||
console.error('Unhandled HTTP response error. Invalid payload %o', payload);
|
||||
return;
|
||||
}
|
||||
|
||||
let jqXHR = payload.data.jqXHR;
|
||||
let title = `${jqXHR.status}: ${jqXHR.statusText} - ${payload.name}`;
|
||||
let reason = '';
|
||||
|
||||
if(jqXHR.responseJSON){
|
||||
// ... valid JSON response
|
||||
let response = jqXHR.responseJSON;
|
||||
|
||||
if(response.error && response.error.length > 0){
|
||||
// build error notification reason from errors
|
||||
reason = response.error.map(error => error.text || error.status).join('\n');
|
||||
|
||||
// check if errors might belong to a HTML form -> check "context"
|
||||
if(payload.context.formElement){
|
||||
// show form messages e.g. validation errors
|
||||
payload.context.formElement.showFormMessage(response.error);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
reason = 'Invalid JSON response';
|
||||
}
|
||||
|
||||
showNotify({title: title, text: reason, type: 'error'});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2822,43 +2896,6 @@ define([
|
||||
Init.currentMapData = Init.currentMapData.filter(mapData => mapData.config.id !== mapId);
|
||||
};
|
||||
|
||||
/**
|
||||
* get the current log data for the current user character
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentCharacterLog = () => getObjVal(getCurrentUserData(), 'character.log') || false;
|
||||
|
||||
/**
|
||||
* get information for the current mail user
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
if(currentUserData){
|
||||
// user data is set -> user data will be set AFTER the main init request!
|
||||
let characterData = currentUserData.character;
|
||||
if(characterData){
|
||||
if(option === 'privateId'){
|
||||
userInfo = characterData.id;
|
||||
}
|
||||
|
||||
if(option === 'allianceId' && characterData.alliance){
|
||||
userInfo = characterData.alliance.id;
|
||||
}
|
||||
|
||||
if(option === 'corporationId' && characterData.corporation){
|
||||
userInfo = characterData.corporation.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* get "nearBy" systemData based on a jump radius around a currentSystem
|
||||
* @param currentSystemData
|
||||
@@ -3646,13 +3683,14 @@ define([
|
||||
deleteCurrentMapData: deleteCurrentMapData,
|
||||
setCurrentUserData: setCurrentUserData,
|
||||
getCurrentUserData: getCurrentUserData,
|
||||
getCurrentCharacter: getCurrentCharacter,
|
||||
getCurrentCharacterData: getCurrentCharacterData,
|
||||
getCurrentCharacterId: getCurrentCharacterId,
|
||||
setCurrentSystemData: setCurrentSystemData,
|
||||
getCurrentSystemData: getCurrentSystemData,
|
||||
deleteCurrentSystemData:deleteCurrentSystemData,
|
||||
getCurrentLocationData: getCurrentLocationData,
|
||||
getCurrentUserInfo: getCurrentUserInfo,
|
||||
getCurrentCharacterLog: getCurrentCharacterLog,
|
||||
findInViewport: findInViewport,
|
||||
initScrollSpy: initScrollSpy,
|
||||
getConfirmationTemplate: getConfirmationTemplate,
|
||||
@@ -3674,6 +3712,7 @@ define([
|
||||
getLocalStore: getLocalStore,
|
||||
getResizeManager: getResizeManager,
|
||||
clearSessionStorage: clearSessionStorage,
|
||||
hasRight: hasRight,
|
||||
getBrowserTabId: getBrowserTabId,
|
||||
singleDoubleClick: singleDoubleClick,
|
||||
getTableId: getTableId,
|
||||
|
||||
3
js/lib/select2.min.js
vendored
3
js/lib/select2.min.js
vendored
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
@@ -46,7 +46,7 @@ requirejs.config({
|
||||
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart
|
||||
peityInlineChart: 'lib/jquery.peity.min', // v3.3.0 Inline Chart - http://benpickles.github.io/peity/
|
||||
hoverIntent: 'lib/jquery.hoverIntent.min', // v1.10.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
|
||||
select2: 'lib/select2.min', // v4.0.3 Drop Down customization - https://select2.github.io
|
||||
select2: 'lib/select2.min', // v4.0.13 Drop Down customization - https://select2.github.io
|
||||
validator: 'lib/validator.min', // v0.10.1 Validator for Bootstrap 3 - https://github.com/1000hz/bootstrap-validator
|
||||
lazylinepainter: 'lib/jquery.lazylinepainter-1.5.1.min', // v1.5.1 SVG line animation plugin - http://lazylinepainter.info
|
||||
blueImpGallery: 'lib/blueimp-gallery', // v2.21.3 Image Gallery - https://github.com/blueimp/Gallery
|
||||
|
||||
@@ -38,8 +38,6 @@ define([], () => {
|
||||
updateUserData: '/api/map/updateUserData', // ajax URL - main map user data trigger
|
||||
updateUnloadData: '/api/map/updateUnloadData', // post URL - for my sync onUnload
|
||||
// map API
|
||||
saveMap: '/api/map/save', // ajax URL - save/update map
|
||||
deleteMap: '/api/map/delete', // ajax URL - delete map
|
||||
importMap: '/api/map/import', // ajax URL - import map
|
||||
getMapConnectionData: '/api/map/getConnectionData', // ajax URL - get connection data
|
||||
getMapLogData: '/api/map/getLogData', // ajax URL - get logs data
|
||||
@@ -138,6 +136,18 @@ define([], () => {
|
||||
class: 'fa-hat-wizard',
|
||||
label: 'hat wizard',
|
||||
unicode: ''
|
||||
},{
|
||||
class: 'fa-cross',
|
||||
label: 'cross',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-cannabis',
|
||||
label: 'cannabis',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-spider',
|
||||
label: 'spider',
|
||||
unicode: ''
|
||||
}, {
|
||||
class: 'fa-plane',
|
||||
label: 'plane',
|
||||
|
||||
@@ -194,7 +194,7 @@ define([
|
||||
currentUserIsHere &&
|
||||
!userWasHere &&
|
||||
Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')) &&
|
||||
Boolean(Util.getObjVal(Util.getCurrentUserData(), 'character.selectLocation'))
|
||||
Boolean(Util.getCurrentCharacterData('selectLocation'))
|
||||
){
|
||||
Util.triggerMenuAction(map.getContainer(), 'SelectSystem', {systemId: system.data('id'), forceSelect: false});
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ define([
|
||||
let mapElement = $(this);
|
||||
let mapOverlay = MapOverlayUtil.getMapOverlay(mapElement, 'local');
|
||||
let currentMapData = Util.getCurrentMapData(mapId);
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
let currentCharacterLog = Util.getCurrentCharacterData('log');
|
||||
let clearLocal = true;
|
||||
|
||||
if(
|
||||
@@ -2891,7 +2891,7 @@ define([
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogSystemId = Util.getObjVal(Util.getCurrentCharacterLog(), 'system.id') || 0;
|
||||
let characterLogSystemId = Util.getObjVal(Util.getCurrentCharacterData('log'), 'system.id') || 0;
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
|
||||
@@ -186,7 +186,7 @@ define([
|
||||
systemData = options.systemData;
|
||||
}else{
|
||||
// ... check for current active system (characterLog) -----------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
let currentCharacterLog = Util.getCurrentCharacterData('log');
|
||||
if(currentCharacterLog !== false){
|
||||
// set system from 'characterLog' data as pre-selected system
|
||||
systemData = Util.getObjVal(currentCharacterLog, 'system');
|
||||
|
||||
@@ -2005,60 +2005,26 @@ define([
|
||||
*/
|
||||
let checkRight = (right, mapConfig) => {
|
||||
let hasAccess = false;
|
||||
let currentUserData = Util.getCurrentUserData();
|
||||
if(currentUserData){
|
||||
// ...there is an active user
|
||||
let currentCharacterData = Util.getObjVal(currentUserData, 'character');
|
||||
if(currentCharacterData){
|
||||
// ... there is an active character
|
||||
let currentCharacterRole = Util.getObjVal(currentCharacterData, 'role');
|
||||
if(currentCharacterRole){
|
||||
// ... active character has a role assigned
|
||||
let mapType = Util.getObjVal(mapConfig, 'type.name');
|
||||
let accessObjectId = Util.getCurrentUserInfo(mapType + 'Id');
|
||||
|
||||
let mapType = Util.getObjVal(mapConfig, 'type.name');
|
||||
let mapAccess = Util.getObjVal(mapConfig, 'access.' + (mapType === 'private' ? 'character' : mapType)) || [];
|
||||
|
||||
// this is either Ally/Corp or Character Id
|
||||
let accessObjectId = Util.getCurrentUserInfo(mapType + 'Id');
|
||||
|
||||
// check whether character has map access
|
||||
let hasMapAccess = mapAccess.some((accessObj) => {
|
||||
return (accessObj.id === accessObjectId);
|
||||
});
|
||||
|
||||
if(hasMapAccess){
|
||||
// ... this should ALWAYS be be true!
|
||||
switch(mapType){
|
||||
case 'private':
|
||||
hasAccess = true;
|
||||
break;
|
||||
case 'corporation':
|
||||
let objectRights = Util.getObjVal(currentCharacterData, mapType + '.rights') || [];
|
||||
|
||||
let objectRight = objectRights.find((objectRight) => {
|
||||
return objectRight.right.name === right;
|
||||
});
|
||||
|
||||
if(objectRight){
|
||||
// ... Ally/Corp has the right we are looking for assigned with a required role
|
||||
if(
|
||||
currentCharacterRole.name === 'SUPER' ||
|
||||
objectRight.role.name === 'MEMBER' ||
|
||||
objectRight.role.name === currentCharacterRole.name
|
||||
){
|
||||
hasAccess = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'alliance':
|
||||
hasAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check whether character has map access
|
||||
let mapAccess = Util.getObjVal(mapConfig, 'access.' + (mapType === 'private' ? 'character' : mapType)) || [];
|
||||
let hasMapAccess = mapAccess.some(accessObj => accessObj.id === accessObjectId);
|
||||
if(hasMapAccess){
|
||||
// ... this should ALWAYS be be true!
|
||||
switch(mapType){
|
||||
case 'private':
|
||||
hasAccess = true;
|
||||
break;
|
||||
case 'corporation':
|
||||
hasAccess = Util.hasRight(right, mapType);
|
||||
break;
|
||||
case 'alliance':
|
||||
hasAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasAccess;
|
||||
};
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@ define([
|
||||
mapIds: mapId ? [mapId] : [],
|
||||
getMapUserData: Util.getSyncType() === 'webSocket' ? 0 : 1,
|
||||
mapTracking: locationToggle ? locationToggle.checked | 0 : 0, // location tracking
|
||||
systemData: Util.getCurrentSystemData(mapId)
|
||||
systemData: mapId ? Util.getCurrentSystemData(mapId) : []
|
||||
};
|
||||
|
||||
if(newSystemPositions){
|
||||
@@ -540,7 +540,8 @@ define([
|
||||
// clear both main update request trigger timer
|
||||
clearUpdateTimeouts();
|
||||
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = `${status} ${jqXHR.status}`;
|
||||
let firstError = error;
|
||||
let errorData = [];
|
||||
let redirect = false; // redirect user to other page e.g. login
|
||||
let reload = true; // reload current page (default: true)
|
||||
@@ -552,6 +553,7 @@ define([
|
||||
responseObj.error &&
|
||||
responseObj.error.length > 0
|
||||
){
|
||||
firstError = responseObj.error[0].status;
|
||||
errorData = responseObj.error;
|
||||
}
|
||||
|
||||
@@ -569,7 +571,7 @@ define([
|
||||
console.error(' ↪ %s Error response: %o', jqXHR.url, errorData);
|
||||
$(document).trigger('pf:shutdown', {
|
||||
status: jqXHR.status,
|
||||
reason: reason,
|
||||
reason: `${reason}: ${firstError}`,
|
||||
error: errorData,
|
||||
redirect: redirect,
|
||||
reload: reload
|
||||
|
||||
@@ -823,17 +823,17 @@ define([
|
||||
});
|
||||
|
||||
// changes in current userData ----------------------------------------------------------------------------
|
||||
documentElement.on('pf:changedUserData', (e, userData, changes) => {
|
||||
documentElement.on('pf:changedUserData', (e, changes) => {
|
||||
// update menu buttons (en/disable)
|
||||
if(changes.characterId){
|
||||
documentElement.trigger('pf:updateMenuOptions', {
|
||||
menuGroup: 'userOptions',
|
||||
payload: Boolean(Util.getObjVal(userData, 'character.id'))
|
||||
payload: Boolean(Util.getCurrentCharacterData('id'))
|
||||
});
|
||||
}
|
||||
|
||||
// update header
|
||||
updateHeaderUserData(userData, changes).then();
|
||||
updateHeaderUserData(changes).then();
|
||||
});
|
||||
|
||||
// shutdown the program -> show dialog --------------------------------------------------------------------
|
||||
@@ -873,7 +873,7 @@ define([
|
||||
// add error information (if available)
|
||||
if(data.error && data.error.length){
|
||||
for(let error of data.error){
|
||||
options.content.textSmaller.push(error.message);
|
||||
options.content.textSmaller.push(error.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,7 +929,7 @@ define([
|
||||
//modalElement.find('form').filter((i, form) => $(form).data('bs.validator')).validator('destroy');
|
||||
|
||||
// destroy all popovers
|
||||
modalElement.find('.' + Util.config.popoverTriggerClass).popover('destroy');
|
||||
modalElement.destroyPopover(true);
|
||||
|
||||
// destroy all Select2
|
||||
modalElement.find('.' + Util.config.select2Class)
|
||||
@@ -1050,18 +1050,17 @@ define([
|
||||
|
||||
/**
|
||||
* update all header elements with current userData
|
||||
* @param userData
|
||||
* @param changes
|
||||
* @returns {Promise<[any, any, any, any, any, any, any, any, any, any]>}
|
||||
* @returns {Promise<[]>}
|
||||
*/
|
||||
let updateHeaderUserData = (userData, changes) => {
|
||||
let updateHeaderUserData = changes => {
|
||||
let updateTasks = [];
|
||||
|
||||
if(changes.characterLogLocation){
|
||||
updateTasks.push(updateMapTrackingToggle(Boolean(Util.getObjVal(userData, 'character.logLocation'))));
|
||||
updateTasks.push(updateMapTrackingToggle(Boolean(Util.getCurrentCharacterData('logLocation'))));
|
||||
}
|
||||
if(changes.charactersIds){
|
||||
updateTasks.push(updateHeaderCharacterSwitch(userData, changes.characterId));
|
||||
updateTasks.push(updateHeaderCharacterSwitch(changes.characterId));
|
||||
}
|
||||
if(
|
||||
changes.characterSystemId ||
|
||||
@@ -1070,7 +1069,7 @@ define([
|
||||
changes.characterStructureId ||
|
||||
changes.characterLogHistory
|
||||
){
|
||||
updateTasks.push(updateHeaderCharacterLocation(userData, changes.characterShipType));
|
||||
updateTasks.push(updateHeaderCharacterLocation(changes.characterShipType));
|
||||
}
|
||||
|
||||
return Promise.all(updateTasks);
|
||||
@@ -1099,22 +1098,21 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* @param userData
|
||||
* @param changedCharacter
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let updateHeaderCharacterSwitch = (userData, changedCharacter) => {
|
||||
let updateHeaderCharacterSwitch = changedCharacter => {
|
||||
let executor = resolve => {
|
||||
let userInfoElement = $('.' + config.headUserCharacterClass);
|
||||
// toggle element
|
||||
animateHeaderElement(userInfoElement, userInfoElement => {
|
||||
if(changedCharacter){
|
||||
// current character changed
|
||||
userInfoElement.find('span').text(Util.getObjVal(userData, 'character.name'));
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('characters', Util.getObjVal(userData, 'character.id')));
|
||||
userInfoElement.find('span').text(Util.getCurrentCharacterData('name'));
|
||||
userInfoElement.find('img').attr('src', Util.eveImageUrl('characters', Util.getCurrentCharacterData('id')));
|
||||
}
|
||||
// init "character switch" popover
|
||||
userInfoElement.initCharacterSwitchPopover(userData);
|
||||
userInfoElement.initCharacterSwitchPopover();
|
||||
|
||||
resolve({
|
||||
action: 'updateHeaderCharacterSwitch',
|
||||
@@ -1127,28 +1125,26 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userData
|
||||
* @param changedShip
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let updateHeaderCharacterLocation = (userData, changedShip) => {
|
||||
let updateHeaderCharacterLocation = changedShip => {
|
||||
let executor = resolve => {
|
||||
let userLocationElement = $('#' + Util.config.headUserLocationId);
|
||||
let breadcrumbHtml = '';
|
||||
let logData = Util.getObjVal(userData, 'character.log');
|
||||
let logData = Util.getCurrentCharacterData('log');
|
||||
let logDataAll = [];
|
||||
|
||||
if(logData){
|
||||
let shipData = Util.getObjVal(userData, 'character.log.ship');
|
||||
let shipData = Util.getObjVal(logData, 'ship');
|
||||
let shipTypeId = Util.getObjVal(shipData, 'typeId') || 0;
|
||||
let shipTypeName = Util.getObjVal(shipData, 'typeName') || '';
|
||||
|
||||
let stationData = Util.getObjVal(userData, 'character.log.station');
|
||||
let stationData = Util.getObjVal(logData, 'station');
|
||||
let stationId = Util.getObjVal(stationData, 'id') || 0;
|
||||
let stationName = Util.getObjVal(stationData, 'name') || '';
|
||||
|
||||
let structureData = Util.getObjVal(userData, 'character.log.structure');
|
||||
let structureData = Util.getObjVal(logData, 'structure');
|
||||
let structureTypeId = Util.getObjVal(structureData, 'type.id') || 0;
|
||||
let structureTypeName = Util.getObjVal(structureData, 'type.name') || '';
|
||||
let structureId = Util.getObjVal(structureData, 'id') || 0;
|
||||
@@ -1157,7 +1153,7 @@ define([
|
||||
logDataAll.push(logData);
|
||||
|
||||
// check for log history data as well
|
||||
let logHistoryData = Util.getObjVal(userData, 'character.logHistory');
|
||||
let logHistoryData = Util.getCurrentCharacterData('logHistory');
|
||||
if(logHistoryData){
|
||||
// check if there are more history log entries than max visual limit
|
||||
if(logHistoryData.length > config.headMaxLocationHistoryBreadcrumbs){
|
||||
|
||||
@@ -53,8 +53,9 @@ define([
|
||||
captchaImageId: config.captchaImageId,
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
ccpImageServer: Init.url.ccpImageServer,
|
||||
roleLabel: Util.getLabelByRole(Util.getObjVal(Util.getCurrentUserData(), 'character.role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect'))
|
||||
roleLabel: Util.getLabelByRole(Util.getCurrentCharacterData('role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')),
|
||||
hasRightCorporationShare: Util.hasRight('map_share', 'corporation')
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
@@ -193,8 +193,8 @@ define([
|
||||
});
|
||||
});
|
||||
|
||||
mapElement.initTooltips();
|
||||
mapElement.hideLoadingAnimation();
|
||||
mapElement.initTooltips({container: '.modal'});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -219,14 +219,6 @@ define([
|
||||
|
||||
systemsElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
systemTable.on('init.dt', function(){
|
||||
systemsElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = systemsElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
let systemsDataTable = systemTable.DataTable({
|
||||
pageLength: 20,
|
||||
paging: true,
|
||||
@@ -514,6 +506,9 @@ define([
|
||||
}
|
||||
],
|
||||
initComplete: function(settings){
|
||||
systemsElement.hideLoadingAnimation();
|
||||
systemsElement.initTooltips({container: '.modal'});
|
||||
|
||||
Counter.initTableCounter(this, ['updated:name']);
|
||||
}
|
||||
});
|
||||
@@ -542,15 +537,6 @@ define([
|
||||
|
||||
connectionsElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
// table init complete
|
||||
connectionTable.on('init.dt', function(){
|
||||
connectionsElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = connectionsElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
// connections table ------------------------------------------------------------------------------------------
|
||||
let connectionDataTable = connectionTable.dataTable({
|
||||
pageLength: 20,
|
||||
@@ -701,6 +687,9 @@ define([
|
||||
}
|
||||
],
|
||||
initComplete: function(settings){
|
||||
connectionsElement.hideLoadingAnimation();
|
||||
connectionsElement.initTooltips({container: '.modal'});
|
||||
|
||||
Counter.initTableCounter(this, ['updated:name']);
|
||||
}
|
||||
});
|
||||
@@ -721,17 +710,6 @@ define([
|
||||
|
||||
usersElement.showLoadingAnimation(config.loadingOptions);
|
||||
|
||||
// table init complete
|
||||
userTable.on('init.dt', function(){
|
||||
usersElement.hideLoadingAnimation();
|
||||
|
||||
// init table tooltips
|
||||
let tooltipElements = usersElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: usersElement.parent()
|
||||
});
|
||||
});
|
||||
|
||||
// users table ------------------------------------------------------------------------------------------------
|
||||
// prepare users data for dataTables
|
||||
let currentMapUserData = Util.getCurrentMapUserData( mapData.config.id );
|
||||
@@ -941,7 +919,11 @@ define([
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
initComplete: function(settings){
|
||||
usersElement.hideLoadingAnimation();
|
||||
usersElement.initTooltips({container: '.modal'});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -9,8 +9,9 @@ define([
|
||||
'app/render',
|
||||
'bootbox',
|
||||
'app/map/util',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap) => {
|
||||
'app/module_map',
|
||||
'app/map/overlay/util',
|
||||
], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap, MapOverlayUtil) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -99,144 +100,39 @@ define([
|
||||
'text!templates/form/map.html',
|
||||
'mustache'
|
||||
], (templateMapDialog, templateMapForm, Mustache) => {
|
||||
let selectOption = value => () => (val, render) => {
|
||||
if(render(val) === String(value)){
|
||||
return 'selected';
|
||||
}
|
||||
};
|
||||
|
||||
let dialogTitle = 'Map settings';
|
||||
|
||||
// if there are no maps -> hide settings tab
|
||||
let hideSettingsTab = false;
|
||||
let hideEditTab = false;
|
||||
let hideDownloadTab = false;
|
||||
let hideEditTab = mapData === false;
|
||||
let hideSettingsTab = mapData === false;
|
||||
let hideDownloadTab = mapData === false;
|
||||
|
||||
let hasRightMapCreate = true;
|
||||
let hasRightMapUpdate = true;
|
||||
let hasRightMapExport = true;
|
||||
let hasRightMapImport = true;
|
||||
|
||||
if(mapData === false){
|
||||
hideSettingsTab = true;
|
||||
hideEditTab = true;
|
||||
hideDownloadTab = true;
|
||||
}else{
|
||||
hasRightMapUpdate = MapUtil.checkRight('map_update', mapData.config);
|
||||
hasRightMapExport = MapUtil.checkRight('map_export', mapData.config);
|
||||
hasRightMapImport = MapUtil.checkRight('map_import', mapData.config);
|
||||
}
|
||||
let hasRightMapUpdate = MapUtil ? MapUtil.checkRight('map_update', mapData.config) : true;
|
||||
let hasRightMapExport = MapUtil ? MapUtil.checkRight('map_export', mapData.config) : true;
|
||||
let hasRightMapImport = MapUtil ? MapUtil.checkRight('map_import', mapData.config) : true;
|
||||
let hasRightMapShare = MapUtil ? MapUtil.checkRight('map_share', mapData.config) : true;
|
||||
|
||||
// available map "types" for a new or existing map
|
||||
let mapTypes = MapUtil.getMapTypes(true);
|
||||
|
||||
let mapFormData = {
|
||||
select2Class: Util.config.select2Class,
|
||||
scope: MapUtil.getMapScopes(),
|
||||
type: mapTypes,
|
||||
icon: MapUtil.getMapIcons(),
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
formInfoContainerClass: Util.config.formInfoContainerClass
|
||||
};
|
||||
|
||||
// render "new map" tab content -----------------------------------------------------------------------
|
||||
let mapFormDataNew = $.extend({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapCreate,
|
||||
nameInputId: config.newNameInputId,
|
||||
iconSelectId: config.newIconSelectId,
|
||||
scopeSelectId: config.newScopeSelectId,
|
||||
typeSelectId: config.newTypeSelectId
|
||||
});
|
||||
let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew);
|
||||
|
||||
// render "edit map" tab content ----------------------------------------------------------------------
|
||||
let mapFormDataEdit = $.extend({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapUpdate,
|
||||
nameInputId: config.editNameInputId,
|
||||
iconSelectId: config.editIconSelectId,
|
||||
scopeSelectId: config.editScopeSelectId,
|
||||
typeSelectId: config.editTypeSelectId
|
||||
});
|
||||
let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit);
|
||||
contentEditMap = $(contentEditMap);
|
||||
|
||||
// current map access info
|
||||
let accessCharacter = [];
|
||||
let accessCorporation = [];
|
||||
let accessAlliance = [];
|
||||
let deleteExpiredConnections = true;
|
||||
let deleteEolConnections = true;
|
||||
let persistentAliases = true;
|
||||
let persistentSignatures = true;
|
||||
let trackAbyssalJumps = true;
|
||||
|
||||
let logActivity = true;
|
||||
let logHistory = true;
|
||||
|
||||
let slackWebHookURL = '';
|
||||
let slackUsername = '';
|
||||
let slackIcon = '';
|
||||
let slackChannelHistory = '';
|
||||
let slackChannelRally = '';
|
||||
let slackEnabled = false;
|
||||
let slackHistoryEnabled = false;
|
||||
let slackRallyEnabled = false;
|
||||
let slackSectionShow = false;
|
||||
|
||||
let discordUsername = '';
|
||||
let discordWebHookURLRally = '';
|
||||
let discordWebHookURLHistory = '';
|
||||
let discordEnabled = false;
|
||||
let discordRallyEnabled = false;
|
||||
let discordHistoryEnabled = false;
|
||||
let discordSectionShow = false;
|
||||
|
||||
if(mapData !== false){
|
||||
// set current map information
|
||||
contentEditMap.find('input[name="id"]').val( mapData.config.id );
|
||||
contentEditMap.find('select[name="icon"]').val( mapData.config.icon );
|
||||
contentEditMap.find('input[name="name"]').val( mapData.config.name );
|
||||
contentEditMap.find('select[name="scopeId"]').val( mapData.config.scope.id );
|
||||
contentEditMap.find('select[name="typeId"]').val( mapData.config.type.id );
|
||||
|
||||
accessCharacter = mapData.config.access.character;
|
||||
accessCorporation = mapData.config.access.corporation;
|
||||
accessAlliance = mapData.config.access.alliance;
|
||||
|
||||
deleteExpiredConnections = mapData.config.deleteExpiredConnections;
|
||||
deleteEolConnections = mapData.config.deleteEolConnections;
|
||||
persistentAliases = mapData.config.persistentAliases;
|
||||
persistentSignatures = mapData.config.persistentSignatures;
|
||||
trackAbyssalJumps = mapData.config.trackAbyssalJumps;
|
||||
|
||||
logActivity = mapData.config.logging.activity;
|
||||
logHistory = mapData.config.logging.history;
|
||||
|
||||
slackWebHookURL = mapData.config.logging.slackWebHookURL;
|
||||
slackUsername = mapData.config.logging.slackUsername;
|
||||
slackIcon = mapData.config.logging.slackIcon;
|
||||
slackChannelHistory = mapData.config.logging.slackChannelHistory;
|
||||
slackChannelRally = mapData.config.logging.slackChannelRally;
|
||||
slackEnabled = Boolean(Util.getObjVal(Init, 'slack.status'));
|
||||
slackHistoryEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled'));
|
||||
slackRallyEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled'));
|
||||
slackSectionShow = (slackEnabled && slackWebHookURL.length > 0);
|
||||
|
||||
discordUsername = Util.getObjVal(mapData, 'config.logging.discordUsername');
|
||||
discordWebHookURLRally = Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally');
|
||||
discordWebHookURLHistory = Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory');
|
||||
discordEnabled = Boolean(Util.getObjVal(Init, 'discord.status'));
|
||||
discordRallyEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled'));
|
||||
discordHistoryEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled'));
|
||||
discordSectionShow = (discordEnabled && (discordWebHookURLRally.length > 0 || discordWebHookURLHistory.length > 0));
|
||||
|
||||
// remove "#" from Slack channels
|
||||
slackChannelHistory = slackChannelHistory.indexOf('#') === 0 ? slackChannelHistory.substr(1) : slackChannelHistory;
|
||||
slackChannelRally = slackChannelRally.indexOf('#') === 0 ? slackChannelRally.substr(1) : slackChannelRally;
|
||||
}
|
||||
|
||||
// render main dialog ---------------------------------------------------------------------------------
|
||||
let mapDialogData = {
|
||||
id: config.newMapDialogId,
|
||||
mapData: mapData,
|
||||
type: mapTypes,
|
||||
|
||||
hasRightMapUpdate,
|
||||
hasRightMapExport,
|
||||
hasRightMapImport,
|
||||
hasRightMapShare,
|
||||
|
||||
// message container
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
@@ -253,9 +149,9 @@ define([
|
||||
dialogMapSettingsContainerId: config.dialogMapSettingsContainerId,
|
||||
dialogMapDownloadContainerId: config.dialogMapDownloadContainerId,
|
||||
|
||||
hideEditTab: hideEditTab,
|
||||
hideSettingsTab: hideSettingsTab,
|
||||
hideDownloadTab: hideDownloadTab,
|
||||
hideEditTab,
|
||||
hideSettingsTab,
|
||||
hideDownloadTab,
|
||||
|
||||
// settings tab --------------
|
||||
deleteExpiredConnectionsId : config.deleteExpiredConnectionsId,
|
||||
@@ -263,57 +159,59 @@ define([
|
||||
persistentAliasesId : config.persistentAliasesId,
|
||||
persistentSignaturesId : config.persistentSignaturesId,
|
||||
trackAbyssalJumpsId : config.trackAbyssalJumpsId,
|
||||
deleteExpiredConnections: deleteExpiredConnections,
|
||||
deleteEolConnections: deleteEolConnections,
|
||||
persistentAliases: persistentAliases,
|
||||
persistentSignatures: persistentSignatures,
|
||||
trackAbyssalJumps: trackAbyssalJumps,
|
||||
|
||||
logHistoryId: config.logHistoryId,
|
||||
logActivityId: config.logActivityId,
|
||||
logActivity: logActivity,
|
||||
logHistory: logHistory,
|
||||
|
||||
deleteExpiredConnections: true,
|
||||
deleteEolConnections: true,
|
||||
persistentAliases: true,
|
||||
persistentSignatures: true,
|
||||
trackAbyssalJumps: true,
|
||||
logActivity: true,
|
||||
logHistory: true,
|
||||
|
||||
slackWebHookURLId: config.slackWebHookURLId,
|
||||
slackUsernameId: config.slackUsernameId,
|
||||
slackIconId: config.slackIconId,
|
||||
slackChannelHistoryId: config.slackChannelHistoryId,
|
||||
slackChannelRallyId: config.slackChannelRallyId,
|
||||
slackWebHookURL: slackWebHookURL,
|
||||
slackUsername: slackUsername,
|
||||
slackIcon: slackIcon,
|
||||
slackChannelHistory: slackChannelHistory,
|
||||
slackChannelRally: slackChannelRally,
|
||||
slackEnabled: slackEnabled,
|
||||
slackHistoryEnabled: slackHistoryEnabled,
|
||||
slackRallyEnabled: slackRallyEnabled,
|
||||
slackSectionShow: slackSectionShow,
|
||||
|
||||
slackWebHookURL: '',
|
||||
slackUsername: '',
|
||||
slackIcon: '',
|
||||
slackChannelHistory: '',
|
||||
slackChannelRally: '',
|
||||
slackEnabled: false,
|
||||
slackHistoryEnabled: false,
|
||||
slackRallyEnabled: false,
|
||||
slackSectionShow: false,
|
||||
|
||||
discordUsernameId: config.discordUsernameId,
|
||||
discordWebHookURLRallyId: config.discordWebHookURLRallyId,
|
||||
discordWebHookURLHistoryId: config.discordWebHookURLHistoryId,
|
||||
discordUsername: discordUsername,
|
||||
discordWebHookURLRally: discordWebHookURLRally,
|
||||
discordWebHookURLHistory: discordWebHookURLHistory,
|
||||
discordEnabled: discordEnabled,
|
||||
discordRallyEnabled: discordRallyEnabled,
|
||||
discordHistoryEnabled: discordHistoryEnabled,
|
||||
discordSectionShow: discordSectionShow,
|
||||
|
||||
discordUsername: '',
|
||||
discordWebHookURLRally: '',
|
||||
discordWebHookURLHistory: '',
|
||||
discordEnabled: false,
|
||||
discordRallyEnabled: false,
|
||||
discordHistoryEnabled: false,
|
||||
discordSectionShow: false,
|
||||
|
||||
// map access ----------------
|
||||
characterSelectId: config.characterSelectId,
|
||||
corporationSelectId: config.corporationSelectId,
|
||||
allianceSelectId: config.allianceSelectId,
|
||||
|
||||
// map access objects --------
|
||||
accessCharacter: accessCharacter,
|
||||
accessCorporation: accessCorporation,
|
||||
accessAlliance: accessAlliance,
|
||||
|
||||
// access limitations --------
|
||||
maxCharacter: Init.mapTypes.private.defaultConfig.max_shared,
|
||||
maxCorporation: Init.mapTypes.corporation.defaultConfig.max_shared,
|
||||
maxAlliance: Init.mapTypes.alliance.defaultConfig.max_shared,
|
||||
|
||||
accessCharacter: [],
|
||||
accessCorporation: [],
|
||||
accessAlliance: [],
|
||||
|
||||
// download tab --------------
|
||||
dialogMapExportFormId: config.dialogMapExportFormId,
|
||||
dialogMapImportFormId: config.dialogMapImportFormId,
|
||||
@@ -323,25 +221,100 @@ define([
|
||||
fieldImportId: config.fieldImportId,
|
||||
dialogMapImportInfoId: config.dialogMapImportInfoId,
|
||||
|
||||
hasRightMapUpdate: hasRightMapUpdate,
|
||||
hasRightMapExport: hasRightMapExport,
|
||||
hasRightMapImport: hasRightMapImport,
|
||||
|
||||
formatFilename: function(){
|
||||
// format filename from "map name" (initial)
|
||||
return function(mapName, render){
|
||||
let filename = render(mapName);
|
||||
return formatFilename(filename);
|
||||
};
|
||||
}
|
||||
formatFilename: () => (mapName, render) => formatFilename(render(mapName))
|
||||
};
|
||||
|
||||
if(mapData !== false){
|
||||
Object.assign(mapDialogData, {
|
||||
deleteExpiredConnections: mapData.config.deleteExpiredConnections,
|
||||
deleteEolConnections: mapData.config.deleteEolConnections,
|
||||
persistentAliases: mapData.config.persistentAliases,
|
||||
persistentSignatures: mapData.config.persistentSignatures,
|
||||
trackAbyssalJumps: mapData.config.trackAbyssalJumps,
|
||||
logActivity: mapData.config.logging.activity,
|
||||
logHistory: mapData.config.logging.history,
|
||||
|
||||
slackWebHookURL: mapData.config.logging.slackWebHookURL,
|
||||
slackUsername: mapData.config.logging.slackUsername,
|
||||
slackIcon: mapData.config.logging.slackIcon,
|
||||
slackChannelHistory: mapData.config.logging.slackChannelHistory,
|
||||
slackChannelRally: mapData.config.logging.slackChannelRally,
|
||||
slackEnabled: Boolean(Util.getObjVal(Init, 'slack.status')),
|
||||
|
||||
discordUsername: Util.getObjVal(mapData, 'config.logging.discordUsername'),
|
||||
discordWebHookURLRally: Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally'),
|
||||
discordWebHookURLHistory: Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory'),
|
||||
discordEnabled: Boolean(Util.getObjVal(Init, 'discord.status')),
|
||||
|
||||
accessCharacter: mapData.config.access.character,
|
||||
accessCorporation: mapData.config.access.corporation,
|
||||
accessAlliance: mapData.config.access.alliance
|
||||
});
|
||||
|
||||
Object.assign(mapDialogData, {
|
||||
// remove "#" from Slack channels
|
||||
slackChannelHistory: mapDialogData.slackChannelHistory.indexOf('#') === 0 ? mapDialogData.slackChannelHistory.substr(1) : mapDialogData.slackChannelHistory,
|
||||
slackChannelRally: mapDialogData.slackChannelRally.indexOf('#') === 0 ? mapDialogData.slackChannelRally.substr(1) : mapDialogData.slackChannelRally,
|
||||
|
||||
slackHistoryEnabled: mapDialogData.slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled')),
|
||||
slackRallyEnabled: mapDialogData.slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled')),
|
||||
slackSectionShow: (mapDialogData.slackEnabled && mapDialogData.slackWebHookURL.length > 0),
|
||||
|
||||
discordRallyEnabled: mapDialogData.discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled')),
|
||||
discordHistoryEnabled: mapDialogData.discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled')),
|
||||
discordSectionShow: (mapDialogData.discordEnabled && (mapDialogData.discordWebHookURLRally.length > 0 || mapDialogData.discordWebHookURLHistory.length > 0)),
|
||||
});
|
||||
}
|
||||
|
||||
let contentDialog = Mustache.render(templateMapDialog, mapDialogData);
|
||||
contentDialog = $(contentDialog);
|
||||
|
||||
// set tab content
|
||||
// "new map" + "edit map" tab base --------------------------------------------------------------------
|
||||
let mapFormData = {
|
||||
select2Class: Util.config.select2Class,
|
||||
scope: MapUtil.getMapScopes(),
|
||||
type: mapTypes,
|
||||
icon: MapUtil.getMapIcons(),
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
formInfoContainerClass: Util.config.formInfoContainerClass
|
||||
};
|
||||
|
||||
// render "new map" tab content -----------------------------------------------------------------------
|
||||
let mapFormDataNew = Object.assign({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapCreate,
|
||||
nameInputId: config.newNameInputId,
|
||||
iconSelectId: config.newIconSelectId,
|
||||
scopeSelectId: config.newScopeSelectId,
|
||||
typeSelectId: config.newTypeSelectId,
|
||||
|
||||
mapId: 0,
|
||||
mapIcon: undefined,
|
||||
mapName: undefined,
|
||||
mapScopeId: undefined,
|
||||
mapTypeId: undefined
|
||||
});
|
||||
let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew);
|
||||
$('#' + config.dialogMapNewContainerId, contentDialog).html(contentNewMap);
|
||||
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
|
||||
|
||||
// render "edit map" tab content ----------------------------------------------------------------------
|
||||
if(!hideEditTab){
|
||||
let mapFormDataEdit = Object.assign({}, mapFormData, {
|
||||
hasRightMapForm: hasRightMapUpdate,
|
||||
nameInputId: config.editNameInputId,
|
||||
iconSelectId: config.editIconSelectId,
|
||||
scopeSelectId: config.editScopeSelectId,
|
||||
typeSelectId: config.editTypeSelectId,
|
||||
|
||||
mapId: mapData.config.id,
|
||||
mapIcon: selectOption(mapData.config.icon),
|
||||
mapName: mapData.config.name,
|
||||
mapScopeId: selectOption(mapData.config.scope.id),
|
||||
mapTypeId: selectOption(mapData.config.type.id)
|
||||
});
|
||||
let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit);
|
||||
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
|
||||
}
|
||||
|
||||
let mapInfoDialog = bootbox.dialog({
|
||||
title: dialogTitle,
|
||||
@@ -355,7 +328,6 @@ define([
|
||||
label: '<i class="fas fa-check fa-fw"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function(){
|
||||
|
||||
// get the current active form
|
||||
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
|
||||
|
||||
@@ -375,9 +347,7 @@ define([
|
||||
});
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === true){
|
||||
if(form.isValidForm()){
|
||||
// lock dialog
|
||||
let dialogContent = mapInfoDialog.find('.modal-content');
|
||||
dialogContent.showLoadingAnimation();
|
||||
@@ -386,68 +356,36 @@ define([
|
||||
let formData = form.getFormValues();
|
||||
|
||||
// add value prefixes (Slack channels)
|
||||
let tmpVal;
|
||||
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelHistory')) === 'string' && tmpVal.length){
|
||||
formData.slackChannelHistory = '#' + tmpVal;
|
||||
}
|
||||
if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelRally')) === 'string' && tmpVal.length){
|
||||
formData.slackChannelRally = '#' + tmpVal;
|
||||
}
|
||||
Object.keys(formData).map((key, index) => {
|
||||
if(['slackChannelHistory', 'slackChannelRally'].includes(key))
|
||||
formData[key] = (formData[key].length ? '#' : '') + formData[key];
|
||||
});
|
||||
|
||||
// checkbox fix -> settings tab
|
||||
if( form.find('#' + config.deleteExpiredConnectionsId).length ){
|
||||
formData.deleteExpiredConnections = formData.hasOwnProperty('deleteExpiredConnections') ? parseInt( formData.deleteExpiredConnections ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.deleteEolConnectionsId).length ){
|
||||
formData.deleteEolConnections = formData.hasOwnProperty('deleteEolConnections') ? parseInt( formData.deleteEolConnections ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.persistentAliasesId).length ){
|
||||
formData.persistentAliases = formData.hasOwnProperty('persistentAliases') ? parseInt( formData.persistentAliases ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.persistentSignaturesId).length ){
|
||||
formData.persistentSignatures = formData.hasOwnProperty('persistentSignatures') ? parseInt( formData.persistentSignatures ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.trackAbyssalJumpsId).length ){
|
||||
formData.trackAbyssalJumps = formData.hasOwnProperty('trackAbyssalJumps') ? parseInt( formData.trackAbyssalJumps ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.logHistoryId).length ){
|
||||
formData.logHistory = formData.hasOwnProperty('logHistory') ? parseInt( formData.logHistory ) : 0;
|
||||
}
|
||||
if( form.find('#' + config.logActivityId).length ){
|
||||
formData.logActivity = formData.hasOwnProperty('logActivity') ? parseInt( formData.logActivity ) : 0;
|
||||
}
|
||||
MapOverlayUtil.getMapOverlay($(mapData.map.getContainer()), 'timer').startMapUpdateCounter();
|
||||
|
||||
let requestData = {formData: formData};
|
||||
let method = formData.id ? 'PATCH' : 'PUT';
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveMap,
|
||||
data: requestData,
|
||||
dataType: 'json'
|
||||
}).done(function(responseData){
|
||||
if(responseData.error.length){
|
||||
form.showFormMessage(responseData.error);
|
||||
}else{
|
||||
// success
|
||||
Util.showNotify({title: dialogTitle, text: 'Map: ' + responseData.mapData.mapData.name, type: 'success'});
|
||||
Util.request(method, 'map', formData.id, formData, {
|
||||
formElement: form // for error form messages
|
||||
}, context => {
|
||||
// always do
|
||||
dialogContent.hideLoadingAnimation();
|
||||
}).then(
|
||||
payload => {
|
||||
let mapData = Util.getObjVal(payload, 'data.mapData');
|
||||
Util.showNotify({title: dialogTitle, text: `Map: ${Util.getObjVal(mapData, 'name')}`, type: 'success'});
|
||||
|
||||
// update map-tab Element
|
||||
let tabLinkEls = Util.getMapTabLinkElements(Util.getMapModule()[0], responseData.mapData.mapData.id);
|
||||
let tabLinkEls = Util.getMapTabLinkElements(Util.getMapModule()[0], Util.getObjVal(mapData, 'id'));
|
||||
if(tabLinkEls.length === 1){
|
||||
ModuleMap.updateTabData(tabLinkEls[0], responseData.mapData.mapData);
|
||||
ModuleMap.updateTabData(tabLinkEls[0], mapData);
|
||||
}
|
||||
|
||||
$(mapInfoDialog).modal('hide');
|
||||
Util.triggerMenuAction(document, 'Close');
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveMap', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
|
||||
}).always(function(){
|
||||
dialogContent.hideLoadingAnimation();
|
||||
});
|
||||
},
|
||||
Util.handleAjaxErrorResponse
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -487,11 +425,11 @@ define([
|
||||
// get current active form(tab)
|
||||
let form = $('#' + config.newMapDialogId).find('form').filter(':visible');
|
||||
|
||||
form.showFormMessage([{type: 'info', message: 'Creating new maps or change settings may take a few seconds'}]);
|
||||
form.showFormMessage([{type: 'info', text: 'Creating new maps or change settings may take a few seconds'}]);
|
||||
|
||||
if(mapData === false){
|
||||
// no map data found (probably new user
|
||||
form.showFormMessage([{type: 'warning', message: 'No maps found. Create a new map before you can start'}]);
|
||||
form.showFormMessage([{type: 'warning', text: 'No maps found. Create a new map before you can start'}]);
|
||||
}
|
||||
|
||||
// init "download tab" ============================================================================
|
||||
@@ -573,7 +511,7 @@ define([
|
||||
importData.mapData.push( JSON.parse( readEvent.target.result ) );
|
||||
}catch(error){
|
||||
filesCountFail++;
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'File can not be parsed'}]);
|
||||
importFormElement.showFormMessage([{type: 'error', text: 'File can not be parsed'}]);
|
||||
}
|
||||
|
||||
// start import when all files are parsed
|
||||
@@ -640,7 +578,7 @@ define([
|
||||
}
|
||||
});
|
||||
}else{
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'The File APIs are not fully supported in this browser.'}]);
|
||||
importFormElement.showFormMessage([{type: 'error', text: 'The File APIs are not fully supported in this browser.'}]);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -789,39 +727,32 @@ define([
|
||||
* @param mapData
|
||||
*/
|
||||
$.fn.showDeleteMapDialog = function(mapData){
|
||||
let mapName = mapData.config.name;
|
||||
let mapNameStr = '<span class="txt-color txt-color-danger">' + mapName + '</span>';
|
||||
let mapId = Util.getObjVal(mapData, 'config.id');
|
||||
let mapName = Util.getObjVal(mapData, 'config.name');
|
||||
if(!mapId) return;
|
||||
|
||||
let mapNameStr = `<span class="txt-color txt-color-danger">${mapName}</span>`;
|
||||
|
||||
let mapDeleteDialog = bootbox.confirm({
|
||||
message: 'Delete map "' + mapNameStr + '"?',
|
||||
message: `Delete map "${mapNameStr}"?`,
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: '<i class="fas fa-trash fa-fw"></i> delete map',
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result){
|
||||
callback: result => {
|
||||
if(result){
|
||||
// lock dialog
|
||||
let dialogContent = mapDeleteDialog.find('.modal-content');
|
||||
dialogContent.showLoadingAnimation();
|
||||
|
||||
let data = {mapData: mapData.config};
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.deleteMap,
|
||||
data: data,
|
||||
dataType: 'json'
|
||||
}).done(function(data){
|
||||
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': deleteMap', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
}).always(function(){
|
||||
$(mapDeleteDialog).modal('hide');
|
||||
});
|
||||
Util.request('DELETE', 'map', mapId, {}, {}).then(
|
||||
payload => {
|
||||
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
|
||||
},
|
||||
Util.handleAjaxErrorResponse
|
||||
).finally(() => mapDeleteDialog.modal('hide'));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -830,5 +761,4 @@ define([
|
||||
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
@@ -632,7 +632,7 @@ define([
|
||||
// get current ship data ----------------------------------------------------------
|
||||
massShipCell.parent().toggle(showShip);
|
||||
if(showShip){
|
||||
shipData = Util.getObjVal(Util.getCurrentCharacterLog(), 'ship');
|
||||
shipData = Util.getObjVal(Util.getCurrentCharacterData('log'), 'ship');
|
||||
if(shipData){
|
||||
if(shipData.mass){
|
||||
massShip = parseInt(shipData.mass);
|
||||
|
||||
@@ -807,13 +807,13 @@ define([
|
||||
// -> add a modal button for pre-fill modal with it
|
||||
// -> systemId must match systemId from current character log
|
||||
let currentUserData = Util.getCurrentUserData();
|
||||
let characterStructureId = Util.getCurrentCharacterData('log.structure.id') || 0;
|
||||
let characterStructureName = Util.getCurrentCharacterData('log.structure.name') || '';
|
||||
let characterStructureTypeId = Util.getCurrentCharacterData('log.structure.type.id') || 0;
|
||||
let characterStructureTypeName = Util.getCurrentCharacterData('log.structure.type.name') || '';
|
||||
let isCurrentLocation = false;
|
||||
let characterStructureId = Util.getObjVal(currentUserData, 'character.log.structure.id') || 0;
|
||||
let characterStructureName = Util.getObjVal(currentUserData, 'character.log.structure.name') || '';
|
||||
let characterStructureTypeId = Util.getObjVal(currentUserData, 'character.log.structure.type.id') || 0;
|
||||
let characterStructureTypeName = Util.getObjVal(currentUserData, 'character.log.structure.type.name') || '';
|
||||
|
||||
if(this._systemData.id === Util.getObjVal(currentUserData, 'character.log.system.id')){
|
||||
if(this._systemData.id === Util.getCurrentCharacterData('log.system.id')){
|
||||
isCurrentLocation = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -732,7 +732,7 @@ define([
|
||||
let systemSecClass = this._config.systemSecurityClassPrefix + tempSystemSec.replace('.', '-');
|
||||
|
||||
// check for wormhole
|
||||
let icon = 'fas fa-square';
|
||||
let icon = 'fas fa-square-full';
|
||||
if(isWormholeSystemName(systemName)){
|
||||
icon = 'fas fa-dot-circle';
|
||||
}
|
||||
|
||||
@@ -1243,7 +1243,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
enrichParsedSignatureData(signatureData){
|
||||
let characterData = Util.getObjVal(Util.getCurrentUserData(), 'character');
|
||||
let characterData = Util.getCurrentCharacter();
|
||||
let timestamp = Math.floor((new Date()).getTime() / 1000);
|
||||
|
||||
for(let i = 0; i < signatureData.length; i++){
|
||||
|
||||
@@ -259,30 +259,31 @@ define([
|
||||
* @param errors
|
||||
*/
|
||||
$.fn.showFormMessage = function(errors){
|
||||
|
||||
let formElement = $(this);
|
||||
|
||||
let errorMessage = [];
|
||||
let warningMessage = [];
|
||||
let infoMessage = [];
|
||||
for(let i = 0; i < errors.length; i++){
|
||||
if(errors[i].type === 'error'){
|
||||
errorMessage.push( errors[i].message );
|
||||
|
||||
for (let error of errors) {
|
||||
let message = `${error.text}`;
|
||||
if(error.type === 'error'){
|
||||
message = `${error.status} - ${message}`;
|
||||
errorMessage.push(message);
|
||||
|
||||
// mark form field as invalid in case of a validation error
|
||||
if(
|
||||
errors[i].field &&
|
||||
errors[i].field.length > 0
|
||||
error.field &&
|
||||
error.field.length > 0
|
||||
){
|
||||
let formField = formElement.find('[name="' + errors[i].field + '"]');
|
||||
let formField = formElement.find('[name="' + error.field + '"]');
|
||||
let formGroup = formField.parents('.form-group').removeClass('has-success').addClass('has-error');
|
||||
let formHelp = formGroup.find('.help-block').text(errors[i].message);
|
||||
let formHelp = formGroup.find('.help-block').text(error.text);
|
||||
}
|
||||
|
||||
}else if(errors[i].type === 'warning'){
|
||||
warningMessage.push( errors[i].message );
|
||||
}else if(errors[i].type === 'info'){
|
||||
infoMessage.push( errors[i].message );
|
||||
}else if(error.type === 'warning'){
|
||||
warningMessage.push(message);
|
||||
}else if(error.type === 'info'){
|
||||
infoMessage.push(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,10 +596,10 @@ define([
|
||||
|
||||
/**
|
||||
* add character switch popover
|
||||
* @param userData
|
||||
*/
|
||||
$.fn.initCharacterSwitchPopover = function(userData){
|
||||
$.fn.initCharacterSwitchPopover = function(){
|
||||
let elements = $(this);
|
||||
let userData = getCurrentUserData();
|
||||
let eventNamespace = 'hideCharacterPopup';
|
||||
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function(template, Mustache){
|
||||
@@ -1820,14 +1821,16 @@ define([
|
||||
|
||||
// check if userData is valid
|
||||
if(userData && userData.character && userData.characters){
|
||||
// check new vs. old userData for changes
|
||||
let changes = compareUserData(getCurrentUserData(), userData);
|
||||
// check if there is any change
|
||||
if(Object.values(changes).some(val => val)){
|
||||
$(document).trigger('pf:changedUserData', [userData, changes]);
|
||||
}
|
||||
|
||||
Init.currentUserData = userData;
|
||||
isSet = true;
|
||||
|
||||
// check if there is any change
|
||||
if(Object.values(changes).some(val => val)){
|
||||
$(document).trigger('pf:changedUserData', [changes]);
|
||||
}
|
||||
}else{
|
||||
console.error('Could not set userData %o. Missing or malformed obj', userData);
|
||||
}
|
||||
@@ -1836,28 +1839,71 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* get currentUserData from "global" variable
|
||||
* get currentUserData from "global" var
|
||||
* @returns {*}
|
||||
*/
|
||||
let getCurrentUserData = () => {
|
||||
return Init.currentUserData;
|
||||
};
|
||||
|
||||
/**
|
||||
* get currentCharacterData
|
||||
* @see getCurrentUserData
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
let getCurrentCharacter = () => getObjVal(getCurrentUserData(), 'character') || false;
|
||||
|
||||
/**
|
||||
* get data from currentCharacterData (e.g. id)
|
||||
* @see getCurrentCharacter
|
||||
* @param key
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
let getCurrentCharacterData = key => getObjVal(getCurrentCharacter(), key) || false;
|
||||
|
||||
/**
|
||||
* get either active characterID or characterId from initial page load
|
||||
* @returns {number}
|
||||
*/
|
||||
let getCurrentCharacterId = () => {
|
||||
let currentCharacterId = parseInt(getObjVal(getCurrentUserData(), 'character.id')) || 0;
|
||||
|
||||
let currentCharacterId = parseInt(getCurrentCharacterData('id')) || 0;
|
||||
if(!currentCharacterId){
|
||||
// no active character... -> get default characterId from initial page load
|
||||
currentCharacterId = parseInt(document.body.getAttribute('data-character-id'));
|
||||
}
|
||||
|
||||
return currentCharacterId;
|
||||
};
|
||||
|
||||
/**
|
||||
* get information for the current mail user
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
if(currentUserData){
|
||||
// user data is set -> user data will be set AFTER the main init request!
|
||||
let characterData = currentUserData.character;
|
||||
if(characterData){
|
||||
if(option === 'privateId'){
|
||||
userInfo = characterData.id;
|
||||
}
|
||||
|
||||
if(option === 'allianceId' && characterData.alliance){
|
||||
userInfo = characterData.alliance.id;
|
||||
}
|
||||
|
||||
if(option === 'corporationId' && characterData.corporation){
|
||||
userInfo = characterData.corporation.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* compares two userData objects for changes that are relevant
|
||||
* @param oldUserData
|
||||
@@ -1886,6 +1932,29 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* checks if currentCharacter has a role that matches a specific right
|
||||
* @param right
|
||||
* @param objKey
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let hasRight = (right, objKey) => {
|
||||
let hasRight = false;
|
||||
let objectRights = getCurrentCharacterData(`${objKey}.rights`) || [];
|
||||
let objectRight = objectRights.find(objectRight => objectRight.right.name === right);
|
||||
if(objectRight){
|
||||
let characterRole = getCurrentCharacterData('role');
|
||||
if(
|
||||
characterRole.name === 'SUPER' ||
|
||||
objectRight.role.name === 'MEMBER' ||
|
||||
objectRight.role.name === characterRole.name
|
||||
){
|
||||
hasRight = true;
|
||||
}
|
||||
}
|
||||
return hasRight;
|
||||
};
|
||||
|
||||
/**
|
||||
* get a unique ID for each tab
|
||||
* -> store ID in session storage
|
||||
@@ -2021,31 +2090,36 @@ define([
|
||||
* global ajax error handler -> handles .fail() requests
|
||||
* @param payload
|
||||
*/
|
||||
let handleAjaxErrorResponse = (payload) => {
|
||||
let handleAjaxErrorResponse = payload => {
|
||||
// handle only request errors
|
||||
if(payload.action === 'request'){
|
||||
let jqXHR = payload.data.jqXHR;
|
||||
let reason = '';
|
||||
|
||||
if(jqXHR.responseJSON){
|
||||
// ... valid JSON response
|
||||
let response = jqXHR.responseJSON;
|
||||
|
||||
if(response.error && response.error.length > 0){
|
||||
// build error notification reason from errors
|
||||
reason = response.error.map(error => error.message ? error.message : error.status).join('\n');
|
||||
|
||||
// check if errors might belong to a HTML form -> check "context"
|
||||
if(payload.context.formElement){
|
||||
// show form messages e.g. validation errors
|
||||
payload.context.formElement.showFormMessage(response.error);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
reason = 'Invalid JSON response';
|
||||
}
|
||||
showNotify({title: jqXHR.status + ': ' + payload.name, text: reason, type: 'error'});
|
||||
if(payload.action !== 'request'){
|
||||
console.error('Unhandled HTTP response error. Invalid payload %o', payload);
|
||||
return;
|
||||
}
|
||||
|
||||
let jqXHR = payload.data.jqXHR;
|
||||
let title = `${jqXHR.status}: ${jqXHR.statusText} - ${payload.name}`;
|
||||
let reason = '';
|
||||
|
||||
if(jqXHR.responseJSON){
|
||||
// ... valid JSON response
|
||||
let response = jqXHR.responseJSON;
|
||||
|
||||
if(response.error && response.error.length > 0){
|
||||
// build error notification reason from errors
|
||||
reason = response.error.map(error => error.text || error.status).join('\n');
|
||||
|
||||
// check if errors might belong to a HTML form -> check "context"
|
||||
if(payload.context.formElement){
|
||||
// show form messages e.g. validation errors
|
||||
payload.context.formElement.showFormMessage(response.error);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
reason = 'Invalid JSON response';
|
||||
}
|
||||
|
||||
showNotify({title: title, text: reason, type: 'error'});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2822,43 +2896,6 @@ define([
|
||||
Init.currentMapData = Init.currentMapData.filter(mapData => mapData.config.id !== mapId);
|
||||
};
|
||||
|
||||
/**
|
||||
* get the current log data for the current user character
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentCharacterLog = () => getObjVal(getCurrentUserData(), 'character.log') || false;
|
||||
|
||||
/**
|
||||
* get information for the current mail user
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
if(currentUserData){
|
||||
// user data is set -> user data will be set AFTER the main init request!
|
||||
let characterData = currentUserData.character;
|
||||
if(characterData){
|
||||
if(option === 'privateId'){
|
||||
userInfo = characterData.id;
|
||||
}
|
||||
|
||||
if(option === 'allianceId' && characterData.alliance){
|
||||
userInfo = characterData.alliance.id;
|
||||
}
|
||||
|
||||
if(option === 'corporationId' && characterData.corporation){
|
||||
userInfo = characterData.corporation.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* get "nearBy" systemData based on a jump radius around a currentSystem
|
||||
* @param currentSystemData
|
||||
@@ -3646,13 +3683,14 @@ define([
|
||||
deleteCurrentMapData: deleteCurrentMapData,
|
||||
setCurrentUserData: setCurrentUserData,
|
||||
getCurrentUserData: getCurrentUserData,
|
||||
getCurrentCharacter: getCurrentCharacter,
|
||||
getCurrentCharacterData: getCurrentCharacterData,
|
||||
getCurrentCharacterId: getCurrentCharacterId,
|
||||
setCurrentSystemData: setCurrentSystemData,
|
||||
getCurrentSystemData: getCurrentSystemData,
|
||||
deleteCurrentSystemData:deleteCurrentSystemData,
|
||||
getCurrentLocationData: getCurrentLocationData,
|
||||
getCurrentUserInfo: getCurrentUserInfo,
|
||||
getCurrentCharacterLog: getCurrentCharacterLog,
|
||||
findInViewport: findInViewport,
|
||||
initScrollSpy: initScrollSpy,
|
||||
getConfirmationTemplate: getConfirmationTemplate,
|
||||
@@ -3674,6 +3712,7 @@ define([
|
||||
getLocalStore: getLocalStore,
|
||||
getResizeManager: getResizeManager,
|
||||
clearSessionStorage: clearSessionStorage,
|
||||
hasRight: hasRight,
|
||||
getBrowserTabId: getBrowserTabId,
|
||||
singleDoubleClick: singleDoubleClick,
|
||||
getTableId: getTableId,
|
||||
|
||||
3
public/js/v2.0.0/lib/select2.min.js
vendored
3
public/js/v2.0.0/lib/select2.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -36,13 +36,16 @@
|
||||
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabNew}}in active{{/openTabNew}}" id="{{dialogMapNewContainerId}}"></div>
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabEdit}}in active{{/openTabEdit}}" id="{{dialogMapEditContainerId}}"></div>
|
||||
|
||||
{{^hideEditTab}}
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabEdit}}in active{{/openTabEdit}}" id="{{dialogMapEditContainerId}}"></div>
|
||||
{{/hideEditTab}}
|
||||
|
||||
{{^hideSettingsTab}}
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabSettings}}in active{{/openTabSettings}}" id="{{dialogMapSettingsContainerId}}">
|
||||
{{#hasRightMapUpdate}}
|
||||
<form role="form" class="form-horizontal">
|
||||
|
||||
<form role="form" class="form-horizontal">
|
||||
{{#hasRightMapUpdate}}
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-8">
|
||||
<h4 class="pf-dynamic-area">Map options</h4>
|
||||
@@ -201,9 +204,9 @@
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="Send new 'Rally point' notifications to a Slack channel"></i>
|
||||
</label>
|
||||
<div class="col-sm-6 col-md-8">
|
||||
<div class="input-icon-left" {{^slackRallyEnabled}}title="Globally disabled for this map type"{{/slackRallyEnabled}}>
|
||||
<div class="input-icon-left" {{^slackRallyEnabled}}title="Globally disabled for this map type" {{/slackRallyEnabled}}>
|
||||
<i class="fas fa-hashtag"></i>
|
||||
<input name="slackChannelRally" type="text" class="form-control" id="{{slackChannelRallyId}}" value="{{slackChannelRally}}" placeholder="map_rally" pattern="^[_\-A-z0-9]{1,}$" data-error="Allowed chars (A-z, 0-9, _, -)" {{^slackRallyEnabled}}disabled{{/slackRallyEnabled}}>
|
||||
<input name="slackChannelRally" type="text" class="form-control" id="{{slackChannelRallyId}}" value="{{slackChannelRally}}" placeholder="map_rally" pattern="^[_\-A-z0-9]{1,}$" data-error="Allowed chars (A-z, 0-9, _, -)" {{^slackRallyEnabled}}disabled{{/slackRallyEnabled}} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="note help-block with-errors"></div>
|
||||
@@ -303,9 +306,17 @@
|
||||
{{/discordEnabled}}
|
||||
|
||||
</div>
|
||||
{{/hasRightMapUpdate}}
|
||||
{{^hasRightMapUpdate}}
|
||||
<div class="alert alert-info">
|
||||
<span class="txt-color txt-color-info">Restricted</span>
|
||||
<small>You don´t have the required roles.</small>
|
||||
</div>
|
||||
{{/hasRightMapUpdate}}
|
||||
|
||||
<h4 class="pf-dynamic-area">Share settings</h4>
|
||||
|
||||
{{#hasRightMapShare}}
|
||||
<div class="row">
|
||||
<div class="col-sm-11">
|
||||
<blockquote>
|
||||
@@ -313,8 +324,7 @@
|
||||
Use this feature with caution! - Shared map entities have full map access.
|
||||
They even can take over control by removing other entities from this list.
|
||||
</p>
|
||||
<small>Reduce this risk by creating a new map for joined OPs.
|
||||
</small>
|
||||
<small>Reduce this risk by creating a new map for joined OPs.</small>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
@@ -385,15 +395,16 @@
|
||||
</div>
|
||||
{{/accessAlliance.length}}
|
||||
|
||||
<input type="hidden" name="id" value="{{ mapData.config.id }}" />
|
||||
</form>
|
||||
{{/hasRightMapUpdate}}
|
||||
{{^hasRightMapUpdate}}
|
||||
<div class="alert alert-info">
|
||||
<span class="txt-color txt-color-info">Restricted</span>
|
||||
<small>You don´t have the required roles.</small>
|
||||
</div>
|
||||
{{/hasRightMapUpdate}}
|
||||
{{/hasRightMapShare}}
|
||||
{{^hasRightMapShare}}
|
||||
<div class="alert alert-info">
|
||||
<span class="txt-color txt-color-info">Restricted</span>
|
||||
<small>You don´t have the required roles.</small>
|
||||
</div>
|
||||
{{/hasRightMapShare}}
|
||||
|
||||
<input type="hidden" name="id" value="{{ mapData.config.id }}" />
|
||||
</form>
|
||||
</div>
|
||||
{{/hideSettingsTab}}
|
||||
|
||||
|
||||
@@ -184,18 +184,25 @@
|
||||
</div>
|
||||
|
||||
{{#corporation}}
|
||||
<h4 class="pf-dynamic-area"><img src="{{ccpImageServer}}/Corporation/{{id}}_64.png"> Corporation maps "<em class="pf-map-type-corporation">{{name}}</em>"</h4>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-9">
|
||||
<label class="control-label" for="corporationSharing">
|
||||
<input id="corporationSharing" type="checkbox" name="corporationSharing" data-toggle="toggle" value="1" {{#shared}}checked{{/shared}}>
|
||||
map invite for corporation maps
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-sm-3"></div>
|
||||
</div>
|
||||
<h4 class="pf-dynamic-area"><img src="{{ccpImageServer}}/Corporation/{{id}}_64.png"> Corporation maps "<em class="pf-map-type-corporation">{{name}}</em>"</h4>
|
||||
|
||||
{{#hasRightCorporationShareUpdate}}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-9">
|
||||
<label class="control-label" for="corporationSharing">
|
||||
<input id="corporationSharing" type="checkbox" name="corporationSharing" data-toggle="toggle" value="1" {{#shared}}checked{{/shared}}>
|
||||
map invite for corporation maps
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-sm-3"></div>
|
||||
</div>
|
||||
{{/hasRightCorporationShareUpdate}}
|
||||
{{^hasRightCorporationShareUpdate}}
|
||||
<div class="alert alert-info">
|
||||
<span class="txt-color txt-color-info">Restricted</span>
|
||||
<small>You don´t have the required roles.</small>
|
||||
</div>
|
||||
{{/hasRightCorporationShareUpdate}}
|
||||
{{/corporation}}
|
||||
|
||||
{{#alliance}}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="col-sm-8">
|
||||
<select name="icon" id="{{iconSelectId}}" class="form-control pf-form-icon-field {{select2Class}}">
|
||||
{{#icon}}
|
||||
<option value="{{class}}" >{{{unicode}}}</option>
|
||||
<option value="{{class}}" {{#mapIcon}}{{class}}{{/mapIcon}}>{{{unicode}}}</option>
|
||||
{{/icon}}
|
||||
</select>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="form-group">
|
||||
<label for="{{nameInputId}}" class="col-sm-2 control-label">Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" class="form-control" id="{{nameInputId}}" value="" placeholder="Map name" data-error="Name required" data-minlength="3" data-minlength-error="Min. of 3 characters" required>
|
||||
<input name="name" type="text" class="form-control" id="{{nameInputId}}" value="{{mapName}}" placeholder="Map name" data-error="Name required" data-minlength="3" data-minlength-error="Min. of 3 characters" required>
|
||||
<span class="note help-block with-errors">Choose a meaningful name</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,7 +32,7 @@
|
||||
<div class="col-sm-10">
|
||||
<select name="scopeId" id="{{scopeSelectId}}" class="form-control {{select2Class}}">
|
||||
{{#scope}}
|
||||
<option value="{{id}}">{{label}}</option>
|
||||
<option value="{{id}}" {{#mapScopeId}}{{id}}{{/mapScopeId}}>{{label}}</option>
|
||||
{{/scope}}
|
||||
</select>
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@
|
||||
<div class="col-sm-10">
|
||||
<select name="typeId" id="{{typeSelectId}}" class="form-control {{select2Class}}">
|
||||
{{#type}}
|
||||
<option value="{{id}}">{{label}}</option>
|
||||
<option value="{{id}}" {{#mapTypeId}}{{id}}{{/mapTypeId}}>{{label}}</option>
|
||||
{{/type}}
|
||||
</select>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="id" value="0" />
|
||||
<input type="hidden" name="id" value="{{mapId}}" />
|
||||
|
||||
|
||||
<div class="{{formInfoContainerClass}} alert alert-info" style="display: none;">
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
<div class="alert {{@notificationTypeClass}}">
|
||||
<span class="txt-color {{@notificationColorClass}}">{{ @notification->title }}</span>
|
||||
<check if="{{ @notification->message }}">
|
||||
<small>{{ @notification->message }}</small>
|
||||
<check if="{{ @notification->text }}">
|
||||
<small>{{ @notification->text }}</small>
|
||||
</check>
|
||||
</div>
|
||||
</check>
|
||||
@@ -11,8 +11,8 @@
|
||||
Use your browsers Back button to navigate to the page you have previously come
|
||||
<a href="{{ @errorData->redirectUrl }}">from</a>.<br>
|
||||
|
||||
<check if="{{ @errorData->message }}">
|
||||
Message: {{ @errorData->message }}
|
||||
<check if="{{ @errorData->text }}">
|
||||
Message: {{ @errorData->text }}
|
||||
</check>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
Status: '{{ @errorData->status }}'<br>
|
||||
|
||||
<check if="{{ @errorData->message }}">
|
||||
Message: {{ @errorData->message }}
|
||||
<check if="{{ @errorData->text }}">
|
||||
Message: {{ @errorData->text }}
|
||||
</check>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="alert alert-danger">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><i class="fas fa-times"></i></button>
|
||||
<span class="txt-color txt-color-danger">({{ @errorData->code }}) {{ @errorData->status }}</span>
|
||||
<small> {{ @errorData->message }}</small>
|
||||
<small> {{ @errorData->text }}</small>
|
||||
</div>
|
||||
</check>
|
||||
</div>
|
||||
|
||||
@@ -767,6 +767,10 @@
|
||||
padding-right: 8px; // overwrite default
|
||||
}
|
||||
|
||||
.table{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.pf-setup-body-cronjob{
|
||||
.panel-footer{
|
||||
display: flex; // align multiple error/warning/.. elements
|
||||
|
||||
@@ -59,8 +59,9 @@ $mapModuleGridRowMinHeight: 38px;
|
||||
@media screen and (min-width: $screen-lg){
|
||||
grid-template-areas:
|
||||
"area2 map map map"
|
||||
"area2 area1 area1 area3"
|
||||
"area2 area1 area1 area3";
|
||||
grid-template-columns: minmax($colMinWidth, 1fr) 1fr minmax($colMinWidth, 1fr) 1fr;
|
||||
grid-template-columns: minmax($colMinWidth, 1fr) 1fr 1fr minmax($colMinWidth, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
sass/library/select2/_core.scss
vendored
19
sass/library/select2/_core.scss
vendored
@@ -34,15 +34,16 @@
|
||||
}
|
||||
|
||||
.select2-hidden-accessible {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
pointer-events: none;
|
||||
border: 0 !important;
|
||||
clip: rect(0 0 0 0) !important;
|
||||
-webkit-clip-path: inset(50%) !important;
|
||||
clip-path: inset(50%) !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
@import "theme/pathfinder/_layout";
|
||||
|
||||
1
sass/library/select2/_multiple.scss
vendored
1
sass/library/select2/_multiple.scss
vendored
@@ -26,6 +26,7 @@
|
||||
border: none;
|
||||
font-size: 100%;
|
||||
margin-top: 5px;
|
||||
padding: 0;
|
||||
|
||||
&::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
|
||||
4
sass/library/select2/_single.scss
vendored
4
sass/library/select2/_single.scss
vendored
@@ -18,6 +18,10 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select2-selection__clear {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
&[dir="rtl"] {
|
||||
|
||||
@@ -6,7 +6,6 @@ $selection-color: #444 !default;
|
||||
|
||||
$border-color: $gray-light !default;
|
||||
$border-radius: 0px !default;
|
||||
$border-radius-choice: 2px !default;
|
||||
|
||||
$focus-border-color: $teal-lighter !default;
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
color: $gray-dark;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius;
|
||||
|
||||
cursor: text;
|
||||
|
||||
outline: 0;
|
||||
|
||||
&:focus {
|
||||
@@ -24,9 +26,12 @@
|
||||
.select2-selection__choice {
|
||||
background-color: $gray-lighter;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius-choice;
|
||||
border-radius: $border-radius;
|
||||
|
||||
cursor: default;
|
||||
|
||||
float: left;
|
||||
|
||||
margin-right: 5px;
|
||||
margin-top: 5px;
|
||||
padding: 0 5px;
|
||||
@@ -35,27 +40,22 @@
|
||||
.select2-selection__choice__remove {
|
||||
color: $remove-color;
|
||||
cursor: pointer;
|
||||
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
|
||||
margin-right: 4px;
|
||||
|
||||
&:hover {
|
||||
color: $remove-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-selection__placeholder {
|
||||
color: $gray-light;
|
||||
}
|
||||
}
|
||||
|
||||
&[dir="rtl"] {
|
||||
.select2-selection--multiple {
|
||||
.select2-selection__choice {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.select2-selection__choice {
|
||||
margin-left: 5px;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
background-color: $gray-dark;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius;
|
||||
|
||||
outline: 0;
|
||||
height: 32px;
|
||||
padding: 6px 16px;
|
||||
@@ -19,10 +20,13 @@
|
||||
div[class^='col-']:first-child{
|
||||
padding-left: 0; // overwrite default padding for "selected" option(s) in custom Bootstrap col layout
|
||||
}
|
||||
|
||||
> .fas {
|
||||
margin-left: 8px; // arrow icon for e.g. wormhole "selected" option
|
||||
}
|
||||
}
|
||||
|
||||
.select2-selection__clear {
|
||||
color: $remove-color;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
@@ -40,14 +44,19 @@
|
||||
|
||||
.select2-selection__arrow {
|
||||
background-color: $gray-dark;
|
||||
|
||||
border: none;
|
||||
border-left: none;
|
||||
border-left: 1px solid transparent;
|
||||
border-top-right-radius: $border-radius;
|
||||
border-bottom-right-radius: $border-radius;
|
||||
|
||||
height: 30px;
|
||||
|
||||
position: absolute;
|
||||
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
|
||||
width: 20px;
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
@import "library/x-editable/_bootstrap-editable"; // X-editable - v1.5.1
|
||||
@import "library/slidebars/_slidebars"; // Slidebars Navigation
|
||||
@import "library/easy-pie-chart/_easyPieChart"; // Easy Pie Chart 2.1.6
|
||||
@import "library/select2/_core"; // Select2 4.0.3
|
||||
@import "library/select2/_core"; // Select2 4.0.13
|
||||
@import "library/blue-imp-gallery/_blueimp-gallery"; // Blue Imp Gallery
|
||||
@import "library/blue-imp-gallery/_bootstrap-image-gallery"; // Blue Imp Gallery Bootstrap
|
||||
@import "library/blue-imp-gallery/_bootstrap-image-gallery"; // Blue Imp Gallery Bootstrap
|
||||
|
||||
Reference in New Issue
Block a user