fix(xo-web/settings/acls): freactal to fix lifecycle issues (#3548)

This commit is contained in:
Pierre Donias 2018-10-18 13:47:48 +02:00 committed by Julien Fontanet
parent f6fcae4489
commit 2ae660a46b

View File

@ -7,7 +7,6 @@ import forEach from 'lodash/forEach'
import isEmpty from 'lodash/isEmpty'
import keyBy from 'lodash/keyBy'
import map from 'lodash/map'
import pickBy from 'lodash/pickBy'
import React from 'react'
import renderXoItem, { renderXoItemFromId } from 'render-xo-item'
import some from 'lodash/some'
@ -15,9 +14,10 @@ import SortedTable from 'sorted-table'
import toArray from 'lodash/toArray'
import Upgrade from 'xoa-upgrade'
import store from 'store'
import { connectStore } from 'utils'
import { addSubscriptions, connectStore } from 'utils'
import { Container } from 'grid'
import { error } from 'notification'
import { injectState, provideState } from '@julien-f/freactal'
import {
SelectHighLevelObject,
SelectRole,
@ -80,92 +80,57 @@ const ACL_ACTIONS = [
},
]
@connectStore(() => {
const getHighLevelObjects = createSelector(
createGetObjectsOfType('host'),
createGetObjectsOfType('network'),
createGetObjectsOfType('pool'),
createGetObjectsOfType('SR'),
createGetObjectsOfType('VM'),
createGetObjectsOfType('VM-snapshot'),
(hosts, networks, pools, srs, vms, snapshots) => ({
...keyBy(hosts, 'id'),
...keyBy(networks, 'id'),
...keyBy(pools, 'id'),
...keyBy(snapshots, 'id'),
...keyBy(srs, 'id'),
...keyBy(vms, 'id'),
})
)
return { xoObjects: getHighLevelObjects }
})
class AclTable extends Component {
componentWillMount () {
let subjects = {}
const refresh = (newSubjects = undefined) => {
newSubjects && (subjects = newSubjects)
const { xoObjects } = this.props
const { acls, roles } = this.state
const resolvedAcls = filter(
map(acls, ({ id, subject, object, action }) => ({
id,
subject: subjects[subject] || subject,
object: xoObjects[object] || object,
action: roles[action] || action,
})),
({ subject, object, action }) =>
subject && object && action && object.type !== 'VM-snapshot'
)
this.setState({
resolvedAcls,
})
}
const unsubscribeAcls = subscribeAcls(acls =>
this.setState({ acls }, refresh)
)
const unsubscribeRoles = subscribeRoles(roles =>
this.setState({ roles: keyBy(roles, 'id') }, refresh)
)
const unsubscribeGroups = subscribeGroups(groups => {
groups = keyBy(groups, 'id')
refresh({
...pickBy(subjects, subject => subject.type === 'user'),
...groups,
})
})
const unsubscribeUsers = subscribeUsers(users => {
users = keyBy(users, 'id')
refresh({
...pickBy(subjects, subject => subject.type === 'group'),
...users,
})
})
this.componentWillUnmount = () => {
unsubscribeAcls()
unsubscribeGroups()
unsubscribeRoles()
unsubscribeUsers()
}
}
render () {
const { resolvedAcls = [] } = this.state
return isEmpty(resolvedAcls) ? (
<p>
<em>{_('aclNoneFound')}</em>
</p>
) : (
<SortedTable
actions={ACL_ACTIONS}
collection={resolvedAcls}
columns={ACL_COLUMNS}
/>
)
}
}
const AclTable = [
connectStore({
hosts: createGetObjectsOfType('host'),
networks: createGetObjectsOfType('network'),
pools: createGetObjectsOfType('pool'),
srs: createGetObjectsOfType('SR'),
vms: createGetObjectsOfType('VM'),
}),
addSubscriptions({
acls: subscribeAcls,
roles: subscribeRoles,
groups: subscribeGroups,
users: subscribeUsers,
}),
provideState({
computed: {
acls: (
{ groups, roles, users },
{ acls, hosts, networks, pools, srs, vms }
) =>
filter(
map(acls, ({ id, subject, object, action }) => ({
id,
subject: users[subject] || groups[subject],
object:
hosts[object] ||
networks[object] ||
pools[object] ||
srs[object] ||
vms[object],
action: roles[action],
})),
({ subject, object, action }) =>
subject !== undefined &&
object !== undefined &&
action !== undefined
),
groups: (_, { groups }) => keyBy(groups, 'id'),
roles: (_, { roles }) => keyBy(roles, 'id'),
users: (_, { users }) => keyBy(users, 'id'),
},
}),
injectState,
({ state }) => (
<SortedTable
actions={ACL_ACTIONS}
collection={state.acls}
columns={ACL_COLUMNS}
/>
),
].reduceRight((value, decorator) => decorator(value))
export default class Acls extends Component {
constructor (props) {