- Improved signature table column "type", new connection "size" label shown in cell, closed #874
- Improved client side JS in-memory cache performance - Fixed some UI glitches on small (mobile) screens with some _tooltip_ select fields
This commit is contained in:
275
js/app/cache.js
Normal file
275
js/app/cache.js
Normal file
@@ -0,0 +1,275 @@
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Abstract Cache Strategy class
|
||||
* @type {AbstractStrategy}
|
||||
*/
|
||||
let AbstractStrategy = class AbstractStrategy {
|
||||
constructor(){
|
||||
if(new.target === AbstractStrategy){
|
||||
throw new TypeError('Cannot construct AbstractStrategy instances directly');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* factory for Strategy* instances
|
||||
* @returns {AbstractStrategy}
|
||||
*/
|
||||
static create(){
|
||||
return new this();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LIFO Cache Strategy - First In First Out
|
||||
* -> The cache evicts the entries in the order they were added,
|
||||
* without any regard to how often or how many times they were accessed before.
|
||||
* @type {StrategyFIFO}
|
||||
*/
|
||||
let StrategyFIFO = class StrategyFIFO extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.age();
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return b - a;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LFU Cache Strategy - Least Frequently Used
|
||||
* -> The cache evicts the entries in order how often have been accessed.
|
||||
* Those that are used least often are discarded first
|
||||
* @type {StrategyLFU}
|
||||
*/
|
||||
let StrategyLFU = class StrategyLFU extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.hitCount;
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LRU Cache Strategy - Least Recently Used
|
||||
* -> The cache evicts entries that have not been used for the longest amount of time.
|
||||
* No matter how often they have been accessed.
|
||||
* @type {StrategyLRU}
|
||||
*/
|
||||
let StrategyLRU = class StrategyLRU extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.hits[metaData.hits.length - 1] || metaData.set;
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Each entry in cache also has its own instance of CacheEntryMeta
|
||||
* -> The configured Cache Strategy use this meta data for eviction policy
|
||||
* @type {CacheEntryMeta}
|
||||
*/
|
||||
let CacheEntryMeta = class CacheEntryMeta {
|
||||
constructor(ttl, tSet){
|
||||
this.ttl = ttl;
|
||||
this.tSet = tSet || this.constructor.now();
|
||||
this.tHits = [];
|
||||
}
|
||||
|
||||
get set(){
|
||||
return this.tSet;
|
||||
}
|
||||
|
||||
get hits(){
|
||||
return this.tHits;
|
||||
}
|
||||
|
||||
get hitCount(){
|
||||
return this.hits.length;
|
||||
}
|
||||
|
||||
newHit(current){
|
||||
this.tHits.push(current || this.constructor.now());
|
||||
}
|
||||
|
||||
age(current){
|
||||
return (current || this.constructor.now()) - this.tSet;
|
||||
}
|
||||
|
||||
expired(current){
|
||||
return this.ttl < this.age(current);
|
||||
}
|
||||
|
||||
static now(){
|
||||
return new Date().getTime() / 1000;
|
||||
}
|
||||
|
||||
static create(ttl, tSet){
|
||||
return new this(ttl, tSet);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Each instance of Cache represents a key value in memory data store
|
||||
* -> Name should be set to identify current Cache instance
|
||||
* -> Default ttl can be overwritten by individual entries
|
||||
* -> Cache Strategy handles eviction policy
|
||||
* -> Buffer Size (in percent) can be used to remove e.g. 10% of all entries
|
||||
* if cache reaches maxSize limit, to increase performance.
|
||||
* @type {Cache}
|
||||
*/
|
||||
let Cache = class Cache {
|
||||
|
||||
constructor(config){
|
||||
this.config = Object.assign({
|
||||
name: 'Default', // custom name for identification
|
||||
ttl: 3600,
|
||||
maxSize: 600,
|
||||
bufferSize: 10, // in percent
|
||||
strategy: 'FIFO',
|
||||
debug: false
|
||||
}, config);
|
||||
|
||||
this.store = new Map();
|
||||
this.metaStore = new WeakMap();
|
||||
this.strategy = this.constructor.setStrategy(this.config.strategy);
|
||||
|
||||
this.debug = (msg,...data) => {
|
||||
if(this.config.debug){
|
||||
data = (data || []);
|
||||
data.unshift(this.config.name);
|
||||
console.info('debug: CACHE %o | ' + msg, ...data);
|
||||
}
|
||||
};
|
||||
|
||||
this.debug('New Cache instance');
|
||||
}
|
||||
|
||||
get size(){
|
||||
return this.store.size;
|
||||
}
|
||||
|
||||
isFull(){
|
||||
return this.size>= this.config.maxSize;
|
||||
}
|
||||
|
||||
set(key, value, ttl){
|
||||
if(this.store.has(key)){
|
||||
this.debug('SET key %o, UPDATE value %o', key, value);
|
||||
this.store.set(key, value);
|
||||
}else{
|
||||
this.debug('SET key %o, NEW value %o', key, value);
|
||||
if(this.isFull()){
|
||||
this.debug(' ↪ FULL trim cache…');
|
||||
this.trim(this.trimCount(1));
|
||||
}
|
||||
this.store.set(key, value);
|
||||
}
|
||||
|
||||
this.metaStore.set(value, CacheEntryMeta.create(ttl || this.config.ttl));
|
||||
}
|
||||
|
||||
get(key){
|
||||
if(this.store.has(key)){
|
||||
let value = this.store.get(key);
|
||||
if(value){
|
||||
let metaData = this.metaStore.get(value);
|
||||
if(metaData.expired()){
|
||||
this.debug('EXPIRED key %o delete', key);
|
||||
this.delete(key);
|
||||
}else{
|
||||
this.debug('HIT key %o', key);
|
||||
metaData.newHit();
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.debug('MISS key %o', key);
|
||||
}
|
||||
|
||||
getOrDefault(key, def){
|
||||
return this.get(key) || def;
|
||||
}
|
||||
|
||||
keysForTrim(count){
|
||||
let trimKeys = [];
|
||||
let compare = [];
|
||||
for(let [key, value] of this.store){
|
||||
let metaData = this.metaStore.get(value);
|
||||
if(metaData.expired()){
|
||||
trimKeys.push(key);
|
||||
if(count === trimKeys.length){
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
compare.push({
|
||||
key: key,
|
||||
value: this.strategy.valueToCompare(metaData)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let countLeft = count - trimKeys.length;
|
||||
if(countLeft > 0){
|
||||
compare = compare.sort((a, b) => this.strategy.compare(a.value, b.value));
|
||||
trimKeys = trimKeys.concat(compare.splice(0, countLeft).map(a => a.key));
|
||||
}
|
||||
|
||||
return trimKeys;
|
||||
}
|
||||
|
||||
keys(){
|
||||
return this.store.keys();
|
||||
}
|
||||
|
||||
delete(key){
|
||||
return this.store.delete(key);
|
||||
}
|
||||
|
||||
clear(){
|
||||
this.store.clear();
|
||||
}
|
||||
|
||||
trimCount(spaceLeft){
|
||||
let bufferSize = Math.max(Math.round(this.config.maxSize / 100 * this.config.bufferSize), spaceLeft);
|
||||
return Math.min(Math.max(this.size - this.config.maxSize + bufferSize, 0), this.size);
|
||||
}
|
||||
|
||||
trim(count){
|
||||
if(count > 0){
|
||||
let trimKeys = this.keysForTrim(count);
|
||||
if(count > trimKeys.length){
|
||||
console.warn(' ↪ Failed to trim(%i) entries. Only %i in store', count, this.size);
|
||||
}
|
||||
this.debug(' ↪ DELETE min %i keys: %o', count, trimKeys);
|
||||
trimKeys.forEach(key => this.delete(key));
|
||||
}
|
||||
}
|
||||
|
||||
status(){
|
||||
return {
|
||||
config: this.config,
|
||||
store: this.store,
|
||||
metaStore: this.metaStore
|
||||
};
|
||||
}
|
||||
|
||||
static setStrategy(name){
|
||||
switch(name){
|
||||
case 'FIFO': return StrategyFIFO.create();
|
||||
case 'LFU': return StrategyLFU.create();
|
||||
case 'LRU': return StrategyLRU.create();
|
||||
default:
|
||||
throw new ReferenceError('Unknown cache strategy name: ' + name);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Cache;
|
||||
});
|
||||
@@ -530,7 +530,7 @@ define([
|
||||
// ... get endpoint label for source || target system
|
||||
if(tmpSystem && tmpSystem){
|
||||
// ... get all available signature type (wormholes) names
|
||||
let availableSigTypeNames = SystemSignatures.getAllSignatureNamesBySystem(tmpSystem, 5);
|
||||
let availableSigTypeNames = SystemSignatures.getSignatureTypeOptionsBySystem(tmpSystem, 5);
|
||||
let flattenSigTypeNames = Util.flattenXEditableSelectArray(availableSigTypeNames);
|
||||
|
||||
if(flattenSigTypeNames.hasOwnProperty(signatureData.typeId)){
|
||||
|
||||
@@ -9,7 +9,7 @@ define([
|
||||
'app/render',
|
||||
'app/map/worker',
|
||||
'peityInlineChart',
|
||||
], function($, Init, Util, Render, MapWorker){
|
||||
], ($, Init, Util, Render, MapWorker) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
|
||||
@@ -77,14 +77,23 @@ define([
|
||||
/**
|
||||
* format results data for signature type select
|
||||
* @param state
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
* @param container
|
||||
* @param customOptions
|
||||
* @returns {*|k.fn.init|jQuery|HTMLElement}
|
||||
*/
|
||||
let formatSignatureTypeSelectionData = state => {
|
||||
let formatSignatureTypeSelectionData = (state, container, customOptions) => {
|
||||
let parts = state.text.split(' - ');
|
||||
|
||||
let markup = '';
|
||||
if(parts.length === 2){
|
||||
// wormhole data -> 2 columns
|
||||
let name = parts[0];
|
||||
let sizeLabel;
|
||||
if(Util.getObjVal(customOptions, 'showWhSizeLabel')){
|
||||
let wormholeSizeData = Util.getObjVal(Init, 'wormholes.' + name + '.size');
|
||||
sizeLabel = Util.getObjVal(wormholeSizeData, 'label') || '';
|
||||
}
|
||||
|
||||
let securityClass = Util.getSecurityClassForSystem(getSystemSecurityFromLabel(parts[1]));
|
||||
// some labels have a "suffix" label that should not have the securityClass
|
||||
let labelParts = parts[1].split(/\s(.+)/);
|
||||
@@ -93,9 +102,14 @@ define([
|
||||
|
||||
let classes = [securityClass, Util.config.popoverTriggerClass, Util.config.helpDefaultClass];
|
||||
|
||||
markup += '<span>' + parts[0] + '</span> ';
|
||||
markup += '<span>' + name + '</span>';
|
||||
if(sizeLabel !== undefined){
|
||||
markup += '<span><kbd>' + sizeLabel + '</kbd></span>';
|
||||
}else{
|
||||
markup += ' ';
|
||||
}
|
||||
markup += '<i class="fas fa-long-arrow-alt-right txt-color txt-color-grayLight"></i>';
|
||||
markup += '<span class="' + classes.join(' ') + '" data-name="' + parts[0] + '"> ' + label + '</span>';
|
||||
markup += '<span class="' + classes.join(' ') + '" data-name="' + name + '"> ' + label + '</span>';
|
||||
if(suffix.length){
|
||||
markup += ' <span>' + suffix + '</span>';
|
||||
}
|
||||
@@ -343,15 +357,15 @@ define([
|
||||
let hideShatteredClass = !data.shattered ? 'hide' : '';
|
||||
|
||||
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
|
||||
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<div class="col-xs-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
|
||||
markup += '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.secClass + '">' + data.security + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + shatteredClass + '">';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.secClass + '">' + data.security + '</div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + shatteredClass + '">';
|
||||
markup += '<i class="fas fa-fw fa-chart-pie ' + hideShatteredClass + '"></i>';
|
||||
markup += '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ define([
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// init tooltips ------------------------------------------------------------------------------------------
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
|
||||
@@ -6,8 +6,9 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/cache',
|
||||
'morris'
|
||||
], ($, Init, Util, Morris) => {
|
||||
], ($, Init, Util, Cache, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -39,7 +40,12 @@ define([
|
||||
maxCountKills: 43
|
||||
};
|
||||
|
||||
let cache = {};
|
||||
let cache = new Cache({
|
||||
name: 'killboardModule',
|
||||
ttl: 60 * 60,
|
||||
maxSize: 600,
|
||||
debug: false
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -59,9 +65,10 @@ define([
|
||||
*/
|
||||
let loadKillmailData = (requestData, context, callback) => {
|
||||
let cacheKey = 'killmail_' + requestData.killId;
|
||||
if(cache[cacheKey]){
|
||||
let responseData = cache.get(cacheKey);
|
||||
if(responseData){
|
||||
// ... already cached -> return from cache
|
||||
callback(context, cache[cacheKey])
|
||||
callback(context, responseData)
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
}else{
|
||||
// ...not cached -> request data
|
||||
@@ -73,7 +80,7 @@ define([
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
cache[cacheKey] = responseData;
|
||||
cache.set(cacheKey, responseData);
|
||||
|
||||
callback(this, responseData)
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
@@ -93,12 +100,14 @@ define([
|
||||
*/
|
||||
let showKills = (killboardElement, systemId, chunkSize) => {
|
||||
if(chunkSize){
|
||||
let cacheKey = 'zkb_' + systemId;
|
||||
let data = cache.getOrDefault(cacheKey, []);
|
||||
if(
|
||||
killboardElement.children().length < config.maxCountKills &&
|
||||
cache['zkb_' + systemId].length
|
||||
data.length
|
||||
){
|
||||
// next killmail to load
|
||||
let nextZkb = cache['zkb_' + systemId].shift();
|
||||
let nextZkb = data.shift();
|
||||
|
||||
loadKillmailData({
|
||||
killId: parseInt(nextZkb.killmail_id) || 0,
|
||||
@@ -219,7 +228,7 @@ define([
|
||||
}).done(function(result){
|
||||
// zkb result needs to be cached and becomes reduced on "load more"
|
||||
let cacheKey = 'zkb_' + systemData.systemId;
|
||||
cache[cacheKey] = result;
|
||||
cache.set(cacheKey, result);
|
||||
|
||||
if(result.length){
|
||||
// kills found -> insert hidden warning for recent kills
|
||||
|
||||
@@ -6,12 +6,13 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/cache',
|
||||
'bootbox',
|
||||
'app/counter',
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'app/ui/form_element'
|
||||
], ($, Init, Util, bootbox, Counter, Map, MapUtil, FormElement) => {
|
||||
], ($, Init, Util, Cache, bootbox, Counter, Map, MapUtil, FormElement) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -51,6 +52,7 @@ define([
|
||||
|
||||
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (sig name)
|
||||
|
||||
tableCellTypeClass: 'pf-table-type-cell', // class for "type" cells
|
||||
tableCellConnectionClass: 'pf-table-connection-cell', // class for "connection" cells
|
||||
tableCellFocusClass: 'pf-table-focus-cell', // class for "tab-able" cells. enable focus()
|
||||
tableCellCounterClass: 'pf-table-counter-cell', // class for "counter" cells
|
||||
@@ -76,7 +78,12 @@ define([
|
||||
sigInfoCountConDeleteId: 'pf-sig-info-count-con-delete' // id for "connection delete" counter
|
||||
};
|
||||
|
||||
let sigNameCache = {}; // cache signature names
|
||||
let sigTypeOptionsCache = new Cache({ // cache signature names
|
||||
name: 'sigTypeOptions',
|
||||
ttl: 60 * 5,
|
||||
maxSize: 100,
|
||||
debug: false
|
||||
});
|
||||
|
||||
let validSignatureNames = [ // allowed signature type/names
|
||||
'Cosmic Anomaly',
|
||||
@@ -244,7 +251,7 @@ define([
|
||||
* @param groupId
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllSignatureNames = (systemData, systemTypeId, areaId, groupId) => {
|
||||
let getSignatureTypeOptions = (systemData, systemTypeId, areaId, groupId) => {
|
||||
systemTypeId = parseInt(systemTypeId || 0);
|
||||
areaId = parseInt(areaId || 0);
|
||||
groupId = parseInt(groupId || 0);
|
||||
@@ -257,16 +264,18 @@ define([
|
||||
|
||||
let cacheKey = [systemTypeId, areaId, groupId].join('_');
|
||||
|
||||
newSelectOptions = sigTypeOptionsCache.getOrDefault(cacheKey, []);
|
||||
|
||||
// check for cached signature names
|
||||
if(sigNameCache.hasOwnProperty( cacheKey )){
|
||||
if(newSelectOptions.length){
|
||||
// cached signatures do not include static WHs!
|
||||
// -> ".slice(0)" creates copy
|
||||
newSelectOptions = sigNameCache[cacheKey].slice(0);
|
||||
newSelectOptions = newSelectOptions.slice(0);
|
||||
newSelectOptionsCount = getOptionsCount('children', newSelectOptions);
|
||||
}else{
|
||||
// get new Options ----------
|
||||
// get all possible "static" signature names by the selected groupId
|
||||
let tempSelectOptions = Util.getAllSignatureNames(systemTypeId, areaId, groupId);
|
||||
let tempSelectOptions = Util.getSignatureTypeNames(systemTypeId, areaId, groupId);
|
||||
|
||||
// format options into array with objects advantages: keep order, add more options (whs), use optgroup
|
||||
if(tempSelectOptions){
|
||||
@@ -351,7 +360,7 @@ define([
|
||||
}
|
||||
|
||||
// update cache (clone array) -> further manipulation to this array, should not be cached
|
||||
sigNameCache[cacheKey] = newSelectOptions.slice(0);
|
||||
sigTypeOptionsCache.set(cacheKey, newSelectOptions.slice(0));
|
||||
}
|
||||
|
||||
// static wormholes (DO NOT CACHE) (not all C2 WHs have the same statics,...
|
||||
@@ -382,11 +391,11 @@ define([
|
||||
* @param groupId
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllSignatureNamesBySystem = (systemElement, groupId) => {
|
||||
let getSignatureTypeOptionsBySystem = (systemElement, groupId) => {
|
||||
let systemTypeId = systemElement.data('typeId');
|
||||
let areaId = Util.getAreaIdBySecurity(systemElement.data('security'));
|
||||
let systemData = {statics: systemElement.data('statics')};
|
||||
return getAllSignatureNames(systemData, systemTypeId, areaId, groupId);
|
||||
return getSignatureTypeOptions(systemData, systemTypeId, areaId, groupId);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -882,7 +891,7 @@ define([
|
||||
// try to get "typeId" from description string
|
||||
let sigDescriptionLowerCase = sigDescription.toLowerCase();
|
||||
|
||||
let typeOptions = getAllSignatureNames(
|
||||
let typeOptions = getSignatureTypeOptions(
|
||||
systemData,
|
||||
systemData.type.id,
|
||||
Util.getAreaIdBySecurity(systemData.security),
|
||||
@@ -1721,7 +1730,7 @@ define([
|
||||
title: 'type',
|
||||
type: 'string', // required for sort/filter because initial data type is numeric
|
||||
width: 180,
|
||||
class: [config.tableCellFocusClass].join(' '),
|
||||
class: [config.tableCellFocusClass, config.tableCellTypeClass].join(' '),
|
||||
data: 'typeId',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
let tableApi = this.api();
|
||||
@@ -1749,7 +1758,7 @@ define([
|
||||
// -> "rowData" param is not current state, values are "on createCell()" state
|
||||
let rowData = tableApi.row($(cell).parents('tr')).data();
|
||||
|
||||
let typeOptions = getAllSignatureNames(
|
||||
let typeOptions = getSignatureTypeOptions(
|
||||
systemData,
|
||||
systemData.type.id,
|
||||
Util.getAreaIdBySecurity(systemData.security),
|
||||
@@ -1760,7 +1769,7 @@ define([
|
||||
display: function(value, sourceData){
|
||||
let selected = $.fn.editableutils.itemsByValue(value, sourceData);
|
||||
if(selected.length && selected[0].value > 0){
|
||||
$(this).html(FormElement.formatSignatureTypeSelectionData({text: selected[0].text}));
|
||||
$(this).html(FormElement.formatSignatureTypeSelectionData({text: selected[0].text}, undefined, {showWhSizeLabel: true}));
|
||||
}else{
|
||||
$(this).empty();
|
||||
}
|
||||
@@ -3307,6 +3316,6 @@ define([
|
||||
updateModule: updateModule,
|
||||
beforeHide: beforeHide,
|
||||
beforeDestroy: beforeDestroy,
|
||||
getAllSignatureNamesBySystem: getAllSignatureNamesBySystem
|
||||
getSignatureTypeOptionsBySystem: getSignatureTypeOptionsBySystem
|
||||
};
|
||||
});
|
||||
@@ -2586,7 +2586,7 @@ define([
|
||||
* @param sigGroupId
|
||||
* @returns {{}}
|
||||
*/
|
||||
let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => {
|
||||
let getSignatureTypeNames = (systemTypeId, areaId, sigGroupId) => {
|
||||
let signatureNames = {};
|
||||
if(
|
||||
SignatureType[systemTypeId] &&
|
||||
@@ -3553,7 +3553,7 @@ define([
|
||||
getTrueSecClassForSystem: getTrueSecClassForSystem,
|
||||
getStatusInfoForSystem: getStatusInfoForSystem,
|
||||
getSignatureGroupOptions: getSignatureGroupOptions,
|
||||
getAllSignatureNames: getAllSignatureNames,
|
||||
getSignatureTypeNames: getSignatureTypeNames,
|
||||
getAreaIdBySecurity: getAreaIdBySecurity,
|
||||
setCurrentMapUserData: setCurrentMapUserData,
|
||||
getCurrentMapUserData: getCurrentMapUserData,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
275
public/js/v1.5.5/app/cache.js
Normal file
275
public/js/v1.5.5/app/cache.js
Normal file
@@ -0,0 +1,275 @@
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Abstract Cache Strategy class
|
||||
* @type {AbstractStrategy}
|
||||
*/
|
||||
let AbstractStrategy = class AbstractStrategy {
|
||||
constructor(){
|
||||
if(new.target === AbstractStrategy){
|
||||
throw new TypeError('Cannot construct AbstractStrategy instances directly');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* factory for Strategy* instances
|
||||
* @returns {AbstractStrategy}
|
||||
*/
|
||||
static create(){
|
||||
return new this();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LIFO Cache Strategy - First In First Out
|
||||
* -> The cache evicts the entries in the order they were added,
|
||||
* without any regard to how often or how many times they were accessed before.
|
||||
* @type {StrategyFIFO}
|
||||
*/
|
||||
let StrategyFIFO = class StrategyFIFO extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.age();
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return b - a;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LFU Cache Strategy - Least Frequently Used
|
||||
* -> The cache evicts the entries in order how often have been accessed.
|
||||
* Those that are used least often are discarded first
|
||||
* @type {StrategyLFU}
|
||||
*/
|
||||
let StrategyLFU = class StrategyLFU extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.hitCount;
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LRU Cache Strategy - Least Recently Used
|
||||
* -> The cache evicts entries that have not been used for the longest amount of time.
|
||||
* No matter how often they have been accessed.
|
||||
* @type {StrategyLRU}
|
||||
*/
|
||||
let StrategyLRU = class StrategyLRU extends AbstractStrategy {
|
||||
valueToCompare(metaData){
|
||||
return metaData.hits[metaData.hits.length - 1] || metaData.set;
|
||||
}
|
||||
|
||||
compare(a, b){
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Each entry in cache also has its own instance of CacheEntryMeta
|
||||
* -> The configured Cache Strategy use this meta data for eviction policy
|
||||
* @type {CacheEntryMeta}
|
||||
*/
|
||||
let CacheEntryMeta = class CacheEntryMeta {
|
||||
constructor(ttl, tSet){
|
||||
this.ttl = ttl;
|
||||
this.tSet = tSet || this.constructor.now();
|
||||
this.tHits = [];
|
||||
}
|
||||
|
||||
get set(){
|
||||
return this.tSet;
|
||||
}
|
||||
|
||||
get hits(){
|
||||
return this.tHits;
|
||||
}
|
||||
|
||||
get hitCount(){
|
||||
return this.hits.length;
|
||||
}
|
||||
|
||||
newHit(current){
|
||||
this.tHits.push(current || this.constructor.now());
|
||||
}
|
||||
|
||||
age(current){
|
||||
return (current || this.constructor.now()) - this.tSet;
|
||||
}
|
||||
|
||||
expired(current){
|
||||
return this.ttl < this.age(current);
|
||||
}
|
||||
|
||||
static now(){
|
||||
return new Date().getTime() / 1000;
|
||||
}
|
||||
|
||||
static create(ttl, tSet){
|
||||
return new this(ttl, tSet);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Each instance of Cache represents a key value in memory data store
|
||||
* -> Name should be set to identify current Cache instance
|
||||
* -> Default ttl can be overwritten by individual entries
|
||||
* -> Cache Strategy handles eviction policy
|
||||
* -> Buffer Size (in percent) can be used to remove e.g. 10% of all entries
|
||||
* if cache reaches maxSize limit, to increase performance.
|
||||
* @type {Cache}
|
||||
*/
|
||||
let Cache = class Cache {
|
||||
|
||||
constructor(config){
|
||||
this.config = Object.assign({
|
||||
name: 'Default', // custom name for identification
|
||||
ttl: 3600,
|
||||
maxSize: 600,
|
||||
bufferSize: 10, // in percent
|
||||
strategy: 'FIFO',
|
||||
debug: false
|
||||
}, config);
|
||||
|
||||
this.store = new Map();
|
||||
this.metaStore = new WeakMap();
|
||||
this.strategy = this.constructor.setStrategy(this.config.strategy);
|
||||
|
||||
this.debug = (msg,...data) => {
|
||||
if(this.config.debug){
|
||||
data = (data || []);
|
||||
data.unshift(this.config.name);
|
||||
console.info('debug: CACHE %o | ' + msg, ...data);
|
||||
}
|
||||
};
|
||||
|
||||
this.debug('New Cache instance');
|
||||
}
|
||||
|
||||
get size(){
|
||||
return this.store.size;
|
||||
}
|
||||
|
||||
isFull(){
|
||||
return this.size>= this.config.maxSize;
|
||||
}
|
||||
|
||||
set(key, value, ttl){
|
||||
if(this.store.has(key)){
|
||||
this.debug('SET key %o, UPDATE value %o', key, value);
|
||||
this.store.set(key, value);
|
||||
}else{
|
||||
this.debug('SET key %o, NEW value %o', key, value);
|
||||
if(this.isFull()){
|
||||
this.debug(' ↪ FULL trim cache…');
|
||||
this.trim(this.trimCount(1));
|
||||
}
|
||||
this.store.set(key, value);
|
||||
}
|
||||
|
||||
this.metaStore.set(value, CacheEntryMeta.create(ttl || this.config.ttl));
|
||||
}
|
||||
|
||||
get(key){
|
||||
if(this.store.has(key)){
|
||||
let value = this.store.get(key);
|
||||
if(value){
|
||||
let metaData = this.metaStore.get(value);
|
||||
if(metaData.expired()){
|
||||
this.debug('EXPIRED key %o delete', key);
|
||||
this.delete(key);
|
||||
}else{
|
||||
this.debug('HIT key %o', key);
|
||||
metaData.newHit();
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.debug('MISS key %o', key);
|
||||
}
|
||||
|
||||
getOrDefault(key, def){
|
||||
return this.get(key) || def;
|
||||
}
|
||||
|
||||
keysForTrim(count){
|
||||
let trimKeys = [];
|
||||
let compare = [];
|
||||
for(let [key, value] of this.store){
|
||||
let metaData = this.metaStore.get(value);
|
||||
if(metaData.expired()){
|
||||
trimKeys.push(key);
|
||||
if(count === trimKeys.length){
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
compare.push({
|
||||
key: key,
|
||||
value: this.strategy.valueToCompare(metaData)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let countLeft = count - trimKeys.length;
|
||||
if(countLeft > 0){
|
||||
compare = compare.sort((a, b) => this.strategy.compare(a.value, b.value));
|
||||
trimKeys = trimKeys.concat(compare.splice(0, countLeft).map(a => a.key));
|
||||
}
|
||||
|
||||
return trimKeys;
|
||||
}
|
||||
|
||||
keys(){
|
||||
return this.store.keys();
|
||||
}
|
||||
|
||||
delete(key){
|
||||
return this.store.delete(key);
|
||||
}
|
||||
|
||||
clear(){
|
||||
this.store.clear();
|
||||
}
|
||||
|
||||
trimCount(spaceLeft){
|
||||
let bufferSize = Math.max(Math.round(this.config.maxSize / 100 * this.config.bufferSize), spaceLeft);
|
||||
return Math.min(Math.max(this.size - this.config.maxSize + bufferSize, 0), this.size);
|
||||
}
|
||||
|
||||
trim(count){
|
||||
if(count > 0){
|
||||
let trimKeys = this.keysForTrim(count);
|
||||
if(count > trimKeys.length){
|
||||
console.warn(' ↪ Failed to trim(%i) entries. Only %i in store', count, this.size);
|
||||
}
|
||||
this.debug(' ↪ DELETE min %i keys: %o', count, trimKeys);
|
||||
trimKeys.forEach(key => this.delete(key));
|
||||
}
|
||||
}
|
||||
|
||||
status(){
|
||||
return {
|
||||
config: this.config,
|
||||
store: this.store,
|
||||
metaStore: this.metaStore
|
||||
};
|
||||
}
|
||||
|
||||
static setStrategy(name){
|
||||
switch(name){
|
||||
case 'FIFO': return StrategyFIFO.create();
|
||||
case 'LFU': return StrategyLFU.create();
|
||||
case 'LRU': return StrategyLRU.create();
|
||||
default:
|
||||
throw new ReferenceError('Unknown cache strategy name: ' + name);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Cache;
|
||||
});
|
||||
@@ -530,7 +530,7 @@ define([
|
||||
// ... get endpoint label for source || target system
|
||||
if(tmpSystem && tmpSystem){
|
||||
// ... get all available signature type (wormholes) names
|
||||
let availableSigTypeNames = SystemSignatures.getAllSignatureNamesBySystem(tmpSystem, 5);
|
||||
let availableSigTypeNames = SystemSignatures.getSignatureTypeOptionsBySystem(tmpSystem, 5);
|
||||
let flattenSigTypeNames = Util.flattenXEditableSelectArray(availableSigTypeNames);
|
||||
|
||||
if(flattenSigTypeNames.hasOwnProperty(signatureData.typeId)){
|
||||
|
||||
@@ -9,7 +9,7 @@ define([
|
||||
'app/render',
|
||||
'app/map/worker',
|
||||
'peityInlineChart',
|
||||
], function($, Init, Util, Render, MapWorker){
|
||||
], ($, Init, Util, Render, MapWorker) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
|
||||
@@ -77,14 +77,23 @@ define([
|
||||
/**
|
||||
* format results data for signature type select
|
||||
* @param state
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
* @param container
|
||||
* @param customOptions
|
||||
* @returns {*|k.fn.init|jQuery|HTMLElement}
|
||||
*/
|
||||
let formatSignatureTypeSelectionData = state => {
|
||||
let formatSignatureTypeSelectionData = (state, container, customOptions) => {
|
||||
let parts = state.text.split(' - ');
|
||||
|
||||
let markup = '';
|
||||
if(parts.length === 2){
|
||||
// wormhole data -> 2 columns
|
||||
let name = parts[0];
|
||||
let sizeLabel;
|
||||
if(Util.getObjVal(customOptions, 'showWhSizeLabel')){
|
||||
let wormholeSizeData = Util.getObjVal(Init, 'wormholes.' + name + '.size');
|
||||
sizeLabel = Util.getObjVal(wormholeSizeData, 'label') || '';
|
||||
}
|
||||
|
||||
let securityClass = Util.getSecurityClassForSystem(getSystemSecurityFromLabel(parts[1]));
|
||||
// some labels have a "suffix" label that should not have the securityClass
|
||||
let labelParts = parts[1].split(/\s(.+)/);
|
||||
@@ -93,9 +102,14 @@ define([
|
||||
|
||||
let classes = [securityClass, Util.config.popoverTriggerClass, Util.config.helpDefaultClass];
|
||||
|
||||
markup += '<span>' + parts[0] + '</span> ';
|
||||
markup += '<span>' + name + '</span>';
|
||||
if(sizeLabel !== undefined){
|
||||
markup += '<span><kbd>' + sizeLabel + '</kbd></span>';
|
||||
}else{
|
||||
markup += ' ';
|
||||
}
|
||||
markup += '<i class="fas fa-long-arrow-alt-right txt-color txt-color-grayLight"></i>';
|
||||
markup += '<span class="' + classes.join(' ') + '" data-name="' + parts[0] + '"> ' + label + '</span>';
|
||||
markup += '<span class="' + classes.join(' ') + '" data-name="' + name + '"> ' + label + '</span>';
|
||||
if(suffix.length){
|
||||
markup += ' <span>' + suffix + '</span>';
|
||||
}
|
||||
@@ -343,15 +357,15 @@ define([
|
||||
let hideShatteredClass = !data.shattered ? 'hide' : '';
|
||||
|
||||
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
|
||||
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<div class="col-xs-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
|
||||
markup += '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.secClass + '">' + data.security + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + shatteredClass + '">';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.secClass + '">' + data.security + '</div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + shatteredClass + '">';
|
||||
markup += '<i class="fas fa-fw fa-chart-pie ' + hideShatteredClass + '"></i>';
|
||||
markup += '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
|
||||
markup += '<div class="col-xs-2 text-right ' + data.trueSecClass + '">' + data.trueSec + '</div></div>';
|
||||
|
||||
return markup;
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ define([
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// init tooltips ------------------------------------------------------------------------------------------
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
|
||||
@@ -6,8 +6,9 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/cache',
|
||||
'morris'
|
||||
], ($, Init, Util, Morris) => {
|
||||
], ($, Init, Util, Cache, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -39,7 +40,12 @@ define([
|
||||
maxCountKills: 43
|
||||
};
|
||||
|
||||
let cache = {};
|
||||
let cache = new Cache({
|
||||
name: 'killboardModule',
|
||||
ttl: 60 * 60,
|
||||
maxSize: 600,
|
||||
debug: false
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -59,9 +65,10 @@ define([
|
||||
*/
|
||||
let loadKillmailData = (requestData, context, callback) => {
|
||||
let cacheKey = 'killmail_' + requestData.killId;
|
||||
if(cache[cacheKey]){
|
||||
let responseData = cache.get(cacheKey);
|
||||
if(responseData){
|
||||
// ... already cached -> return from cache
|
||||
callback(context, cache[cacheKey])
|
||||
callback(context, responseData)
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
}else{
|
||||
// ...not cached -> request data
|
||||
@@ -73,7 +80,7 @@ define([
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
cache[cacheKey] = responseData;
|
||||
cache.set(cacheKey, responseData);
|
||||
|
||||
callback(this, responseData)
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
@@ -93,12 +100,14 @@ define([
|
||||
*/
|
||||
let showKills = (killboardElement, systemId, chunkSize) => {
|
||||
if(chunkSize){
|
||||
let cacheKey = 'zkb_' + systemId;
|
||||
let data = cache.getOrDefault(cacheKey, []);
|
||||
if(
|
||||
killboardElement.children().length < config.maxCountKills &&
|
||||
cache['zkb_' + systemId].length
|
||||
data.length
|
||||
){
|
||||
// next killmail to load
|
||||
let nextZkb = cache['zkb_' + systemId].shift();
|
||||
let nextZkb = data.shift();
|
||||
|
||||
loadKillmailData({
|
||||
killId: parseInt(nextZkb.killmail_id) || 0,
|
||||
@@ -219,7 +228,7 @@ define([
|
||||
}).done(function(result){
|
||||
// zkb result needs to be cached and becomes reduced on "load more"
|
||||
let cacheKey = 'zkb_' + systemData.systemId;
|
||||
cache[cacheKey] = result;
|
||||
cache.set(cacheKey, result);
|
||||
|
||||
if(result.length){
|
||||
// kills found -> insert hidden warning for recent kills
|
||||
|
||||
@@ -6,12 +6,13 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/cache',
|
||||
'bootbox',
|
||||
'app/counter',
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'app/ui/form_element'
|
||||
], ($, Init, Util, bootbox, Counter, Map, MapUtil, FormElement) => {
|
||||
], ($, Init, Util, Cache, bootbox, Counter, Map, MapUtil, FormElement) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -51,6 +52,7 @@ define([
|
||||
|
||||
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (sig name)
|
||||
|
||||
tableCellTypeClass: 'pf-table-type-cell', // class for "type" cells
|
||||
tableCellConnectionClass: 'pf-table-connection-cell', // class for "connection" cells
|
||||
tableCellFocusClass: 'pf-table-focus-cell', // class for "tab-able" cells. enable focus()
|
||||
tableCellCounterClass: 'pf-table-counter-cell', // class for "counter" cells
|
||||
@@ -76,7 +78,12 @@ define([
|
||||
sigInfoCountConDeleteId: 'pf-sig-info-count-con-delete' // id for "connection delete" counter
|
||||
};
|
||||
|
||||
let sigNameCache = {}; // cache signature names
|
||||
let sigTypeOptionsCache = new Cache({ // cache signature names
|
||||
name: 'sigTypeOptions',
|
||||
ttl: 60 * 5,
|
||||
maxSize: 100,
|
||||
debug: false
|
||||
});
|
||||
|
||||
let validSignatureNames = [ // allowed signature type/names
|
||||
'Cosmic Anomaly',
|
||||
@@ -244,7 +251,7 @@ define([
|
||||
* @param groupId
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllSignatureNames = (systemData, systemTypeId, areaId, groupId) => {
|
||||
let getSignatureTypeOptions = (systemData, systemTypeId, areaId, groupId) => {
|
||||
systemTypeId = parseInt(systemTypeId || 0);
|
||||
areaId = parseInt(areaId || 0);
|
||||
groupId = parseInt(groupId || 0);
|
||||
@@ -257,16 +264,18 @@ define([
|
||||
|
||||
let cacheKey = [systemTypeId, areaId, groupId].join('_');
|
||||
|
||||
newSelectOptions = sigTypeOptionsCache.getOrDefault(cacheKey, []);
|
||||
|
||||
// check for cached signature names
|
||||
if(sigNameCache.hasOwnProperty( cacheKey )){
|
||||
if(newSelectOptions.length){
|
||||
// cached signatures do not include static WHs!
|
||||
// -> ".slice(0)" creates copy
|
||||
newSelectOptions = sigNameCache[cacheKey].slice(0);
|
||||
newSelectOptions = newSelectOptions.slice(0);
|
||||
newSelectOptionsCount = getOptionsCount('children', newSelectOptions);
|
||||
}else{
|
||||
// get new Options ----------
|
||||
// get all possible "static" signature names by the selected groupId
|
||||
let tempSelectOptions = Util.getAllSignatureNames(systemTypeId, areaId, groupId);
|
||||
let tempSelectOptions = Util.getSignatureTypeNames(systemTypeId, areaId, groupId);
|
||||
|
||||
// format options into array with objects advantages: keep order, add more options (whs), use optgroup
|
||||
if(tempSelectOptions){
|
||||
@@ -351,7 +360,7 @@ define([
|
||||
}
|
||||
|
||||
// update cache (clone array) -> further manipulation to this array, should not be cached
|
||||
sigNameCache[cacheKey] = newSelectOptions.slice(0);
|
||||
sigTypeOptionsCache.set(cacheKey, newSelectOptions.slice(0));
|
||||
}
|
||||
|
||||
// static wormholes (DO NOT CACHE) (not all C2 WHs have the same statics,...
|
||||
@@ -382,11 +391,11 @@ define([
|
||||
* @param groupId
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllSignatureNamesBySystem = (systemElement, groupId) => {
|
||||
let getSignatureTypeOptionsBySystem = (systemElement, groupId) => {
|
||||
let systemTypeId = systemElement.data('typeId');
|
||||
let areaId = Util.getAreaIdBySecurity(systemElement.data('security'));
|
||||
let systemData = {statics: systemElement.data('statics')};
|
||||
return getAllSignatureNames(systemData, systemTypeId, areaId, groupId);
|
||||
return getSignatureTypeOptions(systemData, systemTypeId, areaId, groupId);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -882,7 +891,7 @@ define([
|
||||
// try to get "typeId" from description string
|
||||
let sigDescriptionLowerCase = sigDescription.toLowerCase();
|
||||
|
||||
let typeOptions = getAllSignatureNames(
|
||||
let typeOptions = getSignatureTypeOptions(
|
||||
systemData,
|
||||
systemData.type.id,
|
||||
Util.getAreaIdBySecurity(systemData.security),
|
||||
@@ -1721,7 +1730,7 @@ define([
|
||||
title: 'type',
|
||||
type: 'string', // required for sort/filter because initial data type is numeric
|
||||
width: 180,
|
||||
class: [config.tableCellFocusClass].join(' '),
|
||||
class: [config.tableCellFocusClass, config.tableCellTypeClass].join(' '),
|
||||
data: 'typeId',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
let tableApi = this.api();
|
||||
@@ -1749,7 +1758,7 @@ define([
|
||||
// -> "rowData" param is not current state, values are "on createCell()" state
|
||||
let rowData = tableApi.row($(cell).parents('tr')).data();
|
||||
|
||||
let typeOptions = getAllSignatureNames(
|
||||
let typeOptions = getSignatureTypeOptions(
|
||||
systemData,
|
||||
systemData.type.id,
|
||||
Util.getAreaIdBySecurity(systemData.security),
|
||||
@@ -1760,7 +1769,7 @@ define([
|
||||
display: function(value, sourceData){
|
||||
let selected = $.fn.editableutils.itemsByValue(value, sourceData);
|
||||
if(selected.length && selected[0].value > 0){
|
||||
$(this).html(FormElement.formatSignatureTypeSelectionData({text: selected[0].text}));
|
||||
$(this).html(FormElement.formatSignatureTypeSelectionData({text: selected[0].text}, undefined, {showWhSizeLabel: true}));
|
||||
}else{
|
||||
$(this).empty();
|
||||
}
|
||||
@@ -3307,6 +3316,6 @@ define([
|
||||
updateModule: updateModule,
|
||||
beforeHide: beforeHide,
|
||||
beforeDestroy: beforeDestroy,
|
||||
getAllSignatureNamesBySystem: getAllSignatureNamesBySystem
|
||||
getSignatureTypeOptionsBySystem: getSignatureTypeOptionsBySystem
|
||||
};
|
||||
});
|
||||
@@ -2586,7 +2586,7 @@ define([
|
||||
* @param sigGroupId
|
||||
* @returns {{}}
|
||||
*/
|
||||
let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => {
|
||||
let getSignatureTypeNames = (systemTypeId, areaId, sigGroupId) => {
|
||||
let signatureNames = {};
|
||||
if(
|
||||
SignatureType[systemTypeId] &&
|
||||
@@ -3553,7 +3553,7 @@ define([
|
||||
getTrueSecClassForSystem: getTrueSecClassForSystem,
|
||||
getStatusInfoForSystem: getStatusInfoForSystem,
|
||||
getSignatureGroupOptions: getSignatureGroupOptions,
|
||||
getAllSignatureNames: getAllSignatureNames,
|
||||
getSignatureTypeNames: getSignatureTypeNames,
|
||||
getAreaIdBySecurity: getAreaIdBySecurity,
|
||||
setCurrentMapUserData: setCurrentMapUserData,
|
||||
getCurrentMapUserData: getCurrentMapUserData,
|
||||
|
||||
@@ -69,10 +69,10 @@
|
||||
|
||||
<div id="{{sectionInfoId}}" class="collapse">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="col-xs-5 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-4 col-sm-3 control-label">Alias</label>
|
||||
<div class="col-xs-8 col-sm-9">
|
||||
<label class="col-xs-3 col-sm-3 control-label">Alias</label>
|
||||
<div class="col-xs-9 col-sm-9">
|
||||
<div class="controls">
|
||||
<div id="{{aliasId}}" class="form-control-static pf-dynamic-area"></div>
|
||||
</div>
|
||||
@@ -80,10 +80,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div class="col-xs-4 col-sm-3">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-4 col-sm-8 control-label">Signatures</label>
|
||||
<div class="col-xs-8 col-sm-4">
|
||||
<label class="col-xs-7 col-sm-8 control-label">Signatures</label>
|
||||
<div class="col-xs-5 col-sm-4">
|
||||
<div class="controls">
|
||||
<div id="{{signaturesId}}" class="form-control-static pf-dynamic-area text-right txt-color"></div>
|
||||
</div>
|
||||
@@ -91,17 +91,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div class="col-xs-3 col-sm-3">
|
||||
<div id="{{createdId}}" class="well well-sm well-text-number text-center" title="first create"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="col-xs-9 col-sm-9">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-12 col-sm-2 control-label">Description</label>
|
||||
<div class="col-xs-12 col-sm-10">
|
||||
<label class="col-xs-3 col-sm-2 control-label">Description</label>
|
||||
<div class="col-xs-9 col-sm-10">
|
||||
<div class="controls">
|
||||
<div id="{{descriptionId}}" class="form-control-static pf-dynamic-area"></div>
|
||||
</div>
|
||||
@@ -109,7 +109,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div class="col-xs-3 col-sm-3">
|
||||
<div id="{{updatedId}}" class="well well-sm well-text-number text-center" title="last update/delete"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
// splash loading animation ============================================================================
|
||||
|
||||
.pf-color-line{
|
||||
|
||||
@@ -187,6 +187,9 @@ em,
|
||||
letter-spacing: .02em;
|
||||
line-height: 16px;
|
||||
text-rendering: geometricPrecision;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,6 +542,25 @@ select:active, select:hover {
|
||||
}
|
||||
}
|
||||
|
||||
&.pf-table-type-cell{
|
||||
> span {
|
||||
&:first-child{
|
||||
display: inline-block;
|
||||
width: 28px;
|
||||
}
|
||||
&:nth-child(2){
|
||||
display: inline-block;
|
||||
width: 22px;
|
||||
|
||||
kbd{
|
||||
&:empty{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.pf-table-image-cell{
|
||||
padding: 0 !important;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
|
||||
Reference in New Issue
Block a user