Merge pull request #351 from exodus4d/develop

v1.1.6
This commit is contained in:
Mark Friedrich
2016-10-18 19:53:20 +02:00
committed by GitHub
93 changed files with 3378 additions and 407 deletions

View File

@@ -17,15 +17,18 @@ sixthHour = */10 * * * *
halfHour = */30 * * * *
[CRON.jobs]
; delete character log data
deleteLogData = Cron\CharacterUpdate->deleteLogData, @sixthHour
; delete expired signatures
deleteSignatures = Cron\MapUpdate->deleteSignatures, @halfHour
; import system data (jump, kill,..) from CCP API
importSystemData = Cron\CcpSystemsUpdate->importSystemData, @hourly
; disable outdated maps
deactivateMapData = Cron\MapUpdate->deactivateMapData, @hourly
; delete character log data
deleteLogData = Cron\CharacterUpdate->deleteLogData, @sixthHour
; delete disabled maps
deleteMapData = Cron\MapUpdate->deleteMapData, @downtime
@@ -33,7 +36,7 @@ deleteMapData = Cron\MapUpdate->deleteMapData, @downtime
deleteAuthenticationData = Cron\CharacterUpdate->deleteAuthenticationData, @downtime
; delete expired cache files
deleteExpiredCacheData = Cron\Cache->deleteExpiredData, @weekly
deleteExpiredCacheData = Cron\Cache->deleteExpiredData, @downtime
; delete expired signatures
deleteSignatures = Cron\MapUpdate->deleteSignatures, @halfHour
; delete old statistics (activity log) data
deleteStatisticsData = Cron\StatisticsUpdate->deleteStatisticsData, @weekly

View File

