feat(pool,vm/logs): use SortedTable (#2513)

This commit is contained in:
Rajaa.BARHTAOUI 2018-01-11 14:51:59 +01:00 committed by Pierre Donias
parent 898434b267
commit c787988b06
4 changed files with 98 additions and 165 deletions

View File

@ -1465,6 +1465,10 @@ const messages = {
logNoStackTrace: 'No stack trace', logNoStackTrace: 'No stack trace',
logNoParams: 'No params', logNoParams: 'No params',
logDelete: 'Delete log', logDelete: 'Delete log',
logsDelete: 'Delete logs',
logDeleteMultiple: 'Delete log{nLogs, plural, one {} other {s}}',
logDeleteMultipleMessage:
'Are you sure you want to delete {nLogs, number} log{nLogs, plural, one {} other {s}}?',
logDeleteAll: 'Delete all logs', logDeleteAll: 'Delete all logs',
logDeleteAllTitle: 'Delete all logs', logDeleteAllTitle: 'Delete all logs',
logDeleteAllMessage: 'Are you sure you want to delete all the logs?', logDeleteAllMessage: 'Are you sure you want to delete all the logs?',

View File

@ -1425,6 +1425,12 @@ export const deletePbd = pbd => _call('pbd.delete', { id: resolveId(pbd) })
export const deleteMessage = message => export const deleteMessage = message =>
_call('message.delete', { id: resolveId(message) }) _call('message.delete', { id: resolveId(message) })
export const deleteMessages = logs =>
confirm({
title: _('logDeleteMultiple', { nLogs: logs.length }),
body: _('logDeleteMultipleMessage', { nLogs: logs.length }),
}).then(() => Promise.all(map(logs, deleteMessage)), noop)
// Tags -------------------------------------------------------------- // Tags --------------------------------------------------------------
export const addTag = (object, tag) => export const addTag = (object, tag) =>

View File

@ -1,122 +1,68 @@
import _ from 'intl' import _ from 'intl'
import ActionRow from 'action-row-button'
import React, { Component } from 'react' import React, { Component } from 'react'
import TabButton from 'tab-button' import SortedTable from 'sorted-table'
import { deleteMessage } from 'xo'
import { createPager, createSelector } from 'selectors'
import { FormattedRelative, FormattedTime } from 'react-intl' import { FormattedRelative, FormattedTime } from 'react-intl'
import { Container, Row, Col } from 'grid' import { deleteMessage, deleteMessages } from 'xo'
import { ceil, isEmpty, map } from 'lodash'
const LOGS_PER_PAGE = 10 const LOG_COLUMNS = [
{
default: true,
itemRenderer: log => (
<div>
<FormattedTime
value={log.time * 1000}
minute='numeric'
hour='numeric'
day='numeric'
month='long'
year='numeric'
/>{' '}
(<FormattedRelative value={log.time * 1000} />)
</div>
),
name: _('logDate'),
sortCriteria: 'time',
},
{
itemRenderer: log => log.name,
name: _('logName'),
sortCriteria: 'name',
},
{
itemRenderer: log => log.body,
name: _('logContent'),
sortCriteria: 'body',
},
]
const INDIVIDUAL_ACTIONS = [
{
handler: deleteMessage,
icon: 'delete',
label: _('logDelete'),
level: 'danger',
},
]
const GROUPED_ACTIONS = [
{
handler: deleteMessages,
icon: 'delete',
label: _('logsDelete'),
level: 'danger',
},
]
export default class TabLogs extends Component { export default class TabLogs extends Component {
constructor () {
super()
this.getLogs = createPager(
() => this.props.logs,
() => this.state.page,
LOGS_PER_PAGE
)
this.getNPages = createSelector(
() => (this.props.logs ? this.props.logs.length : 0),
nLogs => ceil(nLogs / LOGS_PER_PAGE)
)
this.state = {
page: 1,
}
}
_deleteAllLogs = () => map(this.props.logs, deleteMessage)
_nextPage = () =>
this.setState({ page: Math.min(this.state.page + 1, this.getNPages()) })
_previousPage = () =>
this.setState({ page: Math.max(this.state.page - 1, 1) })
render () { render () {
const logs = this.getLogs()
const { page } = this.state
return ( return (
<Container> <SortedTable
{isEmpty(logs) ? ( collection={this.props.logs}
<Row> columns={LOG_COLUMNS}
<Col mediumSize={6} className='text-xs-center'> groupedActions={GROUPED_ACTIONS}
<br /> individualActions={INDIVIDUAL_ACTIONS}
<h4>{_('noLogs')}</h4> stateUrlParam='s'
</Col> />
</Row>
) : (
<div>
<Row>
<Col className='text-xs-right'>
<TabButton
btnStyle='secondary'
disabled={page === 1}
handler={this._previousPage}
icon='previous'
/>
<TabButton
btnStyle='secondary'
disabled={page === this.getNPages()}
handler={this._nextPage}
icon='next'
/>
<TabButton
btnStyle='danger'
handler={this._removeAllLogs} // FIXME: define this method
icon='delete'
labelId='logRemoveAll'
/>
</Col>
</Row>
<Row>
<Col>
<table className='table'>
<thead className='thead-default'>
<tr>
<th>{_('logDate')}</th>
<th>{_('logName')}</th>
<th>{_('logContent')}</th>
<th>{_('logAction')}</th>
</tr>
</thead>
<tbody>
{map(logs, log => (
<tr key={log.id}>
<td>
<FormattedTime
value={log.time * 1000}
minute='numeric'
hour='numeric'
day='numeric'
month='long'
year='numeric'
/>{' '}
(<FormattedRelative value={log.time * 1000} />)
</td>
<td>{log.name}</td>
<td>{log.body}</td>
<td>
<ActionRow
btnStyle='danger'
handler={deleteMessage}
handlerParam={log}
icon='delete'
/>
</td>
</tr>
))}
</tbody>
</table>
</Col>
</Row>
</div>
)}
</Container>
) )
} }
} }

View File

@ -1,19 +1,13 @@
import _ from 'intl' import _ from 'intl'
import ActionRowButton from 'action-row-button'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import React, { Component } from 'react' import React, { Component } from 'react'
import SortedTable from 'sorted-table' import SortedTable from 'sorted-table'
import TabButton from 'tab-button'
import { connectStore } from 'utils' import { connectStore } from 'utils'
import { deleteMessage } from 'xo'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { Container, Row, Col } from 'grid'
import { createGetObjectMessages } from 'selectors' import { createGetObjectMessages } from 'selectors'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { deleteMessage, deleteMessages } from 'xo'
const LOG_COLUMNS = [ const LOG_COLUMNS = [
{ {
name: _('logDate'),
itemRenderer: log => ( itemRenderer: log => (
<span> <span>
<FormattedTime <FormattedTime
@ -27,29 +21,37 @@ const LOG_COLUMNS = [
(<FormattedRelative value={log.time * 1000} />) (<FormattedRelative value={log.time * 1000} />)
</span> </span>
), ),
sortCriteria: log => log.time, name: _('logDate'),
sortCriteria: 'time',
sortOrder: 'desc', sortOrder: 'desc',
}, },
{ {
name: _('logName'),
itemRenderer: log => log.name, itemRenderer: log => log.name,
sortCriteria: log => log.name, name: _('logName'),
sortCriteria: 'name',
}, },
{ {
name: _('logContent'),
itemRenderer: log => log.body, itemRenderer: log => log.body,
sortCriteria: log => log.body, name: _('logContent'),
sortCriteria: 'body',
}, },
]
const INDIVIDUAL_ACTIONS = [
{ {
name: _('logAction'), handler: deleteMessage,
itemRenderer: log => ( icon: 'delete',
<ActionRowButton label: _('logDelete'),
btnStyle='danger' level: 'danger',
handler={deleteMessage} },
handlerParam={log} ]
icon='delete'
/> const GROUPED_ACTIONS = [
), {
handler: deleteMessages,
icon: 'delete',
label: _('logsDelete'),
level: 'danger',
}, },
] ]
@ -61,40 +63,15 @@ const LOG_COLUMNS = [
}) })
}) })
export default class TabLogs extends Component { export default class TabLogs extends Component {
_deleteAllLogs = () => map(this.props.logs, deleteMessage)
render () { render () {
const { logs } = this.props
if (isEmpty(logs)) {
return (
<Row>
<Col className='text-xs-center'>
<br />
<h4>{_('noLogs')}</h4>
</Col>
</Row>
)
}
return ( return (
<Container> <SortedTable
<Row> collection={this.props.logs}
<Col className='text-xs-right'> columns={LOG_COLUMNS}
<TabButton groupedActions={GROUPED_ACTIONS}
btnStyle='danger' individualActions={INDIVIDUAL_ACTIONS}
handler={this._deleteAllLogs} stateUrlParam='s'
icon='delete' />
labelId='logRemoveAll'
/>
</Col>
</Row>
<Row>
<Col>
<SortedTable collection={logs} columns={LOG_COLUMNS} />
</Col>
</Row>
</Container>
) )
} }
} }