feat(xo-web): confirm modal before manual backup run (#2717)
Fixes #2355
This commit is contained in:
committed by
Pierre Donias
parent
0a5e1a9bce
commit
b47789bf82
@@ -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:',
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user