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 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 {
|
class HistoryList extends Component {
|
||||||
|
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { showData: false };
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.fetchHistory();
|
this.props.fetchHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
getIcon (type) {
|
toggleShowDiff () {
|
||||||
if (type.indexOf('created') > -1 ) {
|
this.setState({ showData: !this.state.showData });
|
||||||
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';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { history } = this.props;
|
const { history } = this.props;
|
||||||
|
if (history.length < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const entries = history.map((entry) => <HistoryItem key={`log${entry.id}`} entry={entry} showData={this.state.showData} />);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List ripple >
|
<div>
|
||||||
<ListSubHeader caption="History" />
|
<h5>History</h5>
|
||||||
{history.length > 0 ? history.map((log, i) => {
|
<Switch
|
||||||
const actions = [];
|
checked={this.state.showData}
|
||||||
|
label="Show full events"
|
||||||
|
onChange={this.toggleShowDiff.bind(this)}
|
||||||
const icon = this.getIcon(log.type);
|
/>
|
||||||
|
<table className={style.history}>
|
||||||
const caption = <div>{log.data.name} <small>{log.type}</small></div>;
|
<tbody>
|
||||||
|
{entries}
|
||||||
return (
|
</tbody>
|
||||||
<ListItem key={i}
|
</table>
|
||||||
leftIcon={icon}
|
</div>
|
||||||
rightActions={actions}
|
|
||||||
caption={caption}
|
|
||||||
legend={log.createdAt} />
|
|
||||||
);
|
|
||||||
}) : <ListItem caption="No log entries" />}
|
|
||||||
|
|
||||||
</List>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default HistoryList;
|
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