parent
53f470518b
commit
0b9d031965
@ -256,6 +256,7 @@ const messages = {
|
|||||||
jobMergedDataSpeed: 'Merge speed:',
|
jobMergedDataSpeed: 'Merge speed:',
|
||||||
allJobCalls: 'All',
|
allJobCalls: 'All',
|
||||||
job: 'Job',
|
job: 'Job',
|
||||||
|
jobEdit: 'Edit job',
|
||||||
jobModalTitle: 'Job {job}',
|
jobModalTitle: 'Job {job}',
|
||||||
jobId: 'ID',
|
jobId: 'ID',
|
||||||
jobType: 'Type',
|
jobType: 'Type',
|
||||||
@ -290,11 +291,12 @@ const messages = {
|
|||||||
'You are editing Schedule {name} ({id}). Saving will override previous schedule state.',
|
'You are editing Schedule {name} ({id}). Saving will override previous schedule state.',
|
||||||
jobEditMessage:
|
jobEditMessage:
|
||||||
'You are editing job {name} ({id}). Saving will override previous job state.',
|
'You are editing job {name} ({id}). Saving will override previous job state.',
|
||||||
scheduleEdit: 'Edit',
|
scheduleEdit: 'Edit schedule',
|
||||||
scheduleSave: 'Save',
|
scheduleSave: 'Save',
|
||||||
cancelScheduleEdition: 'Cancel',
|
cancelScheduleEdition: 'Cancel',
|
||||||
scheduleAdd: 'Add a schedule',
|
scheduleAdd: 'Add a schedule',
|
||||||
scheduleDelete: 'Delete',
|
scheduleDelete: 'Delete',
|
||||||
|
scheduleRun: 'Run schedule',
|
||||||
deleteSelectedSchedules: 'Delete selected schedules',
|
deleteSelectedSchedules: 'Delete selected schedules',
|
||||||
noScheduledJobs: 'No scheduled jobs.',
|
noScheduledJobs: 'No scheduled jobs.',
|
||||||
newSchedule: 'New schedule',
|
newSchedule: 'New schedule',
|
||||||
@ -1160,7 +1162,6 @@ const messages = {
|
|||||||
scheduleTimezone: 'Timezone',
|
scheduleTimezone: 'Timezone',
|
||||||
scheduleExportRetention: 'Export ret.',
|
scheduleExportRetention: 'Export ret.',
|
||||||
scheduleSnapshotRetention: 'Snapshot ret.',
|
scheduleSnapshotRetention: 'Snapshot ret.',
|
||||||
scheduleRun: 'Run',
|
|
||||||
getRemote: 'Get remote',
|
getRemote: 'Get remote',
|
||||||
listRemote: 'List Remote',
|
listRemote: 'List Remote',
|
||||||
simpleBackup: 'simple',
|
simpleBackup: 'simple',
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import _ from 'intl'
|
import _ from 'intl'
|
||||||
import ActionRowButton from 'action-row-button'
|
|
||||||
import filter from 'lodash/filter'
|
|
||||||
import find from 'lodash/find'
|
|
||||||
import forEach from 'lodash/forEach'
|
|
||||||
import Icon from 'icon'
|
import Icon from 'icon'
|
||||||
import Link from 'link'
|
import Link from 'link'
|
||||||
import LogList from '../../logs'
|
import LogList from '../../logs'
|
||||||
import map from 'lodash/map'
|
|
||||||
import orderBy from 'lodash/orderBy'
|
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
|
import SortedTable from 'sorted-table'
|
||||||
import StateButton from 'state-button'
|
import StateButton from 'state-button'
|
||||||
import Tooltip from 'tooltip'
|
import Tooltip from 'tooltip'
|
||||||
import Upgrade from 'xoa-upgrade'
|
import Upgrade from 'xoa-upgrade'
|
||||||
@ -16,8 +11,10 @@ import { addSubscriptions } from 'utils'
|
|||||||
import { Container } from 'grid'
|
import { Container } from 'grid'
|
||||||
import { createSelector } from 'selectors'
|
import { createSelector } from 'selectors'
|
||||||
import { Card, CardHeader, CardBlock } from 'card'
|
import { Card, CardHeader, CardBlock } from 'card'
|
||||||
|
import { filter, find, forEach, orderBy } from 'lodash'
|
||||||
import {
|
import {
|
||||||
deleteSchedule,
|
deleteSchedule,
|
||||||
|
deleteSchedules,
|
||||||
disableSchedule,
|
disableSchedule,
|
||||||
enableSchedule,
|
enableSchedule,
|
||||||
runJob,
|
runJob,
|
||||||
@ -32,12 +29,88 @@ const jobKeyToLabel = {
|
|||||||
genericTask: _('customJob'),
|
genericTask: _('customJob'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SCHEDULES_COLUMNS = [
|
||||||
|
{
|
||||||
|
itemRenderer: schedule => (
|
||||||
|
<span>{`${schedule.name} (${schedule.id.slice(4, 8)})`}</span>
|
||||||
|
),
|
||||||
|
name: _('schedule'),
|
||||||
|
sortCriteria: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemRenderer: (schedule, { jobs, isScheduleUserMissing }) => {
|
||||||
|
const jobId = schedule.jobId
|
||||||
|
const job = jobs[jobId]
|
||||||
|
|
||||||
|
return (
|
||||||
|
job !== undefined && (
|
||||||
|
<div>
|
||||||
|
<span>{`${job.name} - ${job.method} (${jobId.slice(4, 8)})`}</span>{' '}
|
||||||
|
{isScheduleUserMissing[schedule.id] && (
|
||||||
|
<Tooltip content={_('jobUserNotFound')}>
|
||||||
|
<Icon className='mr-1' icon='error' />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
<Link
|
||||||
|
className='btn btn-sm btn-primary ml-1'
|
||||||
|
to={`/jobs/${job.id}/edit`}
|
||||||
|
>
|
||||||
|
<Tooltip content={_('jobEdit')}>
|
||||||
|
<Icon icon='edit' />
|
||||||
|
</Tooltip>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
name: _('job'),
|
||||||
|
sortCriteria: (schedule, { jobs }) => {
|
||||||
|
const job = jobs[schedule.jobId]
|
||||||
|
return job !== undefined && job.name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemRenderer: schedule => schedule.cron,
|
||||||
|
name: _('jobScheduling'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
itemRenderer: schedule => (
|
||||||
|
<StateButton
|
||||||
|
disabledLabel={_('jobStateDisabled')}
|
||||||
|
disabledHandler={enableSchedule}
|
||||||
|
disabledTooltip={_('logIndicationToEnable')}
|
||||||
|
enabledLabel={_('jobStateEnabled')}
|
||||||
|
enabledHandler={disableSchedule}
|
||||||
|
enabledTooltip={_('logIndicationToDisable')}
|
||||||
|
handlerParam={schedule.id}
|
||||||
|
state={schedule.enabled}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
name: _('jobState'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const ACTIONS = [
|
||||||
|
{
|
||||||
|
handler: deleteSchedules,
|
||||||
|
icon: 'delete',
|
||||||
|
individualHandler: deleteSchedule,
|
||||||
|
individualLabel: _('scheduleDelete'),
|
||||||
|
label: _('deleteSelectedSchedules'),
|
||||||
|
level: 'danger',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
@addSubscriptions({
|
@addSubscriptions({
|
||||||
users: subscribeUsers,
|
users: subscribeUsers,
|
||||||
})
|
})
|
||||||
export default class Overview extends Component {
|
export default class Overview extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
router: React.PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -82,31 +155,6 @@ export default class Overview extends Component {
|
|||||||
return jobs[schedule.jobId]
|
return jobs[schedule.jobId]
|
||||||
}
|
}
|
||||||
|
|
||||||
_getJobLabel (job = {}) {
|
|
||||||
return `${job.name} - ${job.method} (${job.id.slice(4, 8)})`
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScheduleLabel (schedule) {
|
|
||||||
return `${schedule.name} (${schedule.id.slice(4, 8)})`
|
|
||||||
}
|
|
||||||
|
|
||||||
_getScheduleToggle (schedule) {
|
|
||||||
const { id } = schedule
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StateButton
|
|
||||||
disabledLabel={_('jobStateDisabled')}
|
|
||||||
disabledHandler={enableSchedule}
|
|
||||||
disabledTooltip={_('logIndicationToEnable')}
|
|
||||||
enabledLabel={_('jobStateEnabled')}
|
|
||||||
enabledHandler={disableSchedule}
|
|
||||||
enabledTooltip={_('logIndicationToDisable')}
|
|
||||||
handlerParam={id}
|
|
||||||
state={schedule.enabled}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
_getIsScheduleUserMissing = createSelector(
|
_getIsScheduleUserMissing = createSelector(
|
||||||
() => this.state.schedules,
|
() => this.state.schedules,
|
||||||
() => this.props.users,
|
() => this.props.users,
|
||||||
@ -114,7 +162,7 @@ export default class Overview extends Component {
|
|||||||
const isScheduleUserMissing = {}
|
const isScheduleUserMissing = {}
|
||||||
|
|
||||||
forEach(schedules, schedule => {
|
forEach(schedules, schedule => {
|
||||||
isScheduleUserMissing[schedule.id] = !!find(
|
isScheduleUserMissing[schedule.id] = !find(
|
||||||
users,
|
users,
|
||||||
user => user.id === this._getScheduleJob(schedule).userId
|
user => user.id === this._getScheduleJob(schedule).userId
|
||||||
)
|
)
|
||||||
@ -124,11 +172,29 @@ export default class Overview extends Component {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_individualActions = [
|
||||||
|
{
|
||||||
|
disabled: (schedule, { isScheduleUserMissing }) =>
|
||||||
|
isScheduleUserMissing[schedule.id],
|
||||||
|
handler: schedule => runJob(schedule.jobId),
|
||||||
|
icon: 'run-schedule',
|
||||||
|
label: _('scheduleRun'),
|
||||||
|
level: 'warning',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
handler: schedule =>
|
||||||
|
this.context.router.push({
|
||||||
|
pathname: `/jobs/schedules/${schedule.id}/edit`,
|
||||||
|
}),
|
||||||
|
icon: 'edit',
|
||||||
|
label: _('scheduleEdit'),
|
||||||
|
level: 'primary',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { schedules } = this.state
|
const { schedules } = this.state
|
||||||
|
|
||||||
const isScheduleUserMissing = this._getIsScheduleUserMissing()
|
|
||||||
|
|
||||||
return process.env.XOA_PLAN > 3 ? (
|
return process.env.XOA_PLAN > 3 ? (
|
||||||
<Container>
|
<Container>
|
||||||
<Card>
|
<Card>
|
||||||
@ -136,73 +202,16 @@ export default class Overview extends Component {
|
|||||||
<Icon icon='schedule' /> {_('backupSchedules')}
|
<Icon icon='schedule' /> {_('backupSchedules')}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBlock>
|
<CardBlock>
|
||||||
{schedules.length ? (
|
<SortedTable
|
||||||
<table className='table'>
|
actions={ACTIONS}
|
||||||
<thead className='thead-default'>
|
collection={schedules}
|
||||||
<tr>
|
columns={SCHEDULES_COLUMNS}
|
||||||
<th>{_('schedule')}</th>
|
data-isScheduleUserMissing={this._getIsScheduleUserMissing()}
|
||||||
<th>{_('job')}</th>
|
data-jobs={this.state.jobs || {}}
|
||||||
<th className='hidden-xs-down'>{_('jobScheduling')}</th>
|
individualActions={this._individualActions}
|
||||||
<th>{_('jobState')}</th>
|
shortcutsTarget='body'
|
||||||
<th className='text-xs-right'>{_('jobAction')}</th>
|
stateUrlParam='s'
|
||||||
</tr>
|
/>
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{map(schedules, (schedule, key) => {
|
|
||||||
const job = this._getScheduleJob(schedule)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr key={key}>
|
|
||||||
<td>
|
|
||||||
{this._getScheduleLabel(schedule)}
|
|
||||||
<Link
|
|
||||||
className='btn btn-sm btn-primary ml-1'
|
|
||||||
to={`/jobs/schedules/${schedule.id}/edit`}
|
|
||||||
>
|
|
||||||
<Icon icon='edit' />
|
|
||||||
</Link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{this._getJobLabel(job)}
|
|
||||||
<Link
|
|
||||||
className='btn btn-sm btn-primary ml-1'
|
|
||||||
to={`/jobs/${job.id}/edit`}
|
|
||||||
>
|
|
||||||
<Icon icon='edit' />
|
|
||||||
</Link>
|
|
||||||
</td>
|
|
||||||
<td className='hidden-xs-down'>{schedule.cron}</td>
|
|
||||||
<td>{this._getScheduleToggle(schedule)}</td>
|
|
||||||
<td className='text-xs-right'>
|
|
||||||
<fieldset>
|
|
||||||
{!isScheduleUserMissing[schedule.id] && (
|
|
||||||
<Tooltip content={_('jobUserNotFound')}>
|
|
||||||
<Icon className='mr-1' icon='error' />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<ActionRowButton
|
|
||||||
icon='delete'
|
|
||||||
btnStyle='danger'
|
|
||||||
handler={deleteSchedule}
|
|
||||||
handlerParam={schedule}
|
|
||||||
/>
|
|
||||||
<ActionRowButton
|
|
||||||
disabled={!isScheduleUserMissing[schedule.id]}
|
|
||||||
icon='run-schedule'
|
|
||||||
btnStyle='warning'
|
|
||||||
handler={runJob}
|
|
||||||
handlerParam={schedule.jobId}
|
|
||||||
/>
|
|
||||||
</fieldset>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
) : (
|
|
||||||
<p>{_('noScheduledJobs')}</p>
|
|
||||||
)}
|
|
||||||
</CardBlock>
|
</CardBlock>
|
||||||
</Card>
|
</Card>
|
||||||
<LogList jobKeys={Object.keys(jobKeyToLabel)} />
|
<LogList jobKeys={Object.keys(jobKeyToLabel)} />
|
||||||
|
Loading…
Reference in New Issue
Block a user