feat(xo-web): confirm modal before manual backup run (#2717)

Fixes #2355
This commit is contained in:
Rajaa.BARHTAOUI
2018-03-29 15:06:50 +02:00
committed by Pierre Donias
parent 0a5e1a9bce
commit b47789bf82
3 changed files with 77 additions and 48 deletions

View File

@@ -276,6 +276,7 @@ const messages = {
jobTimezone: 'Timezone',
jobServerTimezone: 'Server',
runJob: 'Run job',
runJobConfirm: 'Are you sure you want to run {backupType} {id} ({tag})?',
runJobVerbose: 'One shot running started. See overview for logs.',
jobFinished: 'Finished',
jobInterrupted: 'Interrupted',
@@ -318,6 +319,7 @@ const messages = {
migrateBackupSchedule: 'Migrate to backup NG',
migrateBackupScheduleMessage:
'This will migrate this backup to a backup NG. This operation is not reversible. Do you want to continue?',
runBackupNgJobConfirm: 'Are you sure you want to run {name} ({id})?',
// ------ New backup -----
newBackupSelection: 'Select your backup type:',

View File

@@ -5,6 +5,7 @@ import Icon from 'icon'
import React from 'react'
import SortedTable from 'sorted-table'
import StateButton from 'state-button'
import { confirm } from 'modal'
import { map, groupBy } from 'lodash'
import { Card, CardHeader, CardBlock } from 'card'
import { constructQueryString } from 'smart-backup'
@@ -28,6 +29,15 @@ import New from './new'
import FileRestore from './file-restore'
import Restore from './restore'
const _runBackupNgJob = ({ id, name, schedule }) =>
confirm({
title: _('runJob'),
body: _('runBackupNgJobConfirm', {
id: id.slice(0, 5),
name: <strong>{name}</strong>,
}),
}).then(() => runBackupNgJob({ id, schedule }))
const SchedulePreviewBody = ({ item: job, userData: { schedulesByJob } }) => (
<table>
<tr className='text-muted'>
@@ -57,12 +67,13 @@ const SchedulePreviewBody = ({ item: job, userData: { schedulesByJob } }) => (
</td>
<td>
<ActionButton
handler={runBackupNgJob}
btnStyle='primary'
data-id={job.id}
data-name={job.name}
data-schedule={schedule.id}
handler={_runBackupNgJob}
icon='run-schedule'
size='small'
data-id={job.id}
data-schedule={schedule.id}
btnStyle='primary'
/>
</td>
</tr>

View File

@@ -10,6 +10,7 @@ import React from 'react'
import SortedTable from 'sorted-table'
import StateButton from 'state-button'
import Tooltip from 'tooltip'
import { confirm } from 'modal'
import { addSubscriptions } from 'utils'
import { constructQueryString } from 'smart-backup'
import { createSelector } from 'selectors'
@@ -36,6 +37,16 @@ const jobKeyToLabel = {
rollingSnapshot: _('rollingSnapshot'),
}
const _runJob = ({ jobLabel, jobId, scheduleTag }) =>
confirm({
title: _('runJob'),
body: _('runJobConfirm', {
backupType: <strong>{jobLabel}</strong>,
id: <strong>{jobId.slice(4, 8)}</strong>,
tag: scheduleTag,
}),
}).then(() => runJob(jobId))
const JOB_COLUMNS = [
{
name: _('jobId'),
@@ -81,50 +92,55 @@ const JOB_COLUMNS = [
},
{
name: _('jobAction'),
itemRenderer: ({ redirect, schedule }, isScheduleUserMissing) => (
<fieldset>
{!isScheduleUserMissing[schedule.id] && (
<Tooltip content={_('backupUserNotFound')}>
<Icon className='mr-1' icon='error' />
</Tooltip>
)}
<Link
className='btn btn-sm btn-primary mr-1'
to={`/backup/${schedule.id}/edit`}
>
<Icon icon='edit' />
</Link>
<ButtonGroup>
{redirect && (
<ActionRowButton
btnStyle='primary'
handler={redirect}
icon='preview'
tooltip={_('redirectToMatchingVms')}
/>
itemRenderer: (item, isScheduleUserMissing) => {
const { redirect, schedule } = item
const { id } = schedule
return (
<fieldset>
{isScheduleUserMissing[id] && (
<Tooltip content={_('backupUserNotFound')}>
<Icon className='mr-1' icon='error' />
</Tooltip>
)}
<ActionRowButton
icon='delete'
btnStyle='danger'
handler={deleteBackupSchedule}
handlerParam={schedule}
/>
<ActionRowButton
disabled={!isScheduleUserMissing[schedule.id]}
icon='run-schedule'
btnStyle='warning'
handler={runJob}
handlerParam={schedule.jobId}
/>
<ActionRowButton
icon='migrate-job'
btnStyle='danger'
handler={migrateBackupSchedule}
handlerParam={schedule.jobId}
/>
</ButtonGroup>
</fieldset>
),
<Link
className='btn btn-sm btn-primary mr-1'
to={`/backup/${id}/edit`}
>
<Icon icon='edit' />
</Link>
<ButtonGroup>
{redirect && (
<ActionRowButton
btnStyle='primary'
handler={redirect}
icon='preview'
tooltip={_('redirectToMatchingVms')}
/>
)}
<ActionRowButton
btnStyle='warning'
disabled={isScheduleUserMissing[id]}
handler={_runJob}
handlerParam={item}
icon='run-schedule'
/>
<ActionRowButton
icon='migrate-job'
btnStyle='danger'
handler={migrateBackupSchedule}
handlerParam={schedule.jobId}
/>
<ActionRowButton
btnStyle='danger'
handler={deleteBackupSchedule}
handlerParam={schedule}
icon='delete'
/>
</ButtonGroup>
</fieldset>
)
},
textAlign: 'right',
},
]
@@ -200,7 +216,7 @@ export default class Overview extends Component {
(schedules, jobs, users) => {
const isScheduleUserMissing = {}
forEach(schedules, schedule => {
isScheduleUserMissing[schedule.id] = !!(
isScheduleUserMissing[schedule.id] = !(
jobs && find(users, user => user.id === jobs[schedule.jobId].userId)
)
})