chore(package): update react-virtualized (#2556)
`form/select` has been redeveloped for the occasion with the following features: - not clearable when required and not multiple - when no options available, marked as loading - when required and only one option, it is automatically selected
This commit is contained in:
parent
23e992de85
commit
dc12896b19
@ -132,7 +132,7 @@
|
|||||||
"react-shortcuts": "^2.0.0",
|
"react-shortcuts": "^2.0.0",
|
||||||
"react-sparklines": "1.6.0",
|
"react-sparklines": "1.6.0",
|
||||||
"react-test-renderer": "^15.6.2",
|
"react-test-renderer": "^15.6.2",
|
||||||
"react-virtualized": "^8.0.8",
|
"react-virtualized": "^9.15.0",
|
||||||
"readable-stream": "^2.3.3",
|
"readable-stream": "^2.3.3",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
"redux-thunk": "^2.0.1",
|
"redux-thunk": "^2.0.1",
|
||||||
|
@ -10,7 +10,7 @@ import getEventValue from './get-event-value'
|
|||||||
const VERBOSE = false
|
const VERBOSE = false
|
||||||
|
|
||||||
const get = (object, path, depth) => {
|
const get = (object, path, depth) => {
|
||||||
if (depth >= path.length) {
|
if (object == null || depth >= path.length) {
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import propTypes from '../prop-types-decorator'
|
|||||||
import { formatSizeRaw, parseSize } from '../utils'
|
import { formatSizeRaw, parseSize } from '../utils'
|
||||||
|
|
||||||
export Select from './select'
|
export Select from './select'
|
||||||
export SelectPlainObject from './select-plain-object'
|
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
import uncontrollableInput from 'uncontrollable-input'
|
|
||||||
import Component from 'base-component'
|
|
||||||
import find from 'lodash/find'
|
|
||||||
import map from 'lodash/map'
|
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
import propTypes from '../prop-types-decorator'
|
|
||||||
|
|
||||||
import Select from './select'
|
|
||||||
|
|
||||||
@propTypes({
|
|
||||||
autoFocus: propTypes.bool,
|
|
||||||
disabled: propTypes.bool,
|
|
||||||
optionRenderer: propTypes.func,
|
|
||||||
multi: propTypes.bool,
|
|
||||||
onChange: propTypes.func,
|
|
||||||
options: propTypes.array,
|
|
||||||
placeholder: propTypes.node,
|
|
||||||
predicate: propTypes.func,
|
|
||||||
required: propTypes.bool,
|
|
||||||
value: propTypes.any,
|
|
||||||
})
|
|
||||||
@uncontrollableInput()
|
|
||||||
export default class SelectPlainObject extends Component {
|
|
||||||
componentDidMount () {
|
|
||||||
const { options, value } = this.props
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
options: this._computeOptions(options),
|
|
||||||
value: this._computeValue(value, this.props),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps (newProps) {
|
|
||||||
if (newProps !== this.props) {
|
|
||||||
this.setState({
|
|
||||||
options: this._computeOptions(newProps.options),
|
|
||||||
value: this._computeValue(newProps.value, newProps),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeValue (value, props = this.props) {
|
|
||||||
let { optionKey } = props
|
|
||||||
optionKey || (optionKey = 'id')
|
|
||||||
const reduceValue = value =>
|
|
||||||
value != null ? value[optionKey] || value : ''
|
|
||||||
if (props.multi) {
|
|
||||||
if (!Array.isArray(value)) {
|
|
||||||
value = [value]
|
|
||||||
}
|
|
||||||
return map(value, reduceValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return reduceValue(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
_computeOptions (options) {
|
|
||||||
const { optionKey = 'id' } = this.props
|
|
||||||
const { optionRenderer = o => o.label || o[optionKey] || o } = this.props
|
|
||||||
return map(options, option => ({
|
|
||||||
value: option[optionKey] || option,
|
|
||||||
label: optionRenderer(option),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
_getObject (value) {
|
|
||||||
if (value == null) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const { optionKey = 'id', options } = this.props
|
|
||||||
|
|
||||||
const pickValue = value => {
|
|
||||||
value = value.value || value
|
|
||||||
return find(
|
|
||||||
options,
|
|
||||||
option => option[optionKey] === value || option === value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.multi) {
|
|
||||||
return map(value, pickValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pickValue(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleChange = value => {
|
|
||||||
const { onChange } = this.props
|
|
||||||
|
|
||||||
if (onChange) {
|
|
||||||
onChange(this._getObject(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderOption = option => option.label
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { props, state } = this
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
autoFocus={props.autoFocus}
|
|
||||||
disabled={props.disabled}
|
|
||||||
multi={props.multi}
|
|
||||||
onChange={this._handleChange}
|
|
||||||
openOnFocus
|
|
||||||
optionRenderer={this._renderOption}
|
|
||||||
options={state.options}
|
|
||||||
placeholder={props.placeholder}
|
|
||||||
required={props.required}
|
|
||||||
value={state.value}
|
|
||||||
valueRenderer={this._renderOption}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,138 +1,160 @@
|
|||||||
import map from 'lodash/map'
|
import classNames from 'classnames'
|
||||||
import React, { Component } from 'react'
|
import isEmpty from 'lodash/isEmpty'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import React from 'react'
|
||||||
import ReactSelect from 'react-select'
|
import ReactSelect from 'react-select'
|
||||||
import sum from 'lodash/sum'
|
import uncontrollableInput from 'uncontrollable-input'
|
||||||
import { AutoSizer, CellMeasurer, List } from 'react-virtualized'
|
import {
|
||||||
|
AutoSizer,
|
||||||
import propTypes from '../prop-types-decorator'
|
CellMeasurer,
|
||||||
|
CellMeasurerCache,
|
||||||
const SELECT_MENU_STYLE = {
|
List,
|
||||||
overflow: 'hidden',
|
} from 'react-virtualized'
|
||||||
}
|
|
||||||
|
|
||||||
const SELECT_STYLE = {
|
const SELECT_STYLE = {
|
||||||
minWidth: '10em',
|
minWidth: '10em',
|
||||||
}
|
}
|
||||||
|
const MENU_STYLE = {
|
||||||
const LIST_STYLE = {
|
overflow: 'hidden',
|
||||||
whiteSpace: 'normal',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_OPTIONS = 5
|
@uncontrollableInput()
|
||||||
|
export default class Select extends React.PureComponent {
|
||||||
// See: https://github.com/bvaughn/react-virtualized-select/blob/master/source/VirtualizedSelect/VirtualizedSelect.js
|
|
||||||
@propTypes({
|
|
||||||
maxHeight: propTypes.number,
|
|
||||||
})
|
|
||||||
export default class Select extends Component {
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
maxHeight: 200,
|
maxHeight: 200,
|
||||||
optionRenderer: (option, labelKey) => option[labelKey],
|
|
||||||
|
multi: ReactSelect.defaultProps.multi,
|
||||||
|
options: [],
|
||||||
|
required: ReactSelect.defaultProps.required,
|
||||||
|
valueKey: ReactSelect.defaultProps.valueKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderMenu = ({ focusedOption, options, ...otherOptions }) => {
|
static propTypes = {
|
||||||
const { maxHeight } = this.props
|
autoSelectSingleOption: PropTypes.bool, // default to props.required
|
||||||
|
maxHeight: PropTypes.number,
|
||||||
|
options: PropTypes.array.isRequired, // cannot be an object
|
||||||
|
}
|
||||||
|
|
||||||
const focusedOptionIndex = options.indexOf(focusedOption)
|
_cellMeasurerCache = new CellMeasurerCache({
|
||||||
let height = options.length > MAX_OPTIONS && maxHeight
|
fixedWidth: true,
|
||||||
|
|
||||||
const wrappedRowRenderer = ({ index, key, style }) =>
|
|
||||||
this._optionRenderer({
|
|
||||||
...otherOptions,
|
|
||||||
focusedOption,
|
|
||||||
focusedOptionIndex,
|
|
||||||
key,
|
|
||||||
option: options[index],
|
|
||||||
options,
|
|
||||||
style,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// https://github.com/JedWatson/react-select/blob/dd32c27d7ea338a93159da5e40bc06697d0d86f9/src/utils/defaultMenuRenderer.js#L4
|
||||||
|
_renderMenu (opts) {
|
||||||
|
const { focusOption, options, selectValue } = opts
|
||||||
|
|
||||||
|
const focusFromEvent = event =>
|
||||||
|
focusOption(options[event.currentTarget.dataset.index])
|
||||||
|
const selectFromEvent = event =>
|
||||||
|
selectValue(options[event.currentTarget.dataset.index])
|
||||||
|
const renderRow = opts2 =>
|
||||||
|
this._renderRow(opts, opts2, focusFromEvent, selectFromEvent)
|
||||||
|
|
||||||
|
let focusedOptionIndex = options.indexOf(opts.focusedOption)
|
||||||
|
if (focusedOptionIndex === -1) {
|
||||||
|
focusedOptionIndex = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const { length } = options
|
||||||
|
const { maxHeight } = this.props
|
||||||
|
const { rowHeight } = this._cellMeasurerCache
|
||||||
|
|
||||||
|
let height = 0
|
||||||
|
for (let i = 0; i < length; ++i) {
|
||||||
|
height += rowHeight({ index: i })
|
||||||
|
if (height > maxHeight) {
|
||||||
|
height = maxHeight
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoSizer disableHeight>
|
<AutoSizer disableHeight>
|
||||||
{({ width }) =>
|
{({ width }) => (
|
||||||
width ? (
|
|
||||||
<CellMeasurer
|
|
||||||
cellRenderer={({ rowIndex }) =>
|
|
||||||
wrappedRowRenderer({ index: rowIndex })
|
|
||||||
}
|
|
||||||
columnCount={1}
|
|
||||||
rowCount={options.length}
|
|
||||||
// FIXME: 16 px: ugly workaround to take into account the scrollbar
|
|
||||||
// during the offscreen render to measure the row height
|
|
||||||
// See https://github.com/bvaughn/react-virtualized/issues/401
|
|
||||||
width={width - 16}
|
|
||||||
>
|
|
||||||
{({ getRowHeight }) => {
|
|
||||||
if (options.length <= MAX_OPTIONS) {
|
|
||||||
height = sum(
|
|
||||||
map(options, (_, index) => getRowHeight({ index }))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<List
|
<List
|
||||||
|
deferredMeasurementCache={this._cellMeasurerCache}
|
||||||
height={height}
|
height={height}
|
||||||
rowCount={options.length}
|
rowCount={length}
|
||||||
rowHeight={getRowHeight}
|
rowHeight={rowHeight}
|
||||||
rowRenderer={wrappedRowRenderer}
|
rowRenderer={renderRow}
|
||||||
scrollToIndex={focusedOptionIndex}
|
scrollToIndex={focusedOptionIndex}
|
||||||
style={LIST_STYLE}
|
|
||||||
width={width}
|
width={width}
|
||||||
/>
|
/>
|
||||||
)
|
)}
|
||||||
}}
|
|
||||||
</CellMeasurer>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
</AutoSizer>
|
</AutoSizer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
_renderMenu = this._renderMenu.bind(this)
|
||||||
|
|
||||||
_optionRenderer = ({
|
_renderRow (
|
||||||
|
{
|
||||||
focusedOption,
|
focusedOption,
|
||||||
focusOption,
|
focusOption,
|
||||||
key,
|
inputValue,
|
||||||
labelKey,
|
optionClassName,
|
||||||
option,
|
optionRenderer,
|
||||||
style,
|
options,
|
||||||
selectValue,
|
selectValue,
|
||||||
}) => {
|
},
|
||||||
let className = 'Select-option'
|
{ index, key, parent, style },
|
||||||
|
focusFromEvent,
|
||||||
if (option === focusedOption) {
|
selectFromEvent
|
||||||
className += ' is-focused'
|
) {
|
||||||
}
|
const option = options[index]
|
||||||
|
|
||||||
const { disabled } = option
|
const { disabled } = option
|
||||||
|
|
||||||
if (disabled) {
|
|
||||||
className += ' is-disabled'
|
|
||||||
}
|
|
||||||
|
|
||||||
const { props } = this
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<CellMeasurer
|
||||||
className={className}
|
cache={this._cellMeasurerCache}
|
||||||
onClick={disabled ? undefined : () => selectValue(option)}
|
columnIndex={0}
|
||||||
onMouseOver={disabled ? undefined : () => focusOption(option)}
|
|
||||||
style={style}
|
|
||||||
key={key}
|
key={key}
|
||||||
|
parent={parent}
|
||||||
|
rowIndex={index}
|
||||||
>
|
>
|
||||||
{props.optionRenderer(option, labelKey)}
|
<div
|
||||||
|
className={classNames('Select-option', optionClassName, {
|
||||||
|
'is-disabled': disabled,
|
||||||
|
'is-focused': option === focusedOption,
|
||||||
|
})}
|
||||||
|
data-index={index}
|
||||||
|
onClick={disabled ? undefined : selectFromEvent}
|
||||||
|
onMouseEnter={disabled ? undefined : focusFromEvent}
|
||||||
|
style={style}
|
||||||
|
title={option.title}
|
||||||
|
>
|
||||||
|
{optionRenderer(option, index, inputValue)}
|
||||||
</div>
|
</div>
|
||||||
|
</CellMeasurer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.componentDidUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate () {
|
||||||
|
const { props } = this
|
||||||
|
const { autoSelectSingleOption = props.required, options } = props
|
||||||
|
if (autoSelectSingleOption && options != null && options.length === 1) {
|
||||||
|
const value = options[0][props.valueKey]
|
||||||
|
props.onChange(props.multi ? [value] : value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { props } = this
|
||||||
|
const { multi } = props
|
||||||
return (
|
return (
|
||||||
<ReactSelect
|
<ReactSelect
|
||||||
closeOnSelect={!this.props.multi}
|
|
||||||
{...this.props}
|
|
||||||
backspaceToRemoveMessage=''
|
backspaceToRemoveMessage=''
|
||||||
menuRenderer={this._renderMenu}
|
clearable={multi || !props.required}
|
||||||
menuStyle={SELECT_MENU_STYLE}
|
closeOnSelect={!multi}
|
||||||
|
isLoading={!props.disabled && isEmpty(props.options)}
|
||||||
style={SELECT_STYLE}
|
style={SELECT_STYLE}
|
||||||
|
valueRenderer={props.optionRenderer}
|
||||||
|
{...props}
|
||||||
|
menuRenderer={this._renderMenu}
|
||||||
|
menuStyle={MENU_STYLE}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import classNames from 'classnames'
|
import PropTypes from 'prop-types'
|
||||||
import { parse as parseRemote } from 'xo-remote-parser'
|
import { parse as parseRemote } from 'xo-remote-parser'
|
||||||
import {
|
import {
|
||||||
assign,
|
assign,
|
||||||
@ -23,14 +23,12 @@ import {
|
|||||||
|
|
||||||
import _ from './intl'
|
import _ from './intl'
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Component from './base-component'
|
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
import propTypes from './prop-types-decorator'
|
|
||||||
import renderXoItem from './render-xo-item'
|
import renderXoItem from './render-xo-item'
|
||||||
|
import Select from './form/select'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import Tooltip from './tooltip'
|
import Tooltip from './tooltip'
|
||||||
import uncontrollableInput from 'uncontrollable-input'
|
import uncontrollableInput from 'uncontrollable-input'
|
||||||
import { Select } from './form'
|
|
||||||
import {
|
import {
|
||||||
createCollectionWrapper,
|
createCollectionWrapper,
|
||||||
createFilter,
|
createFilter,
|
||||||
@ -112,23 +110,18 @@ const options = props => ({
|
|||||||
* ]
|
* ]
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
@propTypes({
|
class GenericSelect extends React.Component {
|
||||||
autoFocus: propTypes.bool,
|
static propTypes = {
|
||||||
clearable: propTypes.bool,
|
hasSelectAll: PropTypes.bool,
|
||||||
disabled: propTypes.bool,
|
multi: PropTypes.bool,
|
||||||
hasSelectAll: propTypes.bool,
|
onChange: PropTypes.func.isRequired,
|
||||||
multi: propTypes.bool,
|
xoContainers: PropTypes.array,
|
||||||
onChange: propTypes.func,
|
xoObjects: PropTypes.oneOfType([
|
||||||
placeholder: propTypes.any.isRequired,
|
PropTypes.array,
|
||||||
required: propTypes.bool,
|
PropTypes.objectOf(PropTypes.array),
|
||||||
value: propTypes.any,
|
|
||||||
xoContainers: propTypes.array,
|
|
||||||
xoObjects: propTypes.oneOfType([
|
|
||||||
propTypes.array,
|
|
||||||
propTypes.objectOf(propTypes.array),
|
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
})
|
}
|
||||||
export class GenericSelect extends Component {
|
|
||||||
_getObjectsById = createSelector(
|
_getObjectsById = createSelector(
|
||||||
() => this.props.xoObjects,
|
() => this.props.xoObjects,
|
||||||
objects =>
|
objects =>
|
||||||
@ -142,8 +135,8 @@ export class GenericSelect extends Component {
|
|||||||
// createCollectionWrapper with a depth?
|
// createCollectionWrapper with a depth?
|
||||||
const { name } = this.constructor
|
const { name } = this.constructor
|
||||||
|
|
||||||
let options = []
|
let options
|
||||||
if (!containers) {
|
if (containers === undefined) {
|
||||||
if (__DEV__ && !isArray(objects)) {
|
if (__DEV__ && !isArray(objects)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${name}: without xoContainers, xoObjects must be an array`
|
`${name}: without xoContainers, xoObjects must be an array`
|
||||||
@ -151,12 +144,14 @@ export class GenericSelect extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
options = map(objects, getOption)
|
options = map(objects, getOption)
|
||||||
} else if (__DEV__ && isArray(objects)) {
|
} else {
|
||||||
|
if (__DEV__ && isArray(objects)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${name}: with xoContainers, xoObjects must be an object`
|
`${name}: with xoContainers, xoObjects must be an object`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options = []
|
||||||
forEach(containers, container => {
|
forEach(containers, container => {
|
||||||
options.push({
|
options.push({
|
||||||
disabled: true,
|
disabled: true,
|
||||||
@ -167,11 +162,11 @@ export class GenericSelect extends Component {
|
|||||||
options.push(getOption(object, container))
|
options.push(getOption(object, container))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const values = this._getSelectValue()
|
|
||||||
const objectsById = this._getObjectsById()
|
const objectsById = this._getObjectsById()
|
||||||
const addIfMissing = val => {
|
const addIfMissing = val => {
|
||||||
if (val && !objectsById[val]) {
|
if (val != null && !(val in objectsById)) {
|
||||||
options.push({
|
options.push({
|
||||||
disabled: true,
|
disabled: true,
|
||||||
id: val,
|
id: val,
|
||||||
@ -185,6 +180,7 @@ export class GenericSelect extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const values = this._getSelectedIds()
|
||||||
if (isArray(values)) {
|
if (isArray(values)) {
|
||||||
forEach(values, addIfMissing)
|
forEach(values, addIfMissing)
|
||||||
} else {
|
} else {
|
||||||
@ -195,27 +191,25 @@ export class GenericSelect extends Component {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_getSelectValue = createSelector(
|
_getSelectedIds = createSelector(
|
||||||
() => this.props.value,
|
() => this.props.value,
|
||||||
createCollectionWrapper(getIds)
|
createCollectionWrapper(getIds)
|
||||||
)
|
)
|
||||||
|
|
||||||
_getNewSelectedObjects = createSelector(
|
_getSelectedObjects = (() => {
|
||||||
|
const helper = createSelector(
|
||||||
this._getObjectsById,
|
this._getObjectsById,
|
||||||
value => value,
|
value => value,
|
||||||
(objectsById, value) =>
|
(objectsById, value) =>
|
||||||
value == null
|
isArray(value)
|
||||||
? value
|
|
||||||
: isArray(value)
|
|
||||||
? map(value, value => objectsById[value.value])
|
? map(value, value => objectsById[value.value])
|
||||||
: objectsById[value.value]
|
: objectsById[value.value]
|
||||||
)
|
)
|
||||||
|
return value => (value == null ? value : helper(value))
|
||||||
|
})()
|
||||||
|
|
||||||
_onChange = value => {
|
_onChange = value => {
|
||||||
const { onChange } = this.props
|
this.props.onChange(this._getSelectedObjects(value))
|
||||||
if (onChange) {
|
|
||||||
onChange(this._getNewSelectedObjects(value))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_selectAll = () => {
|
_selectAll = () => {
|
||||||
@ -225,46 +219,31 @@ export class GenericSelect extends Component {
|
|||||||
// GroupBy: Display option with margin if not disabled and containers exists.
|
// GroupBy: Display option with margin if not disabled and containers exists.
|
||||||
_renderOption = option => (
|
_renderOption = option => (
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={
|
||||||
!option.disabled && this.props.xoContainers && 'ml-1'
|
!option.disabled && this.props.xoContainers !== undefined
|
||||||
)}
|
? 'ml-1'
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{renderXoItem(option.xoItem)}
|
{renderXoItem(option.xoItem)}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const { hasSelectAll, xoContainers, xoObjects, ...props } = this.props
|
||||||
autoFocus,
|
|
||||||
disabled,
|
|
||||||
hasSelectAll,
|
|
||||||
multi,
|
|
||||||
placeholder,
|
|
||||||
required,
|
|
||||||
|
|
||||||
clearable = Boolean(multi || !required),
|
|
||||||
} = this.props
|
|
||||||
|
|
||||||
const select = (
|
const select = (
|
||||||
<Select
|
<Select
|
||||||
{...{
|
{...props}
|
||||||
autoFocus,
|
|
||||||
clearable,
|
|
||||||
disabled,
|
|
||||||
multi,
|
|
||||||
placeholder,
|
|
||||||
required,
|
|
||||||
}}
|
|
||||||
onChange={this._onChange}
|
onChange={this._onChange}
|
||||||
openOnFocus
|
openOnFocus
|
||||||
optionRenderer={this._renderOption}
|
optionRenderer={this._renderOption}
|
||||||
options={this._getOptions()}
|
options={this._getOptions()}
|
||||||
value={this._getSelectValue()}
|
value={this._getSelectedIds()}
|
||||||
valueRenderer={this._renderOption}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!multi || !hasSelectAll) {
|
if (!props.multi || !hasSelectAll) {
|
||||||
return select
|
return select
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,16 +274,15 @@ const makeStoreSelect = (createSelectors, defaultProps) =>
|
|||||||
|
|
||||||
const makeSubscriptionSelect = (subscribe, props) =>
|
const makeSubscriptionSelect = (subscribe, props) =>
|
||||||
uncontrollableInput(options)(
|
uncontrollableInput(options)(
|
||||||
class extends Component {
|
class extends React.PureComponent {
|
||||||
constructor (props) {
|
state = {}
|
||||||
super(props)
|
|
||||||
|
|
||||||
this._getFilteredXoContainers = createFilter(
|
_getFilteredXoContainers = createFilter(
|
||||||
() => this.state.xoContainers,
|
() => this.state.xoContainers,
|
||||||
() => this.props.containerPredicate
|
() => this.props.containerPredicate
|
||||||
)
|
)
|
||||||
|
|
||||||
this._getFilteredXoObjects = createSelector(
|
_getFilteredXoObjects = createSelector(
|
||||||
() => this.state.xoObjects,
|
() => this.state.xoObjects,
|
||||||
() => this.state.xoContainers && this._getFilteredXoContainers(),
|
() => this.state.xoContainers && this._getFilteredXoContainers(),
|
||||||
() => this.props.predicate,
|
() => this.props.predicate,
|
||||||
@ -324,7 +302,6 @@ const makeSubscriptionSelect = (subscribe, props) =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
this.componentWillUnmount = subscribe(::this.setState)
|
this.componentWillUnmount = subscribe(::this.setState)
|
||||||
@ -577,10 +554,7 @@ export const SelectHighLevelObject = makeStoreSelect(
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export const SelectVdi = propTypes({
|
export const SelectVdi = makeStoreSelect(
|
||||||
srPredicate: propTypes.func,
|
|
||||||
})(
|
|
||||||
makeStoreSelect(
|
|
||||||
() => {
|
() => {
|
||||||
const getSrs = createGetObjectsOfType('SR').filter(
|
const getSrs = createGetObjectsOfType('SR').filter(
|
||||||
(_, props) => props.srPredicate
|
(_, props) => props.srPredicate
|
||||||
@ -605,8 +579,10 @@ export const SelectVdi = propTypes({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ placeholder: _('selectVdis') }
|
{ placeholder: _('selectVdis') }
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
SelectVdi.propTypes = {
|
||||||
|
srPredicate: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
@ -747,7 +723,7 @@ export const SelectResourceSet = makeSubscriptionSelect(
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export class SelectResourceSetsVmTemplate extends Component {
|
export class SelectResourceSetsVmTemplate extends React.PureComponent {
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
@ -782,7 +758,7 @@ export class SelectResourceSetsVmTemplate extends Component {
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export class SelectResourceSetsSr extends Component {
|
export class SelectResourceSetsSr extends React.PureComponent {
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
@ -813,7 +789,7 @@ export class SelectResourceSetsSr extends Component {
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export class SelectResourceSetsVdi extends Component {
|
export class SelectResourceSetsVdi extends React.PureComponent {
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
@ -853,7 +829,7 @@ export class SelectResourceSetsVdi extends Component {
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export class SelectResourceSetsNetwork extends Component {
|
export class SelectResourceSetsNetwork extends React.PureComponent {
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
@ -894,12 +870,13 @@ export class SelectResourceSetsNetwork extends Component {
|
|||||||
ipPools: subscribeIpPools,
|
ipPools: subscribeIpPools,
|
||||||
resourceSets: subscribeResourceSets,
|
resourceSets: subscribeResourceSets,
|
||||||
}))
|
}))
|
||||||
@propTypes({
|
export class SelectResourceSetIp extends React.Component {
|
||||||
containerPredicate: propTypes.func,
|
static propTypes = {
|
||||||
predicate: propTypes.func,
|
containerPredicate: PropTypes.func,
|
||||||
resourceSetId: propTypes.string.isRequired,
|
predicate: PropTypes.func,
|
||||||
})
|
resourceSetId: PropTypes.string.isRequired,
|
||||||
export class SelectResourceSetIp extends Component {
|
}
|
||||||
|
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
@ -958,7 +935,7 @@ export class SelectResourceSetIp extends Component {
|
|||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
export class SelectSshKey extends Component {
|
export class SelectSshKey extends React.PureComponent {
|
||||||
get value () {
|
get value () {
|
||||||
return this.refs.select.value
|
return this.refs.select.value
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@ import endsWith from 'lodash/endsWith'
|
|||||||
import Icon from 'icon'
|
import Icon from 'icon'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import replace from 'lodash/replace'
|
import replace from 'lodash/replace'
|
||||||
|
import Select from 'form/select'
|
||||||
import Tooltip from 'tooltip'
|
import Tooltip from 'tooltip'
|
||||||
import { Container, Col, Row } from 'grid'
|
import { Container, Col, Row } from 'grid'
|
||||||
import { createSelector } from 'reselect'
|
import { createSelector } from 'reselect'
|
||||||
import { formatSize } from 'utils'
|
import { formatSize } from 'utils'
|
||||||
import { FormattedDate } from 'react-intl'
|
import { FormattedDate } from 'react-intl'
|
||||||
import { SelectPlainObject } from 'form'
|
|
||||||
import { filter, includes, isEmpty, map } from 'lodash'
|
import { filter, includes, isEmpty, map } from 'lodash'
|
||||||
import { scanDisk, scanFiles } from 'xo'
|
import { scanDisk, scanFiles } from 'xo'
|
||||||
|
|
||||||
@ -251,23 +251,25 @@ export default class RestoreFileModalBody extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
onChange={this._onBackupChange}
|
onChange={this._onBackupChange}
|
||||||
optionKey='id'
|
|
||||||
optionRenderer={backupOptionRenderer}
|
optionRenderer={backupOptionRenderer}
|
||||||
options={backups}
|
options={backups}
|
||||||
placeholder={_('restoreFilesSelectBackup')}
|
placeholder={_('restoreFilesSelectBackup')}
|
||||||
value={backup}
|
value={backup}
|
||||||
|
valueKey='id'
|
||||||
/>
|
/>
|
||||||
{backup && [
|
{backup && [
|
||||||
<br />,
|
<br />,
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
onChange={this._onDiskChange}
|
onChange={this._onDiskChange}
|
||||||
optionKey='id'
|
|
||||||
optionRenderer={diskOptionRenderer}
|
optionRenderer={diskOptionRenderer}
|
||||||
options={backup.disks}
|
options={backup.disks}
|
||||||
placeholder={_('restoreFilesSelectDisk')}
|
placeholder={_('restoreFilesSelectDisk')}
|
||||||
value={disk}
|
value={disk}
|
||||||
|
valueKey='id'
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
{scanDiskError && (
|
{scanDiskError && (
|
||||||
@ -279,13 +281,14 @@ export default class RestoreFileModalBody extends Component {
|
|||||||
!scanDiskError &&
|
!scanDiskError &&
|
||||||
!noPartitions && [
|
!noPartitions && [
|
||||||
<br />,
|
<br />,
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
onChange={this._onPartitionChange}
|
onChange={this._onPartitionChange}
|
||||||
optionKey='id'
|
|
||||||
optionRenderer={partitionOptionRenderer}
|
optionRenderer={partitionOptionRenderer}
|
||||||
options={partitions}
|
options={partitions}
|
||||||
placeholder={_('restoreFilesSelectPartition')}
|
placeholder={_('restoreFilesSelectPartition')}
|
||||||
value={partition}
|
value={partition}
|
||||||
|
valueKey='id'
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
{(partition || (disk && !scanDiskError && noPartitions)) && [
|
{(partition || (disk && !scanDiskError && noPartitions)) && [
|
||||||
@ -311,13 +314,14 @@ export default class RestoreFileModalBody extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Container>,
|
</Container>,
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
onChange={this._onFileChange}
|
onChange={this._onFileChange}
|
||||||
optionKey='id'
|
|
||||||
optionRenderer={fileOptionRenderer}
|
optionRenderer={fileOptionRenderer}
|
||||||
options={this._getSelectableFiles()}
|
options={this._getSelectableFiles()}
|
||||||
placeholder={_('restoreFilesSelectFiles')}
|
placeholder={_('restoreFilesSelectFiles')}
|
||||||
value={null}
|
value={null}
|
||||||
|
valueKey='id'
|
||||||
/>,
|
/>,
|
||||||
<br />,
|
<br />,
|
||||||
<div>
|
<div>
|
||||||
|
@ -22,7 +22,7 @@ import { addSubscriptions, noop } from 'utils'
|
|||||||
import { Container, Row, Col } from 'grid'
|
import { Container, Row, Col } from 'grid'
|
||||||
import { FormattedDate, injectIntl } from 'react-intl'
|
import { FormattedDate, injectIntl } from 'react-intl'
|
||||||
import { info, error } from 'notification'
|
import { info, error } from 'notification'
|
||||||
import { SelectPlainObject, Toggle } from 'form'
|
import { Select, Toggle } from 'form'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
importBackup,
|
importBackup,
|
||||||
@ -210,14 +210,15 @@ class _ModalBody extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
onChange={this.linkState('backup')}
|
onChange={this.linkState('backup')}
|
||||||
optionKey='path'
|
|
||||||
optionRenderer={backupOptionRenderer}
|
optionRenderer={backupOptionRenderer}
|
||||||
options={props.backups}
|
options={props.backups}
|
||||||
placeholder={props.intl.formatMessage(
|
placeholder={props.intl.formatMessage(
|
||||||
messages.importBackupModalSelectBackup
|
messages.importBackupModalSelectBackup
|
||||||
)}
|
)}
|
||||||
|
valueKey='path'
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<ChooseSrForEachVdisModal
|
<ChooseSrForEachVdisModal
|
||||||
|
@ -3,6 +3,7 @@ import ActionButton from 'action-button'
|
|||||||
import ActionRowButton from 'action-row-button'
|
import ActionRowButton from 'action-row-button'
|
||||||
import Button from 'button'
|
import Button from 'button'
|
||||||
import Component from 'base-component'
|
import Component from 'base-component'
|
||||||
|
import defined from 'xo-defined'
|
||||||
import delay from 'lodash/delay'
|
import delay from 'lodash/delay'
|
||||||
import find from 'lodash/find'
|
import find from 'lodash/find'
|
||||||
import forEach from 'lodash/forEach'
|
import forEach from 'lodash/forEach'
|
||||||
@ -13,6 +14,7 @@ import isEmpty from 'lodash/isEmpty'
|
|||||||
import map from 'lodash/map'
|
import map from 'lodash/map'
|
||||||
import mapValues from 'lodash/mapValues'
|
import mapValues from 'lodash/mapValues'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import Select from 'form/select'
|
||||||
import size from 'lodash/size'
|
import size from 'lodash/size'
|
||||||
import Tooltip from 'tooltip'
|
import Tooltip from 'tooltip'
|
||||||
import Upgrade from 'xoa-upgrade'
|
import Upgrade from 'xoa-upgrade'
|
||||||
@ -21,7 +23,6 @@ import { createSelector } from 'selectors'
|
|||||||
import { error } from 'notification'
|
import { error } from 'notification'
|
||||||
import { generateUiSchema } from 'xo-json-schema-input'
|
import { generateUiSchema } from 'xo-json-schema-input'
|
||||||
import { injectIntl } from 'react-intl'
|
import { injectIntl } from 'react-intl'
|
||||||
import { SelectPlainObject } from 'form'
|
|
||||||
import { SelectSubject } from 'select-objects'
|
import { SelectSubject } from 'select-objects'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -119,17 +120,7 @@ export default class Jobs extends Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (props) {
|
|
||||||
const { currentUser } = props
|
|
||||||
const { owner } = this.state
|
|
||||||
|
|
||||||
if (currentUser && !owner) {
|
|
||||||
this.setState({ owner: currentUser.id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
this.setState({ owner: this.props.user && this.props.user.id })
|
|
||||||
this.componentWillUnmount = subscribeJobs(jobs => {
|
this.componentWillUnmount = subscribeJobs(jobs => {
|
||||||
const j = {}
|
const j = {}
|
||||||
for (const id in jobs) {
|
for (const id in jobs) {
|
||||||
@ -279,7 +270,7 @@ export default class Jobs extends Component {
|
|||||||
params.value
|
params.value
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
userId: owner,
|
userId: owner !== undefined ? owner : this.props.currentUser.id,
|
||||||
timeout: timeout ? timeout * 1e3 : undefined,
|
timeout: timeout ? timeout * 1e3 : undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,8 +363,8 @@ export default class Jobs extends Component {
|
|||||||
type === 'user' && permission === 'admin'
|
type === 'user' && permission === 'admin'
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { state } = this
|
const { props, state } = this
|
||||||
const { action, actions, job, jobs, owner } = state
|
const { action, actions, job, jobs } = state
|
||||||
const { formatMessage } = this.props.intl
|
const { formatMessage } = this.props.intl
|
||||||
|
|
||||||
const isJobUserMissing = this._getIsJobUserMissing()
|
const isJobUserMissing = this._getIsJobUserMissing()
|
||||||
@ -387,7 +378,7 @@ export default class Jobs extends Component {
|
|||||||
placeholder={_('jobOwnerPlaceholder')}
|
placeholder={_('jobOwnerPlaceholder')}
|
||||||
predicate={this._subjectPredicate}
|
predicate={this._subjectPredicate}
|
||||||
required
|
required
|
||||||
value={owner}
|
value={defined(state.owner, () => props.currentUser.id)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
@ -397,12 +388,13 @@ export default class Jobs extends Component {
|
|||||||
pattern='[^_]+'
|
pattern='[^_]+'
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<SelectPlainObject
|
<Select
|
||||||
ref='method'
|
labelKey='method'
|
||||||
options={actions}
|
|
||||||
optionKey='method'
|
|
||||||
onChange={this._handleSelectMethod}
|
onChange={this._handleSelectMethod}
|
||||||
|
options={actions}
|
||||||
placeholder={_('jobActionPlaceHolder')}
|
placeholder={_('jobActionPlaceHolder')}
|
||||||
|
ref='method'
|
||||||
|
valueKey='method'
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type='number'
|
type='number'
|
||||||
|
@ -10,7 +10,7 @@ import React, { Component } from 'react'
|
|||||||
import Scheduler, { SchedulePreview } from 'scheduling'
|
import Scheduler, { SchedulePreview } from 'scheduling'
|
||||||
import { error } from 'notification'
|
import { error } from 'notification'
|
||||||
import { injectIntl } from 'react-intl'
|
import { injectIntl } from 'react-intl'
|
||||||
import { SelectPlainObject, Toggle } from 'form'
|
import { Select, Toggle } from 'form'
|
||||||
import {
|
import {
|
||||||
createSchedule,
|
createSchedule,
|
||||||
deleteSchedule,
|
deleteSchedule,
|
||||||
@ -223,10 +223,11 @@ export default class Schedules extends Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='form-group'>
|
<div className='form-group'>
|
||||||
<SelectPlainObject
|
<Select
|
||||||
|
labelKey='name'
|
||||||
ref='job'
|
ref='job'
|
||||||
options={map(jobs)}
|
options={map(jobs)}
|
||||||
optionKey='id'
|
valueKey='id'
|
||||||
placeholder={this.props.intl.formatMessage(
|
placeholder={this.props.intl.formatMessage(
|
||||||
messages.jobScheduleJobPlaceHolder
|
messages.jobScheduleJobPlaceHolder
|
||||||
)}
|
)}
|
||||||
|
@ -381,6 +381,7 @@ export class Edit extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col mediumSize={4}>
|
<Col mediumSize={4}>
|
||||||
<SelectSubject
|
<SelectSubject
|
||||||
|
autoSelectSingleOption={false}
|
||||||
hasSelectAll
|
hasSelectAll
|
||||||
multi
|
multi
|
||||||
onChange={this.linkState('subjects')}
|
onChange={this.linkState('subjects')}
|
||||||
@ -390,6 +391,7 @@ export class Edit extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col mediumSize={4}>
|
<Col mediumSize={4}>
|
||||||
<SelectPool
|
<SelectPool
|
||||||
|
autoSelectSingleOption={false}
|
||||||
hasSelectAll
|
hasSelectAll
|
||||||
multi
|
multi
|
||||||
onChange={this._updateSelectedPools}
|
onChange={this._updateSelectedPools}
|
||||||
@ -414,6 +416,7 @@ export class Edit extends Component {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col mediumSize={4}>
|
<Col mediumSize={4}>
|
||||||
<SelectVmTemplate
|
<SelectVmTemplate
|
||||||
|
autoSelectSingleOption={false}
|
||||||
disabled={!state.nPools}
|
disabled={!state.nPools}
|
||||||
hasSelectAll
|
hasSelectAll
|
||||||
multi
|
multi
|
||||||
@ -425,6 +428,7 @@ export class Edit extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col mediumSize={4}>
|
<Col mediumSize={4}>
|
||||||
<SelectSr
|
<SelectSr
|
||||||
|
autoSelectSingleOption={false}
|
||||||
disabled={!state.nPools}
|
disabled={!state.nPools}
|
||||||
hasSelectAll
|
hasSelectAll
|
||||||
multi
|
multi
|
||||||
@ -436,6 +440,7 @@ export class Edit extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col mediumSize={4}>
|
<Col mediumSize={4}>
|
||||||
<SelectNetwork
|
<SelectNetwork
|
||||||
|
autoSelectSingleOption={false}
|
||||||
disabled={!state.nSrs}
|
disabled={!state.nSrs}
|
||||||
hasSelectAll
|
hasSelectAll
|
||||||
multi
|
multi
|
||||||
@ -535,8 +540,8 @@ export class Edit extends Component {
|
|||||||
<Col mediumSize={7}>
|
<Col mediumSize={7}>
|
||||||
<SelectIpPool
|
<SelectIpPool
|
||||||
onChange={this._onChangeIpPool}
|
onChange={this._onChangeIpPool}
|
||||||
value=''
|
|
||||||
predicate={this._getIpPoolPredicate()}
|
predicate={this._getIpPoolPredicate()}
|
||||||
|
value={null}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -166,7 +166,7 @@ export default class Acls extends Component {
|
|||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
action: '',
|
action: null,
|
||||||
objects: [],
|
objects: [],
|
||||||
subjects: [],
|
subjects: [],
|
||||||
typeFilters: {},
|
typeFilters: {},
|
||||||
|
11
yarn.lock
11
yarn.lock
@ -1270,7 +1270,7 @@ babel-runtime@^5.8.25:
|
|||||||
dependencies:
|
dependencies:
|
||||||
core-js "^1.0.0"
|
core-js "^1.0.0"
|
||||||
|
|
||||||
babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
|
babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
|
||||||
version "6.26.0"
|
version "6.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7292,14 +7292,15 @@ react-transition-group@^2.2.0:
|
|||||||
prop-types "^15.5.8"
|
prop-types "^15.5.8"
|
||||||
warning "^3.0.0"
|
warning "^3.0.0"
|
||||||
|
|
||||||
react-virtualized@^8.0.8:
|
react-virtualized@^9.15.0:
|
||||||
version "8.11.4"
|
version "9.17.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-8.11.4.tgz#0bb94f1ecbd286d07145ce63983d0a11724522c0"
|
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.17.3.tgz#3854588f067235c00ae5cd134d96508956630033"
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-runtime "^6.11.6"
|
babel-runtime "^6.26.0"
|
||||||
classnames "^2.2.3"
|
classnames "^2.2.3"
|
||||||
dom-helpers "^2.4.0 || ^3.0.0"
|
dom-helpers "^2.4.0 || ^3.0.0"
|
||||||
loose-envify "^1.3.0"
|
loose-envify "^1.3.0"
|
||||||
|
prop-types "^15.5.4"
|
||||||
|
|
||||||
react@^15.4.1:
|
react@^15.4.1:
|
||||||
version "15.6.2"
|
version "15.6.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user