Просмотр исходного кода

impl GrantSelector with reactstrap

Yuki Takei 6 лет назад
Родитель
Сommit
b3fe8ae9e9
1 измененных файлов с 45 добавлено и 89 удалено
  1. 45 89
      src/client/js/components/SavePageControls/GrantSelector.jsx

+ 45 - 89
src/client/js/components/SavePageControls/GrantSelector.jsx

@@ -3,22 +3,20 @@ import PropTypes from 'prop-types';
 
 import { withTranslation } from 'react-i18next';
 
-// TODO: GW-333
-// 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 {
+  FormGroup,
+  UncontrolledDropdown,
+  DropdownToggle, DropdownMenu, DropdownItem,
+
   Modal, ModalHeader, ModalBody,
 } from 'reactstrap';
 
+
 import AppContainer from '../../services/AppContainer';
 
 import { createSubscribedElement } from '../UnstatedUtils';
 
-const SPECIFIED_GROUP_VALUE = 'specifiedGroup';
-
 /**
  * Page grant select component
  *
@@ -43,11 +41,8 @@ class GrantSelector extends React.Component {
         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'
+        grant: 5, iconClass: 'icon-options', styleClass: '', label: 'Only inside the group', reselectLabel: 'Reselect the group',
+      },
     ];
 
     this.state = {
@@ -75,25 +70,6 @@ class GrantSelector extends React.Component {
     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());
-
-  }
-
   showSelectGroupModal() {
     this.retrieveUserGroupRelations();
     this.setState({ isSelectGroupModalShown: true });
@@ -127,16 +103,10 @@ class GrantSelector extends React.Component {
   /**
    * change event handler for grant selector
    */
-  changeGrantHandler() {
-    const grant = +this.grantSelectorInputEl.value;
-
+  changeGrantHandler(grant) {
     // select group
     if (grant === 5) {
       this.showSelectGroupModal();
-      /*
-       * reset grant selector to state
-       */
-      this.grantSelectorInputEl.value = this.state.grant;
       return;
     }
 
@@ -165,63 +135,50 @@ class GrantSelector extends React.Component {
    */
   renderGrantSelector() {
     const { t } = this.props;
+    const { grantGroup } = this.state;
+
+    let dropdownToggleLabelElm = null;
 
     let index = 0;
-    let selectedValue = this.state.grant;
-    const grantElems = this.availableGrants.map((opt) => {
-      const dataContent = `<i class="icon icon-fw ${opt.iconClass} ${opt.styleClass}"></i> <span class="${opt.styleClass}">${t(opt.label)}</span>`;
-      return <option key={index++} value={opt.grant} data-content={dataContent}>{t(opt.label)}</option>;
+    const dropdownMenuElems = this.availableGrants.map((opt) => {
+      let label = opt.label;
+      // rewrite label when grantGroup is selected
+      if (opt.grant === 5 && grantGroup != null) {
+        label = opt.reselectLabel;
+      }
+      const labelElm = <><i className={`icon icon-fw ${opt.iconClass} ${opt.styleClass}`}></i> <span className={opt.styleClass}>{t(label)}</span></>;
+
+      // set dropdownToggleLabelElm
+      if (this.state.grant === opt.grant) {
+        dropdownToggleLabelElm = labelElm;
+      }
+
+      return (
+        <DropdownItem key={index++} onClick={() => this.changeGrantHandler(opt.grant)}>
+          {labelElm}
+        </DropdownItem>
+      );
     });
 
-    const grantGroup = this.state.grantGroup;
+    // add specified group option
     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);
+      dropdownMenuElems.push(
+        <DropdownItem>
+          <i className="icon icon-fw icon-organization text-success"></i> <span className="group-name text-success">{this.getGroupName()}</span>
+        </DropdownItem>,
+      );
     }
 
-    /*
-     * react-bootstrap couldn't be rendered only with React feature.
-     * see also 'componentDidUpdate'
-     */
-
-    // add specified group option
-    grantElems.push(
-      <option
-        key="specifiedGroupKey"
-        value={SPECIFIED_GROUP_VALUE}
-        style={{ display: grantGroup ? 'inherit' : 'none' }}
-        data-content={`<i class="icon icon-fw icon-organization text-success"></i> <span class="group-name text-success">${this.getGroupName()}</span>`}
-      >
-        {this.getGroupName()}
-      </option>,
-    );
-
-    const bsClassName = 'form-control-dummy'; // set form-control* to shrink width
     return (
-      <FormGroup className="grant-selector m-b-0">
-        <FormControl
-          disabled={this.props.disabled}
-          componentClass="select"
-          placeholder="select"
-          defaultValue={selectedValue}
-          bsClass={bsClassName}
-          className="btn-group-sm selectpicker"
-          onChange={this.changeGrantHandler}
-          inputRef={(el) => { this.grantSelectorInputEl = el }}
-        >
-
-          {grantElems}
-
-        </FormControl>
+      <FormGroup className="grant-selector mb-0">
+        <UncontrolledDropdown direction="up" size="sm">
+          <DropdownToggle caret disabled={this.props.disabled}>
+            {dropdownToggleLabelElm}
+          </DropdownToggle>
+          <DropdownMenu>
+            {dropdownMenuElems}
+          </DropdownMenu>
+        </UncontrolledDropdown>
       </FormGroup>
     );
   }
@@ -278,8 +235,7 @@ class GrantSelector extends React.Component {
   render() {
     return (
       <React.Fragment>
-        {/* FIXME: activate in GW-412 */}
-        {/* { this.renderGrantSelector() } */}
+        { this.renderGrantSelector() }
         { !this.props.disabled && this.renderSelectGroupModal() }
       </React.Fragment>
     );