* This fixes an issue where we need to use id to get the name. * This fixes support for the singleusergroup plugin, by using id instead of name when saving included groups. Similar to what becky did for members [1] and same for when deleting included group. * Adds more tests to make sure we don't have problems saving / deleting included groups. [1] I588b525fd40c6dbef0a372d103f4cca3ea0466fd Bug: Issue 9000 Change-Id: Icaeee771cf09dabc345860a836157db93ef21d33
		
			
				
	
	
		
			280 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * @license
 | 
						|
 * Copyright (C) 2017 The Android Open Source Project
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
(function() {
 | 
						|
  'use strict';
 | 
						|
 | 
						|
  const SUGGESTIONS_LIMIT = 15;
 | 
						|
  const SAVING_ERROR_TEXT = 'Group may not exist, or you may not have '+
 | 
						|
      'permission to add it';
 | 
						|
 | 
						|
  const URL_REGEX = '^(?:[a-z]+:)?//';
 | 
						|
 | 
						|
  Polymer({
 | 
						|
    is: 'gr-group-members',
 | 
						|
 | 
						|
    properties: {
 | 
						|
      groupId: Number,
 | 
						|
      _groupMemberSearchId: String,
 | 
						|
      _groupMemberSearchName: String,
 | 
						|
      _includedGroupSearchId: String,
 | 
						|
      _includedGroupSearchName: String,
 | 
						|
      _loading: {
 | 
						|
        type: Boolean,
 | 
						|
        value: true,
 | 
						|
      },
 | 
						|
      _groupName: String,
 | 
						|
      _groupMembers: Object,
 | 
						|
      _includedGroups: Object,
 | 
						|
      _itemName: String,
 | 
						|
      _itemType: String,
 | 
						|
      _queryMembers: {
 | 
						|
        type: Function,
 | 
						|
        value() {
 | 
						|
          return this._getAccountSuggestions.bind(this);
 | 
						|
        },
 | 
						|
      },
 | 
						|
      _queryIncludedGroup: {
 | 
						|
        type: Function,
 | 
						|
        value() {
 | 
						|
          return this._getGroupSuggestions.bind(this);
 | 
						|
        },
 | 
						|
      },
 | 
						|
      _groupOwner: {
 | 
						|
        type: Boolean,
 | 
						|
        value: false,
 | 
						|
      },
 | 
						|
      _isAdmin: {
 | 
						|
        type: Boolean,
 | 
						|
        value: false,
 | 
						|
      },
 | 
						|
    },
 | 
						|
 | 
						|
    behaviors: [
 | 
						|
      Gerrit.BaseUrlBehavior,
 | 
						|
      Gerrit.URLEncodingBehavior,
 | 
						|
    ],
 | 
						|
 | 
						|
    attached() {
 | 
						|
      this._loadGroupDetails();
 | 
						|
 | 
						|
      this.fire('title-change', {title: 'Members'});
 | 
						|
    },
 | 
						|
 | 
						|
    _loadGroupDetails() {
 | 
						|
      if (!this.groupId) { return; }
 | 
						|
 | 
						|
      const promises = [];
 | 
						|
 | 
						|
      const errFn = response => {
 | 
						|
        this.fire('page-error', {response});
 | 
						|
      };
 | 
						|
 | 
						|
      return this.$.restAPI.getGroupConfig(this.groupId, errFn)
 | 
						|
          .then(config => {
 | 
						|
            if (!config || !config.name) { return Promise.resolve(); }
 | 
						|
 | 
						|
            this._groupName = config.name;
 | 
						|
 | 
						|
            promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
 | 
						|
              this._isAdmin = isAdmin ? true : false;
 | 
						|
            }));
 | 
						|
 | 
						|
            promises.push(this.$.restAPI.getIsGroupOwner(config.name)
 | 
						|
                .then(isOwner => {
 | 
						|
                  this._groupOwner = isOwner ? true : false;
 | 
						|
                }));
 | 
						|
 | 
						|
            promises.push(this.$.restAPI.getGroupMembers(config.name).then(
 | 
						|
                members => {
 | 
						|
                  this._groupMembers = members;
 | 
						|
                }));
 | 
						|
 | 
						|
            promises.push(this.$.restAPI.getIncludedGroup(config.name)
 | 
						|
                .then(includedGroup => {
 | 
						|
                  this._includedGroups = includedGroup;
 | 
						|
                }));
 | 
						|
 | 
						|
            return Promise.all(promises).then(() => {
 | 
						|
              this._loading = false;
 | 
						|
            });
 | 
						|
          });
 | 
						|
    },
 | 
						|
 | 
						|
    _computeLoadingClass(loading) {
 | 
						|
      return loading ? 'loading' : '';
 | 
						|
    },
 | 
						|
 | 
						|
    _isLoading() {
 | 
						|
      return this._loading || this._loading === undefined;
 | 
						|
    },
 | 
						|
 | 
						|
    _computeGroupUrl(url) {
 | 
						|
      if (!url) { return; }
 | 
						|
 | 
						|
      const r = new RegExp(URL_REGEX, 'i');
 | 
						|
      if (r.test(url)) {
 | 
						|
        return url;
 | 
						|
      }
 | 
						|
 | 
						|
      // For GWT compatibility
 | 
						|
      if (url.startsWith('#')) {
 | 
						|
        return this.getBaseUrl() + url.slice(1);
 | 
						|
      }
 | 
						|
      return this.getBaseUrl() + url;
 | 
						|
    },
 | 
						|
 | 
						|
    _handleSavingGroupMember() {
 | 
						|
      return this.$.restAPI.saveGroupMembers(this._groupName,
 | 
						|
          this._groupMemberSearchId).then(config => {
 | 
						|
            if (!config) {
 | 
						|
              return;
 | 
						|
            }
 | 
						|
            this.$.restAPI.getGroupMembers(this._groupName).then(members => {
 | 
						|
              this._groupMembers = members;
 | 
						|
            });
 | 
						|
            this._groupMemberSearchName = '';
 | 
						|
            this._groupMemberSearchId = '';
 | 
						|
          });
 | 
						|
    },
 | 
						|
 | 
						|
    _handleDeleteConfirm() {
 | 
						|
      this.$.overlay.close();
 | 
						|
      if (this._itemType === 'member') {
 | 
						|
        return this.$.restAPI.deleteGroupMembers(this._groupName,
 | 
						|
            this._itemId)
 | 
						|
            .then(itemDeleted => {
 | 
						|
              if (itemDeleted.status === 204) {
 | 
						|
                this.$.restAPI.getGroupMembers(this._groupName)
 | 
						|
                    .then(members => {
 | 
						|
                      this._groupMembers = members;
 | 
						|
                    });
 | 
						|
              }
 | 
						|
            });
 | 
						|
      } else if (this._itemType === 'includedGroup') {
 | 
						|
        return this.$.restAPI.deleteIncludedGroup(this._groupName,
 | 
						|
            this._itemId)
 | 
						|
            .then(itemDeleted => {
 | 
						|
              if (itemDeleted.status === 204 || itemDeleted.status === 205) {
 | 
						|
                this.$.restAPI.getIncludedGroup(this._groupName)
 | 
						|
                    .then(includedGroup => {
 | 
						|
                      this._includedGroups = includedGroup;
 | 
						|
                    });
 | 
						|
              }
 | 
						|
            });
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    _handleConfirmDialogCancel() {
 | 
						|
      this.$.overlay.close();
 | 
						|
    },
 | 
						|
 | 
						|
    _handleDeleteMember(e) {
 | 
						|
      const id = e.model.get('item._account_id');
 | 
						|
      const name = e.model.get('item.name');
 | 
						|
      const username = e.model.get('item.username');
 | 
						|
      const email = e.model.get('item.email');
 | 
						|
      const item = username || name || email || id;
 | 
						|
      if (!item) {
 | 
						|
        return '';
 | 
						|
      }
 | 
						|
      this._itemName = item;
 | 
						|
      this._itemId = id;
 | 
						|
      this._itemType = 'member';
 | 
						|
      this.$.overlay.open();
 | 
						|
    },
 | 
						|
 | 
						|
    _handleSavingIncludedGroups() {
 | 
						|
      return this.$.restAPI.saveIncludedGroup(this._groupName,
 | 
						|
          this._includedGroupSearchId, err => {
 | 
						|
            if (err.status === 404) {
 | 
						|
              this.dispatchEvent(new CustomEvent('show-alert', {
 | 
						|
                detail: {message: SAVING_ERROR_TEXT},
 | 
						|
                bubbles: true,
 | 
						|
              }));
 | 
						|
              return err;
 | 
						|
            }
 | 
						|
            throw Error(err.statusText);
 | 
						|
          })
 | 
						|
          .then(config => {
 | 
						|
            if (!config) {
 | 
						|
              return;
 | 
						|
            }
 | 
						|
            this.$.restAPI.getIncludedGroup(this._groupName)
 | 
						|
                .then(includedGroup => {
 | 
						|
                  this._includedGroups = includedGroup;
 | 
						|
                });
 | 
						|
            this._includedGroupSearchName = '';
 | 
						|
            this._includedGroupSearchId = '';
 | 
						|
          });
 | 
						|
    },
 | 
						|
 | 
						|
    _handleDeleteIncludedGroup(e) {
 | 
						|
      const id = decodeURIComponent(e.model.get('item.id'));
 | 
						|
      const name = e.model.get('item.name');
 | 
						|
      const item = name || id;
 | 
						|
      if (!item) { return ''; }
 | 
						|
      this._itemName = item;
 | 
						|
      this._itemId = id;
 | 
						|
      this._itemType = 'includedGroup';
 | 
						|
      this.$.overlay.open();
 | 
						|
    },
 | 
						|
 | 
						|
    _getAccountSuggestions(input) {
 | 
						|
      if (input.length === 0) { return Promise.resolve([]); }
 | 
						|
      return this.$.restAPI.getSuggestedAccounts(
 | 
						|
          input, SUGGESTIONS_LIMIT).then(accounts => {
 | 
						|
            const accountSuggestions = [];
 | 
						|
            let nameAndEmail;
 | 
						|
            if (!accounts) { return []; }
 | 
						|
            for (const key in accounts) {
 | 
						|
              if (!accounts.hasOwnProperty(key)) { continue; }
 | 
						|
              if (accounts[key].email !== undefined) {
 | 
						|
                nameAndEmail = accounts[key].name +
 | 
						|
                  ' <' + accounts[key].email + '>';
 | 
						|
              } else {
 | 
						|
                nameAndEmail = accounts[key].name;
 | 
						|
              }
 | 
						|
              accountSuggestions.push({
 | 
						|
                name: nameAndEmail,
 | 
						|
                value: accounts[key]._account_id,
 | 
						|
              });
 | 
						|
            }
 | 
						|
            return accountSuggestions;
 | 
						|
          });
 | 
						|
    },
 | 
						|
 | 
						|
    _getGroupSuggestions(input) {
 | 
						|
      return this.$.restAPI.getSuggestedGroups(input)
 | 
						|
          .then(response => {
 | 
						|
            const groups = [];
 | 
						|
            for (const key in response) {
 | 
						|
              if (!response.hasOwnProperty(key)) { continue; }
 | 
						|
              groups.push({
 | 
						|
                name: key,
 | 
						|
                value: decodeURIComponent(response[key].id),
 | 
						|
              });
 | 
						|
            }
 | 
						|
            return groups;
 | 
						|
          });
 | 
						|
    },
 | 
						|
 | 
						|
    _computeHideItemClass(owner, admin) {
 | 
						|
      return admin || owner ? '' : 'canModify';
 | 
						|
    },
 | 
						|
  });
 | 
						|
})();
 |