js/components/logs_table.js
// NPM IMPORTS
// import assert from 'assert'
import _ from 'lodash'
import Immutable from 'immutable'
// COMMON IMPORTS
import T from '../../../node_modules/devapt-core-common/dist/js/utils/types'
import uid from '../../../node_modules/devapt-core-common/dist/js/utils/uid'
// BROWSER IMPORTS
import Table from './table'
const context = 'browser/components/logs_table'
/**
* @file UI component class.
* @author Luc BORIES
* @license Apache-2.0
*/
export default class LogsTable extends Table
{
/**
* Creates an instance of LogsTable.
*
* @param {object} arg_runtime - client runtime.
* @param {object} arg_state - component state.
* @param {string} arg_log_context - context of traces of this instance (optional).
*
* @returns {nothing}
*/
constructor(arg_runtime, arg_state, arg_log_context)
{
const log_context = arg_log_context ? arg_log_context : context
super(arg_runtime, arg_state, log_context)
this.is_logs_table_component = true
this.register_state_value_change_handle(['selected_column'], 'handle_selected_column_change')
this._elements_cache = {}
this._filters = {}
// DEBUG
// this.enable_trace()
}
/**
* Build a table row DOM element.
*
* @param {array} arg_row_array - row values array.
* @param {integer} arg_row_index - row index.
* @param {integer} arg_max_cols - max columns number.
*
* @returns {Element} - TD DOM Element.
*/
build_row(arg_row_array, arg_row_index, arg_max_cols)
{
const td_elem = super.build_row(arg_row_array, arg_row_index, arg_max_cols)
const log_uid = 'log_' + uid()
arg_row_array.push(log_uid)
td_elem.setAttribute('data-devapt-log_uid', log_uid)
const row_record = {
elem:td_elem,
log:arg_row_array,
log_uid:log_uid,
row_index:arg_row_index
}
this._elements_cache[log_uid] = row_record
this.apply_filter_on_row_record(row_record)
return td_elem
}
/**
* Get column index from its name.
*
* @param {string} arg_column_name - column name.
*
* @returns {integer} - column index
*/
get_column_index(arg_column_name)
{
switch(arg_column_name){
case 'ts': return 0
case 'level': return 1
case 'source': return 2
case 'context': return 3
case 'instance': return 4
case 'group': return 5
case 'action': return 6
case 'text': return 7
}
return 0
}
/**
* Delete table row DOM element.
*
* @param {Element} arg_row_elem - row TR Element.
*
* @returns {nothing}
*/
delete_row_elem(arg_row_elem)
{
const log_uid = arg_row_elem.getAttribute('data-devapt-log_uid')
delete this._elements_cache[log_uid]
}
apply_filter(arg_filter_value, arg_cell_value)
{
const filter_mode_not = ('' + arg_filter_value).startsWith('NOT ') ? true : false
if (filter_mode_not)
{
return ('' + arg_cell_value).search(arg_filter_value.substr(4)) < 0
}
return ('' + arg_cell_value).search(arg_filter_value) >= 0
}
apply_filter_on_row_record(arg_row_record)
{
let match = true
_.forEach(this._filters,
(filter)=>{
if (match && arg_row_record.log.length > filter.index)
{
const column_value = arg_row_record.log[filter.index]
const cell_match = this.apply_filter(filter.value, column_value)
match = filter.value == '' || cell_match
}
}
)
// console.log('apply_filter_on_row_record:match %b', match, this._filters, row_record.elem.style.display)
if (match)
{
arg_row_record.elem.style.display = 'table-row'
} else {
arg_row_record.elem.style.display = 'none'
}
}
/**
* Filter a column.
*
* @param {array} arg_row_array - row values array.
* @param {integer} arg_row_index - row index.
* @param {integer} arg_max_cols - max columns number.
*
* @returns {string} - HTML TR string
*/
do_action_filter_column(arg_column_name, arg_filter_value)
{
// console.log(context + ':do_action_filter_column:column=%s, filter=%s',arg_column_name, arg_filter_value, this._elements_cache)
const column_index = this.get_column_index(arg_column_name)
this._filters[arg_column_name] = { value:arg_filter_value, index:column_index }
_.forEach(this._elements_cache,
(row_record)=>{
this.apply_filter_on_row_record(row_record)
}
)
}
/**
* Handle click on TH tags.
*
* @param {any} arg_stream_data - object record: { component_name:string, event_name:string, dom_selector:string, target:object, data:any }.
*
* @returns {nothing}
*/
do_click_th(arg_stream_data)
{
this.dispatch_update_state_value_action(['selected_column'], arg_stream_data.target.id)
}
/**
* Handle selected_column state change.
*
* @param {array} arg_path - value state path.
* @param {Immutable.*} arg_previous_value - previous state value.
* @param {Immutable.*} arg_new_value - new state value.
*
* @returns {nothing}
*/
handle_selected_column_change(arg_path, arg_previous_value, arg_new_value)
{
console.log(context + ':handle_selected_column_change', arg_path, arg_previous_value, arg_new_value)
if (! arg_previous_value && ! arg_new_value)
{
console.log(context + ':handle_selected_column_change:no previous and no new values', arg_path, arg_previous_value, arg_new_value)
return
}
if ( Immutable.is(arg_previous_value, arg_new_value) )
{
console.log(context + ':handle_selected_column_change:previous value = new value', arg_path, arg_previous_value, arg_new_value)
return
}
const new_value = arg_new_value && arg_new_value.toJS() ? arg_new_value.toJS() : undefined
if ( ! T.isString(new_value) )
{
console.warn(context + ':handle_selected_column_change:bad new value string', arg_path, arg_previous_value, arg_new_value)
return
}
// TODO
}
}