fix(xo-web/backup/edit): tags overwritten by default ones (#5136)
Introduced by 1c042778b6
See xoa-support#2663
It was due to a race condition between the fetch of the default excluded tags
and the fetch of the job (and its schedules) which made the component populate
the form with the job's information.
Changes:
- `Edit` waits for the `job` and the `schedules` before rendering its child
- `New`'s wrapper waits for the `remotes` and the `suggestedExcludedTags` before
rendering `New`
- `New`: `updateParams` is now called in `initialize` because we don't need to
wait for the job and the schedules any more to be able to populate the form
This commit is contained in:
parent
3720a46ff3
commit
cda39ec256
@ -12,6 +12,7 @@
|
||||
> Users must be able to say: “I had this issue, happy to know it's fixed”
|
||||
|
||||
- [Proxy] Don't use configured HTTP proxy to connect to XO proxy
|
||||
- [Smart backup/edit] Fix "Excluded VMs tags" being reset to the default ones (PR [#5136](https://github.com/vatesfr/xen-orchestra/pull/5136))
|
||||
|
||||
### Packages to release
|
||||
|
||||
@ -31,3 +32,4 @@
|
||||
> In case of conflict, the highest (lowest in previous list) `$version` wins.
|
||||
|
||||
- xo-server patch
|
||||
- xo-web patch
|
||||
|
@ -539,6 +539,7 @@ const messages = {
|
||||
deleteOldBackupsFirstMessage:
|
||||
'Delete old backups before backing up the VMs. If the new backup fails, you will lose your old backups.',
|
||||
customTag: 'Custom tag',
|
||||
editJobNotFound: "The job you're trying to edit wasn't found",
|
||||
|
||||
// ------ New Remote -----
|
||||
newRemote: 'New file system remote',
|
||||
|
@ -1,6 +1,8 @@
|
||||
import _ from 'intl'
|
||||
import addSubscriptions from 'add-subscriptions'
|
||||
import decorate from 'apply-decorators'
|
||||
import defined from '@xen-orchestra/defined'
|
||||
import Icon from 'icon'
|
||||
import React from 'react'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { find, groupBy, keyBy } from 'lodash'
|
||||
@ -28,11 +30,21 @@ export default decorate([
|
||||
defined(find(jobs, { id }), find(metadataJobs, { id })),
|
||||
schedules: (_, { schedulesByJob, routeParams: { id } }) =>
|
||||
schedulesByJob && keyBy(schedulesByJob[id], 'id'),
|
||||
loading: (_, props) =>
|
||||
props.jobs === undefined ||
|
||||
props.metadataJobs === undefined ||
|
||||
props.schedulesByJob === undefined,
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ state: { job = {}, schedules } }) =>
|
||||
job.type === 'backup' ? (
|
||||
({ state: { job, loading, schedules } }) =>
|
||||
loading ? (
|
||||
_('statusLoading')
|
||||
) : job === undefined ? (
|
||||
<span className='text-danger'>
|
||||
<Icon icon='error' /> {_('editJobNotFound')}
|
||||
</span>
|
||||
) : job.type === 'backup' ? (
|
||||
<New job={job} schedules={schedules} />
|
||||
) : (
|
||||
<Metadata job={job} schedules={schedules} />
|
||||
|
@ -216,7 +216,11 @@ const createDoesRetentionExist = name => {
|
||||
return ({ propSettings, settings = propSettings }) => settings.some(predicate)
|
||||
}
|
||||
|
||||
const getInitialState = ({ preSelectedVmIds, setHomeVmIdsSelection }) => {
|
||||
const getInitialState = ({
|
||||
preSelectedVmIds,
|
||||
setHomeVmIdsSelection,
|
||||
suggestedExcludedTags,
|
||||
}) => {
|
||||
setHomeVmIdsSelection([]) // Clear preselected vmIds
|
||||
return {
|
||||
_displayAdvancedSettings: undefined,
|
||||
@ -228,7 +232,6 @@ const getInitialState = ({ preSelectedVmIds, setHomeVmIdsSelection }) => {
|
||||
deltaMode: false,
|
||||
drMode: false,
|
||||
name: '',
|
||||
paramsUpdated: false,
|
||||
remotes: [],
|
||||
schedules: {},
|
||||
settings: undefined,
|
||||
@ -236,7 +239,7 @@ const getInitialState = ({ preSelectedVmIds, setHomeVmIdsSelection }) => {
|
||||
smartMode: false,
|
||||
snapshotMode: false,
|
||||
srs: [],
|
||||
tags: {},
|
||||
tags: { notValues: suggestedExcludedTags },
|
||||
vms: preSelectedVmIds,
|
||||
}
|
||||
}
|
||||
@ -281,15 +284,12 @@ const DeleteOldBackupsFirst = ({ handler, handlerParam, value }) => (
|
||||
</ActionButton>
|
||||
)
|
||||
|
||||
export default decorate([
|
||||
const New = decorate([
|
||||
New => props => (
|
||||
<Upgrade place='newBackup' required={2}>
|
||||
<New {...props} />
|
||||
</Upgrade>
|
||||
),
|
||||
addSubscriptions({
|
||||
remotes: subscribeRemotes,
|
||||
}),
|
||||
connectStore(() => ({
|
||||
hostsById: createGetObjectsOfType('host'),
|
||||
poolsById: createGetObjectsOfType('pool'),
|
||||
@ -300,8 +300,10 @@ export default decorate([
|
||||
provideState({
|
||||
initialState: getInitialState,
|
||||
effects: {
|
||||
initialize: async function () {
|
||||
this.state.tags = { notValues: await getSuggestedExcludedTags() }
|
||||
initialize: function ({ updateParams }) {
|
||||
if (this.state.edition) {
|
||||
updateParams()
|
||||
}
|
||||
},
|
||||
createJob: () => async state => {
|
||||
if (state.isJobInvalid) {
|
||||
@ -506,7 +508,6 @@ export default decorate([
|
||||
|
||||
return {
|
||||
name: job.name,
|
||||
paramsUpdated: true,
|
||||
smartMode: job.vms.id === undefined,
|
||||
snapshotMode: some(
|
||||
job.settings,
|
||||
@ -710,8 +711,7 @@ export default decorate([
|
||||
type: 'VM',
|
||||
}
|
||||
),
|
||||
needUpdateParams: (state, { job, schedules }) =>
|
||||
job !== undefined && schedules !== undefined && !state.paramsUpdated,
|
||||
edition: (_, { job }) => job !== undefined,
|
||||
isJobInvalid: state =>
|
||||
state.missingName ||
|
||||
state.missingVms ||
|
||||
@ -820,10 +820,6 @@ export default decorate([
|
||||
timeout,
|
||||
} = settings.get('') || {}
|
||||
|
||||
if (state.needUpdateParams) {
|
||||
effects.updateParams()
|
||||
}
|
||||
|
||||
return (
|
||||
<form id={state.formId}>
|
||||
<Container>
|
||||
@ -1227,7 +1223,7 @@ export default decorate([
|
||||
<Row>
|
||||
<Card>
|
||||
<CardBlock>
|
||||
{state.paramsUpdated ? (
|
||||
{state.edition ? (
|
||||
<ActionButton
|
||||
btnStyle='primary'
|
||||
form={state.formId}
|
||||
@ -1270,3 +1266,24 @@ export default decorate([
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
export default decorate([
|
||||
addSubscriptions({
|
||||
remotes: subscribeRemotes,
|
||||
}),
|
||||
provideState({
|
||||
computed: {
|
||||
loading: (state, props) =>
|
||||
state.suggestedExcludedTags === undefined ||
|
||||
props.remotes === undefined,
|
||||
suggestedExcludedTags: () => getSuggestedExcludedTags(),
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ state: { loading, suggestedExcludedTags }, ...props }) =>
|
||||
loading ? (
|
||||
_('statusLoading')
|
||||
) : (
|
||||
<New suggestedExcludedTags={suggestedExcludedTags} {...props} />
|
||||
),
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user