Remove concept of expand/collapse and redesign log table rows

Each row sized to fit content, if the keys/values list is too long it
scrolls. Should comfortably fit about 17 items before scrolling
pull/10616/head
Alex P 2018-02-05 14:15:56 -08:00
parent b615be2f23
commit fb86889286
7 changed files with 66 additions and 168 deletions

View File

@ -1,101 +1,45 @@
import React, {Component, PropTypes} from 'react'
import React, {PropTypes} from 'react'
class LogItemKapacitorPoint extends Component {
renderKeysAndValues = (object, name, expanded) => {
if (!object) {
return <span className="logs-table--empty-cell">--</span>
}
const objKeys = Object.keys(object)
const objValues = Object.values(object)
const renderKeysAndValues = (object, name) => {
if (!object) {
return <span className="logs-table--empty-cell">--</span>
}
const objKeys = Object.keys(object)
const objValues = Object.values(object)
if (objKeys.length > 2) {
return expanded
? <div className="logs-table--key-values">
<h1>
{`${objKeys.length} ${name}`}
</h1>
<div className="logs-table--keys-scrollbox">
{objKeys.map((objKey, i) =>
<div key={i} className="logs-table--key-value">
{objKey}: <span>{objValues[i]}</span>
</div>
)}
</div>
</div>
: <div className="logs-table--key-values">
<h1>
{`${objKeys.length} ${name}`}
</h1>
<div className="logs-table--many-keys">Click to expand...</div>
</div>
}
return (
<div className="logs-table--key-values">
<h1>
{`${objKeys.length} ${name}`}
</h1>
return (
<div className="logs-table--key-values">
<h1>
{`${objKeys.length} ${name}`}
</h1>
<div className="logs-table--keys-scrollbox">
{objKeys.map((objKey, i) =>
<div key={i} className="logs-table--key-value">
{objKey}: <span>{objValues[i]}</span>
</div>
)}
</div>
)
}
handleToggleExpand = () => {
const {onToggleExpandLog, logIndex} = this.props
if (this.isExpandable()) {
onToggleExpandLog(logIndex)
}
}
isExpandable = () => {
const {logItem} = this.props
if (
Object.keys(logItem.tag).length > 2 ||
Object.keys(logItem.field).length > 2
) {
return true
}
return false
}
render() {
const {logItem} = this.props
const rowClass = `logs-table--row${this.isExpandable()
? ' logs-table--row__expandable'
: ''}${logItem.expanded ? ' expanded' : ''}`
return (
<div className={rowClass} onClick={this.handleToggleExpand}>
<div className="logs-table--divider">
<div className={`logs-table--level ${logItem.lvl}`} />
<div className="logs-table--timestamp">
{logItem.ts}
</div>
</div>
<div className="logs-table--details">
<div className="logs-table--service">Kapacitor Point</div>
<div className="logs-table--blah">
{this.renderKeysAndValues(logItem.tag, 'Tags', logItem.expanded)}
{this.renderKeysAndValues(
logItem.field,
'Fields',
logItem.expanded
)}
</div>
</div>
</div>
)
}
</div>
)
}
const LogItemKapacitorPoint = ({logItem}) =>
<div className="logs-table--row">
<div className="logs-table--divider">
<div className={`logs-table--level ${logItem.lvl}`} />
<div className="logs-table--timestamp">
{logItem.ts}
</div>
</div>
<div className="logs-table--details">
<div className="logs-table--service">Kapacitor Point</div>
<div className="logs-table--blah">
{renderKeysAndValues(logItem.tag, 'Tags')}
{renderKeysAndValues(logItem.field, 'Fields')}
</div>
</div>
</div>
const {func, number, shape, string} = PropTypes
const {shape, string} = PropTypes
LogItemKapacitorPoint.propTypes = {
logItem: shape({
@ -104,8 +48,6 @@ LogItemKapacitorPoint.propTypes = {
tag: shape.isRequired,
field: shape.isRequired,
}),
onToggleExpandLog: func.isRequired,
logIndex: number.isRequired,
}
export default LogItemKapacitorPoint

View File

@ -5,29 +5,24 @@ import FancyScrollbar from 'src/shared/components/FancyScrollbar'
const numLogsToRender = 200
const LogsTable = ({logs, onToggleExpandLog}) =>
<div className="logs-table--container">
const LogsTable = ({logs}) =>
<div className="logs-table">
<div className="logs-table--header">
<h2 className="panel-title">{`${numLogsToRender} Most Recent Logs`}</h2>
{`${numLogsToRender} Most Recent Logs`}
</div>
<FancyScrollbar
autoHide={false}
className="logs-table--panel fancy-scroll--kapacitor"
className="logs-table--container fancy-scroll--kapacitor"
>
{logs
.slice(0, numLogsToRender)
.map((log, i) =>
<LogsTableRow
key={log.key}
logItem={log}
index={i}
onToggleExpandLog={onToggleExpandLog}
/>
<LogsTableRow key={log.key} logItem={log} index={i} />
)}
</FancyScrollbar>
</div>
const {arrayOf, func, shape, string} = PropTypes
const {arrayOf, shape, string} = PropTypes
LogsTable.propTypes = {
logs: arrayOf(
@ -38,7 +33,6 @@ LogsTable.propTypes = {
msg: string.isRequired,
})
).isRequired,
onToggleExpandLog: func.isRequired,
}
export default LogsTable

View File

@ -8,7 +8,7 @@ import LogItemKapacitorError from 'src/kapacitor/components/LogItemKapacitorErro
import LogItemKapacitorDebug from 'src/kapacitor/components/LogItemKapacitorDebug'
import LogItemInfluxDBDebug from 'src/kapacitor/components/LogItemInfluxDBDebug'
const LogsTableRow = ({logItem, index, onToggleExpandLog}) => {
const LogsTableRow = ({logItem, index}) => {
if (logItem.service === 'sessions') {
return <LogItemSession logItem={logItem} logIndex={index} />
}
@ -16,13 +16,7 @@ const LogsTableRow = ({logItem, index, onToggleExpandLog}) => {
return <LogItemHTTP logItem={logItem} logIndex={index} />
}
if (logItem.service === 'kapacitor' && logItem.msg === 'point') {
return (
<LogItemKapacitorPoint
logItem={logItem}
logIndex={index}
onToggleExpandLog={onToggleExpandLog}
/>
)
return <LogItemKapacitorPoint logItem={logItem} logIndex={index} />
}
if (logItem.service === 'httpd_server_errors' && logItem.lvl === 'error') {
return <LogItemHTTPError logItem={logItem} logIndex={index} />
@ -59,7 +53,7 @@ const LogsTableRow = ({logItem, index, onToggleExpandLog}) => {
)
}
const {func, number, shape, string} = PropTypes
const {number, shape, string} = PropTypes
LogsTableRow.propTypes = {
logItem: shape({
@ -69,7 +63,6 @@ LogsTableRow.propTypes = {
msg: string.isRequired,
}).isRequired,
index: number.isRequired,
onToggleExpandLog: func.isRequired,
}
export default LogsTableRow

View File

@ -20,7 +20,6 @@ const Tickscript = ({
isNewTickscript,
areLogsVisible,
areLogsEnabled,
onToggleExpandLog,
onToggleLogsVisibility,
}) =>
<div className="page">
@ -52,9 +51,7 @@ const Tickscript = ({
unsavedChanges={unsavedChanges}
/>
</div>
{areLogsVisible
? <LogsTable logs={logs} onToggleExpandLog={onToggleExpandLog} />
: null}
{areLogsVisible ? <LogsTable logs={logs} /> : null}
</div>
</div>
@ -82,7 +79,6 @@ Tickscript.propTypes = {
onChangeID: func.isRequired,
isNewTickscript: bool.isRequired,
unsavedChanges: bool,
onToggleExpandLog: func.isRequired,
}
export default Tickscript

View File

@ -2,7 +2,6 @@ import React, {PropTypes, Component} from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import uuid from 'node-uuid'
import _ from 'lodash'
import Tickscript from 'src/kapacitor/components/Tickscript'
import * as kapactiorActionCreators from 'src/kapacitor/actions/view'
@ -157,13 +156,6 @@ class TickscriptPage extends Component {
})
}
handleToggleExpandLog = logIndex => {
const {logs} = this.state
logs[logIndex].expanded = !_.get(logs[logIndex], 'expanded', false)
this.setState({logs})
}
handleSave = async () => {
const {kapacitor, task} = this.state
const {
@ -251,7 +243,6 @@ class TickscriptPage extends Component {
areLogsVisible={areLogsVisible}
areLogsEnabled={areLogsEnabled}
onToggleLogsVisibility={this.handleToggleLogsVisibility}
onToggleExpandLog={this.handleToggleExpandLog}
/>
)
}

View File

@ -9,11 +9,10 @@ $logs-row-indent: 6px;
$logs-level-dot: 8px;
$logs-margin: 4px;
.logs-table--container {
.logs-table {
width: 50%;
position: relative;
height: 100%;
@include gradient-v(mix($g3-castle, $g2-kevlar),mix($g1-raven, $g0-obsidian));
}
.logs-table--header {
display: flex;
@ -23,27 +22,28 @@ $logs-margin: 4px;
height: $logs-table-header-height;
padding: 0 $logs-table-padding 0 ($logs-table-padding / 2);
background-color: $g4-onyx;
white-space: nowrap;
font-size: 17px;
@include no-user-select();
letter-spacing: 0.015em;
font-weight: 500;
}
.logs-table--panel {
.logs-table--container {
position: absolute !important;
top: $logs-table-header-height;
left: 0;
width: 100%;
height: calc(100% - #{$logs-table-header-height}) !important;
@include gradient-v(mix($g3-castle, $g2-kevlar),mix($g1-raven, $g0-obsidian));
}
.logs-table {
height: 100%;
}
.logs-table--row {
position: relative;
overflow: hidden;
height: 87px; // Fixed height, required for Infinite Scroll, allows for 2 tags / fields per line
padding: 8px ($logs-table-padding - 16px) 8px ($logs-table-padding / 2);
border-bottom: 2px solid $g3-castle;
transition: background-color 0.25s ease;
&:first-child {
&:last-of-type {
border-bottom: none;
}
}
@ -61,13 +61,13 @@ $logs-margin: 4px;
&.debug {background-color: $c-comet;}
&.info {background-color: $g6-smoke;}
&.warn {background-color: $c-pineapple;}
&.ok {background-color: $c-rainforest;}
&.ok {background-color: $c-pool;}
&.error {background-color: $c-dreamsicle;}
}
.logs-table--timestamp {
font-family: $code-font;
font-weight: 500;
font-size: 11px;
font-size: 13px;
color: $g9-mountain;
flex: 1 0 0;
}
@ -75,9 +75,10 @@ $logs-margin: 4px;
display: flex;
align-items: flex-start;
font-size: 13px;
color: $g13-mist;
color: $g11-sidewalk;
font-weight: 600;
padding-left: ($logs-level-dot + $logs-row-indent);
margin-top: 1px;
.error {color: $c-dreamsicle;}
.debug {color: $c-comet;}
@ -106,38 +107,17 @@ $logs-margin: 4px;
letter-spacing: normal;
line-height: 1.42857143em;
text-transform: uppercase;
color: $g16-pearl;
}
.logs-table--key-value {
white-space: nowrap;
}
.logs-table--key-value span {
color: $c-pool;
}
.logs-table--many-keys {
color: $g9-mountain;
width: 100%;
display: inline-block;
font-style: italic;
}
// Styles for Expandable Log Items
.logs-table--row.logs-table--row__expandable {
&:hover {
background-color: fade-out($g0-obsidian, 0.7);
cursor: zoom-in;
}
&.expanded {
background-color: $g0-obsidian;
height: 240px;
&:hover {
background-color: $g0-obsidian;
cursor: zoom-out;
}
}
color: $c-rainforest;
}
.logs-table--keys-scrollbox {
width: 100%;
height: 190px;
overflow-y: scroll;
@include custom-scrollbar($g0-obsidian,$g7-graphite);
max-height: 300px;
overflow-y: auto;
@include custom-scrollbar-round($g0-obsidian,$c-rainforest);
}

View File

@ -71,16 +71,18 @@ $scrollbar-offset: 3px;
width: $scrollbar-width;
border-top-right-radius: $radius;
border-top-left-radius: $radius;
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
border-bottom-right-radius: $radius;
&-button {
background-color: $trackColor;
}
&-track {
background-color: $trackColor;
border-top-right-radius: $radius;
border-bottom-right-radius: $radius;
border-top-right-radius: ($scrollbar-width / 2);
border-top-left-radius: ($scrollbar-width / 2);
border-bottom-left-radius: ($scrollbar-width / 2);
border-bottom-right-radius: ($scrollbar-width / 2);
}
&-track-piece {
background-color: $trackColor;