import React from 'react'; import PropTypes from 'prop-types'; import { translate } from 'react-i18next'; import FormGroup from 'react-bootstrap/es/FormGroup'; import FormControl from 'react-bootstrap/es/FormControl'; import ListGroup from 'react-bootstrap/es/ListGroup'; import ListGroupItem from 'react-bootstrap/es/ListGroupItem'; import Modal from 'react-bootstrap/es/Modal'; const SPECIFIED_GROUP_VALUE = 'specifiedGroup'; /** * Page grant select component * * @export * @class GrantSelector * @extends {React.Component} */ class GrantSelector extends React.Component { constructor(props) { super(props); this.availableGrants = [ { grant: 1, iconClass: 'icon-people', styleClass: '', label: 'Public' }, { grant: 2, iconClass: 'icon-link', styleClass: 'text-info', label: 'Anyone with the link' }, // { grant: 3, iconClass: '', label: 'Specified users only' }, { grant: 4, iconClass: 'icon-lock', styleClass: 'text-danger', label: 'Just me' }, { grant: 5, iconClass: 'icon-options', styleClass: '', label: 'Only inside the group' }, // appeared only one of these 'grant: 5' { grant: 5, iconClass: 'icon-options', styleClass: '', label: 'Reselect the group' }, // appeared only one of these 'grant: 5' ]; this.state = { grant: this.props.grant || 1, // default: 1 userRelatedGroups: [], isSelectGroupModalShown: false, }; if (this.props.grantGroupId !== '') { this.state.grantGroup = { _id: this.props.grantGroupId, name: this.props.grantGroupName }; } // retrieve xss library from window this.xss = window.xss; this.getCurrentOptionsToSave = this.getCurrentOptionsToSave.bind(this); this.showSelectGroupModal = this.showSelectGroupModal.bind(this); this.hideSelectGroupModal = this.hideSelectGroupModal.bind(this); this.getGroupName = this.getGroupName.bind(this); this.changeGrantHandler = this.changeGrantHandler.bind(this); this.groupListItemClickHandler = this.groupListItemClickHandler.bind(this); } componentDidUpdate(prevProps, prevState) { /* * set SPECIFIED_GROUP_VALUE to grant selector * cz: bootstrap-select input element has the defferent state to React component */ if (this.state.grantGroup != null) { this.grantSelectorInputEl.value = SPECIFIED_GROUP_VALUE; } // refresh bootstrap-select // see https://silviomoreto.github.io/bootstrap-select/methods/#selectpickerrefresh $('.grant-selector .selectpicker').selectpicker('refresh'); //// DIRTY HACK -- 2018.05.25 Yuki Takei // set group name to the bootstrap-select options // cz: .selectpicker('refresh') doesn't replace data-content $('.grant-selector .group-name').text(this.getGroupName()); } getCurrentOptionsToSave() { const options = { grant: this.state.grant }; if (this.state.grantGroup != null) { options.grantUserGroupId = this.state.grantGroup._id; } return options; } showSelectGroupModal() { this.retrieveUserGroupRelations(); this.setState({ isSelectGroupModalShown: true }); } hideSelectGroupModal() { this.setState({ isSelectGroupModalShown: false }); } getGroupName() { const grantGroup = this.state.grantGroup; return grantGroup ? this.xss.process(grantGroup.name) : ''; } /** * Retrieve user-group-relations data from backend */ retrieveUserGroupRelations() { this.props.crowi.apiGet('/me/user-group-relations') .then(res => { return res.userGroupRelations; }) .then(userGroupRelations => { const userRelatedGroups = userGroupRelations.map(relation => { return relation.relatedGroup; }); this.setState({userRelatedGroups}); }); } /** * change event handler for grant selector */ changeGrantHandler() { const grant = +this.grantSelectorInputEl.value; // select group if (grant === 5) { this.showSelectGroupModal(); /* * reset grant selector to state */ this.grantSelectorInputEl.value = this.state.grant; return; } this.setState({ grant, grantGroup: null }); } groupListItemClickHandler(grantGroup) { this.setState({ grant: 5, grantGroup }); // hide modal this.hideSelectGroupModal(); } /** * Render grant selector DOM. * @returns * @memberof GrantSelector */ renderGrantSelector() { const { t } = this.props; let index = 0; let selectedValue = this.state.grant; const grantElems = this.availableGrants.map((opt) => { const dataContent = ` ${t(opt.label)}`; return ; }); const grantGroup = this.state.grantGroup; if (grantGroup != null) { selectedValue = SPECIFIED_GROUP_VALUE; // DIRTY HACK -- 2018.05.25 Yuki Takei // remove 'Only inside the group' item // cz: .selectpicker('refresh') doesn't replace data-content grantElems.splice(3, 1); } else { // DIRTY HACK -- 2018.05.25 Yuki Takei // remove 'Reselect the group' item // cz: .selectpicker('refresh') doesn't replace data-content grantElems.splice(4, 1); } /* * react-bootstrap couldn't be rendered only with React feature. * see also 'componentDidUpdate' */ // add specified group option grantElems.push( ); const bsClassName = 'form-control-dummy'; // set form-control* to shrink width return ( this.grantSelectorInputEl=el }> {grantElems} ); } /** * Render select grantgroup modal. * * @returns * @memberof GrantSelector */ renderSelectGroupModal() { const generateGroupListItems = () => { return this.state.userRelatedGroups.map((group) => { return { this.groupListItemClickHandler(group) }}> (TBD) List group members ; }); }; let content = this.state.userRelatedGroups.length === 0 ?

There is no group to which you belong.

{ this.props.crowi.isAdmin &&

Manage Groups

}
: {generateGroupListItems()} ; return ( Select a Group {content} ); } render() { return {this.renderGrantSelector()} {this.renderSelectGroupModal()} ; } } GrantSelector.propTypes = { t: PropTypes.func.isRequired, // i18next crowi: PropTypes.object.isRequired, grant: PropTypes.number, grantGroupId: PropTypes.string, grantGroupName: PropTypes.string, }; export default translate()(GrantSelector);