fix(xo-web/backup-ng/new): schedule's name overridden with undefined if it's not been edited (#3288)

Fixes #3286
This commit is contained in:
badrAZ 2018-08-14 12:18:41 +02:00 committed by Pierre Donias
parent 11bd75d2fe
commit ba56114e9f
5 changed files with 128 additions and 109 deletions

View File

@ -9,6 +9,8 @@
### Bug fixes
- [Backup NG form] Fix schedule's name overridden with undefined if it's not been edited [#3286](https://github.com/vatesfr/xen-orchestra/issues/3286) (PR [#3288](https://github.com/vatesfr/xen-orchestra/pull/3288))
### Released packages
- xo-server v5.25.0

View File

@ -49,7 +49,7 @@ set.params = {
enabled: { type: 'boolean', optional: true },
id: { type: 'string' },
jobId: { type: 'string', optional: true },
name: { type: 'string', optional: true },
name: { type: ['string', 'null'], optional: true },
timezone: { type: 'string', optional: true },
}

View File

@ -132,7 +132,7 @@ const getInitialState = () => ({
snapshotMode: false,
srs: [],
tags: {},
tmpSchedule: {},
tmpSchedule: undefined,
vms: [],
})
@ -368,7 +368,7 @@ export default [
}),
cancelSchedule: () => state => ({
...state,
tmpSchedule: {},
tmpSchedule: undefined,
editionMode: undefined,
}),
editSchedule: (_, schedule) => state => ({
@ -398,7 +398,6 @@ export default [
settings = propSettings,
tmpSchedule,
}) => {
name = name !== undefined && name.trim() === '' ? undefined : name
if (editionMode === 'creation') {
const id = generateRandomId()
return {
@ -430,7 +429,7 @@ export default [
editionMode: undefined,
schedules,
settings: settings.set(id, setting),
tmpSchedule: {},
tmpSchedule: undefined,
}
},
setPowerState: (_, powerState) => state => ({

View File

@ -1,6 +1,5 @@
import _ from 'intl'
import ActionButton from 'action-button'
import defined from 'xo-defined'
import moment from 'moment-timezone'
import React from 'react'
import Scheduler, { SchedulePreview } from 'scheduling'
@ -32,11 +31,20 @@ export default [
exportRetention,
formId: generateRandomId(),
idInputName: generateRandomId(),
name: undefined,
schedule: undefined,
snapshotRetention,
timezone,
}),
effects: {
setSchedule: (_, { name, value }) => ({
tmpSchedule,
schedule = tmpSchedule,
}) => ({
schedule: {
...schedule,
[name]: value,
},
}),
setExportRetention: (_, value) => state => ({
...state,
exportRetention: value,
@ -49,14 +57,17 @@ export default [
...state,
snapshotRetention: value,
}),
setSchedule: (_, { cronPattern, timezone }) => state => ({
setCronTimezone: (_, { cronPattern, timezone }) => state => ({
...state,
cron: cronPattern,
timezone,
}),
setName: (_, { target: { value } }) => () => ({
name: value,
}),
setName: ({ setSchedule }, { target: { value } }) => () => {
setSchedule({
name: 'name',
value: value.trim() === '' ? null : value,
})
},
},
computed: {
isScheduleInvalid: ({ retentionNeeded, scheduleNotEdited }) =>
@ -80,27 +91,26 @@ export default [
cron,
editionMode,
exportRetention,
name,
schedule,
snapshotRetention,
timezone,
},
{ schedule }
{ schedule: propSchedule }
) =>
editionMode !== 'creation' &&
schedule === undefined &&
isEqual(
{
copyRetention: schedule.copyRetention,
cron: schedule.cron,
exportRetention: schedule.exportRetention,
name: schedule.name,
snapshotRetention: schedule.snapshotRetention,
timezone: schedule.timezone,
copyRetention: propSchedule.copyRetention,
cron: propSchedule.cron,
exportRetention: propSchedule.exportRetention,
snapshotRetention: propSchedule.snapshotRetention,
timezone: propSchedule.timezone,
},
{
copyRetention,
cron,
exportRetention,
name,
snapshotRetention,
timezone,
}
@ -108,93 +118,101 @@ export default [
},
}),
injectState,
({ effects, state }) => (
<form id={state.formId}>
<FormFeedback
component={Card}
error={state.retentionNeeded}
message={_('retentionNeeded')}
>
<CardBlock>
<FormGroup>
<label htmlFor={state.idInputName}>
<strong>{_('formName')}</strong>
</label>
<Input
id={state.idInputName}
onChange={effects.setName}
value={defined(state.name, state.tmpSchedule.name, '')}
({ effects, state }) => {
const { tmpSchedule = {}, schedule = tmpSchedule } = state
const { name } = schedule
return (
<form id={state.formId}>
<FormFeedback
component={Card}
error={state.retentionNeeded}
message={_('retentionNeeded')}
>
<CardBlock>
<FormGroup>
<label htmlFor={state.idInputName}>
<strong>{_('formName')}</strong>
</label>
<Input
id={state.idInputName}
onChange={effects.setName}
value={name}
/>
</FormGroup>
{state.exportMode && (
<FormGroup>
<label>
<strong>{_('exportRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setExportRetention}
value={state.exportRetention}
/>
</FormGroup>
)}
{state.copyMode && (
<FormGroup>
<label>
<strong>{_('copyRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setCopyRetention}
value={state.copyRetention}
/>
</FormGroup>
)}
{state.snapshotMode && (
<FormGroup>
<label>
<strong>{_('snapshotRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setSnapshotRetention}
value={state.snapshotRetention}
/>
</FormGroup>
)}
<Scheduler
onChange={effects.setCronTimezone}
cronPattern={state.cron}
timezone={state.timezone}
/>
</FormGroup>
{state.exportMode && (
<FormGroup>
<label>
<strong>{_('exportRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setExportRetention}
value={state.exportRetention}
/>
</FormGroup>
)}
{state.copyMode && (
<FormGroup>
<label>
<strong>{_('copyRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setCopyRetention}
value={state.copyRetention}
/>
</FormGroup>
)}
{state.snapshotMode && (
<FormGroup>
<label>
<strong>{_('snapshotRetention')}</strong>
</label>
<Number
min='0'
onChange={effects.setSnapshotRetention}
value={state.snapshotRetention}
/>
</FormGroup>
)}
<Scheduler
onChange={effects.setSchedule}
cronPattern={state.cron}
timezone={state.timezone}
/>
<SchedulePreview cronPattern={state.cron} timezone={state.timezone} />
<br />
<ActionButton
btnStyle='primary'
data-copyRetention={state.copyRetention}
data-cron={state.cron}
data-exportRetention={state.exportRetention}
data-name={state.name}
data-snapshotRetention={state.snapshotRetention}
data-timezone={state.timezone}
disabled={state.isScheduleInvalid}
form={state.formId}
handler={effects.saveSchedule}
icon='save'
size='large'
>
{_('formSave')}
</ActionButton>
<ActionButton
className='pull-right'
handler={effects.cancelSchedule}
icon='cancel'
size='large'
>
{_('formCancel')}
</ActionButton>
</CardBlock>
</FormFeedback>
</form>
),
<SchedulePreview
cronPattern={state.cron}
timezone={state.timezone}
/>
<br />
<ActionButton
btnStyle='primary'
data-copyRetention={state.copyRetention}
data-cron={state.cron}
data-exportRetention={state.exportRetention}
data-name={name}
data-snapshotRetention={state.snapshotRetention}
data-timezone={state.timezone}
disabled={state.isScheduleInvalid}
form={state.formId}
handler={effects.saveSchedule}
icon='save'
size='large'
>
{_('formSave')}
</ActionButton>
<ActionButton
className='pull-right'
handler={effects.cancelSchedule}
icon='cancel'
size='large'
>
{_('formCancel')}
</ActionButton>
</CardBlock>
</FormFeedback>
</form>
)
},
].reduceRight((value, decorator) => decorator(value))

View File

@ -152,7 +152,7 @@ export default [
<NewSchedule
copyMode={state.copyMode}
exportMode={state.exportMode}
schedule={state.tmpSchedule}
schedule={state.tmpSchedule || {}}
snapshotMode={state.snapshotMode}
/>
)}