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',
logNoParams: 'No params',
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',
logDeleteAllTitle: 'Delete all 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 =>
_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 --------------------------------------------------------------
export const addTag = (object, tag) =>

View File

@ -1,122 +1,68 @@
import _ from 'intl'
import ActionRow from 'action-row-button'
import React, { Component } from 'react'
import TabButton from 'tab-button'
import { deleteMessage } from 'xo'
import { createPager, createSelector } from 'selectors'
import SortedTable from 'sorted-table'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { Container, Row, Col } from 'grid'
import { ceil, isEmpty, map } from 'lodash'
import { deleteMessage, deleteMessages } from 'xo'
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 {
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 () {
const logs = this.getLogs()
const { page } = this.state
return (
<Container>
{isEmpty(logs) ? (
<Row>
<Col mediumSize={6} className='text-xs-center'>
<br />
<h4>{_('noLogs')}</h4>
</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>
<SortedTable
collection={this.props.logs}
columns={LOG_COLUMNS}
groupedActions={GROUPED_ACTIONS}
individualActions={INDIVIDUAL_ACTIONS}
stateUrlParam='s'
/>
)
}
}

View File

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