feat(xo-web/backup-ng/overview): list the backup job's modes (#3277)

Fixes #3169
This commit is contained in:
badrAZ 2018-08-07 17:22:12 +02:00 committed by Pierre Donias
parent eea52b5166
commit a7dd83772e
8 changed files with 69 additions and 17 deletions

View File

@ -10,6 +10,7 @@
- [Health / Orphaned VMs] Homogenize action buttons in table and enable bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3274](https://github.com/vatesfr/xen-orchestra/pull/3274))
- [Health / Orphaned snapshot VDIs] Homogenize action buttons in table and enable bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3270](https://github.com/vatesfr/xen-orchestra/pull/3270))
- [Health / Alarms] Homogenize action buttons in table and enable bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3271](https://github.com/vatesfr/xen-orchestra/pull/3271))
- [Backup NG Overview] List the Backup NG job's modes [#3169](https://github.com/vatesfr/xen-orchestra/issues/3169) (PR [#3277](https://github.com/vatesfr/xen-orchestra/pull/3277))
### Bug fixes

View File

@ -286,7 +286,7 @@ const messages = {
jobId: 'ID',
jobType: 'Type',
jobName: 'Name',
jobMode: 'Mode',
jobModes: 'Modes',
jobNamePlaceholder: 'Name of your job (forbidden: "_")',
jobStart: 'Start',
jobEnd: 'End',

View File

@ -5,11 +5,12 @@ 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 { confirm } from 'modal'
import { constructQueryString } from 'smart-backup'
import { Container, Row, Col } from 'grid'
import { get } from 'xo-defined'
import { isEmpty, map, groupBy, some } from 'lodash'
import { NavLink, NavTabs } from 'nav'
import { routes } from 'utils'
import {
@ -30,6 +31,17 @@ import New from './new'
import FileRestore from './file-restore'
import Restore from './restore'
import Health from './health'
import { destructPattern } from './utils'
const Ul = props => <ul {...props} style={{ listStyleType: 'none' }} />
const Li = props => (
<li
{...props}
style={{
whiteSpace: 'nowrap',
}}
/>
)
const _runBackupNgJob = ({ id, name, schedule }) =>
confirm({
@ -98,6 +110,34 @@ const SchedulePreviewBody = ({ item: job, userData: { schedulesByJob } }) => (
</table>
)
const MODES = [
{
label: 'rollingSnapshot',
test: job =>
some(job.settings, ({ snapshotRetention }) => snapshotRetention > 0),
},
{
label: 'backup',
test: job =>
job.mode === 'full' && !isEmpty(get(() => destructPattern(job.remotes))),
},
{
label: 'deltaBackup',
test: job =>
job.mode === 'delta' && !isEmpty(get(() => destructPattern(job.remotes))),
},
{
label: 'continuousReplication',
test: job =>
job.mode === 'delta' && !isEmpty(get(() => destructPattern(job.srs))),
},
{
label: 'disasterRecovery',
test: job =>
job.mode === 'full' && !isEmpty(get(() => destructPattern(job.srs))),
},
]
@addSubscriptions({
jobs: subscribeBackupNgJobs,
schedulesByJob: cb =>
@ -131,11 +171,15 @@ class JobsTable extends React.Component {
default: true,
},
{
itemRenderer: _ => (
<span style={{ textTransform: 'capitalize' }}>{_.mode}</span>
itemRenderer: job => (
<Ul>
{MODES.filter(({ test }) => test(job)).map(({ label }) => (
<Li key={label}>{_(label)}</Li>
))}
</Ul>
),
sortCriteria: 'mode',
name: _('jobMode'),
name: _('jobModes'),
},
{
component: SchedulePreviewBody,
@ -146,19 +190,19 @@ class JobsTable extends React.Component {
const { concurrency, offlineSnapshot } = job.settings[''] || {}
return (
<ul style={{ listStyleType: 'none' }}>
<Ul>
{concurrency > 0 && (
<li>{_.keyValue(_('concurrency'), concurrency)}</li>
<Li>{_.keyValue(_('concurrency'), concurrency)}</Li>
)}
{offlineSnapshot && (
<li>
<Li>
{_.keyValue(
_('offlineSnapshot'),
<span className='text-success'>{_('stateEnabled')}</span>
)}
</li>
</Li>
)}
</ul>
</Ul>
)
},
name: _('formNotes'),

View File

@ -43,7 +43,14 @@ import {
import Schedules from './schedules'
import SmartBackup from './smart-backup'
import { FormFeedback, FormGroup, Input, Ul, Li } from './utils'
import {
destructPattern,
FormFeedback,
FormGroup,
Input,
Li,
Ul,
} from './../utils'
// ===================================================================
@ -90,8 +97,6 @@ const constructPattern = values =>
},
}
const destructPattern = pattern => pattern.id.__or || [pattern.id]
const destructVmsPattern = pattern =>
pattern.id === undefined
? {

View File

@ -10,7 +10,7 @@ import { injectState, provideState } from '@julien-f/freactal'
import { isEqual } from 'lodash'
import { Number } from 'form'
import { FormFeedback, FormGroup, Input } from './utils'
import { FormFeedback, FormGroup, Input } from './../utils'
export default [
injectState,

View File

@ -8,7 +8,7 @@ import { injectState, provideState } from '@julien-f/freactal'
import { isEmpty, find, size } from 'lodash'
import NewSchedule from './new-schedule'
import { FormFeedback } from './utils'
import { FormFeedback } from './../utils'
// ===================================================================

View File

@ -8,7 +8,7 @@ import { injectState, provideState } from '@julien-f/freactal'
import { Select } from 'form'
import { SelectPool, SelectTag } from 'select-objects'
import { FormGroup } from './utils'
import { FormGroup } from './../utils'
const VMS_STATUSES_OPTIONS = [
{ value: 'All', label: _('vmStateAll') },

View File

@ -7,6 +7,8 @@ export const Input = props => <input {...props} className='form-control' />
export const Ul = props => <ul {...props} className='list-group' />
export const Li = props => <li {...props} className='list-group-item' />
export const destructPattern = pattern => pattern.id.__or || [pattern.id]
export const FormFeedback = ({
component: Component,
error,