@@ -10,7 +10,7 @@ namespace Controller\Api;
use Controller;
use Model;
class Connection extends Controller\AccessController{
class Connection extends Controller\AccessController {
/**
* @param \Base $f3

View File

@@ -174,6 +174,14 @@ class Map extends Controller\AccessController {
];
$return->maxSharedCount = $maxSharedCount;
// get activity log options per map ---------------------------------------------------------------------------
$activityLogging = [
'character' => $f3->get('PATHFINDER.MAP.PRIVATE.ACTIVITY_LOGGING'),
'corporation' => $f3->get('PATHFINDER.MAP.CORPORATION.ACTIVITY_LOGGING'),
'alliance' => $f3->get('PATHFINDER.MAP.ALLIANCE.ACTIVITY_LOGGING'),
];
$return->activityLogging = $activityLogging;
// get program routes -----------------------------------------------------------------------------------------
$return->routes = [
'ssoLogin' => $this->getF3()->alias( 'sso', ['action' => 'requestAuthorization'] )
@@ -223,11 +231,13 @@ class Map extends Controller\AccessController {
* @var $system Model\SystemModel
*/
$system = Model\BasicModel::getNew('SystemModel');
$system->setActivityLogging(false);
/**
* @var $connection Model\ConnectionModel
*/
$connection = Model\BasicModel::getNew('ConnectionModel');
$connection->setActivityLogging(false);
foreach($importData['mapData'] as $mapData){
if(

View File

@@ -7,6 +7,7 @@
*/
namespace Controller\Api;
use Controller;
use Model;
@@ -15,7 +16,7 @@ use Model;
* Class Route
* @package Controller\Api
*/
class Route extends \Controller\AccessController {
class Route extends Controller\AccessController {
/**
* cache time for static jump data (e.g. K-Space stargates)

View File

@@ -11,7 +11,7 @@ use Controller;
use Model;
class Signature extends Controller\AccessController{
class Signature extends Controller\AccessController {
/**
* event handler

View File

@@ -0,0 +1,291 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 03.10.2016
* Time: 00:29
*/
namespace controller\api;
use Controller;
use Model\CharacterModel;
class Statistic extends Controller\AccessController {
/**
* concat a year and calendar week number
* week numbers > 10 will get prefixed with "0"
* -> e.g. year 2016, week 2 => "201602"
* @param int $year
* @param int $week
* @return string
*/
protected function concatYearWeek($year, $week){
return strval($year) . str_pad($week, 2, 0, STR_PAD_LEFT);
}
/**
* get max count of weeks in a year
* @param $year
* @return int
*/
protected function getIsoWeeksInYear($year) {
$date = new \DateTime;
$date->setISODate($year, 53);
return ($date->format('W') === '53' ? 53 : 52);
}
/**
* get number of weeks for a given period
* @param string $period
* @param int $year
* @return int
*/
protected function getWeekCount($period, $year){
$weeksInYear = $this->getIsoWeeksInYear($year);
switch($period){
case 'yearly':
$weekCount = $weeksInYear;
break;
case 'monthly':
$weekCount = 4;
break;
case 'weekly':
default:
$weekCount = 1;
break;
}
return $weekCount;
}
/**
* calculate calendar week and year for a given offset (weekCount)
* -> count forward OR backward
* @param int $year
* @param int $week
* @param int $weekCount
* @param bool $backwards
* @return array
*/
protected function calculateYearWeekOffset($year, $week, $weekCount, $backwards = false){
$offset = [
'year' => (int)$year,
'week' => (int)$week
];
$weeksInYear = $this->getIsoWeeksInYear($year);
// just for security...
if($offset['week'] > $weeksInYear){
$offset['week'] = $weeksInYear;
}elseif($offset['week'] <= 0){
$offset['week'] = 1;
}
for($i = 1; $i < $weekCount; $i++){
if($backwards){
// calculate backward
$offset['week']--;
if($offset['week'] <= 0){
// year change -> reset yearWeeks
$offset['year']--;
$offset['week'] = $this->getIsoWeeksInYear($offset['year']);
}
}else{
// calculate forward
$offset['week']++;
if($offset['week'] > $weeksInYear){
// year change -> reset yearWeeks
$offset['week'] = 1;
$offset['year']++;
$weeksInYear = $this->getIsoWeeksInYear($offset['year']);
}
}
}
return $offset;
}
/**
* query statistic data for "activity log"
* -> group result by characterId
* @param CharacterModel $character
* @param int $typeId
* @param int $yearStart
* @param int $weekStart
* @param int $yearEnd
* @param int $weekEnd
* @return array
*/
protected function queryStatistic( CharacterModel $character, $typeId, $yearStart, $weekStart, $yearEnd, $weekEnd){
$data = [];
// can be either "characterId" || "corporationId" || "allianceId"
// -> is required (>0) to limit the result to only accessible data for the given character!
$objectId = 0;
// add map-"typeId" (private/corp/ally) condition -------------------------------------------------------------
// check if "ACTIVITY_LOGGING" is active for a given "typeId"
$sqlMapType = "";
switch($typeId){
case 2:
if( $this->getF3()->get('PATHFINDER.MAP.PRIVATE.ACTIVITY_LOGGING') ){
$sqlMapType .= " AND `character`.`id` = :objectId ";
$objectId = $character->_id;
}
break;
case 3:
if(
$this->getF3()->get('PATHFINDER.MAP.CORPORATION.ACTIVITY_LOGGING') &&
$character->hasCorporation()
){
$sqlMapType .= " AND `character`.`corporationId` = :objectId ";
$objectId = $character->get('corporationId', true);
}
break;
case 4:
if(
$this->getF3()->get('PATHFINDER.MAP.ALLIANCE.ACTIVITY_LOGGING') &&
$character->hasAlliance()
){
$sqlMapType .= " AND `character`.`allianceId` = :objectId ";
$objectId = $character->get('allianceId', true);
}
break;
}
if($objectId > 0){
$queryData = [
':active' => 1,
':objectId' => $objectId
];
// date offset condition ----------------------------------------------------------------------------------
$sqlDateOffset = " AND CONCAT(`log`.`year`, `log`.`week`) BETWEEN :yearWeekStart AND :yearWeekEnd ";
$queryData[':yearWeekStart'] = $this->concatYearWeek($yearStart, $weekStart);
$queryData[':yearWeekEnd'] = $this->concatYearWeek($yearEnd, $weekEnd);
// build query --------------------------------------------------------------------------------------------
$sql = "SELECT
`log`.`year`,
`log`.`week`,
`log`.`characterId`,
`character`.`name`,
`character`.`lastLogin`,
SUM(`log`.`systemCreate`) `systemCreate`,
SUM(`log`.`systemUpdate`) `systemUpdate`,
SUM(`log`.`systemDelete`) `systemDelete`,
SUM(`log`.`connectionCreate`) `connectionCreate`,
SUM(`log`.`connectionUpdate`) `connectionUpdate`,
SUM(`log`.`connectionDelete`) `connectionDelete`,
SUM(`log`.`signatureCreate`) `signatureCreate`,
SUM(`log`.`signatureUpdate`) `signatureUpdate`,
SUM(`log`.`signatureDelete`) `signatureDelete`
FROM
`activity_log` `log` INNER JOIN
`character` ON
`character`.`id` = `log`.`characterId`
WHERE
`log`.`active` = :active
" . $sqlMapType . "
" . $sqlDateOffset . "
GROUP BY
`log`.`year`,
`log`.`week`,
`log`.`characterId`
ORDER BY
`log`.`year` DESC, `log`.`week` DESC";
$result = $this->getDB()->exec($sql, $queryData);
if( !empty($result) ){
// group result by characterId
foreach ($result as $key => &$entry) {
$tmp = $entry;
unset($tmp['characterId']);
unset($tmp['name']);
unset($tmp['lastLogin']);
$data[$entry['characterId']]['name'] = $entry['name'];
$data[$entry['characterId']]['lastLogin'] = strtotime($entry['lastLogin']);
$data[$entry['characterId']]['weeks'][ $entry['year'] . $entry['week'] ] = $tmp;
}
}
}
return $data;
}
/**
* get statistics data
* @param \Base $f3
*/
public function getData(\Base $f3){
$postData = (array)$f3->get('POST');
$return = (object) [];
$period = $postData['period'];
$typeId = (int)$postData['typeId'];
$yearStart = (int)$postData['year'];
$weekStart = (int)$postData['week'];
$currentYear = (int)date('o');
$currentWeek = (int)date('W');
if(
$yearStart &&
$weekStart
){
$weekCount = $this->getWeekCount($period, $yearStart);
}else{
// if start date is not set -> calculate it from current data
$tmpYear = $currentYear;
if($period == 'yearly'){
$tmpYear--;
}
$weekCount = $this->getWeekCount($period, $tmpYear);
$offsetStart = $this->calculateYearWeekOffset($currentYear, $currentWeek, $weekCount, true);
$yearStart = $offsetStart['year'];
$weekStart = $offsetStart['week'];
}
// date offset for statistics query
$offset = $this->calculateYearWeekOffset($yearStart, $weekStart, $weekCount);
$activeCharacter = $this->getCharacter();
$return->statistics = $this->queryStatistic($activeCharacter, $typeId, $yearStart, $weekStart, $offset['year'], $offset['week']);
$return->period = $period;
$return->typeId = $typeId;
$return->weekCount = $weekCount;
$return->yearWeeks = [
$yearStart => $this->getIsoWeeksInYear($yearStart),
($yearStart + 1) => $this->getIsoWeeksInYear($yearStart + 1)
];
// pagination offset
$offsetNext = $this->calculateYearWeekOffset($yearStart, $weekStart, $weekCount + 1);
$offsetPrev = $this->calculateYearWeekOffset($yearStart, $weekStart, $weekCount + 1, true);
// check if "next" button is available (not in future)
$currentCurrentDataConcat = intval( $this->concatYearWeek($currentYear, $currentWeek) );
$offsetNextDateConcat = intval( $this->concatYearWeek($offsetNext['year'], $offsetNext['week']) );
if( $offsetNextDateConcat <= $currentCurrentDataConcat){
$return->next = $offsetNext;
}
$return->prev = $offsetPrev;
$return->start = ['year' => $yearStart, 'week' => $weekStart];
$return->offset = $offset;
echo json_encode($return);
}
}

View File

@@ -7,11 +7,12 @@
*/
namespace Controller\Api;
use Controller;
use Controller\Ccp\Sso;
use Data\Mapper as Mapper;
use Model;
class System extends \Controller\AccessController {
class System extends Controller\AccessController {
private $mainQuery = "SELECT
map_sys.constellationID `connstallation_id`,
@@ -68,7 +69,6 @@ class System extends \Controller\AccessController {
* @param \Base $f3
*/
function beforeroute(\Base $f3) {
parent::beforeroute($f3);
// set header for all routes
@@ -80,7 +80,6 @@ class System extends \Controller\AccessController {
* @return string
*/
private function _getQuery(){
$query = $this->mainQuery;
$query .= ' ' . $this->whereQuery;
$query .= ' ' . $this->havingQuery;
@@ -419,8 +418,17 @@ class System extends \Controller\AccessController {
foreach($systemIds as $systemId){
$system->getById($systemId);
if( $system->hasAccess($activeCharacter) ){
$system->setActive(false);
$system->save();
// check whether system should be deleted OR set "inactive"
if(
empty($system->alias) &&
empty($system->description)
){
$system->erase();
}else{
// keep data -> set "inactive"
$system->setActive(false);
$system->save();
}
$system->reset();
}
}

View File

@@ -95,6 +95,9 @@ class Controller {
* @param \Base $f3
*/
public function afterroute(\Base $f3){
// store all user activities that are buffered for logging in this request
self::storeActivities();
if($this->getTemplate()){
// Ajax calls don´t need a page render..
// this happens on client side
@@ -779,6 +782,13 @@ class Controller {
return LogController::getLogger($type);
}
/**
* store activity log data to DB
*/
static function storeActivities(){
LogController::instance()->storeActivities();
}
/**
* removes illegal characters from a Hive-key that are not allowed
* @param $key

View File

@@ -7,10 +7,128 @@
*/
namespace controller;
use DB;
class LogController extends \Prefab {
class LogController extends Controller {
/**
* buffered activity log data for this singleton LogController() class
* -> this buffered data can be stored somewhere (e.g. DB) before HTTP response
* -> should be cleared afterwards!
* @var array
*/
protected $activityLogBuffer = [];
/**
* reserve a "new" character activity for logging
* @param $characterId
* @param $mapId
* @param $action
*/
public function bufferActivity($characterId, $mapId, $action){
$characterId = (int)$characterId;
$mapId = (int)$mapId;
if(
$characterId > 0 &&
$mapId > 0
){
$key = $this->getBufferedActivityKey($characterId, $mapId);
if( is_null($key) ){
$activity = [
'characterId' => $characterId,
'mapId' => $mapId,
$action => 1
];
$this->activityLogBuffer[] = $activity;
}else{
$this->activityLogBuffer[$key][$action]++;
}
}
}
/**
* store all buffered activity log data to DB
*/
public function storeActivities(){
if( !empty($this->activityLogBuffer) ){
$db = DB\Database::instance()->getDB('PF');
$quoteStr = function($str) use ($db) {
return $db->quotekey($str);
};
$placeholderStr = function($str){
return ':' . $str;
};
$updateRule = function($str){
return $str . " = " . $str . " + VALUES(" . $str . ")";
};
$year = (int)date('o');
$yearWeek = (int)date('W');
$db->begin();
foreach($this->activityLogBuffer as $activityData){
$activityData['year'] = $year;
$activityData['week'] = $yearWeek;
$columns = array_keys($activityData);
$columnsQuoted = array_map($quoteStr, $columns);
$placeholder = array_map($placeholderStr, $columns);
$args = array_combine($placeholder, $activityData);
// "filter" columns that can be updated
$columnsForUpdate = array_diff($columns, ['year', 'week', 'characterId', 'mapId']);
$updateSql = array_map($updateRule, $columnsForUpdate);
$sql = "INSERT DELAYED INTO
activity_log (" . implode(', ', $columnsQuoted) . ") values(
" . implode(', ', $placeholder) . "
)
ON DUPLICATE KEY UPDATE
updated = NOW(),
" . implode(', ', $updateSql) . "
";
$db->exec($sql, $args);
}
$db->commit();
// clear activity data for this instance
$this->activityLogBuffer = [];
}
}
/**
* get array key from "buffered activity log" array
* @param int $characterId
* @param int $mapId
* @return int|null
*/
private function getBufferedActivityKey($characterId, $mapId){
$activityKey = null;
if(
$characterId > 0 &&
$mapId > 0
){
foreach($this->activityLogBuffer as $key => $activityData){
if(
$activityData['characterId'] === $characterId &&
$activityData['mapId'] === $mapId
){
$activityKey = $key;
break;
}
}
}
return $activityKey;
}
/**
* get Logger instance

View File

@@ -86,6 +86,8 @@ class Setup extends Controller {
'Model\ConnectionModel',
'Model\SystemSignatureModel',
'Model\ActivityLogModel',
'Model\SystemShipKillModel',
'Model\SystemPodKillModel',
'Model\SystemFactionKillModel',

View File

@@ -47,7 +47,7 @@ class CharacterUpdate {
* delete expired character authentication data
* authentication data is used for cookie based login
* >> php index.php "/cron/deleteAuthenticationData"
* @param $f3
* @param \Base $f3
*/
function deleteAuthenticationData($f3){
DB\Database::instance()->getDB('PF');

View File

@@ -35,11 +35,6 @@ class MapUpdate {
TIMESTAMPDIFF(DAY, map.updated, NOW() ) > :lifetime";
$pfDB->exec($sqlDeactivateExpiredMaps, ['lifetime' => $privateMapLifetime]);
$deactivatedMapsCount = $pfDB->count();
// Log ------------------------
$log = new \Log('cron_' . __FUNCTION__ . '.log');
$log->write( sprintf(self::LOG_TEXT_MAPS, __FUNCTION__, $deactivatedMapsCount) );
}
}
@@ -78,13 +73,13 @@ class MapUpdate {
if($signatureExpire > 0){
$pfDB = DB\Database::instance()->getDB('PF');
$sqlDeleteExpiredSignatures = "DELETE `sys` FROM
`system_signature` `sys` INNER JOIN
$sqlDeleteExpiredSignatures = "DELETE `sigs` FROM
`system_signature` `sigs` INNER JOIN
`system` ON
`system`.`id` = `sys`.`systemId`
`system`.`id` = `sigs`.`systemId`
WHERE
`system`.`active` = 0 AND
TIMESTAMPDIFF(SECOND, `sys`.`updated`, NOW() ) > :lifetime
TIMESTAMPDIFF(SECOND, `sigs`.`updated`, NOW() ) > :lifetime
";
$pfDB->exec($sqlDeleteExpiredSignatures, ['lifetime' => $signatureExpire]);

View File

@@ -0,0 +1,46 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 16.10.2016
* Time: 21:31
*/
namespace cron;
use DB;
class StatisticsUpdate {
const LOG_TEXT_STATISTICS = '%s (%d rows)';
/**
* delete old statistics
* -> older than 1 year
* >> php index.php "/cron/deleteStatisticsData"
* @param \Base $f3
*/
function deleteStatisticsData(\Base $f3){
$currentYear = (int)date('o');
$currentWeek = (int)date('W');
$expiredYear = $currentYear - 1;
$pfDB = DB\Database::instance()->getDB('PF');
$queryData = [
'yearWeekEnd' => strval($expiredYear) . str_pad($currentWeek, 2, 0, STR_PAD_LEFT)
];
$sql = "DELETE FROM
activity_log
WHERE
CONCAT(`year`, `week`) < :yearWeekEnd";
$pfDB->exec($sql, $queryData);
$deletedLogsCount = $pfDB->count();
// Log ------------------------
$log = new \Log('cron_' . __FUNCTION__ . '.log');
$log->write( sprintf(self::LOG_TEXT_STATISTICS, __FUNCTION__, $deletedLogsCount) );
}
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 01.10.2016
* Time: 15:11
*/
namespace Model;
use DB\SQL\Schema;
class ActivityLogModel extends BasicModel {
protected $table = 'activity_log';
protected $fieldConf = [
'active' => [
'type' => Schema::DT_BOOL,
'nullable' => false,
'default' => 1,
'index' => true
],
'characterId' => [
'type' => Schema::DT_INT,
'index' => true,
'belongs-to-one' => 'Model\CharacterModel',
'constraint' => [
[
'table' => 'character',
'on-delete' => 'CASCADE'
]
]
],
'mapId' => [
'type' => Schema::DT_INT,
'index' => true,
'belongs-to-one' => 'Model\MapModel',
'constraint' => [
[
'table' => 'map',
'on-delete' => 'SET NULL' // keep log data on map delete
]
]
],
// system actions -----------------------------------------------------
'systemCreate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'systemUpdate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'systemDelete' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
// connection actions -------------------------------------------------
'connectionCreate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'connectionUpdate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'connectionDelete' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
// signature actions -------------------------------------------------
'signatureCreate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'signatureUpdate' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
'signatureDelete' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => 0,
],
];
public function __construct($db = NULL, $table = NULL, $fluid = NULL, $ttl = 0){
$this->addStaticDateFieldConfig();
parent::__construct($db, $table, $fluid, $ttl);
}
/**
* extent the fieldConf Array with static fields for each table
*/
private function addStaticDateFieldConfig(){
if(is_array($this->fieldConf)){
$staticFieldConfig = [
'year' => [
'type' => Schema::DT_SMALLINT,
'nullable' => false,
'default' => date('o'), // 01.01 could be week 53 -> NOT "current" year!
'index' => true
],
'week' => [ // week in year [1-53]
'type' => Schema::DT_TINYINT,
'nullable' => false,
'default' => 1,
'index' => true
],
];
$this->fieldConf = array_merge($staticFieldConfig, $this->fieldConf);
}
}
/**
* overwrites parent
* @param null $db
* @param null $table
* @param null $fields
* @return bool
*/
public static function setup($db=null, $table=null, $fields=null){
$status = parent::setup($db,$table,$fields);
if($status === true){
$status = parent::setMultiColumnIndex(['year', 'week', 'characterId', 'mapId'], true);
if($status === true){
$status = parent::setMultiColumnIndex(['year', 'week', 'characterId']);
}
}
return $status;
}
}

View File

@@ -56,6 +56,14 @@ abstract class BasicModel extends \DB\Cortex {
*/
protected $allowActiveChange = false;
/**
* enables check for $fieldChanges on update/insert
* -> fields that should be checked need an "activity-log" flag
* in $fieldConf config
* @var bool
*/
protected $enableActivityLogging = true;
/**
* getData() cache key prefix
* -> do not change, otherwise cached data is lost
@@ -77,6 +85,12 @@ abstract class BasicModel extends \DB\Cortex {
*/
public static $enableDataImport = false;
/**
* changed fields (columns) on update/insert
* -> e.g. for character "activity logging"
* @var array
*/
protected $fieldChanges = [];
public function __construct($db = NULL, $table = NULL, $fluid = NULL, $ttl = 0){
@@ -157,10 +171,54 @@ abstract class BasicModel extends \DB\Cortex {
if(!$valid){
$this->throwValidationError($key);
}else{
$this->checkFieldForActivityLogging($key, $val);
return parent::set($key, $val);
}
}
/**
* change default "activity logging" status
* -> enable/disable
* @param $status
*/
public function setActivityLogging($status){
$this->enableActivityLogging = (bool) $status;
}
/**
* check column for value changes,
* --> if column is marked for "activity logging"
* @param string $key
* @param mixed $val
*/
protected function checkFieldForActivityLogging($key, $val){
if( $this->enableActivityLogging ){
$fieldConf = $this->fieldConf[$key];
// check for value changes if field has "activity logging" active
if($fieldConf['activity-log'] === true){
if(
is_numeric($val) ||
$fieldConf['type'] === Schema::DT_BOOL
){
$val = (int)$val;
}
if( $fieldConf['type'] === self::DT_JSON){
$currentValue = $this->get($key);
}else{
$currentValue = $this->get($key, true);
}
if($currentValue !== $val){
// field has changed
in_array($key, $this->fieldChanges) ?: $this->fieldChanges[] = $key;
}
}
}
}
/**
* setter for "active" status
* -> default: keep current "active" status
@@ -638,6 +696,18 @@ abstract class BasicModel extends \DB\Cortex {
return ['added' => $addedCount, 'updated' => $updatedCount, 'deleted' => $deletedCount];
}
/**
* buffer a new activity (action) logging
* -> increment buffered counter
* -> log character activity create/update/delete events
* @param int $characterId
* @param int $mapId
* @param string $action
*/
protected function bufferActivity($characterId, $mapId, $action){
Controller\LogController::instance()->bufferActivity($characterId, $mapId, $action);
}
/**
* get the current class name
* -> namespace not included

View File

@@ -18,11 +18,11 @@ class CharacterLogModel extends BasicModel {
/**
* caching for relational data
* -> 10s matches REST API - Expire: Header-Data
* -> 5s matches REST API - Expire: Header-Data
* for "Location" calls
* @var int
*/
protected $rel_ttl = 10;
protected $rel_ttl = 5;
protected $fieldConf = [
'active' => [

View File

@@ -8,8 +8,9 @@
namespace Model;
use Controller\Api\Route;
use DB\SQL\Schema;
use Controller;
use Controller\Api\Route;
class ConnectionModel extends BasicModel{
@@ -42,7 +43,8 @@ class ConnectionModel extends BasicModel{
'table' => 'system',
'on-delete' => 'CASCADE'
]
]
],
'activity-log' => true
],
'target' => [
'type' => Schema::DT_INT,
@@ -53,15 +55,18 @@ class ConnectionModel extends BasicModel{
'table' => 'system',
'on-delete' => 'CASCADE'
]
]
],
'activity-log' => true
],
'scope' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
'default' => '',
'activity-log' => true
],
'type' => [
'type' => self::DT_JSON
'type' => self::DT_JSON,
'activity-log' => true
],
'eolUpdated' => [
'type' => Schema::DT_TIMESTAMP,
@@ -212,6 +217,66 @@ class ConnectionModel extends BasicModel{
return parent::beforeInsertEvent($self, $pkeys);
}
/**
* Event "Hook" function
* return false will stop any further action
* @param self $self
* @param $pkeys
*/
public function afterInsertEvent($self, $pkeys){
parent::afterInsertEvent($self, $pkeys);
$self->logActivity('connectionCreate');
}
/**
* Event "Hook" function
* return false will stop any further action
* @param self $self
* @param $pkeys
*/
public function afterUpdateEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
$self->logActivity('connectionUpdate');
}
/**
* Event "Hook" function
* can be overwritten
* @param self $self
* @param $pkeys
*/
public function afterEraseEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
$self->logActivity('connectionDelete');
}
/**
* log character activity create/update/delete events
* @param string $action
*/
protected function logActivity($action){
if(
$this->enableActivityLogging &&
(
$action === 'connectionDelete' ||
!empty($this->fieldChanges)
) &&
$this->get('mapId')->isActivityLogEnabled()
){
// TODO implement "dependency injection" for active character object...
$controller = new Controller\Controller();
$currentActiveCharacter = $controller->getCharacter();
$characterId = is_null($currentActiveCharacter) ? 0 : $currentActiveCharacter->_id;
$mapId = $this->get('mapId', true);
parent::bufferActivity($characterId, $mapId, $action);
}
}
/**
* save connection and check if obj is valid
* @return ConnectionModel|false

View File

@@ -609,6 +609,31 @@ class MapModel extends BasicModel {
}
}
/**
* check if "activity logging" is enabled for this map type
* @return bool
*/
public function isActivityLogEnabled(){
$f3 = self::getF3();
$activityLogEnabled = false;
if( $this->isAlliance() ){
if( $f3->get('PATHFINDER.MAP.ALLIANCE.ACTIVITY_LOGGING') ){
$activityLogEnabled = true;
}
}elseif( $this->isCorporation() ){
if( $f3->get('PATHFINDER.MAP.CORPORATION.ACTIVITY_LOGGING') ){
$activityLogEnabled = true;
}
}elseif( $this->isPrivate() ){
if( $f3->get('PATHFINDER.MAP.PRIVATE.ACTIVITY_LOGGING') ){
$activityLogEnabled = true;
}
}
return $activityLogEnabled;
}
/**
* checks whether this map is private map
* @return bool

View File

@@ -24,7 +24,8 @@ class SystemModel extends BasicModel {
'type' => Schema::DT_BOOL,
'nullable' => false,
'default' => 1,
'index' => true
'index' => true,
'activity-log' => true
],
'mapId' => [
'type' => Schema::DT_INT,
@@ -49,7 +50,8 @@ class SystemModel extends BasicModel {
'alias' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
'default' => '',
'activity-log' => true
],
'regionId' => [
'type' => Schema::DT_INT,
@@ -106,12 +108,14 @@ class SystemModel extends BasicModel {
'table' => 'system_status',
'on-delete' => 'CASCADE'
]
]
],
'activity-log' => true
],
'locked' => [
'type' => Schema::DT_BOOL,
'nullable' => false,
'default' => 0
'default' => 0,
'activity-log' => true
],
'rallyUpdated' => [
'type' => Schema::DT_TIMESTAMP,
@@ -125,7 +129,8 @@ class SystemModel extends BasicModel {
'description' => [
'type' => Schema::DT_VARCHAR512,
'nullable' => false,
'default' => ''
'default' => '',
'activity-log' => true
],
'posX' => [
'type' => Schema::DT_INT,
@@ -351,6 +356,18 @@ class SystemModel extends BasicModel {
return $rally;
}
/**
* Event "Hook" function
* return false will stop any further action
* @param self $self
* @param $pkeys
*/
public function afterInsertEvent($self, $pkeys){
parent::afterInsertEvent($self, $pkeys);
$self->logActivity('systemCreate');
}
/**
* Event "Hook" function
* can be overwritten
@@ -360,6 +377,8 @@ class SystemModel extends BasicModel {
* @return bool
*/
public function beforeUpdateEvent($self, $pkeys){
$status = parent::beforeUpdateEvent($self, $pkeys);
if( !$self->isActive()){
// system becomes inactive
// reset "rally point" fields
@@ -372,7 +391,8 @@ class SystemModel extends BasicModel {
$connection->erase();
}
}
return true;
return $status;
}
/**
@@ -382,6 +402,8 @@ class SystemModel extends BasicModel {
* @param $pkeys
*/
public function afterUpdateEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
// check if rally point mail should be send
if(
$self->newRallyPointSet &&
@@ -389,6 +411,41 @@ class SystemModel extends BasicModel {
){
$self->sendRallyPointMail();
}
$activity = ($self->isActive()) ? 'systemUpdate' : 'systemDelete';
$self->logActivity($activity);
}
/**
* Event "Hook" function
* can be overwritten
* @param self $self
* @param $pkeys
*/
public function afterEraseEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
$self->logActivity('systemDelete');
}
/**
* log character activity create/update/delete events
* @param string $action
*/
protected function logActivity($action){
if(
$this->enableActivityLogging &&
(
$action === 'systemDelete' ||
!empty($this->fieldChanges)
) &&
$this->get('mapId')->isActivityLogEnabled()
){
$characterId = $this->get('updatedCharacterId', true);
$mapId = $this->get('mapId', true);
parent::bufferActivity($characterId, $mapId, $action);
}
}
/**

View File

@@ -37,22 +37,26 @@ class SystemSignatureModel extends BasicModel {
'nullable' => false,
'default' => 0,
'index' => true,
'activity-log' => true
],
'typeId' => [
'type' => Schema::DT_INT,
'nullable' => false,
'default' => 0,
'index' => true,
'activity-log' => true
],
'name' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
'default' => '',
'activity-log' => true
],
'description' => [
'type' => Schema::DT_VARCHAR512,
'nullable' => false,
'default' => ''
'default' => '',
'activity-log' => true
],
'createdCharacterId' => [
'type' => Schema::DT_INT,
@@ -172,6 +176,68 @@ class SystemSignatureModel extends BasicModel {
}
}
/**
* Event "Hook" function
* return false will stop any further action
* @param self $self
* @param $pkeys
*/
public function afterInsertEvent($self, $pkeys){
parent::afterInsertEvent($self, $pkeys);
$self->logActivity('signatureCreate');
}
/**
* Event "Hook" function
* return false will stop any further action
* @param self $self
* @param $pkeys
*/
public function afterUpdateEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
$self->logActivity('signatureUpdate');
}
/**
* Event "Hook" function
* can be overwritten
* @param self $self
* @param $pkeys
*/
public function afterEraseEvent($self, $pkeys){
parent::afterUpdateEvent($self, $pkeys);
$self->logActivity('signatureDelete');
}
/**
* log character activity create/update/delete events
* @param string $action
*/
protected function logActivity($action){
if($this->enableActivityLogging){
/**
* @var $map MapModel
*/
$map = $this->get('systemId')->get('mapId');
if(
(
$action === 'signatureDelete' ||
!empty($this->fieldChanges)
) &&
$map->isActivityLogEnabled()
){
$characterId = $this->get('updatedCharacterId', true);
$mapId = $map->_id;
parent::bufferActivity($characterId, $mapId, $action);
}
}
}
/**
* overwrites parent
* @param null $db

View File

@@ -3,7 +3,7 @@
[PATHFINDER]
NAME = Pathfinder
; installed version (used for CSS/JS cache busting)
VERSION = v1.1.5
VERSION = v1.1.6
; contact information [optional]
CONTACT = https://github.com/exodus4d
; public contact email [optional]
@@ -45,23 +45,32 @@ LOGIN = templates/view/login.html
; MAP =============================================================================================
; Map settings for "private", "corporation" and "alliance" maps
; LIFETIME: Map will be deleted after "X" days, by cronjob
; MAX_COUNT: Users can create/view up to "X" maps of a type
; MAX_SHARED: Max number of shared entities per map
; LIFETIME (days):
; - Map will be deleted after "X" days, by cronjob
; MAX_COUNT:
; - Users can create/view up to "X" maps of a type
; MAX_SHARED:
; - Max number of shared entities per map
; ACTIVITY_LOGGING (0: disable, 1: enable):
; - Whether user activity should be logged for a map type
; - E.g. create/update/delete of systems/connections/signatures
[PATHFINDER.MAP.PRIVATE]
LIFETIME = 14
MAX_COUNT = 3
MAX_SHARED = 10
ACTIVITY_LOGGING = 1
[PATHFINDER.MAP.CORPORATION]
LIFETIME = 99999
MAX_COUNT = 3
MAX_SHARED = 3
ACTIVITY_LOGGING = 1
[PATHFINDER.MAP.ALLIANCE]
LIFETIME = 99999
MAX_COUNT = 3
MAX_SHARED = 2
ACTIVITY_LOGGING = 0
; Route search ====================================================================================
[PATHFINDER.ROUTE]
@@ -108,8 +117,8 @@ EXECUTION_LIMIT = 50
CHARACTER_LOG = 300
; expire time for static system data (seconds) (default: 20d)
CONSTELLATION_SYSTEMS = 1728000
; max expire time. Expired cache files will be deleted by cronjob (seconds) (default: 20d)
EXPIRE_MAX = 1728000
; max expire time. Expired cache files will be deleted by cronjob (seconds) (default: 10d)
EXPIRE_MAX = 864000
; expire time for signatures (inactive systems) (seconds) (default 3d)
EXPIRE_SIGNATURES = 259200

View File

@@ -38,9 +38,10 @@ requirejs.config({
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
bootbox: 'lib/bootbox.min', // v4.4.0 Bootbox.js - custom dialogs - http://bootboxjs.com
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.2.0 Inline Chart - http://benpickles.github.io/peity/
dragToSelect: 'lib/jquery.dragToSelect', // v1.1 Drag to Select - http://andreaslagerkvist.com/jquery/drag-to-select
hoverIntent: 'lib/jquery.hoverIntent.minified', // v1.8.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
fullScreen: 'lib/jquery.fullscreen.min', // v0.5.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
fullScreen: 'lib/jquery.fullscreen.min', // v0.6.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
select2: 'lib/select2.min', // v4.0.3 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
@@ -123,6 +124,9 @@ requirejs.config({
easyPieChart: {
deps : ['jquery']
},
peityInlineChart: {
deps : ['jquery']
},
dragToSelect: {
deps : ['jquery']
},

View File

@@ -224,7 +224,8 @@ define(['jquery'], function($) {
3: 'Minor Perimeter Reservoir', //*
4: 'Sizeable Perimeter Reservoir', //*
5: 'Ordinary Perimeter Reservoir', //*
6: 'Vast Frontier Reservoir' //*
6: 'Vast Frontier Reservoir', //*
7: 'Bountiful Frontier Reservoir' //*
},
5: { // Wormhole
// no *wandering* w-space -> k-space wormholes
@@ -235,7 +236,8 @@ define(['jquery'], function($) {
2: 'Common Perimeter Deposit', //*
3: 'Unexceptional Frontier Deposit', //*
4: 'Average Frontier Deposit', //*
5: 'Unusual Core Deposit' //*
5: 'Unusual Core Deposit', //*
6: 'Infrequent Core Deposit' //*
},
7: { // Ghost

View File

@@ -35,7 +35,6 @@ define(['jquery'], function($) {
getSystemGraphData: 'api/system/graphData', // ajax URL - get all system graph data
getConstellationData: 'api/system/constellationData', // ajax URL - get system constellation data
setDestination: 'api/system/setDestination', // ajax URL - set destination
// connection API
saveConnection: 'api/connection/save', // ajax URL - save new connection to map
deleteConnection: 'api/connection/delete', // ajax URL - delete connection from map
@@ -45,6 +44,8 @@ define(['jquery'], function($) {
deleteSignatureData: 'api/signature/delete', // ajax URL - delete signature data for system
// route API
searchRoute: 'api/route/search', // ajax URL - search system routes
// stats API
getStatisticsData: 'api/statistic/getData', // ajax URL - get statistics data (activity log)
// GitHub API
gitHubReleases: 'api/github/releases' // ajax URL - get release info from GitHub
},
@@ -52,6 +53,12 @@ define(['jquery'], function($) {
ccpImageServer: 'https://image.eveonline.com/', // CCP image Server
zKillboard: 'https://zkillboard.com/api/' // killboard api
},
breakpoints: [
{ name: 'desktop', width: Infinity },
{ name: 'tablet', width: 1200 },
{ name: 'fablet', width: 780 },
{ name: 'phone', width: 480 }
],
animationSpeed: {
splashOverlay: 300, // "splash" loading overlay
headerLink: 100, // links in head bar

View File

@@ -59,6 +59,9 @@ define([
galleryThumbContainerId: 'pf-landing-gallery-thumb-container', // id for gallery thumb images
galleryCarouselId: 'pf-landing-gallery-carousel', // id for "carousel" element
// notification panel
notificationPanelId: 'pf-notification-panel', // id for "notification panel" (e.g. last update information)
// server panel
serverPanelId: 'pf-server-panel', // id for EVE Online server status panel
@@ -102,6 +105,14 @@ define([
return '';
};
/**
* set link observer for "version info" dialog
*/
var setVersionLinkObserver = function(){
$('.' + config.navigationVersionLinkClass).off('click').on('click', function(e){
$.fn.releasesDialog();
});
};
/**
* set page observer
@@ -118,11 +129,6 @@ define([
setCookie('cookie', 1, 365);
});
// releases -----------------------------------------------------------
$('.' + config.navigationVersionLinkClass).on('click', function(e){
$.fn.releasesDialog();
});
// manual -------------------------------------------------------------
$('.' + config.navigationLinkManualClass).on('click', function(e){
e.preventDefault();
@@ -135,6 +141,9 @@ define([
$.fn.showCreditsDialog(false, true);
});
// releases -----------------------------------------------------------
setVersionLinkObserver();
// tooltips -----------------------------------------------------------
var mapTooltipOptions = {
toggle: 'tooltip',
@@ -326,6 +335,9 @@ define([
}
};
/**
* init "YouTube" video preview
*/
var initYoutube = function(){
$('.youtube').each(function() {
@@ -446,6 +458,50 @@ define([
}).fail(handleAjaxErrorResponse);
};
/**
* show "notification panel" to user
* -> checks if panel not already shown
*/
var initNotificationPanel = function(){
var storageKey = 'notification_panel';
var currentVersion = $('body').data('version');
var showNotificationPanel = function(){
var data = {};
requirejs(['text!templates/ui/notice.html', 'mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
var notificationPanel = $('#' + config.notificationPanelId);
notificationPanel.html(content);
notificationPanel.velocity('transition.slideUpIn', {
duration: 300,
complete: function(){
setVersionLinkObserver();
// mark panel as "shown"
Util.getLocalStorage().setItem(storageKey, currentVersion);
}
});
});
};
Util.getLocalStorage().getItem(storageKey).then(function(data){
// check if panel was shown before
if(data){
if(data !== this.version){
// show current panel
showNotificationPanel();
}
}else{
// show current panel
showNotificationPanel();
}
}.bind({
version: currentVersion
}));
};
/**
* load character data from cookie information
* -> all validation is done server side!
@@ -520,75 +576,71 @@ define([
}
});
};
// --------------------------------------------------------------------
// request character data for each character panel
$('.' + config.characterSelectionClass + ' .pf-dynamic-area').each(function(){
var characterElement = $(this);
requirejs(['text!templates/ui/character_panel.html', 'mustache'], function(template, Mustache){
characterElement.showLoadingAnimation();
$('.' + config.characterSelectionClass + ' .pf-dynamic-area').each(function(){
var characterElement = $(this);
var requestData = {
cookie: characterElement.data('cookie')
};
characterElement.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.getCookieCharacterData,
data: requestData,
dataType: 'json',
context: {
href: characterElement.data('href'),
cookieName: requestData.cookie,
characterElement: characterElement
}
}).done(function(responseData, textStatus, request){
var characterElement = this.characterElement;
characterElement.hideLoadingAnimation();
var requestData = {
cookie: characterElement.data('cookie')
};
if(
responseData.error &&
responseData.error.length > 0
){
$('.' + config.dynamicMessageContainerClass).showMessage({
type: responseData.error[0].type,
title: 'Character verification failed',
text: responseData.error[0].message
});
}
$.ajax({
type: 'POST',
url: Init.path.getCookieCharacterData,
data: requestData,
dataType: 'json',
context: {
cookieName: requestData.cookie,
characterElement: characterElement
}
}).done(function(responseData, textStatus, request){
this.characterElement.hideLoadingAnimation();
if(responseData.hasOwnProperty('character')){
if(
responseData.error &&
responseData.error.length > 0
){
$('.' + config.dynamicMessageContainerClass).showMessage({
type: responseData.error[0].type,
title: 'Character verification failed',
text: responseData.error[0].message
});
}
var data = {
link: this.href,
cookieName: this.cookieName,
character: responseData.character
};
if(responseData.hasOwnProperty('character')){
var data = {
link: this.characterElement.data('href'),
cookieName: this.cookieName,
character: responseData.character
};
requirejs(['text!templates/ui/character_panel.html', 'mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
characterElement.html(content);
this.characterElement.html(content);
// show character panel (animation settings)
initCharacterAnimation(characterElement.find('.' + config.characterImageWrapperClass));
});
}else{
initCharacterAnimation(this.characterElement.find('.' + config.characterImageWrapperClass));
}else{
// character data not available -> remove panel
removeCharacterPanel(this.characterElement);
}
}).fail(function( jqXHR, status, error) {
var characterElement = this.characterElement;
characterElement.hideLoadingAnimation();
// character data not available -> remove panel
removeCharacterPanel(this.characterElement);
}
}).fail(function( jqXHR, status, error) {
var characterElement = this.characterElement;
characterElement.hideLoadingAnimation();
// character data not available -> remove panel
removeCharacterPanel(this.characterElement);
});
});
});
};
/**
* default ajax error handler
* -> show user notifications
@@ -682,6 +734,10 @@ define([
// init server status information
initServerStatus();
// init notification panel
initNotificationPanel();
// init character select
initCharacterSelect();
// init page observer

View File

@@ -1315,8 +1315,8 @@ define([
setConnectionObserver(map, connection);
}
var addType = $(newConnectionData.type).not(connectionData.type).get();
var removeType = $(connectionData.type).not(newConnectionData.type).get();
var addType = newConnectionData.type.diff( connectionData.type );
var removeType = connectionData.type.diff( newConnectionData.type );
// check if source or target has changed
if(connectionData.source !== newConnectionData.source ){
@@ -1415,7 +1415,7 @@ define([
{subIcon: '', subAction: 'filter_jumpbridge', subText: 'jumpbridge'}
]},
{divider: true, action: 'delete_systems'},
{icon: 'fa-eraser', action: 'delete_systems', text: 'delete systems'}
{icon: 'fa-trash', action: 'delete_systems', text: 'delete systems'}
]
};
@@ -1452,7 +1452,7 @@ define([
]},
{divider: true, action: 'delete_connection'},
{icon: 'fa-eraser', action: 'delete_connection', text: 'delete'}
{icon: 'fa-trash', action: 'delete_connection', text: 'delete'}
]
};
@@ -1495,7 +1495,7 @@ define([
{subIcon: 'fa-step-forward', subAction: 'add_last_waypoint', subText: 'add new [end]'}
]},
{divider: true, action: 'delete_system'},
{icon: 'fa-eraser', action: 'delete_system', text: 'delete system(s)'}
{icon: 'fa-trash', action: 'delete_system', text: 'delete system(s)'}
]
};
@@ -1624,6 +1624,9 @@ define([
var hoverSystem = $(this).parents('.' + config.systemClass);
var hoverSystemId = hoverSystem.attr('id');
// bring system in front (increase zIndex)
hoverSystem.updateSystemZIndex();
// get ship counter and calculate expand height
var userCount = parseInt( hoverSystem.data('userCount') );

View File

@@ -19,6 +19,8 @@ define([
* main init "map" page
*/
$(function(){
Util.initPrototypes();
// set default AJAX config
Util.ajaxSetup();
@@ -60,6 +62,7 @@ define([
Init.maxSharedCount = initData.maxSharedCount;
Init.routes = initData.routes;
Init.notificationStatus = initData.notificationStatus;
Init.activityLogging = initData.activityLogging;
// init tab change observer, Once the timers are available
Page.initTabChangeObserver();

View File

@@ -12,6 +12,7 @@ define([
'text!templates/modules/header.html',
'text!templates/modules/footer.html',
'dialog/notification',
'dialog/stats',
'dialog/map_info',
'dialog/account_settings',
'dialog/manual',
@@ -115,6 +116,22 @@ define([
setDocumentObserver();
};
/**
* get main menu title element
* @param title
* @returns {JQuery|*|jQuery}
*/
var getMenuHeadline = function(title){
return $('<div>', {
class: 'panel-heading'
}).prepend(
$('<h2>',{
class: 'panel-title',
text: title
})
);
};
/**
* load left menu content options
*/
@@ -132,20 +149,27 @@ define([
class: 'fa fa-home fa-fw'
})
)
).append(
getMenuHeadline('Information')
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-info',
href: '#'
}).html('&nbsp;&nbsp;Settings').prepend(
}).html('&nbsp;&nbsp;Statistics').prepend(
$('<i>',{
class: 'fa fa-sliders fa-fw'
class: 'fa fa-line-chart fa-fw'
})
).append(
$('<span>',{
class: 'badge bg-color bg-color-gray txt-color txt-color-warning',
text: 'beta'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowSettingsDialog');
$(document).triggerMenuEvent('ShowStatsDialog');
})
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-info',
href: '#'
}).html('&nbsp;&nbsp;Effect info').prepend(
$('<i>',{
@@ -156,7 +180,7 @@ define([
})
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-info',
href: '#'
}).html('&nbsp;&nbsp;Jump info').prepend(
$('<i>',{
@@ -165,6 +189,19 @@ define([
).on('click', function(){
$(document).triggerMenuEvent('ShowJumpInfo');
})
).append(
getMenuHeadline('Settings')
).append(
$('<a>', {
class: 'list-group-item',
href: '#'
}).html('&nbsp;&nbsp;Account').prepend(
$('<i>',{
class: 'fa fa-sliders fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowSettingsDialog');
})
).append(
$('<a>', {
class: 'list-group-item hide', // trigger by js
@@ -182,7 +219,7 @@ define([
if($.fullscreen.isFullScreen()){
$.fullscreen.exit();
}else{
fullScreenElement.fullscreen({overflow: 'overflow-y', toggleClass: config.fullScreenClass});
fullScreenElement.fullscreen({overflow: 'scroll', toggleClass: config.fullScreenClass});
}
});
})
@@ -197,9 +234,11 @@ define([
).on('click', function(){
$(document).triggerMenuEvent('NotificationTest');
})
).append(
getMenuHeadline('Danger zone')
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-danger',
href: '#'
}).html('&nbsp;&nbsp;Delete account').prepend(
$('<i>',{
@@ -210,7 +249,7 @@ define([
})
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-warning',
href: '#'
}).html('&nbsp;&nbsp;Logout').prepend(
$('<i>',{
@@ -240,24 +279,26 @@ define([
$('<a>', {
class: 'list-group-item',
href: '#'
}).html('&nbsp;&nbsp;Info').prepend(
$('<i>',{
class: 'fa fa-info fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowMapInfo');
}).html('&nbsp;&nbsp;Status').prepend(
$('<i>',{
class: 'fa fa-info fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowMapInfo');
})
).append(
getMenuHeadline('Settings')
).append(
$('<a>', {
class: 'list-group-item',
href: '#'
}).html('&nbsp;&nbsp;Settings').prepend(
}).html('&nbsp;&nbsp;Map config').prepend(
$('<i>',{
class: 'fa fa-sliders fa-fw'
class: 'fa fa-gears fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowMapSettings', {tab: 'settings'});
})
$(document).triggerMenuEvent('ShowMapSettings', {tab: 'settings'});
})
).append(
$('<a>', {
class: 'list-group-item',
@@ -289,34 +330,38 @@ define([
});
})
).append(
$('<a>', {
class: 'list-group-item',
href: '#'
}).html('&nbsp;&nbsp;Task-Manager').prepend(
$('<i>',{
class: 'fa fa-tasks fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowTaskManager');
})
getMenuHeadline('Help')
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-info',
href: '#'
}).html('&nbsp;&nbsp;Manual').prepend(
$('<i>',{
class: 'fa fa-info fa-fw'
class: 'fa fa-book fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('Manual');
})
).append(
$('<a>', {
class: 'list-group-item',
class: 'list-group-item list-group-item-info',
href: '#'
}).html('&nbsp;&nbsp;Delete').prepend(
}).html('&nbsp;&nbsp;Task-Manager').prepend(
$('<i>',{
class: 'fa fa-eraser fa-fw'
class: 'fa fa-tasks fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('ShowTaskManager');
})
).append(
getMenuHeadline('Danger zone')
).append(
$('<a>', {
class: 'list-group-item list-group-item-danger',
href: '#'
}).html('&nbsp;&nbsp;Delete map').prepend(
$('<i>',{
class: 'fa fa-trash fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('DeleteMap');
@@ -494,8 +539,14 @@ define([
}
});
$(document).on('pf:menuShowStatsDialog', function(e){
// show user activity stats dialog
$.fn.showStatsDialog();
return false;
});
$(document).on('pf:menuShowSystemEffectInfo', function(e){
// show system effects info box
// show system effects dialog
$.fn.showSystemEffectInfoDialog();
return false;
});

View File

@@ -295,12 +295,7 @@ define([
order: [[ 9, 'desc' ], [ 3, 'asc' ]],
autoWidth: false,
responsive: {
breakpoints: [
{ name: 'desktop', width: Infinity },
{ name: 'tablet', width: 1200 },
{ name: 'fablet', width: 780 },
{ name: 'phone', width: 480 }
],
breakpoints: Init.breakpoints,
details: false
},
hover: false,

711
js/app/ui/dialog/stats.js Normal file
View File

@@ -0,0 +1,711 @@
/**
* activity stats dialog
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox'
], function($, Init, Util, Render, bootbox, MapUtil) {
'use strict';
var config = {
// dialog
statsDialogId: 'pf-stats-dialog', // id for "stats" dialog
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
dialogNavigationOffsetClass : 'pf-dialog-navigation-offset', // class for "current" offset filter
dialogNavigationPrevClass : 'pf-dialog-navigation-prev', // class for "prev" period load
dialogNavigationNextClass : 'pf-dialog-navigation-next', // class for "next" period load
// stats/dataTable
statsContainerId: 'pf-stats-dialog-container', // class for statistics container (dynamic ajax content)
statsTableId: 'pf-stats-table', // id for statistics table element
tableImageCellClass: 'pf-table-image-cell', // class for table "image" cells
// charts
statsLineChartClass: 'pf-line-chart' // class for inline chart elements
};
/**
* init blank statistics dataTable
* @param dialogElement
*/
var initStatsTable = function(dialogElement){
var columnNumberWidth = 35;
var lineColor = '#477372';
// render function for inline-chart columns
var renderInlineChartColumn = function(data, type, row, meta){
/*
switch(data.type){
case 'C': lineColor = '#5cb85c'; break;
case 'U': lineColor = '#e28a0d'; break;
case 'D': lineColor = '#a52521'; break;
}*/
if( /^\d+$/.test(data.data) ){
// single digit (e.g. single week filter)
return data.data;
}else{
// period -> prepare line chart
return '<span class="' + config.statsLineChartClass + '" data-peity=\'{ "stroke": "' + lineColor + '" }\'>' + data.data + '</span>';
}
};
// render function for numeric columns
var renderNumericColumn = function(data, type, row, meta){
return data.toLocaleString();
};
// get table element
// Due to "complex" table headers, they are already rendered and part of the stats.html file
var table = dialogElement.find('#' + config.statsTableId);
var statsTable = table.DataTable({
pageLength: 30,
lengthMenu: [[10, 20, 30, 50], [10, 20, 30, 50]],
paging: true,
ordering: true,
order: [ 16, 'desc' ],
info: true,
searching: true,
hover: false,
autoWidth: false,
language: {
emptyTable: 'No statistics found',
zeroRecords: 'No characters found',
lengthMenu: 'Show _MENU_ characters',
info: 'Showing _START_ to _END_ of _TOTAL_ characters'
},
columnDefs: [
{
targets: 0,
title: '<i class="fa fa-hashtag"></i>',
orderable: false,
searchable: false,
width: 10,
class: 'text-right',
data: 'character.id'
},{
targets: 1,
title: '',
orderable: false,
searchable: false,
width: 26,
className: ['text-center', config.tableImageCellClass].join(' '),
data: 'character',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Character/' + data.id + '_32.jpg" />';
}
}
},{
targets: 2,
title: 'name',
width: 200,
data: 'character',
render: {
_: 'name',
sort: 'name'
}
},{
targets: 3,
title: 'last login',
searchable: false,
width: 70,
className: ['text-right', 'separator-right'].join(' '),
data: 'character',
render: {
_: 'lastLogin',
sort: 'lastLogin'
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
$(cell).initTimestampCounter();
}
},{
targets: 4,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 5,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 6,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'systemDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 7,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'hidden-xs', 'hidden-sm', 'separator-right'].join(' '),
data: 'systemSum',
render: {
_: renderNumericColumn
}
},{
targets: 8,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 9,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 10,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'connectionDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 11,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'hidden-xs', 'hidden-sm', 'separator-right'].join(' '),
data: 'connectionSum',
render: {
_: renderNumericColumn
}
},{
targets: 12,
title: '<span title="created" data-toggle="tooltip">C&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureCreate',
render: {
_: renderInlineChartColumn
}
},{
targets: 13,
title: '<span title="updated" data-toggle="tooltip">U&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureUpdate',
render: {
_: renderInlineChartColumn
}
},{
targets: 14,
title: '<span title="deleted" data-toggle="tooltip">D&nbsp;&nbsp;</span>',
orderable: false,
searchable: false,
width: columnNumberWidth,
className: ['text-right', 'hidden-xs', 'hidden-sm'].join(' '),
data: 'signatureDelete',
render: {
_: renderInlineChartColumn
}
},{
targets: 15,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: ['text-right', 'hidden-xs', 'hidden-sm', 'separator-right'].join(' '),
data: 'signatureSum',
render: {
_: renderNumericColumn
}
},{
targets: 16,
title: 'Σ&nbsp;&nbsp;',
searchable: false,
width: 20,
className: 'text-right',
data: 'totalSum',
render: {
_: renderNumericColumn
}
}
],
initComplete: function(settings){
var tableApi = this.api();
// initial statistics data request
var requestData = getRequestDataFromTabPanels(dialogElement);
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
},
drawCallback: function(settings){
this.api().rows().nodes().to$().each(function(i, row){
$(row).find('.' + config.statsLineChartClass).peity('line', {
fill: 'transparent',
height: 18,
min: 0,
width: 50
});
});
},
footerCallback: function ( row, data, start, end, display ) {
var api = this.api();
var sumColumnIndexes = [7, 11, 15, 16];
// column data for "sum" columns over this page
var pageTotalColumns = api
.columns( sumColumnIndexes, { page: 'current'} )
.data();
// sum columns for "total" sum
pageTotalColumns.each(function(colData, index){
pageTotalColumns[index] = colData.reduce(function(a, b){
return a + b;
}, 0);
});
$(sumColumnIndexes).each(function(index, value){
$( api.column( value ).footer() ).text( renderNumericColumn(pageTotalColumns[index]) );
});
},
data: [] // will be added dynamic
});
statsTable.on('order.dt search.dt', function(){
statsTable.column(0, {search:'applied', order:'applied'}).nodes().each(function(cell, i){
$(cell).html( (i + 1) + '.&nbsp;&nbsp;');
});
}).draw();
var tooltipElements = dialogElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
};
/**
* request raw statistics data and execute callback
* @param requestData
* @param context
*/
var getStatsData = function(requestData, context){
context.dynamicArea = $('#' + config.statsContainerId + ' .pf-dynamic-area');
context.dynamicArea.showLoadingAnimation();
$.ajax({
type: 'POST',
url: Init.path.getStatisticsData,
data: requestData,
dataType: 'json',
context: context
}).done(function(data){
this.dynamicArea.hideLoadingAnimation();
this.callback(data);
}).fail(function( jqXHR, status, error) {
var reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': loadStatistics', text: reason, type: 'warning'});
});
};
/**
* update dataTable with response data
* update "header"/"filter" elements in dialog
* @param responseData
*/
var drawStatsTable = function(responseData){
var dialogElement = $('#' + config.statsDialogId);
// update filter/header -----------------------------------------------------------------------------
var navigationListElements = $('.' + config.dialogNavigationClass);
navigationListElements.find('a[data-type="typeId"][data-value="' + responseData.typeId + '"]').tab('show');
navigationListElements.find('a[data-type="period"][data-value="' + responseData.period + '"]').tab('show');
// update period pagination -------------------------------------------------------------------------
var prevButton = dialogElement.find('.' + config.dialogNavigationPrevClass);
prevButton.data('newOffset', responseData.prev);
prevButton.find('span').text('Week ' + responseData.prev.week + ', ' + responseData.prev.year);
prevButton.css('visibility', 'visible');
var nextButton = dialogElement.find('.' + config.dialogNavigationNextClass);
if(responseData.next){
nextButton.data('newOffset', responseData.next);
nextButton.find('span').text('Week ' + responseData.next.week + ', ' + responseData.next.year);
nextButton.css('visibility', 'visible');
}else{
nextButton.css('visibility', 'hidden');
}
// update current period information label ----------------------------------------------------------
// if period == "weekly" there is no "offset" -> just a single week
var offsetText = 'Week ' + responseData.start.week + ', ' + responseData.start.year;
if(responseData.period !== 'weekly'){
offsetText += ' <small><i class="fa fa-fw fa-minus"></i></small> ' +
'Week ' + responseData.offset.week + ', ' + responseData.offset.year;
}
dialogElement.find('.' + config.dialogNavigationOffsetClass)
.data('start', responseData.start)
.data('period', responseData.period)
.html(offsetText);
// clear and (re)-fill table ------------------------------------------------------------------------
var formattedData = formatStatisticsData(responseData);
this.tableApi.clear();
this.tableApi.rows.add(formattedData).draw();
};
/**
* format statistics data for dataTable
* -> e.g. format inline-chart data
* @param statsData
* @returns {Array}
*/
var formatStatisticsData = function(statsData){
var formattedData = [];
var yearStart = statsData.start.year;
var weekStart = statsData.start.week;
var weekCount = statsData.weekCount;
var yearWeeks = statsData.yearWeeks;
var tempRand = function(min, max){
return Math.random() * (max - min) + min;
};
// format/sum week statistics data for inline charts
var formatWeekData = function(weeksData){
var currentYear = yearStart;
var currentWeek = weekStart;
var formattedWeeksData = {
systemCreate: [],
systemUpdate: [],
systemDelete: [],
connectionCreate: [],
connectionUpdate: [],
connectionDelete: [],
signatureCreate: [],
signatureUpdate: [],
signatureDelete: [],
systemSum: 0,
connectionSum: 0,
signatureSum: 0
};
for(let i = 0; i < weekCount; i++){
let yearWeekProp = currentYear + '' + currentWeek;
if(weeksData.hasOwnProperty( yearWeekProp )){
let weekData = weeksData[ yearWeekProp ];
// system -------------------------------------------------------------------------------
formattedWeeksData.systemCreate.push( weekData.systemCreate );
formattedWeeksData.systemSum += parseInt( weekData.systemCreate );
formattedWeeksData.systemUpdate.push( weekData.systemUpdate );
formattedWeeksData.systemSum += parseInt( weekData.systemUpdate );
formattedWeeksData.systemDelete.push( weekData.systemDelete );
formattedWeeksData.systemSum += parseInt( weekData.systemDelete );
// connection ---------------------------------------------------------------------------
formattedWeeksData.connectionCreate.push( weekData.connectionCreate );
formattedWeeksData.connectionSum += parseInt( weekData.connectionCreate );
formattedWeeksData.connectionUpdate.push( weekData.connectionUpdate );
formattedWeeksData.connectionSum += parseInt( weekData.connectionUpdate );
formattedWeeksData.connectionDelete.push( weekData.connectionDelete );
formattedWeeksData.connectionSum += parseInt( weekData.connectionDelete );
// signature ----------------------------------------------------------------------------
formattedWeeksData.signatureCreate.push( weekData.signatureCreate );
formattedWeeksData.signatureSum += parseInt( weekData.signatureCreate );
formattedWeeksData.signatureUpdate.push( weekData.signatureUpdate );
formattedWeeksData.signatureSum += parseInt( weekData.signatureUpdate );
formattedWeeksData.signatureDelete.push( weekData.signatureDelete );
formattedWeeksData.signatureSum += parseInt( weekData.signatureDelete );
}else{
// system -------------------------------------------------------------------------------
formattedWeeksData.systemCreate.push(0);
formattedWeeksData.systemUpdate.push(0);
formattedWeeksData.systemDelete.push(0);
// connection ---------------------------------------------------------------------------
formattedWeeksData.connectionCreate.push(0);
formattedWeeksData.connectionUpdate.push(0);
formattedWeeksData.connectionDelete.push(0);
// signature ----------------------------------------------------------------------------
formattedWeeksData.signatureCreate.push(0);
formattedWeeksData.signatureUpdate.push(0);
formattedWeeksData.signatureDelete.push(0);
}
currentWeek++;
if( currentWeek > yearWeeks[currentYear] ){
currentWeek = 1;
currentYear++;
}
}
// system ---------------------------------------------------------------------------------------
formattedWeeksData.systemCreate = formattedWeeksData.systemCreate.join(',');
formattedWeeksData.systemUpdate = formattedWeeksData.systemUpdate.join(',');
formattedWeeksData.systemDelete = formattedWeeksData.systemDelete.join(',');
// connection -----------------------------------------------------------------------------------
formattedWeeksData.connectionCreate = formattedWeeksData.connectionCreate.join(',');
formattedWeeksData.connectionUpdate = formattedWeeksData.connectionUpdate.join(',');
formattedWeeksData.connectionDelete = formattedWeeksData.connectionDelete.join(',');
// signature ------------------------------------------------------------------------------------
formattedWeeksData.signatureCreate = formattedWeeksData.signatureCreate.join(',');
formattedWeeksData.signatureUpdate = formattedWeeksData.signatureUpdate.join(',');
formattedWeeksData.signatureDelete = formattedWeeksData.signatureDelete.join(',');
return formattedWeeksData;
};
$.each(statsData.statistics, function(characterId, data){
var formattedWeeksData = formatWeekData(data.weeks);
var rowData = {
character: {
id: characterId,
name: data.name,
lastLogin: data.lastLogin
},
systemCreate: {
type: 'C',
data: formattedWeeksData.systemCreate
},
systemUpdate: {
type: 'U',
data: formattedWeeksData.systemUpdate
},
systemDelete: {
type: 'D',
data: formattedWeeksData.systemDelete
},
systemSum: formattedWeeksData.systemSum,
connectionCreate: {
type: 'C',
data: formattedWeeksData.connectionCreate
},
connectionUpdate: {
type: 'U',
data: formattedWeeksData.connectionUpdate
},
connectionDelete: {
type: 'D',
data: formattedWeeksData.connectionDelete
},
connectionSum: formattedWeeksData.connectionSum,
signatureCreate: {
type: 'C',
data: formattedWeeksData.signatureCreate
},
signatureUpdate: {
type: 'U',
data: formattedWeeksData.signatureUpdate
},
signatureDelete: {
type: 'D',
data: formattedWeeksData.signatureDelete
},
signatureSum: formattedWeeksData.signatureSum,
totalSum: formattedWeeksData.systemSum + formattedWeeksData.connectionSum + formattedWeeksData.signatureSum
};
formattedData.push(rowData);
});
return formattedData;
};
/**
*
* @param dialogElement
* @returns {{}}
*/
var getRequestDataFromTabPanels = function(dialogElement){
var requestData = {};
// get data from "tab" panel links ------------------------------------------------------------------
var navigationListElements = dialogElement.find('.' + config.dialogNavigationClass);
navigationListElements.find('.' + config.dialogNavigationListItemClass + '.active a').each(function(){
var linkElement = $(this);
requestData[linkElement.data('type')]= linkElement.data('value');
});
// get current period (no offset) data (if available) -----------------------------------------------
var navigationOffsetElement = dialogElement.find('.' + config.dialogNavigationOffsetClass);
var startData = navigationOffsetElement.data('start');
var periodOld = navigationOffsetElement.data('period');
// if period switch was detected
// -> "year" and "week" should not be send
// -> start from "now"
if(
requestData.period === periodOld &&
startData
){
requestData.year = startData.year;
requestData.week = startData.week;
}
return requestData;
};
/**
* check if "activity log" type is enabled for a group
* @param type
* @returns {boolean}
*/
var isTabTypeEnabled = function(type){
var enabled = false;
switch(type){
case 'private':
if(Init.activityLogging.character){
enabled = true;
}
break;
case 'corporation':
if(
Init.activityLogging.corporation &&
Util.getCurrentUserInfo('corporationId')
){
enabled = true;
}
break;
case 'alliance':
if(
Init.activityLogging.alliance &&
Util.getCurrentUserInfo('allianceId')
){
enabled = true;
}
break;
}
return enabled;
};
/**
* show activity stats dialog
*/
$.fn.showStatsDialog = function(){
requirejs(['text!templates/dialog/stats.html', 'mustache', 'peityInlineChart'], function(template, Mustache) {
var data = {
id: config.statsDialogId,
dialogNavigationClass: config.dialogNavigationClass,
dialogNavLiClass: config.dialogNavigationListItemClass,
enablePrivateTab: isTabTypeEnabled('private'),
enableCorporationTab: isTabTypeEnabled('corporation'),
enableAllianceTab: isTabTypeEnabled('alliance'),
statsContainerId: config.statsContainerId,
statsTableId: config.statsTableId,
dialogNavigationOffsetClass: config.dialogNavigationOffsetClass,
dialogNavigationPrevClass: config.dialogNavigationPrevClass,
dialogNavigationNextClass: config.dialogNavigationNextClass
};
var content = Mustache.render(template, data);
var statsDialog = bootbox.dialog({
title: 'Statistics',
message: content,
size: 'large',
show: false,
buttons: {
close: {
label: 'close',
className: 'btn-default'
}
}
});
// model events
statsDialog.on('show.bs.modal', function(e) {
var dialogElement = $(e.target);
initStatsTable(dialogElement);
});
// Tab module events
statsDialog.find('a[data-toggle="tab"]').on('show.bs.tab', function (e, b, c) {
if( $(e.target).parent().hasClass('disabled') ){
// no action on "disabled" tabs
return false;
}
});
statsDialog.find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var requestData = getRequestDataFromTabPanels(statsDialog);
var tableApi = statsDialog.find('#' + config.statsTableId).DataTable();
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
});
// offset change links
statsDialog.find('.' + config.dialogNavigationPrevClass + ', .' + config.dialogNavigationNextClass).on('click', function(){
var offsetData = $(this).data('newOffset');
if(offsetData){
// this should NEVER fail!
// get "base" request data (e.g. typeId, period)
// --> overwrite period data with new period data
var tmpRequestData = getRequestDataFromTabPanels(statsDialog);
var requestData = $.extend({}, tmpRequestData, offsetData);
var tableApi = statsDialog.find('#' + config.statsTableId).DataTable();
getStatsData(requestData, {tableApi: tableApi, callback: drawStatsTable});
}
});
// show dialog
statsDialog.modal('show');
});
};
});

View File

@@ -316,7 +316,7 @@ define([
var settingsDialog = bootbox.dialog({
title: 'Route settings',
message: content,
show: false,
show: false,
buttons: {
close: {
label: 'cancel',
@@ -444,7 +444,6 @@ define([
data: requestData,
context: context
}).done(function(routesData){
this.moduleElement.hideLoadingAnimation();
// execute callback
@@ -886,7 +885,14 @@ define([
};
/**
* draw route table
* @param mapId
* @param moduleElement
* @param systemFromData
* @param routesTable
* @param systemsTo
*/
var drawRouteTable = function(mapId, moduleElement, systemFromData, routesTable, systemsTo){
var requestRouteData = [];
var currentTimestamp = Util.getServerTime().getTime();

View File

@@ -48,7 +48,9 @@ define([
sigTableActionCellClass: 'pf-table-action-cell', // class for "action" cells
// xEditable
editableDiscriptionInputClass: 'pf-editable-description' // class for "description" textarea
moduleIcon: 'pf-module-icon-button', // class for "filter" - icons
editableDescriptionInputClass: 'pf-editable-description', // class for "description" textarea
editableFilterInputClass: 'pf-editable-filter' // class for "filter" selects
};
// lock Signature Table update temporary (until. some requests/animations) are finished
@@ -95,6 +97,10 @@ define([
'Источники сигналов' // == "Cosmic Signature"
];
// some static signature data
var signatureGroupsLabels = Util.getSignatureGroupInfo('label');
var signatureGroupsNames = Util.getSignatureGroupInfo('name');
/**
* collect all data of all editable fields in a signature table
* @returns {Array}
@@ -505,7 +511,7 @@ define([
if(clipboard.length){
var signatureRows = clipboard.split(/\r\n|\r|\n/g);
var signatureGroupOptions = Util.getSignatureGroupInfo('name');
var signatureGroupOptions = signatureGroupsNames;
var invalidSignatures = 0;
for(var i = 0; i < signatureRows.length; i++){
@@ -892,8 +898,7 @@ define([
var systemTypeId = parseInt( signatureGroupField.attr('data-systemTypeId') );
// get all available Signature Types
// json object -> "translate" keys to names
var availableTypes = Util.getSignatureGroupInfo('label');
var availableTypes = signatureGroupsLabels;
// add empty option
availableTypes[0] = '';
@@ -943,7 +948,7 @@ define([
}
});
sigTypeFields.editable({ mode: 'popup',
sigTypeFields.editable({
type: 'select',
title: 'type',
name: 'typeId',
@@ -982,7 +987,7 @@ define([
onblur: 'submit',
mode: 'inline',
showbuttons: false,
inputclass: config.editableDiscriptionInputClass,
inputclass: config.editableDescriptionInputClass,
params: modifyFieldParamsOnSend,
success: function(response, newValue){
if(response){
@@ -1390,12 +1395,74 @@ define([
class: ['display', 'compact', 'nowrap', config.sigTableClass, config.sigTablePrimaryClass].join(' ')
});
// create table footer ----------------------------------------------------------------------------------------
// get column count from default dataTable config
var columnCount = $.fn.dataTable.defaults.columnDefs.length;
var footerHtml = '<tfoot><tr>';
for(let i = 0; i < columnCount; i++){
footerHtml += '<td></td>';
}
footerHtml += '</tr></tfoot>';
table.append(footerHtml);
moduleElement.append(table);
var dataTableOptions = {
data: signatureData,
initComplete: function (settings, json){
// setup filter select in footer
// column indexes that need a filter select
var filterColumnIndexes = [2];
this.api().columns(filterColumnIndexes).every(function(){
var column = this;
var headerLabel = $(column.header()).text();
var selectField = $('<a class="pf-editable ' +
config.moduleIcon + ' ' +
config.editableFilterInputClass +
'" href="#" data-type="select" data-name="' + headerLabel + '"></a>');
// get all available options from column
var source = {};
column.data().unique().sort(function(a,b){
// sort alphabetically
var valA = a.filter.toLowerCase();
var valB = b.filter.toLowerCase();
if(valA < valB) return -1;
if(valA > valB) return 1;
return 0;
}).each(function(callData){
if(callData.filter){
source[callData.filter] = callData.filter;
}
});
// add empty option
source[0] = '';
// add field to footer
selectField.appendTo( $(column.footer()).empty() );
selectField.editable({
emptytext: '<i class="fa fa-filter fa-fw"></i>',
onblur: 'submit',
title: 'filter',
showbuttons: false,
source: source,
value: 0
});
selectField.on('save', { column: column }, function(e, params) {
var val = $.fn.dataTable.util.escapeRegex( params.newValue );
e.data.column.search( val !== '0' ? '^' + val + '$' : '', true, false ).draw();
});
});
}
};
// create signature table and store the jquery object global for this module
signatureTable = table.dataTable( {
data: signatureData
} );
signatureTable = table.dataTable(dataTableOptions);
// make Table editable
signatureTable.makeEditable(systemData);
@@ -1473,7 +1540,8 @@ define([
tempData.group = {
group: sigGroup,
group_sort: data.groupId
sort: signatureGroupsLabels[data.groupId],
filter: signatureGroupsLabels[data.groupId]
};
// set type id ----------------------------------------------------------------------------------------
@@ -1540,7 +1608,7 @@ define([
*/
var initSignatureDataTable = function(systemData){
$.extend( $.fn.dataTable.defaults, {
$.extend( true, $.fn.dataTable.defaults, {
pageLength: -1,
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, 'All']],
order: [1, 'asc'],
@@ -1579,14 +1647,15 @@ define([
},{
targets: 2,
orderable: true,
searchable: false,
searchable: true,
title: 'group',
type: 'html',
width: '50px',
data: 'group',
render: {
_: 'group',
sort: 'group_sort'
sort: 'sort',
filter: 'filter'
}
},{
targets: 3,
@@ -1755,14 +1824,7 @@ define([
}
}
],
createdRow: function(row, data, dataIndex){
},
initComplete: function(settings, json){
// table init complete
}
]
});
};

View File

@@ -121,7 +121,9 @@ define([
var loadingElement = $(this);
var overlay = loadingElement.find('.' + config.ajaxOverlayClass );
$(overlay).velocity('reverse', {
// important: "stop" is required to stop "show" animation
// -> otherwise "complete" callback is not fired!
$(overlay).velocity('stop').velocity('reverse', {
complete: function(){
$(this).remove();
// enable all events
@@ -847,6 +849,18 @@ define([
console.info('PATHFINDER ' + versionNumber);
};
/**
* init utility prototype functions
*/
var initPrototypes = function(){
// Array diff
// [1,2,3,4,5,6].diff( [3,4,5] );
// => [1, 2, 6]
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
};
/**
* set default configuration for "Bootbox" dialogs
*/
@@ -1719,7 +1733,7 @@ define([
var getLocalStorage = function(){
if(localStorage === undefined){
localStorage = localforage.createInstance({
driver: localforage.INDEXEDDB,
driver: [localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE],
name: 'Pathfinder local storage'
});
}
@@ -1818,6 +1832,7 @@ define([
return {
config: config,
showVersionInfo: showVersionInfo,
initPrototypes: initPrototypes,
initDefaultBootboxConfig: initDefaultBootboxConfig,
getCurrentTriggerDelay: getCurrentTriggerDelay,
getServerTime: getServerTime,

View File

@@ -103,12 +103,12 @@ jQuery.fn.dragToSelect = function (conf) {
// Current origin of select box
var selectBoxOrigin = {
left: 0,
left: 0,
top: 0
};
// Create select box
var selectBox = jQuery('<div/>')
var selectBox = $('<div>')
.appendTo(parent)
.attr('class', config.className)
.css('position', 'absolute');
@@ -119,8 +119,8 @@ jQuery.fn.dragToSelect = function (conf) {
return;
}
selectBoxOrigin.left = e.pageX - parentDim.left + parent[0].scrollLeft;
selectBoxOrigin.top = e.pageY - parentDim.top + parent[0].scrollTop;
selectBoxOrigin.left = e.pageX - parentDim.left + parent[0].scrollLeft - 5;
selectBoxOrigin.top = e.pageY - parentDim.top + parent[0].scrollTop - 5;
var css = {
left: selectBoxOrigin.left + 'px',

File diff suppressed because one or more lines are too long

13
js/lib/jquery.peity.min.js vendored Normal file
View File

@@ -0,0 +1,13 @@
// Peity jQuery plugin version 3.2.0
// (c) 2015 Ben Pickles
//
// http://benpickles.github.io/peity
//
// Released under MIT license.
(function(k,w,h,v){var d=k.fn.peity=function(a,b){y&&this.each(function(){var e=k(this),c=e.data("_peity");c?(a&&(c.type=a),k.extend(c.opts,b)):(c=new x(e,a,k.extend({},d.defaults[a],e.data("peity"),b)),e.change(function(){c.draw()}).data("_peity",c));c.draw()});return this},x=function(a,b,e){this.$el=a;this.type=b;this.opts=e},o=x.prototype,q=o.svgElement=function(a,b){return k(w.createElementNS("http://www.w3.org/2000/svg",a)).attr(b)},y="createElementNS"in w&&q("svg",{})[0].createSVGRect;o.draw=
function(){var a=this.opts;d.graphers[this.type].call(this,a);a.after&&a.after.call(this,a)};o.fill=function(){var a=this.opts.fill;return k.isFunction(a)?a:function(b,e){return a[e%a.length]}};o.prepare=function(a,b){this.$svg||this.$el.hide().after(this.$svg=q("svg",{"class":"peity"}));return this.$svg.empty().data("peity",this).attr({height:b,width:a})};o.values=function(){return k.map(this.$el.text().split(this.opts.delimiter),function(a){return parseFloat(a)})};d.defaults={};d.graphers={};d.register=
function(a,b,e){this.defaults[a]=b;this.graphers[a]=e};d.register("pie",{fill:["#ff9900","#fff4dd","#ffc66e"],radius:8},function(a){if(!a.delimiter){var b=this.$el.text().match(/[^0-9\.]/);a.delimiter=b?b[0]:","}b=k.map(this.values(),function(a){return 0<a?a:0});if("/"==a.delimiter)var e=b[0],b=[e,h.max(0,b[1]-e)];for(var c=0,e=b.length,t=0;c<e;c++)t+=b[c];t||(e=2,t=1,b=[0,1]);var l=2*a.radius,l=this.prepare(a.width||l,a.height||l),c=l.width(),f=l.height(),j=c/2,d=f/2,f=h.min(j,d),a=a.innerRadius;
"donut"==this.type&&!a&&(a=0.5*f);for(var r=h.PI,s=this.fill(),g=this.scale=function(a,b){var c=a/t*r*2-r/2;return[b*h.cos(c)+j,b*h.sin(c)+d]},m=0,c=0;c<e;c++){var u=b[c],i=u/t;if(0!=i){if(1==i)if(a)var i=j-0.01,p=d-f,n=d-a,i=q("path",{d:["M",j,p,"A",f,f,0,1,1,i,p,"L",i,n,"A",a,a,0,1,0,j,n].join(" ")});else i=q("circle",{cx:j,cy:d,r:f});else p=m+u,n=["M"].concat(g(m,f),"A",f,f,0,0.5<i?1:0,1,g(p,f),"L"),a?n=n.concat(g(p,a),"A",a,a,0,0.5<i?1:0,0,g(m,a)):n.push(j,d),m+=u,i=q("path",{d:n.join(" ")});
i.attr("fill",s.call(this,u,c,b));l.append(i)}}});d.register("donut",k.extend(!0,{},d.defaults.pie),function(a){d.graphers.pie.call(this,a)});d.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(a){var b=this.values();1==b.length&&b.push(b[0]);for(var e=h.max.apply(h,a.max==v?b:b.concat(a.max)),c=h.min.apply(h,a.min==v?b:b.concat(a.min)),d=this.prepare(a.width,a.height),l=a.strokeWidth,f=d.width(),j=d.height()-l,k=e-c,e=this.x=function(a){return a*
(f/(b.length-1))},r=this.y=function(a){var b=j;k&&(b-=(a-c)/k*j);return b+l/2},s=r(h.max(c,0)),g=[0,s],m=0;m<b.length;m++)g.push(e(m),r(b[m]));g.push(f,s);a.fill&&d.append(q("polygon",{fill:a.fill,points:g.join(" ")}));l&&d.append(q("polyline",{fill:"none",points:g.slice(2,g.length-2).join(" "),stroke:a.stroke,"stroke-width":l,"stroke-linecap":"square"}))});d.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:0.1,width:32},function(a){for(var b=this.values(),e=h.max.apply(h,a.max==
v?b:b.concat(a.max)),c=h.min.apply(h,a.min==v?b:b.concat(a.min)),d=this.prepare(a.width,a.height),l=d.width(),f=d.height(),j=e-c,a=a.padding,k=this.fill(),r=this.x=function(a){return a*l/b.length},s=this.y=function(a){return f-(j?(a-c)/j*f:1)},g=0;g<b.length;g++){var m=r(g+a),u=r(g+1-a)-m,i=b[g],p=s(i),n=p,o;j?0>i?n=s(h.min(e,0)):p=s(h.max(c,0)):o=1;o=p-n;0==o&&(o=1,0<e&&j&&n--);d.append(q("rect",{fill:k.call(this,i,g,b),x:m,y:n,width:u,height:o}))}})})(jQuery,document,Math);

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -1,2 +0,0 @@
var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",config:"app/config",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",login:"./app/login",mappage:"./app/mappage",setup:"./app/setup",jquery:"lib/jquery-3.0.0.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",localForage:"lib/localforage.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6",farahey:"lib/farahey-0.5",customScrollbar:"lib/jquery.mCustomScrollbar.min",mousewheel:"lib/jquery.mousewheel.min",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.minified",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap2-toggle.min",lazyload:"lib/jquery.lazyload.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min","datatables.net":"lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min","datatables.net-buttons":"lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min","datatables.net-buttons-html":"lib/datatables/Buttons-1.2.1/js/buttons.html5.min","datatables.net-responsive":"lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min","datatables.net-select":"lib/datatables/Select-1.2.0/js/dataTables.select.min",pnotify:"lib/pnotify/pnotify","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},farahey:{deps:["jsPlumb"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery","mousewheel"]},"datatables.net":{deps:["jquery"]},"datatables.net-buttons":{deps:["datatables.net"]},"datatables.net-buttons-html":{deps:["datatables.net-buttons"]},"datatables.net-responsive":{deps:["datatables.net"]},"datatables.net-select":{deps:["datatables.net"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris"},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]},lazyload:{deps:["jquery"]}}});require.config({baseUrl:jsBaseUrl});requirejs([mainScriptPath]);
//# sourceMappingURL=app.js.map

View File

@@ -1 +0,0 @@
{"version":3,"sources":["app.js.src.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","dialog","templates","img","login","mappage","setup","jquery","bootstrap","text","mustache","localForage","velocity","velocityUI","slidebars","jsPlumb","farahey","customScrollbar","mousewheel","xEditable","morris","raphael","bootbox","easyPieChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","lazyload","easePack","tweenLite","datatables.net","datatables.net-buttons","datatables.net-buttons-html","datatables.net-responsive","datatables.net-select","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","exports","require"],"mappings":"AACA,GAAIA,gBAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,eAG3CE,WAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRH,OAAQ,aACRI,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,MAAO,cACPC,QAAS,gBACTC,MAAO,cAEPC,OAAQ,uBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,YAAa,sBACbC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,wBACTC,QAAS,kBACTC,gBAAiB,kCACjBC,WAAY,4BACZC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,aAAc,0BACdC,YAAa,kCACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,4BACjBC,SAAU,0BAGVC,SAAU,mBACVC,UAAW,oBAGXC,iBAAkB,6DAClBC,yBAA0B,yDAC1BC,8BAA+B,oDAC/BC,4BAA6B,+DAC7BC,wBAAyB,uDAGzBC,QAAS,sBACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAEzBC,MACI3C,WACI4C,MAAO,WAEXpC,SACIoC,MAAO,YAEXxC,UACIwC,MAAO,WAEXvC,YACIuC,MAAO,aAEXtC,WACIsC,MAAO,WAEXnC,iBACImC,MAAO,SAAU,eAErBd,kBACIc,MAAO,WAEXb,0BACIa,MAAO,mBAEXZ,+BACIY,MAAO,2BAEXX,6BACIW,MAAO,mBAEXV,yBACIU,MAAO,mBAEXjC,WACIiC,MAAO,cAEX9B,SACI8B,MAAO,SAAU,aACjBC,QAAS,WAEbjC,QACIgC,MAAO,SAAU,WACjBC,QAAS,UAEbV,SACIS,MAAQ,WAEZ7B,cACI6B,MAAQ,WAEZ5B,cACI4B,MAAQ,WAEZ3B,aACI2B,MAAQ,WAEZ1B,YACI0B,MAAQ,WAEZzB,SACIyB,MAAQ,UACRC,QAAS,WAEbzB,WACIwB,MAAQ,SAAU,cAEtBvB,iBACIuB,MAAQ,SAAU,cAEtBtB,gBACIsB,MAAQ,WAEZnB,uBACImB,MAAQ,cAEZlB,iBACIkB,MAAQ,WAEZjB,UACIiB,MAAQ,aAQpBE,SAAQzD,QACJC,QAASH,WAIbC,YAAYL","file":"app.js.map"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/js/v1.1.6/app.js Normal file
View File

@@ -0,0 +1,2 @@
var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",config:"app/config",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",login:"./app/login",mappage:"./app/mappage",setup:"./app/setup",jquery:"lib/jquery-3.0.0.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",localForage:"lib/localforage.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6",farahey:"lib/farahey-0.5",customScrollbar:"lib/jquery.mCustomScrollbar.min",mousewheel:"lib/jquery.mousewheel.min",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",peityInlineChart:"lib/jquery.peity.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.minified",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap2-toggle.min",lazyload:"lib/jquery.lazyload.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min","datatables.net":"lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min","datatables.net-buttons":"lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min","datatables.net-buttons-html":"lib/datatables/Buttons-1.2.1/js/buttons.html5.min","datatables.net-responsive":"lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min","datatables.net-select":"lib/datatables/Select-1.2.0/js/dataTables.select.min",pnotify:"lib/pnotify/pnotify","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},farahey:{deps:["jsPlumb"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery","mousewheel"]},"datatables.net":{deps:["jquery"]},"datatables.net-buttons":{deps:["datatables.net"]},"datatables.net-buttons-html":{deps:["datatables.net-buttons"]},"datatables.net-responsive":{deps:["datatables.net"]},"datatables.net-select":{deps:["datatables.net"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris"},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},peityInlineChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]},lazyload:{deps:["jquery"]}}});require.config({baseUrl:jsBaseUrl});requirejs([mainScriptPath]);
//# sourceMappingURL=app.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["app.js.src.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","dialog","templates","img","login","mappage","setup","jquery","bootstrap","text","mustache","localForage","velocity","velocityUI","slidebars","jsPlumb","farahey","customScrollbar","mousewheel","xEditable","morris","raphael","bootbox","easyPieChart","peityInlineChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","lazyload","easePack","tweenLite","datatables.net","datatables.net-buttons","datatables.net-buttons-html","datatables.net-responsive","datatables.net-select","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","exports","require"],"mappings":"AACA,GAAIA,gBAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,eAG3CE,WAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRH,OAAQ,aACRI,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,MAAO,cACPC,QAAS,gBACTC,MAAO,cAEPC,OAAQ,uBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,YAAa,sBACbC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,wBACTC,QAAS,kBACTC,gBAAiB,kCACjBC,WAAY,4BACZC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,iBAAkB,uBAClBC,aAAc,0BACdC,YAAa,kCACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,4BACjBC,SAAU,0BAGVC,SAAU,mBACVC,UAAW,oBAGXC,iBAAkB,6DAClBC,yBAA0B,yDAC1BC,8BAA+B,oDAC/BC,4BAA6B,+DAC7BC,wBAAyB,uDAGzBC,QAAS,sBACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAEzBC,MACI5C,WACI6C,MAAO,WAEXrC,SACIqC,MAAO,YAEXzC,UACIyC,MAAO,WAEXxC,YACIwC,MAAO,aAEXvC,WACIuC,MAAO,WAEXpC,iBACIoC,MAAO,SAAU,eAErBd,kBACIc,MAAO,WAEXb,0BACIa,MAAO,mBAEXZ,+BACIY,MAAO,2BAEXX,6BACIW,MAAO,mBAEXV,yBACIU,MAAO,mBAEXlC,WACIkC,MAAO,cAEX/B,SACI+B,MAAO,SAAU,aACjBC,QAAS,WAEblC,QACIiC,MAAO,SAAU,WACjBC,QAAS,UAEbV,SACIS,MAAQ,WAEZ9B,cACI8B,MAAQ,WAEZ7B,kBACI6B,MAAQ,WAEZ5B,cACI4B,MAAQ,WAEZ3B,aACI2B,MAAQ,WAEZ1B,YACI0B,MAAQ,WAEZzB,SACIyB,MAAQ,UACRC,QAAS,WAEbzB,WACIwB,MAAQ,SAAU,cAEtBvB,iBACIuB,MAAQ,SAAU,cAEtBtB,gBACIsB,MAAQ,WAEZnB,uBACImB,MAAQ,cAEZlB,iBACIkB,MAAQ,WAEZjB,UACIiB,MAAQ,aAQpBE,SAAQ1D,QACJC,QAASH,WAIbC,YAAYL","file":"app.js.map"}

View File

@@ -38,9 +38,10 @@ requirejs.config({
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
bootbox: 'lib/bootbox.min', // v4.4.0 Bootbox.js - custom dialogs - http://bootboxjs.com
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.2.0 Inline Chart - http://benpickles.github.io/peity/
dragToSelect: 'lib/jquery.dragToSelect', // v1.1 Drag to Select - http://andreaslagerkvist.com/jquery/drag-to-select
hoverIntent: 'lib/jquery.hoverIntent.minified', // v1.8.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
fullScreen: 'lib/jquery.fullscreen.min', // v0.5.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
fullScreen: 'lib/jquery.fullscreen.min', // v0.6.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
select2: 'lib/select2.min', // v4.0.3 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
@@ -123,6 +124,9 @@ requirejs.config({
easyPieChart: {
deps : ['jquery']
},
peityInlineChart: {
deps : ['jquery']
},
dragToSelect: {
deps : ['jquery']
},

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

View File

@@ -66,6 +66,7 @@ text!img/logo.svg!strip
text!templates/modules/header.html
text!templates/modules/footer.html
app/ui/dialog/notification.js
app/ui/dialog/stats.js
app/map/util.js
app/ui/dialog/map_info.js
app/ui/dialog/account_settings.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
!function(t,i,e,n){var r=t.fn.peity=function(i,e){l&&this.each(function(){var n=t(this),h=n.data("_peity");h?(i&&(h.type=i),t.extend(h.opts,e)):(h=new a(n,i,t.extend({},r.defaults[i],n.data("peity"),e)),n.change(function(){h.draw()}).data("_peity",h));h.draw()});return this},a=function(t,i,e){this.$el=t;this.type=i;this.opts=e},h=a.prototype,s=h.svgElement=function(e,n){return t(i.createElementNS("http://www.w3.org/2000/svg",e)).attr(n)},l="createElementNS"in i&&s("svg",{})[0].createSVGRect;h.draw=function(){var t=this.opts;r.graphers[this.type].call(this,t);t.after&&t.after.call(this,t)};h.fill=function(){var i=this.opts.fill;return t.isFunction(i)?i:function(t,e){return i[e%i.length]}};h.prepare=function(t,i){this.$svg||this.$el.hide().after(this.$svg=s("svg",{"class":"peity"}));return this.$svg.empty().data("peity",this).attr({height:i,width:t})};h.values=function(){return t.map(this.$el.text().split(this.opts.delimiter),function(t){return parseFloat(t)})};r.defaults={};r.graphers={};r.register=function(t,i,e){this.defaults[t]=i;this.graphers[t]=e};r.register("pie",{fill:["#ff9900","#fff4dd","#ffc66e"],radius:8},function(i){if(!i.delimiter){var n=this.$el.text().match(/[^0-9\.]/);i.delimiter=n?n[0]:","}n=t.map(this.values(),function(t){return t>0?t:0});if("/"==i.delimiter)var r=n[0],n=[r,e.max(0,n[1]-r)];for(var a=0,r=n.length,h=0;r>a;a++)h+=n[a];h||(r=2,h=1,n=[0,1]);var l=2*i.radius,l=this.prepare(i.width||l,i.height||l),a=l.width(),p=l.height(),o=a/2,f=p/2,p=e.min(o,f),i=i.innerRadius;"donut"==this.type&&!i&&(i=.5*p);for(var c=e.PI,u=this.fill(),d=this.scale=function(t,i){var n=t/h*c*2-c/2;return[i*e.cos(n)+o,i*e.sin(n)+f]},g=0,a=0;r>a;a++){var m=n[a],v=m/h;if(0!=v){if(1==v)if(i)var v=o-.01,y=f-p,w=f-i,v=s("path",{d:["M",o,y,"A",p,p,0,1,1,v,y,"L",v,w,"A",i,i,0,1,0,o,w].join(" ")});else v=s("circle",{cx:o,cy:f,r:p});else y=g+m,w=["M"].concat(d(g,p),"A",p,p,0,v>.5?1:0,1,d(y,p),"L"),i?w=w.concat(d(y,i),"A",i,i,0,v>.5?1:0,0,d(g,i)):w.push(o,f),g+=m,v=s("path",{d:w.join(" ")});v.attr("fill",u.call(this,m,a,n));l.append(v)}}});r.register("donut",t.extend(!0,{},r.defaults.pie),function(t){r.graphers.pie.call(this,t)});r.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(t){var i=this.values();1==i.length&&i.push(i[0]);for(var r=e.max.apply(e,t.max==n?i:i.concat(t.max)),a=e.min.apply(e,t.min==n?i:i.concat(t.min)),h=this.prepare(t.width,t.height),l=t.strokeWidth,p=h.width(),o=h.height()-l,f=r-a,r=this.x=function(t){return t*(p/(i.length-1))},c=this.y=function(t){var i=o;f&&(i-=(t-a)/f*o);return i+l/2},u=c(e.max(a,0)),d=[0,u],g=0;g<i.length;g++)d.push(r(g),c(i[g]));d.push(p,u);t.fill&&h.append(s("polygon",{fill:t.fill,points:d.join(" ")}));l&&h.append(s("polyline",{fill:"none",points:d.slice(2,d.length-2).join(" "),stroke:t.stroke,"stroke-width":l,"stroke-linecap":"square"}))});r.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:.1,width:32},function(t){for(var i=this.values(),r=e.max.apply(e,t.max==n?i:i.concat(t.max)),a=e.min.apply(e,t.min==n?i:i.concat(t.min)),h=this.prepare(t.width,t.height),l=h.width(),p=h.height(),o=r-a,t=t.padding,f=this.fill(),c=this.x=function(t){return t*l/i.length},u=this.y=function(t){return p-(o?(t-a)/o*p:1)},d=0;d<i.length;d++){var g,m=c(d+t),v=c(d+1-t)-m,y=i[d],w=u(y),x=w;o?0>y?x=u(e.min(r,0)):w=u(e.max(a,0)):g=1;g=w-x;0==g&&(g=1,r>0&&o&&x--);h.append(s("rect",{fill:f.call(this,y,d,i),x:m,y:x,width:v,height:g}))}})}(jQuery,document,Math);
//# sourceMappingURL=jquery.peity.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
// Peity jQuery plugin version 3.2.0
// (c) 2015 Ben Pickles
//
// http://benpickles.github.io/peity
//
// Released under MIT license.
(function(k,w,h,v){var d=k.fn.peity=function(a,b){y&&this.each(function(){var e=k(this),c=e.data("_peity");c?(a&&(c.type=a),k.extend(c.opts,b)):(c=new x(e,a,k.extend({},d.defaults[a],e.data("peity"),b)),e.change(function(){c.draw()}).data("_peity",c));c.draw()});return this},x=function(a,b,e){this.$el=a;this.type=b;this.opts=e},o=x.prototype,q=o.svgElement=function(a,b){return k(w.createElementNS("http://www.w3.org/2000/svg",a)).attr(b)},y="createElementNS"in w&&q("svg",{})[0].createSVGRect;o.draw=
function(){var a=this.opts;d.graphers[this.type].call(this,a);a.after&&a.after.call(this,a)};o.fill=function(){var a=this.opts.fill;return k.isFunction(a)?a:function(b,e){return a[e%a.length]}};o.prepare=function(a,b){this.$svg||this.$el.hide().after(this.$svg=q("svg",{"class":"peity"}));return this.$svg.empty().data("peity",this).attr({height:b,width:a})};o.values=function(){return k.map(this.$el.text().split(this.opts.delimiter),function(a){return parseFloat(a)})};d.defaults={};d.graphers={};d.register=
function(a,b,e){this.defaults[a]=b;this.graphers[a]=e};d.register("pie",{fill:["#ff9900","#fff4dd","#ffc66e"],radius:8},function(a){if(!a.delimiter){var b=this.$el.text().match(/[^0-9\.]/);a.delimiter=b?b[0]:","}b=k.map(this.values(),function(a){return 0<a?a:0});if("/"==a.delimiter)var e=b[0],b=[e,h.max(0,b[1]-e)];for(var c=0,e=b.length,t=0;c<e;c++)t+=b[c];t||(e=2,t=1,b=[0,1]);var l=2*a.radius,l=this.prepare(a.width||l,a.height||l),c=l.width(),f=l.height(),j=c/2,d=f/2,f=h.min(j,d),a=a.innerRadius;
"donut"==this.type&&!a&&(a=0.5*f);for(var r=h.PI,s=this.fill(),g=this.scale=function(a,b){var c=a/t*r*2-r/2;return[b*h.cos(c)+j,b*h.sin(c)+d]},m=0,c=0;c<e;c++){var u=b[c],i=u/t;if(0!=i){if(1==i)if(a)var i=j-0.01,p=d-f,n=d-a,i=q("path",{d:["M",j,p,"A",f,f,0,1,1,i,p,"L",i,n,"A",a,a,0,1,0,j,n].join(" ")});else i=q("circle",{cx:j,cy:d,r:f});else p=m+u,n=["M"].concat(g(m,f),"A",f,f,0,0.5<i?1:0,1,g(p,f),"L"),a?n=n.concat(g(p,a),"A",a,a,0,0.5<i?1:0,0,g(m,a)):n.push(j,d),m+=u,i=q("path",{d:n.join(" ")});
i.attr("fill",s.call(this,u,c,b));l.append(i)}}});d.register("donut",k.extend(!0,{},d.defaults.pie),function(a){d.graphers.pie.call(this,a)});d.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(a){var b=this.values();1==b.length&&b.push(b[0]);for(var e=h.max.apply(h,a.max==v?b:b.concat(a.max)),c=h.min.apply(h,a.min==v?b:b.concat(a.min)),d=this.prepare(a.width,a.height),l=a.strokeWidth,f=d.width(),j=d.height()-l,k=e-c,e=this.x=function(a){return a*
(f/(b.length-1))},r=this.y=function(a){var b=j;k&&(b-=(a-c)/k*j);return b+l/2},s=r(h.max(c,0)),g=[0,s],m=0;m<b.length;m++)g.push(e(m),r(b[m]));g.push(f,s);a.fill&&d.append(q("polygon",{fill:a.fill,points:g.join(" ")}));l&&d.append(q("polyline",{fill:"none",points:g.slice(2,g.length-2).join(" "),stroke:a.stroke,"stroke-width":l,"stroke-linecap":"square"}))});d.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:0.1,width:32},function(a){for(var b=this.values(),e=h.max.apply(h,a.max==
v?b:b.concat(a.max)),c=h.min.apply(h,a.min==v?b:b.concat(a.min)),d=this.prepare(a.width,a.height),l=d.width(),f=d.height(),j=e-c,a=a.padding,k=this.fill(),r=this.x=function(a){return a*l/b.length},s=this.y=function(a){return f-(j?(a-c)/j*f:1)},g=0;g<b.length;g++){var m=r(g+a),u=r(g+1-a)-m,i=b[g],p=s(i),n=p,o;j?0>i?n=s(h.min(e,0)):p=s(h.max(c,0)):o=1;o=p-n;0==o&&(o=1,0<e&&j&&n--);d.append(q("rect",{fill:k.call(this,i,g,b),x:m,y:n,width:u,height:o}))}})})(jQuery,document,Math);

View File

@@ -58,7 +58,7 @@
<li><i class="fa fa-plus fa-fw"></i> Add a new system at the position, you clicked at</li>
<li><i class="fa fa-object-ungroup fa-fw"></i> Select all (unlocked) systems on the map</li>
<li><i class="fa fa-filter fa-fw"></i> Filter map connections by a scope <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-scope">more</a></small></li>
<li><i class="fa fa-eraser fa-fw"></i> Delete selected systems <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a></small></li>
<li><i class="fa fa-trash fa-fw"></i> Delete selected systems <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a></small></li>
</ul>
<h4 id="pf-manual-scrollspy-anchor-map-select"><i class="fa fa-object-ungroup fa-fw"></i> Select methods</h4>
<ul class="list-unstyled" style=" margin-left: 10px;">
@@ -98,7 +98,7 @@
<p>
Systems are represented by rectangle boxes on a map <small>(<i class="fa fa-code-fork fa-fw"></i><a href="#" data-target="#pf-manual-map">more</a>)</small>.
Pilots can interact with systems like "delete systems" <small>(<i class="fa fa-eraser fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a>)</small> or
Pilots can interact with systems like "delete systems" <small>(<i class="fa fa-trash fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a>)</small> or
"move systems" <small>(<i class="fa fa-arrows-alt fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-move">more</a>)</small>.
</p>
<h4 id="pf-manual-scrollspy-anchor-system-active">Active system</h4>
@@ -176,13 +176,13 @@
<li><i class="fa fa-users fa-fw"></i> Set "Rally Point" for this system <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-rally">more</a></small></li>
<li><i class="fa fa-tags fa-fw"></i> Changes the status of this system <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-status">more</a></small></li>
<li><i class="fa fa-reply fa-rotate-180 fa-fw"></i> Waypoint options for this system <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-waypoint">more</a></small></li>
<li><i class="fa fa-eraser fa-fw"></i> Delete this system and all connections <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a></small></li>
<li><i class="fa fa-trash fa-fw"></i> Delete this system and all connections <small><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a></small></li>
</ul>
<h4 id="pf-manual-scrollspy-anchor-system-locked"><i class="fa fa-lock fa-fw"></i> Locked system</h4>
<p>
Locked systems can´t be selected <small>(<a href="#" data-target="#pf-manual-scrollspy-anchor-map-select">more</a>)</small>,
moved <small>(<i class="fa fa-arrows-alt fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-move">more</a>)</small>
or deleted <small>(<i class="fa fa-eraser fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a>)</small>.
or deleted <small>(<i class="fa fa-trash fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-delete">more</a>)</small>.
</p>
<h4 id="pf-manual-scrollspy-anchor-system-rally"><i class="fa fa-users fa-fw"></i> Rally point</h4>
<p>
@@ -199,7 +199,7 @@
<li>add new [start] -<small> (add new waypoint in front of your waypoint queue)</small></li>
<li>add new [end] -<small> (add new waypoint to the end of your waypoint queue)</small></li>
</ul>
<h4 id="pf-manual-scrollspy-anchor-system-delete"><i class="fa fa-eraser fa-fw"></i> Delete system</h4>
<h4 id="pf-manual-scrollspy-anchor-system-delete"><i class="fa fa-trash fa-fw"></i> Delete system</h4>
<p>
Any system that is not "Locked" <small>(<i class="fa fa-lock fa-fw"></i><a href="#" data-target="#pf-manual-scrollspy-anchor-system-locked">more</a>)</small> can be deleted from a map.
</p>
@@ -263,7 +263,7 @@
<li><i class="fa fa-warning fa-fw"></i> Toggles this connection as <em>"Preserve Mass"</em> <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-mass">more</a></small></li>
<li><i class="fa fa-crosshairs fa-fw"></i> Changes the scope of this connection <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-scope">more</a></small></li>
<li><i class="fa fa-reply fa-rotate-180 fa-fw"></i> Changes the status of this connection <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-status">more</a></small></li>
<li><i class="fa fa-eraser fa-fw"></i> Delete this connection <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-delete">more</a></small></li>
<li><i class="fa fa-trash fa-fw"></i> Delete this connection <small><a href="#" data-target="#pf-manual-scrollspy-anchor-connection-delete">more</a></small></li>
</ul>
<h4 id="pf-manual-scrollspy-anchor-connection-frig"><i class="fa fa-plane fa-fw"></i> Frigate hole</h4>
<p>
@@ -276,7 +276,7 @@
Let your mates know about critical connections that should be mass-saved
(e.g. <span class="pf-system-sec-highSec">H</span> security exits) <small>(<a href="#" data-target="#pf-manual-scrollspy-anchor-system-security">more</a>)</small>.
</p>
<h4 id="pf-manual-scrollspy-anchor-connection-delete"><i class="fa fa-eraser fa-fw"></i> Delete connection</h4>
<h4 id="pf-manual-scrollspy-anchor-connection-delete"><i class="fa fa-trash fa-fw"></i> Delete connection</h4>
<p>
Connections can be detached by several ways.
</p>
@@ -322,7 +322,7 @@
<kbd>click</kbd> the browser tab were <em class="pf-brand">pathfinder</em> is open. Then press <kbd>ctrl</kbd> + <kbd>v</kbd>.<br>
<em class="pf-brand">pathfinder</em> automatically detect the data format and updates the <em>"Signature table"</em>.
</p>
<h4><i class="fa fa-eraser fa-fw"></i> Delete signatures</h4>
<h4><i class="fa fa-trash fa-fw"></i> Delete signatures</h4>
<p>
Signatures can be detached by several ways.
</p>

View File

@@ -88,7 +88,7 @@
<div class="col-sm-offset-1 col-sm-11">
<div class="col-sm-12 col-xs-6 checkbox checkbox-warning checkbox-circle" title="include reduced connections">
<input id="form_wormholes_reduced" name="wormholesReduced" value="1" type="checkbox" checked>
<label for="form_wormholes_reduced">Stage 1 (reduced)</label>
<label for="form_wormholes_reduced">Stage 2 (reduced)</label>
</div>
</div>
</div>
@@ -99,7 +99,7 @@
<div class="col-sm-offset-1 col-sm-11">
<div class="col-sm-12 col-xs-6 checkbox checkbox-danger checkbox-circle" title="include critical connections">
<input id="form_wormholes_critical" name="wormholesCritical" value="1" type="checkbox" checked>
<label for="form_wormholes_critical">Stage 2 (critical)</label>
<label for="form_wormholes_critical">Stage 3 (critical)</label>
</div>
</div>
</div>

View File

@@ -0,0 +1,117 @@
<div id="{{id}}">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header pull-left">
<ul class="nav navbar-nav {{dialogNavigationClass}}">
<li class="{{dialogNavLiClass}} {{^enablePrivateTab}} disabled {{/enablePrivateTab}}">
<a role="tab" data-toggle="tab" data-type="typeId" data-value="2" href="#{{statsContainerId}}">Private</a>
</li>
<li class="{{dialogNavLiClass}} active {{^enableCorporationTab}} disabled {{/enableCorporationTab}}">
<a role="tab" data-toggle="tab" data-type="typeId" data-value="3" href="#{{statsContainerId}}">Corporation</a>
</li>
<li class="{{dialogNavLiClass}} {{^enableAllianceTab}} disabled {{/enableAllianceTab}}">
<a role="tab" data-toggle="tab" data-type="typeId" data-value="4" href="#{{statsContainerId}}">Alliance</a>
</li>
</ul>
</div>
<div class="navbar-header pull-right">
<p class="navbar-text">
<i class="fa fa-filter fa-fw fa-lg"></i>
</p>
<ul class="nav navbar-nav {{dialogNavigationClass}}">
<li class="{{dialogNavLiClass}}">
<a role="tab" data-toggle="tab" data-type="period" data-value="weekly" href="#{{statsContainerId}}">Weekly</a>
</li>
<li class="{{dialogNavLiClass}} active">
<a role="tab" data-toggle="tab" data-type="period" data-value="monthly" href="#{{statsContainerId}}">Monthly</a>
</li>
<li class="{{dialogNavLiClass}}">
<a role="tab" data-toggle="tab" data-type="period" data-value="yearly" href="#{{statsContainerId}}">Yearly</a>
</li>
</ul>
</div>
</nav>
<div class="alert alert-info fade in hidden-md hidden-lg">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><i class="fa fa-close"></i></button>
<span class="txt-color txt-color-information">Info</span>
<small> Your browser window is to small. Resize it to obtain more columns.</small>
</div>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="{{statsContainerId}}">
<h5 class="text-center">
{{! previous button }}
<span class="pull-left pf-dialog-icon-button collapsed {{dialogNavigationPrevClass}}" style="visibility: hidden; min-width: 120px">
<i class="fa fa-fw fa-arrow-left"></i>
<span>&nbsp;</span>
</span>
{{! offset label }}
<span class="{{dialogNavigationOffsetClass}}">&nbsp;</span>
{{! next button }}
<span class="pull-right pf-dialog-icon-button collapsed {{dialogNavigationNextClass}}" style="visibility: hidden; min-width: 120px">
<span>&nbsp;</span>
<i class="fa fa-fw fa-arrow-right"></i>
</span>
</h5>
<div class="pf-dynamic-area">
<table class="compact stripe order-column row-border nowrap" id="{{statsTableId}}">
<thead>
<tr>
<th colspan="4" class="separator-right">character</th>
<th colspan="4" class="separator-right hidden-xs hidden-sm">systems</th>
<th colspan="4" class="separator-right hidden-xs hidden-sm">connection</th>
<th colspan="4" class="separator-right hidden-xs hidden-sm">signatures</th>
<th class="text-right">sum</th>
</tr>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th class="bg-color bg-color-grayDarker"></th>
<th></th>
<th></th>
<th></th>
<th class="bg-color bg-color-grayDarker"></th>
<th></th>
<th></th>
<th></th>
<th class="bg-color bg-color-grayDarker"></th>
<th class="bg-color bg-color-tealDarker txt-color txt-color-orange"></th>
</tr>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>

View File

@@ -1,17 +1,24 @@
{* Login notice information *}
<div class="row text-center">
<div class="col-xs-12 col-md-8 col-md-offset-2 pf-landing-pricing-panel">
<div class="panel panel-primary pricing-big">
<div class="panel-heading" >
<h3 class="panel-title">Release v1.1.5</h3>
<h3 class="panel-title">New release v1.1.6</h3>
</div>
<div class="panel-body no-padding text-align-center">
<div class="price-features" style="min-height: inherit;">
<ul class="list-unstyled text-left">
<li><i class="fa fa-fw fa-angle-right"></i>New: Support for multiple active characters</li>
<li><i class="fa fa-fw fa-angle-right"></i>New: Customizable default routes</li>
<li><i class="fa fa-fw fa-angle-right"></i>New: Filter option for "<em>EOL</em>" connections added to route finder</li>
<li><i class="fa fa-fw fa-angle-right"></i>New: "<em><a target="_self" href="#pf-landing-feature-user-statistics">User Statistics</a></em>" module</li>
<li>
<ul class="list-unstyled text-left">
<li><i class="fa fa-fw fa-angle-right"></i>'private', 'corporation', 'alliance' - statistics</li>
</ul>
</li>
<li><i class="fa fa-fw fa-angle-right"></i>New: "<em>Activity Log</em>" history</li>
<li>
<ul class="list-unstyled text-left">
<li><i class="fa fa-fw fa-angle-right"></i>'weekly', 'monthly', 'yearly' - filters</li>
</ul>
</li>
<li><i class="fa fa-fw fa-angle-double-right"></i>Complete <a href="javascript:void(0)" class="pf-navbar-version-info">changelog</a></li>
</ul>
</div>

View File

@@ -137,8 +137,8 @@
</div>
</div>
{* splash page *}
<include href="templates/ui/notice.html"/>
{* splash page -> shown by Javascript *}
<div id="pf-notification-panel"></div>
</div>
</section>
@@ -186,7 +186,7 @@
</a>
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Pathfinder</h4>
<h4>Pathfinder</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i><span class="txt-color txt-color-greenDark"><e class="fa fa-fw fa-lock"></e>SSL</span> encrypted connection</li>
<li><i></i>User friendly <a class="pf-navbar-manual" href="#">manual</a></li>
@@ -250,7 +250,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Map module</h4>
<h4>Map module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Live synchronisation between clients</li>
<li><i></i>Multiple map support</li>
@@ -329,7 +329,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>System module</h4>
<h4>System module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Quick access to all relevant information</li>
<li>
@@ -368,7 +368,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Signature module</h4>
<h4>Signature module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Share system signature information</li>
<li><i></i>Add/Update multiple signatures at once <kbd>ctrl</kbd> + <kbd>c</kbd></li>
@@ -407,7 +407,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Killboard module</h4>
<h4>Killboard module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i><em><a target="_blank" href="https://github.com/zKillboard/zKillboard/wiki">zkillboard.com</a></em> API integration</li>
<li><i></i>Detailed information about all recent activities in a system</li>
@@ -440,7 +440,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Route module</h4>
<h4>Route module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Search for routes between systems</li>
<li><i></i>Predefined trade hub routes</li>
@@ -477,19 +477,20 @@
</div>
<div class="row">
<div class="col-xs-12 col-sm-3 col-lg-2">
<a class="pf-animate-on-visible pf-animate" href="public/img/landing/statistics_1.jpg" data-description="Statistics" data-gallery="#pf-gallery">
<img class="pf-landing-image-preview pf-landing-image-preview-small" data-original="public/img/landing/thumbs/statistics_1.jpg" width="160" height="160" alt="Statistics">
<a class="pf-animate-on-visible pf-animate" href="public/img/landing/statistics_1.jpg" data-description="System statistics" data-gallery="#pf-gallery">
<img class="pf-landing-image-preview pf-landing-image-preview-small" data-original="public/img/landing/thumbs/statistics_1.jpg" width="160" height="160" alt="System statistics">
</a>
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Statistics module</h4>
<h4>System statistics module</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Integrated live data for all systems</li>
<li><i></i>Live in-game system data</li>
<li>
<ul class="fa-ul">
<li><i></i>System jumps</li>
<li><i></i>System jump data</li>
<li><i></i>Ship/POD kills</li>
<li><i></i>NPC kills</li>
</ul>
@@ -497,9 +498,36 @@
</ul>
</div>
<div class="clearfix visible-xs visible-sm visible-md"></div>
<div class="col-xs-12 col-sm-3 col-lg-2" id="pf-landing-feature-user-statistics">
<a class="pf-animate-on-visible pf-animate" href="public/img/landing/statistics_2.jpg" data-description="User statistics" data-gallery="#pf-gallery">
<img class="pf-landing-image-preview pf-landing-image-preview-small" data-original="public/img/landing/thumbs/statistics_2.jpg" width="160" height="160" alt="User statistics">
</a>
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4>User statistics <span class="label label-success">new</span> </h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>User activity logging</li>
<li>
<ul class="fa-ul">
<li><i></i>Private statistics</li>
<li><i></i>Corporation statistics</li>
<li><i></i>Alliance statistics</li>
</ul>
</li>
<li><i></i>Log history</li>
<li>
<ul class="fa-ul">
<li><i></i>Weekly</li>
<li><i></i>Monthly</li>
<li><i></i>Yearly</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="row text-center hidden-xs">
@@ -634,7 +662,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-server"></i>Requirements check</h4>
<h4><i class="fa fa-fw fa-server"></i> Requirements check</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Checks your server type/status</li>
<li><i></i>Checks your installed PHP version</li>
@@ -656,7 +684,7 @@
</div>
<div class="col-xs-12 col-sm-9 col-lg-4">
<h4><i class="fa fa-fw fa-database"></i>Database setup</h4>
<h4><i class="fa fa-fw fa-database"></i> Database setup</h4>
<ul class="fa-ul pf-landing-list">
<li><i></i>Check DB connections</li>
<li><i></i>Check DB version</li>
@@ -692,7 +720,7 @@
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 col-sm-offset-1 col-md-offset-1 col-lg-offset-1">
<h4><i class="fa fa-fw fa-angle-double-right"></i>About Me</h4>
<h4>About Me</h4>
<p>
I am playing <em><a target="_blank" href="https://www.eveonline.com/">EVE Online</a></em> since almost 4 years.
The majority of time (3+ years), my characters were a part of the <em><a target="_blank" href="https://www.themittani.com/news/j150020-three-alliances-enter-none-leave">"No Holes Barred"</a></em> alliance.
@@ -728,7 +756,7 @@
</div>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<h4><i class="fa fa-fw fa-angle-double-right"></i>Technology stack</h4>
<h4>Technology stack</h4>
<p>
If you are planning to get deeper into the project or even think about hosting it on your own webserver, you should be aware of some important key points.
<em>Pathfinder</em> is not comparable with any "out of the box" web applications or common CMS systems that come along with an auto-install feature.

View File

@@ -157,7 +157,7 @@
<div class="panel-body no-padding text-align-center">
<table class="table">
<tbody>
<thead>
<repeat group="{{ @serverInformation }}" value="{{ @information }}">
<tr>
<td>{{@information.label}}</td>
@@ -165,7 +165,7 @@
</tr>
</repeat>
</tbody>
</thead>
</table>
</div>
@@ -235,7 +235,7 @@
<div class="panel-body no-padding text-align-center">
<table class="table">
<tbody>
<thead>
<repeat group="{{ @environmentInformation }}" value="{{ @environmentData }}">
<tr>
<td>{{@environmentData.label}}</td>
@@ -251,7 +251,7 @@
</td>
</tr>
</repeat>
</tbody>
</thead>
</table>
</div>
@@ -264,11 +264,36 @@
<div class="panel panel-default pricing-big">
<div class="panel-heading text-left">
<h3 class="panel-title">Map restrictions</h3>
<h3 class="panel-title">Registration</h3>
</div>
<div class="panel-body no-padding text-align-center">
<table class="table">
<thead>
<tr>
<td>Status</td>
<td class="text-right col-md-2">
<check if="{{ @PATHFINDER.REGISTRATION.STATUS }}">
<true>
<kbd class="txt-color txt-color-success">enabled</kbd>
</true>
<false>
<kbd class="txt-color txt-color-warning">disabled</kbd>
</false>
</check>
</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="panel-footer text-left">
<h3 class="panel-title">Map restrictions</h3>
</div>
<table class="table">
<thead>
<tr>
@@ -295,17 +320,17 @@
<table class="table">
<thead>
<tr>
<td>Max. shared users (private map)</td>
<td>Max. shared users (private maps)</td>
<td class="text-right col-md-2"><kbd>{{ @PATHFINDER.MAP.PRIVATE.MAX_SHARED }}</kbd></td>
</tr>
</thead>
<tbody>
<tr>
<td>Max. shared users (corporation map)</td>
<td>Max. shared users (corporation maps)</td>
<td class="text-right"><kbd>{{ @PATHFINDER.MAP.CORPORATION.MAX_SHARED }}</kbd></td>
</tr>
<tr>
<td>Max. shared users (alliance map)</td>
<td>Max. shared users (alliance maps)</td>
<td class="text-right"><kbd>{{ @PATHFINDER.MAP.ALLIANCE.MAX_SHARED }}</kbd></td>
</tr>
</tbody>
@@ -318,32 +343,60 @@
<table class="table">
<thead>
<tr>
<td>Private map</td>
<td>Private maps</td>
<td class="text-right col-md-2"><kbd>{{ @PATHFINDER.MAP.PRIVATE.LIFETIME }}</kbd></td>
</tr>
</thead>
<tbody>
<tr>
<td>Corporation map</td>
<td>Corporation maps</td>
<td class="text-right"><kbd>{{ @PATHFINDER.MAP.CORPORATION.LIFETIME }}</kbd></td>
</tr>
<tr>
<td>Alliance map</td>
<td>Alliance maps</td>
<td class="text-right"><kbd>{{ @PATHFINDER.MAP.ALLIANCE.LIFETIME }}</kbd></td>
</tr>
</tbody>
</table>
<div class="panel-footer text-left">
<h3 class="panel-title">Registration</h3>
<h3 class="panel-title">User activity logging</h3>
</div>
<table class="table">
<thead>
<tr>
<td>Status</td>
<td>Private maps</td>
<td class="text-right col-md-2">
<check if="{{ @PATHFINDER.REGISTRATION.STATUS }}">
<check if="{{ @PATHFINDER.MAP.PRIVATE.ACTIVITY_LOGGING }}">
<true>
<kbd class="txt-color txt-color-success">enabled</kbd>
</true>
<false>
<kbd class="txt-color txt-color-warning">disabled</kbd>
</false>
</check>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>Corporation maps</td>
<td class="text-right">
<check if="{{ @PATHFINDER.MAP.CORPORATION.ACTIVITY_LOGGING }}">
<true>
<kbd class="txt-color txt-color-success">enabled</kbd>
</true>
<false>
<kbd class="txt-color txt-color-warning">disabled</kbd>
</false>
</check>
</td>
</tr>
<tr>
<td>Alliance maps</td>
<td class="text-right">
<check if="{{ @PATHFINDER.MAP.ALLIANCE.ACTIVITY_LOGGING }}">
<true>
<kbd class="txt-color txt-color-success">enabled</kbd>
</true>
@@ -353,13 +406,9 @@
</check>
</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>

View File

@@ -19,7 +19,7 @@
&.txt-color-redDarker { color: $red-darker !important; }
&.txt-color-yellow { color: $yellow !important; }
&.txt-color-orange { color: $orange !important; }
&.txt-color-orangeDark { color: $orangeDark !important; }
&.txt-color-orangeDark { color: $orange-dark !important; }
&.txt-color-pink { color: $pink !important; }
&.txt-color-pinkDark { color: $pinkDark !important; }
&.txt-color-purple { color: $purple !important; }
@@ -58,7 +58,9 @@
&.bg-color-darken { background-color: $darken !important; }
&.bg-color-lighten { background-color: $lighten !important; }
&.bg-color-white { background-color: $white !important; }
&.bg-color-gray { background-color: $gray !important; }
&.bg-color-grayDark { background-color: $greyDark !important; }
&.bg-color-grayDarker { background-color: $gray-darker !important; }
&.bg-color-magenta { background-color: $magenta !important; }
&.bg-color-tealLighter { background-color: $teal-lighter !important; }
&.bg-color-tealDarker { background-color: $teal-darker !important; }

View File

@@ -551,7 +551,7 @@ $modal-backdrop-opacity: .3;
$modal-header-border-color: #e5e5e5;
$modal-footer-border-color: $modal-header-border-color;
$modal-lg: 820px;
$modal-lg: 1100px;
$modal-md: 600px;
$modal-sm: 300px;

View File

@@ -405,6 +405,10 @@
}
}
}
#pf-notification-panel{
display: none;
}
}
// demo map -------------------------------------------------------------------

View File

@@ -6,6 +6,7 @@ body{
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}
.pf-body{
@@ -111,7 +112,7 @@ em{
@include transition(color 0.15s ease-out);
&:hover{
color: $orange;
color: $orange !important;
}
}
@@ -196,6 +197,7 @@ select:active, select:hover {
img{
width: 26px; // smaller image (default 32)
box-sizing: content-box;
border-left: 1px solid $gray;
border-right: 1px solid $gray;
}
@@ -227,6 +229,18 @@ select:active, select:hover {
}
}
// column separator
td, th{
&.separator-right{
border-right: 1px solid $gray;
}
svg.peity{
// center vertical in column
display: block;
}
}
}
// table styles ===================================================================================
@@ -293,7 +307,7 @@ table{
// navbar li =====================================================================================
.navbar-nav {
li{
li:not(.disabled){
&:hover, &.active{
&:before{

View File

@@ -239,6 +239,8 @@ $mapWidth: 2500px ;
.pf-system-body-item{
color: lighten($gray-light, 10%);
font-size: 10px;
line-height: 16px;
height: 16px;
.pf-system-body-right{
text-overflow: ellipsis;
@@ -250,13 +252,14 @@ $mapWidth: 2500px ;
.pf-user-status{
font-size: 7px;
width: 10px;
vertical-align: middle;
height: 14px;
}
.pf-system-body-item-name{
display: inline-block;
width: 65px;
overflow: hidden;
height: 10px;
white-space: nowrap;
text-overflow: ellipsis;
}

View File

@@ -58,6 +58,14 @@
.pf-sig-table-edit-name-input{
text-transform: uppercase;
}
// table filter fields
.pf-editable-filter{
// overwrites default xEditable style
color: $gray-light;
border: none;
font-style: normal;
}
}
}

View File

@@ -194,10 +194,7 @@ html.sb-static .sb-slidebar,
*/
.sb-slide, #sb-site, .sb-site-container, .sb-slidebar {
-webkit-transition: -webkit-transform 400ms ease;
-moz-transition: -moz-transform 400ms ease;
-o-transition: -o-transform 400ms ease;
transition: transform 400ms ease;
@include transition( transform 180ms ease-out );
-webkit-transition-property: -webkit-transform, left, right; /* Add left/right for Android < 4.4. */
-webkit-backface-visibility: hidden; /* Prevents flickering. This is non essential, and you may remove it if your having problems with fixed background images in Chrome. */
}