mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
fix EventHistory with diffs
This commit is contained in:
parent
a7c844d716
commit
0c0c61d5a3
2
frontend/dist/bundle.css
vendored
2
frontend/dist/bundle.css
vendored
File diff suppressed because one or more lines are too long
2
frontend/dist/bundle.css.map
vendored
2
frontend/dist/bundle.css.map
vendored
File diff suppressed because one or more lines are too long
42
frontend/dist/bundle.js
vendored
42
frontend/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
2
frontend/dist/bundle.js.map
vendored
2
frontend/dist/bundle.js.map
vendored
File diff suppressed because one or more lines are too long
124
frontend/src/component/history/history-item.jsx
Normal file
124
frontend/src/component/history/history-item.jsx
Normal file
@ -0,0 +1,124 @@
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
|
||||
import FontIcon from 'react-toolbox/lib/font_icon';
|
||||
|
||||
import style from './history.scss';
|
||||
|
||||
const DIFF_PREFIXES = {
|
||||
A: ' ',
|
||||
E: ' ',
|
||||
D: '-',
|
||||
N: '+',
|
||||
};
|
||||
|
||||
const SPADEN_CLASS = {
|
||||
A: style.blue, // array edited
|
||||
E: style.blue, // edited
|
||||
D: style.negative, // deleted
|
||||
N: style.positive, // added
|
||||
};
|
||||
|
||||
class HistoryItem extends Component {
|
||||
|
||||
static propTypes () {
|
||||
return {
|
||||
entry: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
||||
getIcon (type) {
|
||||
if (type.indexOf('created') > -1 ) {
|
||||
return 'add';
|
||||
}
|
||||
|
||||
if (type.indexOf('deleted') > -1 ) {
|
||||
return 'remove';
|
||||
}
|
||||
|
||||
if (type.indexOf('updated') > -1 ) {
|
||||
return 'update';
|
||||
}
|
||||
|
||||
if (type.indexOf('archived') > -1 ) {
|
||||
return 'archived';
|
||||
}
|
||||
return 'bookmark';
|
||||
}
|
||||
|
||||
buildDiff (diff, idx) {
|
||||
let change;
|
||||
const key = diff.path.join('.');
|
||||
|
||||
if (diff.lhs !== undefined && diff.rhs !== undefined) {
|
||||
change = (
|
||||
<div>
|
||||
<div className={SPADEN_CLASS.D}>- {key}: {JSON.stringify(diff.lhs)}</div>
|
||||
<div className={SPADEN_CLASS.N}>+ {key}: {JSON.stringify(diff.rhs)}</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
const spadenClass = SPADEN_CLASS[diff.kind];
|
||||
const prefix = DIFF_PREFIXES[diff.kind];
|
||||
|
||||
change = (<div className={spadenClass}>{prefix} {key}: {JSON.stringify(diff.rhs)}</div>);
|
||||
}
|
||||
|
||||
return (<div key={idx}>{change}</div>);
|
||||
}
|
||||
|
||||
renderEventDiff (logEntry) {
|
||||
if (!logEntry.diffs) {
|
||||
return;
|
||||
}
|
||||
const changes = logEntry.diffs.map(this.buildDiff);
|
||||
return (
|
||||
<code className="smalltext man">{changes.length === 0 ? '(no changes)' : changes}</code>
|
||||
);
|
||||
}
|
||||
|
||||
renderFullEventData (logEntry) {
|
||||
const localEventData = JSON.parse(JSON.stringify(logEntry));
|
||||
delete localEventData.description;
|
||||
delete localEventData.name;
|
||||
delete localEventData.diffs;
|
||||
|
||||
const prettyPrinted = JSON.stringify(localEventData, null, 2);
|
||||
|
||||
return (<code className="JSON smalltext man">{prettyPrinted}</code>);
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
createdBy,
|
||||
id,
|
||||
type,
|
||||
} = this.props.entry;
|
||||
|
||||
const createdAt = (new Date(this.props.entry.createdAt)).toLocaleString('nb-NO');
|
||||
const icon = this.getIcon(type);
|
||||
|
||||
const data = this.props.showData ?
|
||||
this.renderFullEventData(this.props.entry) : this.renderEventDiff(this.props.entry);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<FontIcon value={icon} title={type} /> {type}
|
||||
<dl>
|
||||
<dt>Id:</dt>
|
||||
<dd>{id}</dd>
|
||||
<dt>Type:</dt>
|
||||
<dd>{type}</dd>
|
||||
<dt>Timestamp:</dt>
|
||||
<dd>{createdAt}</dd>
|
||||
<dt>Username:</dt>
|
||||
<dd>{createdBy}</dd>
|
||||
</dl>
|
||||
</td>
|
||||
<td>{data}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HistoryItem;
|
@ -1,58 +1,48 @@
|
||||
import React, { Component } from 'react';
|
||||
import { List, ListItem, ListSubHeader } from 'react-toolbox/lib/list';
|
||||
import HistoryItem from './history-item';
|
||||
import Switch from 'react-toolbox/lib/switch';
|
||||
|
||||
import style from './history.scss';
|
||||
|
||||
class HistoryList extends Component {
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = { showData: false };
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.props.fetchHistory();
|
||||
}
|
||||
|
||||
getIcon (type) {
|
||||
if (type.indexOf('created') > -1 ) {
|
||||
return 'add';
|
||||
}
|
||||
|
||||
if (type.indexOf('deleted') > -1 ) {
|
||||
return 'remove';
|
||||
}
|
||||
|
||||
if (type.indexOf('updated') > -1 ) {
|
||||
return 'update';
|
||||
}
|
||||
|
||||
if (type.indexOf('archived') > -1 ) {
|
||||
return 'archived';
|
||||
}
|
||||
return 'bookmark';
|
||||
toggleShowDiff () {
|
||||
this.setState({ showData: !this.state.showData });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { history } = this.props;
|
||||
|
||||
return (
|
||||
<List ripple >
|
||||
<ListSubHeader caption="History" />
|
||||
{history.length > 0 ? history.map((log, i) => {
|
||||
const actions = [];
|
||||
|
||||
|
||||
const icon = this.getIcon(log.type);
|
||||
|
||||
const caption = <div>{log.data.name} <small>{log.type}</small></div>;
|
||||
|
||||
return (
|
||||
<ListItem key={i}
|
||||
leftIcon={icon}
|
||||
rightActions={actions}
|
||||
caption={caption}
|
||||
legend={log.createdAt} />
|
||||
);
|
||||
}) : <ListItem caption="No log entries" />}
|
||||
|
||||
</List>
|
||||
);
|
||||
}
|
||||
if (history.length < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const entries = history.map((entry) => <HistoryItem key={`log${entry.id}`} entry={entry} showData={this.state.showData} />);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h5>History</h5>
|
||||
<Switch
|
||||
checked={this.state.showData}
|
||||
label="Show full events"
|
||||
onChange={this.toggleShowDiff.bind(this)}
|
||||
/>
|
||||
<table className={style.history}>
|
||||
<tbody>
|
||||
{entries}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default HistoryList;
|
||||
|
78
frontend/src/component/history/history.scss
Normal file
78
frontend/src/component/history/history.scss
Normal file
@ -0,0 +1,78 @@
|
||||
.history {
|
||||
width:100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
padding: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
td + td {
|
||||
border-left: 1px solid white;
|
||||
}
|
||||
|
||||
tr {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
flex: 1;
|
||||
display:inline-block;
|
||||
/* to keep IE happy */
|
||||
}
|
||||
|
||||
code {
|
||||
word-wrap: break-word;
|
||||
white-space: pre;
|
||||
font-family: monospace;
|
||||
line-height: 100%;
|
||||
color: #0B8C8F
|
||||
}
|
||||
|
||||
code > .diff-N {
|
||||
color: green;
|
||||
}
|
||||
|
||||
code > .diff-D {
|
||||
color: red;
|
||||
}
|
||||
|
||||
code > .diff-A, .diff-E {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.positive {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.blue {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
|
||||
dl {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
float: left;
|
||||
clear: left;
|
||||
width: 100px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0 0 0 110px;
|
||||
padding: 0 0 0.5em 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user