feat(xo-web/backup/overview): add link from log to its job (#5202)
See #4564
This commit is contained in:
parent
8d7f8d156f
commit
2f17420721
@ -8,6 +8,7 @@
|
||||
> Users must be able to say: “Nice enhancement, I'm eager to test it”
|
||||
|
||||
- [VM/network] VIF's locking mode: improve tooltip messages [#4713](https://github.com/vatesfr/xen-orchestra/issues/4713) (PR [#5227](https://github.com/vatesfr/xen-orchestra/pull/5227))
|
||||
- [Backup/overview] Link log entry to its job [#4564](https://github.com/vatesfr/xen-orchestra/issues/4564) (PR [#5202](https://github.com/vatesfr/xen-orchestra/pull/5202))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
@ -2092,6 +2092,7 @@ const messages = {
|
||||
backupRestartFailedVms: "Restart failed VMs' backup",
|
||||
backupForceRestartFailedVms: "Force restart failed VMs' backup",
|
||||
clickForMoreInformation: 'Click for more information',
|
||||
goToThisJob: 'Click to go to this job',
|
||||
|
||||
// ----- IPs ------
|
||||
ipPoolName: 'Name',
|
||||
|
@ -25,13 +25,23 @@ const Overview = decorate([
|
||||
legacyJobs: subscribeJobs,
|
||||
}),
|
||||
provideState({
|
||||
initialState: () => ({
|
||||
scrollIntoJobs: undefined,
|
||||
}),
|
||||
effects: {
|
||||
handleJobsRef(_, ref) {
|
||||
if (ref !== null) {
|
||||
this.state.scrollIntoJobs = ref.scrollIntoView.bind(ref)
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
haveLegacyBackups: (_, { legacyJobs }) =>
|
||||
some(legacyJobs, job => legacyJobKey.includes(job.key)),
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ state: { haveLegacyBackups } }) => (
|
||||
({ effects, state: { haveLegacyBackups, scrollIntoJobs } }) => (
|
||||
<div>
|
||||
{haveLegacyBackups && <LegacyOverview />}
|
||||
<div className='mt-2 mb-1'>
|
||||
@ -41,10 +51,12 @@ const Overview = decorate([
|
||||
<Icon icon='backup' /> {_('backupJobs')}
|
||||
</CardHeader>
|
||||
<CardBlock>
|
||||
<JobsTable />
|
||||
<div ref={effects.handleJobsRef}>
|
||||
<JobsTable />
|
||||
</div>
|
||||
</CardBlock>
|
||||
</Card>
|
||||
<LogsTable />
|
||||
<LogsTable scrollIntoJobs={scrollIntoJobs} />
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
|
@ -4,8 +4,10 @@ import addSubscriptions from 'add-subscriptions'
|
||||
import decorate from 'apply-decorators'
|
||||
import Icon from 'icon'
|
||||
import NoObjects from 'no-objects'
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import SortedTable from 'sorted-table'
|
||||
import Tooltip from 'tooltip'
|
||||
import { alert } from 'modal'
|
||||
import { Card, CardHeader, CardBlock } from 'card'
|
||||
import { connectStore, formatSize } from 'utils'
|
||||
@ -13,6 +15,7 @@ import { createGetObjectsOfType } from 'selectors'
|
||||
import { get } from '@xen-orchestra/defined'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { isEmpty, filter, map, keyBy } from 'lodash'
|
||||
import { withRouter } from 'react-router'
|
||||
import {
|
||||
subscribeBackupNgJobs,
|
||||
subscribeBackupNgLogs,
|
||||
@ -49,10 +52,44 @@ export const LogStatus = ({ log, tooltip = _('logDisplayDetails') }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const CURSOR_POINTER_STYLE = { cursor: 'pointer' }
|
||||
const GoToJob = decorate([
|
||||
withRouter,
|
||||
provideState({
|
||||
effects: {
|
||||
goTo() {
|
||||
const { jobId, location, router, scrollIntoJobs } = this.props
|
||||
router.replace({
|
||||
...location,
|
||||
query: { ...location.query, s: `id:${jobId}` },
|
||||
})
|
||||
scrollIntoJobs()
|
||||
},
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ effects, children }) => (
|
||||
<Tooltip content={_('goToThisJob')}>
|
||||
<p onClick={effects.goTo} style={CURSOR_POINTER_STYLE}>
|
||||
{children}
|
||||
</p>
|
||||
</Tooltip>
|
||||
),
|
||||
])
|
||||
|
||||
GoToJob.propTypes = {
|
||||
jobId: PropTypes.string.isRequired,
|
||||
scrollIntoJobs: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
const COLUMNS = [
|
||||
{
|
||||
name: _('jobId'),
|
||||
itemRenderer: log => log.jobId.slice(4, 8),
|
||||
itemRenderer: (log, { scrollIntoJobs }) => (
|
||||
<GoToJob jobId={log.jobId} scrollIntoJobs={scrollIntoJobs}>
|
||||
{log.jobId.slice(4, 8)}
|
||||
</GoToJob>
|
||||
),
|
||||
sortCriteria: log => log.jobId,
|
||||
},
|
||||
{
|
||||
@ -177,7 +214,7 @@ export default decorate([
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ state, jobs }) => (
|
||||
({ state, scrollIntoJobs, jobs }) => (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Icon icon='logs' /> {_('logTitle')}
|
||||
@ -188,6 +225,7 @@ export default decorate([
|
||||
columns={COLUMNS}
|
||||
component={SortedTable}
|
||||
data-jobs={state.jobs}
|
||||
data-scrollIntoJobs={scrollIntoJobs}
|
||||
emptyMessage={_('noLogs')}
|
||||
filters={LOG_FILTERS}
|
||||
stateUrlParam='s_logs'
|
||||
|
Loading…
Reference in New Issue
Block a user