cspace-ui
Version:
CollectionSpace user interface for browsers
174 lines (137 loc) • 3.41 kB
JSX
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Immutable from 'immutable';
import { baseComponents as inputComponents, helpers as inputHelpers } from 'cspace-input';
import styles from '../../../styles/cspace-ui/RolesInput.css';
const {
CheckboxInput,
} = inputComponents;
const {
getPath,
pathPropType,
} = inputHelpers.pathHelpers;
const propTypes = {
/* eslint-disable react/no-unused-prop-types */
name: PropTypes.string,
parentPath: pathPropType,
subpath: pathPropType,
/* eslint-enable react/no-unused-prop-types */
readOnly: PropTypes.bool,
value: PropTypes.oneOfType([
PropTypes.instanceOf(Immutable.List),
PropTypes.instanceOf(Immutable.Map),
]),
roles: PropTypes.instanceOf(Immutable.List),
readRoles: PropTypes.func,
onCommit: PropTypes.func,
};
export default class RolesInput extends Component {
constructor(props) {
super(props);
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
}
componentDidMount() {
const {
roles,
readRoles,
} = this.props;
if (!roles && readRoles) {
readRoles();
}
}
handleCheckboxChange(event) {
const {
onCommit,
} = this.props;
if (onCommit) {
const {
checked,
id,
} = event.target;
const membership = this.getRolesMap() || {};
if (checked) {
membership[id] = true;
} else {
delete membership[id];
}
const newValue = Immutable.List(Object.keys(membership).map((roleId) => Immutable.Map({
roleId,
})));
onCommit(getPath(this.props), newValue);
}
}
getRolesMap() {
const {
value,
} = this.props;
let rolesList = value;
if (!rolesList) {
return undefined;
}
if (!Immutable.List.isList(rolesList)) {
rolesList = Immutable.List.of(rolesList);
}
const roles = {};
rolesList.forEach((role) => {
const roleId = role.get('roleId');
roles[roleId] = true;
});
return roles;
}
renderRoleRows() {
const {
readOnly,
roles,
} = this.props;
const membership = this.getRolesMap() || {};
const rows = roles
.map((role) => {
const displayName = role.get('displayName');
const id = role.get('@csid');
const isMember = !!membership[id];
if (readOnly && !isMember) {
return null;
}
return (
<li key={id}>
<CheckboxInput
checked={isMember}
embedded
id={id}
readOnly={readOnly}
onChange={this.handleCheckboxChange}
/>
<label htmlFor={id}>{displayName}</label>
</li>
);
})
.filter((row) => !!row);
return rows.toJS();
}
render() {
const {
readOnly,
roles,
} = this.props;
if (!roles || roles.size === 0) {
return null;
}
let {
value,
} = this.props;
if (value && !Immutable.List.isList(value)) {
value = Immutable.List.of(value);
}
const rows = this.renderRoleRows();
if (rows.length === 0) {
return null;
}
const className = readOnly ? styles.readOnly : styles.common;
return (
<ul className={className}>
{rows}
</ul>
);
}
}
RolesInput.propTypes = propTypes;