@@ -6,14 +6,17 @@ DEBUG = 0
|
||||
; If TRUE, the framework, after having logged stack trace and errors, stops execution (die without any status) when a non-fatal error is detected.
|
||||
HALT = FALSE
|
||||
|
||||
ONERROR = "Controller\Controller->showError"
|
||||
|
||||
; Timezone to use. Sync program with eve server time
|
||||
TZ = "UTC"
|
||||
|
||||
; Cache backend. Can handle Memcache module, APC, WinCache, XCache and a filesystem-based cache.
|
||||
CACHE = TRUE
|
||||
|
||||
; Callback functions ===================================================================================
|
||||
ONERROR = "Controller\Controller->showError"
|
||||
|
||||
UNLOAD = "Controller\Controller->unload"
|
||||
|
||||
; Path configurations ==================================================================================
|
||||
; relative to "BASE" dir
|
||||
|
||||
|
||||
@@ -141,6 +141,139 @@ class Map extends \Controller\AccessController {
|
||||
echo json_encode($initData);
|
||||
}
|
||||
|
||||
/**
|
||||
* import new map data
|
||||
* @param $f3
|
||||
*/
|
||||
public function import($f3){
|
||||
$importData = (array)$f3->get('POST');
|
||||
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
if(
|
||||
isset($importData['typeId']) &&
|
||||
count($importData['mapData']) > 0
|
||||
){
|
||||
$user = $this->_getUser();
|
||||
|
||||
if($user){
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
|
||||
$map = Model\BasicModel::getNew('MapModel');
|
||||
$system = Model\BasicModel::getNew('SystemModel');
|
||||
$connection = Model\BasicModel::getNew('ConnectionModel');
|
||||
|
||||
foreach($importData['mapData'] as $mapData){
|
||||
if(
|
||||
isset($mapData['config']) &&
|
||||
isset($mapData['data'])
|
||||
){
|
||||
|
||||
|
||||
if(
|
||||
isset($mapData['data']['systems']) &&
|
||||
isset($mapData['data']['connections'])
|
||||
){
|
||||
if(isset($mapData['config']['id'])){
|
||||
unset($mapData['config']['id']);
|
||||
}
|
||||
|
||||
$map->setData($mapData['config']);
|
||||
$map->typeId = (int)$importData['typeId'];
|
||||
$map->save();
|
||||
|
||||
// new system IDs will be generated
|
||||
// therefore we need to temp store a mapping between IDs
|
||||
$tempSystemIdMapping = [];
|
||||
|
||||
foreach($mapData['data']['systems'] as $systemData){
|
||||
if(isset($systemData['id'])){
|
||||
$oldId = (int)$systemData['id'];
|
||||
unset($systemData['id']);
|
||||
|
||||
$system->setData($systemData);
|
||||
$system->mapId = $map;
|
||||
$system->createdCharacterId = $activeCharacter->characterId;
|
||||
$system->updatedCharacterId = $activeCharacter->characterId;
|
||||
$system->save();
|
||||
|
||||
$tempSystemIdMapping[$oldId] = $system->id;
|
||||
$system->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach($mapData['data']['connections'] as $connectionData){
|
||||
// check if source and target IDs match with new system ID
|
||||
if(
|
||||
isset( $tempSystemIdMapping[$connectionData['source']] ) &&
|
||||
isset( $tempSystemIdMapping[$connectionData['target']] )
|
||||
){
|
||||
if(isset($connectionData['id'])){
|
||||
unset($connectionData['id']);
|
||||
}
|
||||
|
||||
$connection->setData($connectionData);
|
||||
$connection->mapId = $map;
|
||||
$connection->source = $tempSystemIdMapping[$connectionData['source']];
|
||||
$connection->target = $tempSystemIdMapping[$connectionData['target']];
|
||||
$connection->save();
|
||||
|
||||
$connection->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// map access info should not automatically imported
|
||||
if($map->isPrivate()){
|
||||
$map->setAccess($user);
|
||||
}elseif($map->isCorporation()){
|
||||
$corporation = $activeCharacter->getCharacter()->getCorporation();
|
||||
if($corporation){
|
||||
$map->setAccess($corporation);
|
||||
}
|
||||
}elseif($map->isAlliance()){
|
||||
$alliance = $activeCharacter->getCharacter()->getAlliance();
|
||||
if($alliance){
|
||||
$map->setAccess($alliance);
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
// systems || connections missing
|
||||
$missingConfigError = (object) [];
|
||||
$missingConfigError->type = 'error';
|
||||
$missingConfigError->message = 'Map data not valid (systems || connections) missing';
|
||||
$return->error[] = $missingConfigError;
|
||||
}
|
||||
|
||||
}else{
|
||||
// map config || systems/connections missing
|
||||
$missingConfigError = (object) [];
|
||||
$missingConfigError->type = 'error';
|
||||
$missingConfigError->message = 'Map data not valid (config || data) missing';
|
||||
$return->error[] = $missingConfigError;
|
||||
}
|
||||
|
||||
|
||||
$map->reset();
|
||||
}
|
||||
}else{
|
||||
// user not found
|
||||
$return->error[] = $this->getUserLoggedOffError();
|
||||
}
|
||||
}else{
|
||||
// map data missing
|
||||
$missingDataError = (object) [];
|
||||
$missingDataError->type = 'error';
|
||||
$missingDataError->message = 'Map data missing';
|
||||
$return->error[] = $missingDataError;
|
||||
}
|
||||
|
||||
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* save a new map or update an existing map
|
||||
* @param $f3
|
||||
@@ -337,7 +470,7 @@ class Map extends \Controller\AccessController {
|
||||
$return->error = [];
|
||||
|
||||
if($user){
|
||||
// -> get active user object
|
||||
// -> get active character
|
||||
$activeCharacter = $user->getActiveUserCharacter();
|
||||
|
||||
$cacheKey = 'user_map_data_' . $activeCharacter->id;
|
||||
@@ -383,10 +516,10 @@ class Map extends \Controller\AccessController {
|
||||
foreach($systems as $i => $systemData){
|
||||
|
||||
// check if current system belongs to the current map
|
||||
$map->filter('systems', array('id = ?', $systemData['id'] ));
|
||||
$map->filter('systems', ['id = ?', $systemData['id'] ]);
|
||||
$filteredMap = $map->find(
|
||||
array('id = ?', $map->id ),
|
||||
array('limit' => 1)
|
||||
['id = ?', $map->id ],
|
||||
['limit' => 1]
|
||||
);
|
||||
|
||||
// this should never fail
|
||||
@@ -412,10 +545,10 @@ class Map extends \Controller\AccessController {
|
||||
foreach($connections as $i => $connectionData){
|
||||
|
||||
// check if the current connection belongs to the current map
|
||||
$map->filter('connections', array('id = ?', $connectionData['id'] ));
|
||||
$map->filter('connections', ['id = ?', $connectionData['id'] ]);
|
||||
$filteredMap = $map->find(
|
||||
array('id = ?', $map->id ),
|
||||
array('limit' => 1)
|
||||
['id = ?', $map->id ],
|
||||
['limit' => 1]
|
||||
);
|
||||
|
||||
// this should never fail
|
||||
|
||||
@@ -217,14 +217,14 @@ class Route extends \Controller\AccessController {
|
||||
SELECT
|
||||
GROUP_CONCAT( NULLIF(map_sys_inner.solarSystemName, NULL) SEPARATOR ':')
|
||||
FROM
|
||||
mapsolarsystemjumps map_jump INNER JOIN
|
||||
mapsolarsystems map_sys_inner ON
|
||||
mapSolarSystemJumps map_jump INNER JOIN
|
||||
mapSolarSystems map_sys_inner ON
|
||||
map_sys_inner.solarSystemID = map_jump.toSolarSystemID
|
||||
WHERE
|
||||
map_jump.fromSolarSystemID = map_sys.solarSystemID
|
||||
) system_neighbours
|
||||
FROM
|
||||
mapsolarsystems map_sys
|
||||
mapSolarSystems map_sys
|
||||
HAVING
|
||||
-- skip systems without neighbors (e.g. WHs)
|
||||
system_neighbours IS NOT NULL
|
||||
|
||||
@@ -26,8 +26,8 @@ class System extends \Controller\AccessController {
|
||||
SELECT
|
||||
LOWER( system_effect.typeName )
|
||||
FROM
|
||||
invtypes system_effect INNER JOIN
|
||||
mapdenormalize map_norm ON
|
||||
invTypes system_effect INNER JOIN
|
||||
mapDenormalize map_norm ON
|
||||
map_norm.typeID = system_effect.typeID
|
||||
WHERE
|
||||
system_effect.groupID = 995 AND
|
||||
@@ -39,16 +39,16 @@ class System extends \Controller\AccessController {
|
||||
SELECT
|
||||
map_worm_class.wormholeClassID system_class
|
||||
FROM
|
||||
maplocationwormholeclasses map_worm_class
|
||||
mapLocationWormholeClasses map_worm_class
|
||||
WHERE
|
||||
map_worm_class.locationID = map_sys.regionID
|
||||
LIMIT 1
|
||||
), 7) security
|
||||
FROM
|
||||
mapsolarsystems map_sys INNER JOIN
|
||||
mapconstellations map_con ON
|
||||
mapSolarSystems map_sys INNER JOIN
|
||||
mapConstellations map_con ON
|
||||
map_con.constellationID = map_sys.constellationID INNER JOIN
|
||||
mapregions map_reg ON
|
||||
mapRegions map_reg ON
|
||||
map_reg.regionID = map_sys.regionID";
|
||||
|
||||
private $whereQuery = "";
|
||||
|
||||
@@ -175,7 +175,7 @@ class Controller {
|
||||
$data = (object) [];
|
||||
$data->trusted = false;
|
||||
$data->values = [];
|
||||
$headerData = apache_request_headers();
|
||||
$headerData = self::getRequestHeaders();
|
||||
|
||||
foreach($headerData as $key => $value){
|
||||
$key = strtolower($key);
|
||||
@@ -199,6 +199,33 @@ class Controller {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return all headers because
|
||||
* getallheaders() is not available under nginx
|
||||
*
|
||||
* @return array (string $key -> string $value)
|
||||
*/
|
||||
static function getRequestHeaders(){
|
||||
$headers = [];
|
||||
|
||||
if(function_exists('apache_request_headers') ){
|
||||
// Apache Webserver
|
||||
$headers = apache_request_headers();
|
||||
}else{
|
||||
// Other webserver, e.g. nginx
|
||||
// Unfortunately this "fallback" does not work for me (Apache)
|
||||
// Therefore we can´t use this for all servers
|
||||
// https://github.com/exodus4d/pathfinder/issues/58
|
||||
foreach($_SERVER as $name => $value){
|
||||
if(substr($name, 0, 5) == 'HTTP_'){
|
||||
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current request was send from inGame
|
||||
* @return bool
|
||||
@@ -282,8 +309,9 @@ class Controller {
|
||||
public function showError($f3){
|
||||
|
||||
// set HTTP status
|
||||
if(!empty($f3->get('ERROR.code'))){
|
||||
$f3->status($f3->get('ERROR.code'));
|
||||
$errorCode = $f3->get('ERROR.code');
|
||||
if(!empty($errorCode)){
|
||||
$f3->status($errorCode);
|
||||
}
|
||||
|
||||
if($f3->get('AJAX')){
|
||||
@@ -293,7 +321,7 @@ class Controller {
|
||||
$return = (object) [];
|
||||
$error = (object) [];
|
||||
$error->type = 'error';
|
||||
$error->code = $f3->get('ERROR.code');
|
||||
$error->code = $errorCode;
|
||||
$error->status = $f3->get('ERROR.status');
|
||||
$error->message = $f3->get('ERROR.text');
|
||||
|
||||
@@ -322,4 +350,12 @@ class Controller {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for framework "unload"
|
||||
* -> config.ini
|
||||
*/
|
||||
public function unload(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,9 @@ class CharacterUpdate {
|
||||
*/
|
||||
function deleteLogData($f3){
|
||||
|
||||
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel');
|
||||
DB\Database::instance()->getDB('PF');
|
||||
|
||||
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel', 0);
|
||||
|
||||
// find "old" character logs
|
||||
$characterLogs = $characterLogModel->find([
|
||||
|
||||
@@ -115,7 +115,6 @@ class BasicModel extends \DB\Cortex {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* extent the fieldConf Array with static fields for each table
|
||||
*/
|
||||
@@ -128,7 +127,7 @@ class BasicModel extends \DB\Cortex {
|
||||
'type' => Schema::DT_TIMESTAMP
|
||||
],
|
||||
'updated' => [
|
||||
'type' => Schema::DT_TIMESTAMP
|
||||
'type' => Schema::DF_CURRENT_TIMESTAMP
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -63,10 +63,21 @@ class MapModel extends BasicModel {
|
||||
|
||||
foreach((array)$data as $key => $value){
|
||||
|
||||
if($key == 'created'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!is_array($value)){
|
||||
if($this->exists($key)){
|
||||
$this->$key = $value;
|
||||
}
|
||||
}else{
|
||||
// special array data
|
||||
if($key == 'scope'){
|
||||
$this->scopeId = (int)$value['id'];
|
||||
}elseif($key == 'type'){
|
||||
$this->typeId = (int)$value['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,12 +172,15 @@ class MapModel extends BasicModel {
|
||||
* @return null
|
||||
*/
|
||||
public function getSystem($systemId){
|
||||
$systems = $this->getSystems();
|
||||
$searchSystem = null;
|
||||
foreach($systems as $system){
|
||||
if($system->id == $systemId){
|
||||
$searchSystem = $system;
|
||||
break;
|
||||
|
||||
if($systemId > 0){
|
||||
$systems = $this->getSystems();
|
||||
foreach($systems as $system){
|
||||
if($system->id == $systemId){
|
||||
$searchSystem = $system;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +193,11 @@ class MapModel extends BasicModel {
|
||||
*/
|
||||
public function getSystems(){
|
||||
// orderBy x-Coordinate for cleaner frontend animation (left to right)
|
||||
$this->filter('systems', ['active = ?', 1], ['order' => 'posX']);
|
||||
$this->filter('systems',
|
||||
['active = :active AND id > 0',
|
||||
':active' => 1
|
||||
],
|
||||
['order' => 'posX']);
|
||||
|
||||
$systems = [];
|
||||
if($this->systems){
|
||||
@@ -210,7 +228,10 @@ class MapModel extends BasicModel {
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getConnections(){
|
||||
$this->filter('connections', ['active = ?', 1]);
|
||||
$this->filter('connections', [
|
||||
'active = :active AND source > 0 AND target > 0',
|
||||
':active' => 1
|
||||
]);
|
||||
|
||||
$connections = [];
|
||||
if($this->connections){
|
||||
|
||||
@@ -45,6 +45,10 @@ class SystemModel extends BasicModel {
|
||||
|
||||
foreach((array)$systemData as $key => $value){
|
||||
|
||||
if($key == 'created'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!is_array($value)){
|
||||
if($this->exists($key)){
|
||||
$this->$key = $value;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[PATHFINDER]
|
||||
NAME = "PATHFINDER"
|
||||
; installed version (used for CSS/JS cache busting)
|
||||
VERSION = "v0.0.14"
|
||||
VERSION = "v0.0.15"
|
||||
; contact information (DO NOT CHANGE)
|
||||
CONTACT = "https://github.com/exodus4d"
|
||||
; source code (DO NOT CHANGE)
|
||||
@@ -39,7 +39,7 @@ DB_PASS =
|
||||
|
||||
; EVE-Online CCP Database export
|
||||
DB_CCP_DNS = mysql:host=localhost;port=3306;dbname=
|
||||
DB_CCP_NAME = eve_test
|
||||
DB_CCP_NAME = eve_parallax_min
|
||||
DB_CCP_USER = root
|
||||
DB_CCP_PASS =
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ define(['jquery'], function($) {
|
||||
// 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
|
||||
// system API
|
||||
searchSystem: 'api/system/search', // ajax URL - search system by name
|
||||
saveSystem: 'api/system/save', // ajax URL - saves system to map
|
||||
|
||||
@@ -7,8 +7,9 @@ define([
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/render',
|
||||
'bootbox'
|
||||
], function($, Init, Util, Render, bootbox) {
|
||||
'bootbox',
|
||||
'app/ccp'
|
||||
], function($, Init, Util, Render, bootbox, CCP) {
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
@@ -17,11 +18,36 @@ define([
|
||||
dialogMapCreateContainerId: 'pf-map-dialog-create', // id for the "new map" container
|
||||
dialogMapEditContainerId: 'pf-map-dialog-edit', // id for the "edit" container
|
||||
dialogMapSettingsContainerId: 'pf-map-dialog-settings', // id for the "settings" container
|
||||
dialogMapDownloadContainerId: 'pf-map-dialog-download', // id for the "download" container
|
||||
|
||||
userSelectId: 'pf-map-dialog-user-select', // id for "user" select
|
||||
corporationSelectId: 'pf-map-dialog-corporation-select', // id for "corporation" select
|
||||
allianceSelectId: 'pf-map-dialog-alliance-select' // id for "alliance" select
|
||||
allianceSelectId: 'pf-map-dialog-alliance-select', // id for "alliance" select
|
||||
|
||||
dialogMapExportFormId: 'pf-map-dialog-form-export', // id for "export" form
|
||||
dialogMapImportFormId: 'pf-map-dialog-form-import', // id for "import" form
|
||||
|
||||
buttonExportId: 'pf-map-dialog-button-export', // id for "export" button
|
||||
buttonImportId: 'pf-map-dialog-button-import', // id for "import" button
|
||||
|
||||
fieldExportId: 'pf-map-filename-export', // id for "export" filename field
|
||||
fieldImportId: 'pf-map-filename-import', // id for "import" filename field
|
||||
dialogMapImportInfoId: 'pf-map-import-container', // id for "info" container
|
||||
dragDropElementClass: 'pf-form-dropzone' // class for "drag&drop" zone
|
||||
};
|
||||
|
||||
/**
|
||||
* format a given string into a valid filename
|
||||
* @param filename
|
||||
* @returns {string}
|
||||
*/
|
||||
var formatFilename = function(filename){
|
||||
filename = filename.replace(/[^a-zA-Z0-9]/g,'_');
|
||||
|
||||
var nowDate = new Date();
|
||||
var filenameDate = nowDate.toISOString().slice(0,10).replace(/-/g, '_');
|
||||
|
||||
return (filename + '_' + filenameDate).replace(/__/g,'_');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -46,15 +72,20 @@ define([
|
||||
// if there are no maps -> hide settings tab
|
||||
var hideSettingsTab = false;
|
||||
var hideEditTab = false;
|
||||
var hideDownloadTab = false;
|
||||
|
||||
if(mapData === false){
|
||||
hideSettingsTab = true;
|
||||
hideEditTab = true;
|
||||
hideDownloadTab = true;
|
||||
}
|
||||
|
||||
// available map "types" for a new or existing map
|
||||
var mapTypes = Util.getMapTypes(true);
|
||||
|
||||
var data = {
|
||||
scope: Util.getMapScopes(),
|
||||
type: Util.getMapTypes(true),
|
||||
type: mapTypes,
|
||||
icon: Util.getMapIcons(),
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
@@ -89,18 +120,29 @@ define([
|
||||
// render main dialog -----------------------------------------------------
|
||||
data = {
|
||||
id: config.newMapDialogId,
|
||||
mapData: mapData,
|
||||
type: mapTypes,
|
||||
isInGameBrowser: CCP.isInGameBrowser(),
|
||||
|
||||
// message container
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
formWarningContainerClass: Util.config.formWarningContainerClass,
|
||||
formInfoContainerClass: Util.config.formInfoContainerClass,
|
||||
|
||||
// default open tab ----------
|
||||
openTabNew: options.tab === 'new',
|
||||
openTabEdit: options.tab === 'edit',
|
||||
openTabSettings: options.tab === 'settings',
|
||||
openTabDownload: options.tab === 'download',
|
||||
|
||||
dialogMapCreateContainerId: config.dialogMapCreateContainerId,
|
||||
dialogMapEditContainerId: config.dialogMapEditContainerId,
|
||||
dialogMapSettingsContainerId: config.dialogMapSettingsContainerId,
|
||||
dialogMapDownloadContainerId: config.dialogMapDownloadContainerId,
|
||||
|
||||
hideEditTab: hideEditTab,
|
||||
hideSettingsTab: hideSettingsTab,
|
||||
hideDownloadTab: hideDownloadTab,
|
||||
|
||||
// settings tab --------------
|
||||
userSelectId: config.userSelectId,
|
||||
@@ -115,18 +157,29 @@ define([
|
||||
// access limitations --------
|
||||
maxUser: Init.maxSharedCount.user,
|
||||
maxCorporation: Init.maxSharedCount.corporation,
|
||||
maxAlliance: Init.maxSharedCount.alliance
|
||||
maxAlliance: Init.maxSharedCount.alliance,
|
||||
|
||||
// download tab --------------
|
||||
dialogMapExportFormId: config.dialogMapExportFormId,
|
||||
dialogMapImportFormId: config.dialogMapImportFormId,
|
||||
buttonExportId: config.buttonExportId,
|
||||
buttonImportId: config.buttonImportId,
|
||||
fieldExportId: config.fieldExportId,
|
||||
fieldImportId: config.fieldImportId,
|
||||
dialogMapImportInfoId: config.dialogMapImportInfoId,
|
||||
|
||||
formatFilename: function(){
|
||||
// format filename from "map name" (initial)
|
||||
return function (mapName, render) {
|
||||
var filename = render(mapName);
|
||||
return formatFilename(filename);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var contentDialog = Mustache.render(templateMapDialog, data);
|
||||
contentDialog = $(contentDialog);
|
||||
|
||||
// set mapId for "settings" tab
|
||||
if(mapData !== false){
|
||||
contentDialog.find('input[name="id"]').val( mapData.config.id );
|
||||
}
|
||||
|
||||
|
||||
// set tab content
|
||||
$('#' + config.dialogMapCreateContainerId, contentDialog).html(contentNewMap);
|
||||
$('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap);
|
||||
@@ -185,7 +238,7 @@ define([
|
||||
|
||||
dialogContent.hideLoadingAnimation();
|
||||
|
||||
if(responseData.error.length > 0){
|
||||
if(responseData.error.length){
|
||||
form.showFormMessage(responseData.error);
|
||||
}else{
|
||||
// success
|
||||
@@ -216,15 +269,23 @@ define([
|
||||
|
||||
|
||||
// after modal is shown =======================================================================
|
||||
mapInfoDialog.on('shown.bs.modal', function(e) {
|
||||
mapInfoDialog.on('shown.bs.modal', function(e){
|
||||
|
||||
mapInfoDialog.initTooltips();
|
||||
|
||||
// prevent "disabled" tabs from being clicked... "bootstrap" bugFix...
|
||||
mapInfoDialog.find('.navbar a[data-toggle=tab]').on('click', function(e){
|
||||
if ($(this).hasClass('disabled')){
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// set form validator
|
||||
mapInfoDialog.find('form').initFormValidation();
|
||||
|
||||
// events for tab change
|
||||
mapInfoDialog.find('.navbar a').on('shown.bs.tab', function (e) {
|
||||
mapInfoDialog.find('.navbar a').on('shown.bs.tab', function(e){
|
||||
|
||||
var selectElementUser = mapInfoDialog.find('#' + config.userSelectId);
|
||||
var selectElementCorporation = mapInfoDialog.find('#' + config.corporationSelectId);
|
||||
@@ -232,7 +293,6 @@ define([
|
||||
|
||||
if($(e.target).attr('href') === '#' + config.dialogMapSettingsContainerId){
|
||||
// "settings" tab
|
||||
|
||||
initSettingsSelectFields(mapInfoDialog);
|
||||
}else{
|
||||
if( $(selectElementUser).data('select2') !== undefined ){
|
||||
@@ -247,6 +307,13 @@ define([
|
||||
$(selectElementAlliance).select2('destroy');
|
||||
}
|
||||
}
|
||||
|
||||
// no "save" dialog button on "in/export" tab
|
||||
if($(e.target).attr('href') === '#' + config.dialogMapDownloadContainerId){
|
||||
mapInfoDialog.find('button.btn-success').hide();
|
||||
}else{
|
||||
mapInfoDialog.find('button.btn-success').show();
|
||||
}
|
||||
});
|
||||
|
||||
// show form messages -------------------------------------
|
||||
@@ -259,17 +326,223 @@ define([
|
||||
// no map data found (probably new user
|
||||
form.showFormMessage([{type: 'warning', message: 'No maps found. Create a new map before you can start'}]);
|
||||
}
|
||||
|
||||
// init select fields in case "settings" tab is open by default
|
||||
if(options.tab === 'settings'){
|
||||
initSettingsSelectFields(mapInfoDialog);
|
||||
}
|
||||
|
||||
// init "download tab" ========================================================================
|
||||
var downloadTabElement = mapInfoDialog.find('#' + config.dialogMapDownloadContainerId);
|
||||
if(downloadTabElement.length){
|
||||
// tab exists
|
||||
|
||||
// export map data ------------------------------------------------------------------------
|
||||
downloadTabElement.find('#' + config.buttonExportId).on('click', { mapData: mapData }, function(e){
|
||||
|
||||
var exportForm = $('#' + config.dialogMapExportFormId);
|
||||
var validExportForm = exportForm.isValidForm();
|
||||
|
||||
if(validExportForm){
|
||||
// set map data right before download
|
||||
$(this).setExportMapData(e.data.mapData);
|
||||
}else{
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// import map data ------------------------------------------------------------------------
|
||||
// check if "FileReader" API is supported
|
||||
var importFormElement = downloadTabElement.find('#' + config.dialogMapImportFormId);
|
||||
if(window.File && window.FileReader && window.FileList && window.Blob){
|
||||
|
||||
// show file info in UI
|
||||
downloadTabElement.find('#' + config.fieldImportId).on('change', function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var infoContainerElement = importFormElement.find('#' + config.dialogMapImportInfoId);
|
||||
infoContainerElement.hide().empty();
|
||||
importFormElement.hideFormMessage('all');
|
||||
|
||||
var output = [];
|
||||
var files = e.target.files;
|
||||
|
||||
for (var i = 0, f; !!(f = files[i]); i++) {
|
||||
output.push(( i + 1 ) + '. file: ' + f.name + ' - ' +
|
||||
f.size + ' bytes; last modified: ' +
|
||||
f.lastModifiedDate.toLocaleDateString() );
|
||||
}
|
||||
|
||||
if(output.length > 0){
|
||||
infoContainerElement.html( output ).show();
|
||||
}
|
||||
|
||||
importFormElement.validator('validate');
|
||||
});
|
||||
|
||||
// drag&drop
|
||||
var importData = {};
|
||||
importData.mapData = [];
|
||||
var files = [];
|
||||
var filesCount = 0;
|
||||
var filesCountFail = 0;
|
||||
|
||||
// onLoad for FileReader API
|
||||
var readerOnLoad = function(readEvent) {
|
||||
|
||||
// get file content
|
||||
try{
|
||||
importData.mapData.push( JSON.parse( readEvent.target.result ) );
|
||||
}catch(error){
|
||||
filesCountFail++;
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'File can not be parsed'}]);
|
||||
}
|
||||
|
||||
// start import when all files are parsed
|
||||
if(
|
||||
filesCount === files.length &&
|
||||
filesCountFail === 0
|
||||
){
|
||||
importMaps(importData);
|
||||
}
|
||||
};
|
||||
|
||||
var handleDragOver = function(dragEvent) {
|
||||
dragEvent.stopPropagation();
|
||||
dragEvent.preventDefault();
|
||||
dragEvent.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
||||
};
|
||||
|
||||
var handleFileSelect = function(evt){
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
|
||||
importData = importFormElement.getFormValues();
|
||||
importData.mapData = [];
|
||||
filesCount = 0;
|
||||
filesCountFail = 0;
|
||||
|
||||
files = evt.dataTransfer.files; // FileList object.
|
||||
|
||||
for (var file; !!(file = files[filesCount]); filesCount++){
|
||||
var reader = new FileReader();
|
||||
reader.onload = readerOnLoad;
|
||||
reader.readAsText(file);
|
||||
}
|
||||
};
|
||||
|
||||
var dropZone = downloadTabElement.find('.' + config.dragDropElementClass);
|
||||
dropZone[0].addEventListener('dragover', handleDragOver, false);
|
||||
dropZone[0].addEventListener('drop', handleFileSelect, false);
|
||||
|
||||
// import "button"
|
||||
downloadTabElement.find('#' + config.buttonImportId).on('click', function(e) {
|
||||
|
||||
importFormElement.validator('validate');
|
||||
var validImportForm = importFormElement.isValidForm();
|
||||
|
||||
if(validImportForm){
|
||||
importData = importFormElement.getFormValues();
|
||||
importData.mapData = [];
|
||||
|
||||
var fileElement = downloadTabElement.find('#' + config.fieldImportId);
|
||||
files = fileElement[0].files;
|
||||
filesCount = 0;
|
||||
filesCountFail = 0;
|
||||
|
||||
for (var file; !!(file = files[filesCount]); filesCount++){
|
||||
var reader = new FileReader();
|
||||
reader.onload = readerOnLoad;
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
}else{
|
||||
importFormElement.showFormMessage([{type: 'error', message: 'The File APIs are not fully supported in this browser.'}]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init select fields in case "settings" tab is open by default
|
||||
if(options.tab === 'settings'){
|
||||
initSettingsSelectFields(mapInfoDialog);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* import new map(s) data
|
||||
* @param importData
|
||||
*/
|
||||
var importMaps = function(importData){
|
||||
|
||||
var importForm = $('#' + config.dialogMapImportFormId);
|
||||
importForm.hideFormMessage('all');
|
||||
|
||||
// lock dialog
|
||||
var dialogContent = importForm.parents('.modal-content');
|
||||
dialogContent.showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.importMap,
|
||||
data: importData,
|
||||
dataType: 'json'
|
||||
}).done(function(responseData){
|
||||
if(responseData.error.length){
|
||||
// form.showFormMessage(responseData.error);
|
||||
importForm.showFormMessage(responseData.error);
|
||||
}else{
|
||||
// success
|
||||
|
||||
Util.showNotify({title: 'Import finished', text: 'Map(s) imported', type: 'success'});
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
var reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': importMap', text: reason, type: 'error'});
|
||||
}).always(function() {
|
||||
importForm.find('input, select').resetFormFields().trigger('change');
|
||||
dialogContent.hideLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* set json map data for export to an element (e.g. <a>-Tag or button) for download
|
||||
* @param mapData
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.setExportMapData = function(mapData){
|
||||
|
||||
var fieldExport = $('#' + config.fieldExportId);
|
||||
var filename = '';
|
||||
var mapDataEncoded = '';
|
||||
|
||||
if(fieldExport.length){
|
||||
filename = fieldExport.val();
|
||||
|
||||
if(filename.length > 0){
|
||||
// remove object properties that should not be included in export
|
||||
// -> e.g. jsPlumb object,...
|
||||
var allowedKeys = ['config', 'data'];
|
||||
|
||||
var replace = function(obj, keys) {
|
||||
var dup = {};
|
||||
for (var key in obj) {
|
||||
if (keys.indexOf(key) !== -1) {
|
||||
dup[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return dup;
|
||||
};
|
||||
|
||||
mapDataEncoded = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify( replace(mapData, allowedKeys) ));
|
||||
}
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var exportButton = $(this);
|
||||
exportButton.attr('href', 'data:' + mapDataEncoded);
|
||||
exportButton.attr('download', filename + '.json');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* init select2 fields within the settings dialog
|
||||
|
||||
@@ -202,7 +202,11 @@ define([
|
||||
return this.each(function(){
|
||||
var field = $(this);
|
||||
|
||||
field.val('');
|
||||
if( !field.is('select') ){
|
||||
// "input"
|
||||
field.val('');
|
||||
}
|
||||
|
||||
field.parents('.form-group').removeClass('has-error has-success');
|
||||
});
|
||||
};
|
||||
@@ -293,6 +297,12 @@ define([
|
||||
case 'info':
|
||||
messageElement = formElement.find('.' + config.formInfoContainerClass);
|
||||
break;
|
||||
case 'all':
|
||||
messageElement = formElement.find(
|
||||
'.' + config.formErrorContainerClass + ', ' +
|
||||
'.' + config.formWarningContainerClass + ', ' +
|
||||
'.' + config.formInfoContainerClass
|
||||
);
|
||||
}
|
||||
|
||||
if(messageElement){
|
||||
@@ -1603,7 +1613,6 @@ define([
|
||||
redirect(data.reroute, ['logout']);
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
|
||||
var reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': logout', text: reason, type: 'error'});
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
15
public/js/v0.0.15/app/landingpage.js
Normal file
15
public/js/v0.0.15/app/landingpage.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/v0.0.15/app/landingpage.js.map
Normal file
1
public/js/v0.0.15/app/landingpage.js.map
Normal file
File diff suppressed because one or more lines are too long
34
public/js/v0.0.15/app/mappage.js
Normal file
34
public/js/v0.0.15/app/mappage.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/v0.0.15/app/mappage.js.map
Normal file
1
public/js/v0.0.15/app/mappage.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/v0.0.15/app/notification.js
Normal file
2
public/js/v0.0.15/app/notification.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/v0.0.15/app/notification.js.map
Normal file
1
public/js/v0.0.15/app/notification.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -3,13 +3,32 @@
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="navbar-header pull-left">
|
||||
<ul class="nav navbar-nav {{dialogNavigationClass}}" role="tablist">
|
||||
<li class="{{#openTabNew}}active{{/openTabNew}}"><a role="tab" data-toggle="tab" data-name="newMap" href="#{{dialogMapCreateContainerId}}"><i class="fa fa-plus fa-fw"></i> New map</a></li>
|
||||
<li class="{{#openTabNew}}active{{/openTabNew}}">
|
||||
<a role="tab" data-toggle="tab" data-name="newMap" href="#{{dialogMapCreateContainerId}}">
|
||||
<i class="fa fa-plus fa-fw"></i> New map
|
||||
</a>
|
||||
</li>
|
||||
{{^hideEditTab}}
|
||||
<li class="{{#openTabEdit}}active{{/openTabEdit}}"><a role="tab" data-toggle="tab" data-name="editMap" href="#{{dialogMapEditContainerId}}"><i class="fa fa-edit fa-fw"></i> Edit map</a></li>
|
||||
<li class="{{#openTabEdit}}active{{/openTabEdit}}">
|
||||
<a role="tab" data-toggle="tab" data-name="editMap" href="#{{dialogMapEditContainerId}}">
|
||||
<i class="fa fa-edit fa-fw"></i> Edit map
|
||||
</a>
|
||||
</li>
|
||||
{{/hideEditTab}}
|
||||
{{^hideSettingsTab}}
|
||||
<li class="{{#openTabSettings}}active{{/openTabSettings}}"><a role="tab" data-toggle="tab" data-name="settings" href="#{{dialogMapSettingsContainerId}}"><i class="fa fa-gears fa-fw"></i> Settings</a></li>
|
||||
<li class="{{#openTabSettings}}active{{/openTabSettings}}">
|
||||
<a role="tab" data-toggle="tab" data-name="settings" href="#{{dialogMapSettingsContainerId}}">
|
||||
<i class="fa fa-gears fa-fw"></i> Settings
|
||||
</a>
|
||||
</li>
|
||||
{{/hideSettingsTab}}
|
||||
{{^hideDownloadTab}}
|
||||
<li class="{{#openTabDownload}}active{{/openTabDownload}} {{#isInGameBrowser}}disabled{{/isInGameBrowser}}" {{#isInGameBrowser}}title="Not working in IGB"{{/isInGameBrowser}}>
|
||||
<a role="tab" data-toggle="tab" data-name="download" href="#{{dialogMapDownloadContainerId}}" {{#isInGameBrowser}}class="disabled"{{/isInGameBrowser}}>
|
||||
<i class="fa fa-exchange fa-fw"></i> Import/Export
|
||||
</a>
|
||||
</li>
|
||||
{{/hideDownloadTab}}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -17,108 +36,181 @@
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabNew}}in active{{/openTabNew}}" id="{{dialogMapCreateContainerId}}"></div>
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabEdit}}in active{{/openTabEdit}}" id="{{dialogMapEditContainerId}}"></div>
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabSettings}}in active{{/openTabSettings}}" id="{{dialogMapSettingsContainerId}}">
|
||||
<form role="form" class="form-horizontal">
|
||||
<h2><i class="fa fa-share-alt fa-fw"></i> Share settings</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-11">
|
||||
<blockquote>
|
||||
<p>
|
||||
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>
|
||||
</blockquote>
|
||||
{{^hideSettingsTab}}
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabSettings}}in active{{/openTabSettings}}" id="{{dialogMapSettingsContainerId}}">
|
||||
<form role="form" class="form-horizontal">
|
||||
<h4><i class="fa fa-share-alt fa-fw"></i> Share settings</h4>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-11">
|
||||
<blockquote>
|
||||
<p>
|
||||
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>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! user search ----------------------------------------------------- }}
|
||||
{{#accessUser.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="{{userSelectId}}">Username</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group" title="add/remove user">
|
||||
<label for="{{userSelectId}}"></label>
|
||||
<select id="{{userSelectId}}" name="mapUsers[]" multiple="multiple">
|
||||
{{#accessUser}}
|
||||
{{! user search ----------------------------------------------------- }}
|
||||
{{#accessUser.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="{{userSelectId}}">Username</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group" title="add/remove user">
|
||||
<label for="{{userSelectId}}"></label>
|
||||
<select id="{{userSelectId}}" name="mapUsers[]" multiple="multiple">
|
||||
{{#accessUser}}
|
||||
<option value="{{id}}" selected>{{name}}</option>
|
||||
{{/accessUser}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search user name (max {{maxUser}})</span>
|
||||
{{/accessUser}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search user name (max {{maxUser}})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/accessUser.length}}
|
||||
{{/accessUser.length}}
|
||||
|
||||
{{! corporation search ---------------------------------------------- }}
|
||||
{{#accessCorporation.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label" for="{{corporationSelectId}}">Corporations</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group" title="add/remove corporations">
|
||||
<label for="{{corporationSelectId}}"></label>
|
||||
<select id="{{corporationSelectId}}" name="mapCorporations[]" multiple="multiple">
|
||||
{{#accessCorporation}}
|
||||
{{! corporation search ---------------------------------------------- }}
|
||||
{{#accessCorporation.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label" for="{{corporationSelectId}}">Corporations</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group" title="add/remove corporations">
|
||||
<label for="{{corporationSelectId}}"></label>
|
||||
<select id="{{corporationSelectId}}" name="mapCorporations[]" multiple="multiple">
|
||||
{{#accessCorporation}}
|
||||
<option value="{{id}}" selected="selected" >{{name}}</option>
|
||||
{{/accessCorporation}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search corporation name (max {{maxCorporation}})</span>
|
||||
{{/accessCorporation}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search corporation name (max {{maxCorporation}})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/accessCorporation.length}}
|
||||
{{/accessCorporation.length}}
|
||||
|
||||
{{! alliance search ------------------------------------------------- }}
|
||||
{{#accessAlliance.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="{{allianceSelectId}}">Alliances</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group" title="add/remove alliances">
|
||||
<label for="{{allianceSelectId}}"></label>
|
||||
<select id="{{allianceSelectId}}" name="mapAlliances[]" multiple="multiple" >
|
||||
{{#accessAlliance}}
|
||||
<option value="{{id}}" selected="selected" >{{name}}</option>
|
||||
{{/accessAlliance}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search alliance name (max {{maxAlliance}})</span>
|
||||
{{! alliance search ------------------------------------------------- }}
|
||||
{{#accessAlliance.length}}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="{{allianceSelectId}}">Alliances</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group" title="add/remove alliances">
|
||||
<label for="{{allianceSelectId}}"></label>
|
||||
<select id="{{allianceSelectId}}" name="mapAlliances[]" multiple="multiple" >
|
||||
{{#accessAlliance}}
|
||||
<option value="{{id}}" selected="selected" >{{name}}</option>
|
||||
{{/accessAlliance}}
|
||||
</select>
|
||||
<span class="help-block with-errors">Search alliance name (max {{maxAlliance}})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/accessAlliance.length}}
|
||||
{{/accessAlliance.length}}
|
||||
|
||||
<input type="hidden" name="id" value="0" />
|
||||
</form>
|
||||
<input type="hidden" name="id" value="{{ mapData.config.id }}" />
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{{/hideSettingsTab}}
|
||||
|
||||
|
||||
{{^hideDownloadTab}}
|
||||
<div role="tabpanel" class="tab-pane fade {{#openTabDownload}}in active{{/openTabDownload}}" id="{{dialogMapDownloadContainerId}}">
|
||||
|
||||
<h4 class="pf-dynamic-area">Map export</h4>
|
||||
<form role="form" class="form-horizontal" id="{{dialogMapExportFormId}}">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="{{fieldExportId}}">Export name</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="{{fieldExportId}}" type="text" name="{{fieldExportId}}" value="{{#formatFilename}}{{mapData.config.name}}{{/formatFilename}}" pattern="^[_a-zA-Z0-9]{1,}$" data-minlength="3" data-minlength-error="Min. of 3 characters" data-error="Invalid format: _ a-z A-Z 0-9" required>
|
||||
<div class="input-group-btn">
|
||||
<a type="button" id="{{buttonExportId}}" class="btn btn-default" href="" download="data.json">
|
||||
<i class="fa fa-fw fa-upload"></i> Export
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<h4 class="pf-dynamic-area">Map Import</h4>
|
||||
<form role="form" class="form-horizontal" id="{{dialogMapImportFormId}}">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="type" class="col-sm-2 control-label">Type</label>
|
||||
<div class="col-sm-3">
|
||||
<select name="typeId" id="type" class="form-control" title="Alliance/Corporation maps require character authentication" data-placement="top">
|
||||
{{#type}}
|
||||
<option value="{{id}}">{{label}}</option>
|
||||
{{/type}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="{{fieldImportId}}">Import file</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="{{fieldImportId}}" type="file" name="{{fieldImportId}}" accept=".json" data-error="Select a valid file" required>
|
||||
<div class="input-group-btn">
|
||||
<button type="button" id="{{buttonImportId}}" class="btn btn-default">
|
||||
<i class="fa fa-fw fa-download"></i> Import
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pf-form-dropzone">Drop map file here</div>
|
||||
|
||||
<h4 id="{{dialogMapImportInfoId}}" class="pf-dynamic-area" style="display: none;"></h4>
|
||||
|
||||
<div class="{{formErrorContainerClass}} alert alert-danger" style="display: none;">
|
||||
<span class="txt-color txt-color-danger">Error</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{/hideDownloadTab}}
|
||||
|
||||
|
||||
<div class="{{formInfoContainerClass}} alert alert-info" style="display: none;">
|
||||
<span class="txt-color txt-color-information">Information</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
|
||||
<div class="{{formWarningContainerClass}} alert alert-warning" style="display: none;">
|
||||
<span class="txt-color txt-color-warning">Warning</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
|
||||
<div class="{{formErrorContainerClass}} alert alert-danger" style="display: none;">
|
||||
<span class="txt-color txt-color-danger">Error</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{{formInfoContainerClass}} alert alert-info" style="display: none;">
|
||||
<span class="txt-color txt-color-information">Information</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
|
||||
<div class="{{formWarningContainerClass}} alert alert-warning" style="display: none;">
|
||||
<span class="txt-color txt-color-warning">Warning</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
|
||||
<div class="{{formErrorContainerClass}} alert alert-danger" style="display: none;">
|
||||
<span class="txt-color txt-color-danger">Error</span>
|
||||
<small> (important non-critical information)</small>
|
||||
</div>
|
||||
</div>
|
||||
@@ -346,7 +346,7 @@ $navbar-default-link-hover-color: $teal-lightest;
|
||||
$navbar-default-link-hover-bg: transparent;
|
||||
$navbar-default-link-active-color: $teal-lighter;
|
||||
$navbar-default-link-active-bg: transparent;
|
||||
$navbar-default-link-disabled-color: #ccc;
|
||||
$navbar-default-link-disabled-color: $gray;
|
||||
$navbar-default-link-disabled-bg: transparent;
|
||||
|
||||
// Navbar brand label
|
||||
|
||||
@@ -236,8 +236,8 @@
|
||||
}
|
||||
|
||||
// sharing dialog =========================================
|
||||
#pf-sharing-dialog{
|
||||
.pf-dynamic-area{
|
||||
h2, h4{
|
||||
&.pf-dynamic-area{
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,39 @@ input, select{
|
||||
@include box-shadow(0 0 0 50px $gray-dark inset !important);
|
||||
-webkit-text-fill-color: $gray-lighter;
|
||||
}
|
||||
|
||||
// file input
|
||||
&::-webkit-file-upload-button{
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: $gray-light;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
// drag&drop zone
|
||||
.pf-form-dropzone{
|
||||
border: 2px dashed $gray-darker;
|
||||
height: 100px;
|
||||
background-color: darken($gray, 3%);
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
line-height: 100px;
|
||||
margin: 15px 0;
|
||||
color: $gray-darker;
|
||||
@include border-radius(10px);
|
||||
@include transition( color 0.18s ease-out, border-color 0.18s ease-out);
|
||||
|
||||
&:hover{
|
||||
color: $teal-lighter;
|
||||
border-color: $teal-lighter;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// fix for bootstrap-toggle plugin
|
||||
.toggle{
|
||||
&.btn:active{
|
||||
|
||||
@@ -729,11 +729,11 @@ select:active, select:hover {
|
||||
|
||||
}
|
||||
|
||||
.tooltip.top .tooltip-arrow,{
|
||||
.tooltip.top .tooltip-arrow{
|
||||
border-top-color: $gray-light;
|
||||
}
|
||||
|
||||
.tooltip.right .tooltip-arrow,{
|
||||
.tooltip.right .tooltip-arrow{
|
||||
border-right-color: $gray-light;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user