blob: 49cd8ead8707eca4ada1ea8c44ac54265cf89951 [file] [log] [blame]
/**
* @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.
*/
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
import '../../../styles/gr-form-styles.js';
import '../../../styles/gr-subpage-styles.js';
import '../../../styles/shared-styles.js';
import '../../shared/gr-autocomplete/gr-autocomplete.js';
import '../../shared/gr-copy-clipboard/gr-copy-clipboard.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../../shared/gr-select/gr-select.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-group_html.js';
const INTERNAL_GROUP_REGEX = /^[\da-f]{40}$/;
const OPTIONS = {
submitFalse: {
value: false,
label: 'False',
},
submitTrue: {
value: true,
label: 'True',
},
};
/**
* @extends PolymerElement
*/
class GrGroup extends GestureEventListeners(
LegacyElementMixin(PolymerElement)) {
static get template() { return htmlTemplate; }
static get is() { return 'gr-group'; }
/**
* Fired when the group name changes.
*
* @event name-changed
*/
static get properties() {
return {
groupId: Number,
_rename: {
type: Boolean,
value: false,
},
_groupIsInternal: Boolean,
_description: {
type: Boolean,
value: false,
},
_owner: {
type: Boolean,
value: false,
},
_options: {
type: Boolean,
value: false,
},
_loading: {
type: Boolean,
value: true,
},
/** @type {?} */
_groupConfig: Object,
_groupConfigOwner: String,
_groupName: Object,
_groupOwner: {
type: Boolean,
value: false,
},
_submitTypes: {
type: Array,
value() {
return Object.values(OPTIONS);
},
},
_query: {
type: Function,
value() {
return this._getGroupSuggestions.bind(this);
},
},
_isAdmin: {
type: Boolean,
value: false,
},
};
}
static get observers() {
return [
'_handleConfigName(_groupConfig.name)',
'_handleConfigOwner(_groupConfig.owner, _groupConfigOwner)',
'_handleConfigDescription(_groupConfig.description)',
'_handleConfigOptions(_groupConfig.options.visible_to_all)',
];
}
/** @override */
attached() {
super.attached();
this._loadGroup();
}
_loadGroup() {
if (!this.groupId) { return; }
const promises = [];
const errFn = response => {
this.dispatchEvent(new CustomEvent('page-error', {
detail: {response},
composed: true, bubbles: true,
}));
};
return this.$.restAPI.getGroupConfig(this.groupId, errFn)
.then(config => {
if (!config || !config.name) { return Promise.resolve(); }
this._groupName = config.name;
this._groupIsInternal = !!config.id.match(INTERNAL_GROUP_REGEX);
promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
this._isAdmin = !!isAdmin;
}));
promises.push(this.$.restAPI.getIsGroupOwner(config.name)
.then(isOwner => {
this._groupOwner = !!isOwner;
}));
// If visible to all is undefined, set to false. If it is defined
// as false, setting to false is fine. If any optional values
// are added with a default of true, then this would need to be an
// undefined check and not a truthy/falsy check.
if (!config.options.visible_to_all) {
config.options.visible_to_all = false;
}
this._groupConfig = config;
this.dispatchEvent(new CustomEvent('title-change', {
detail: {title: config.name},
composed: true, bubbles: true,
}));
return Promise.all(promises).then(() => {
this._loading = false;
});
});
}
_computeLoadingClass(loading) {
return loading ? 'loading' : '';
}
_isLoading() {
return this._loading || this._loading === undefined;
}
_handleSaveName() {
return this.$.restAPI.saveGroupName(this.groupId, this._groupConfig.name)
.then(config => {
if (config.status === 200) {
this._groupName = this._groupConfig.name;
this.dispatchEvent(new CustomEvent('name-changed', {
detail: {name: this._groupConfig.name,
external: this._groupIsExtenral},
composed: true, bubbles: true,
}));
this._rename = false;
}
});
}
_handleSaveOwner() {
let owner = this._groupConfig.owner;
if (this._groupConfigOwner) {
owner = decodeURIComponent(this._groupConfigOwner);
}
return this.$.restAPI.saveGroupOwner(this.groupId,
owner).then(config => {
this._owner = false;
});
}
_handleSaveDescription() {
return this.$.restAPI.saveGroupDescription(this.groupId,
this._groupConfig.description).then(config => {
this._description = false;
});
}
_handleSaveOptions() {
const visible = this._groupConfig.options.visible_to_all;
const options = {visible_to_all: visible};
return this.$.restAPI.saveGroupOptions(this.groupId,
options).then(config => {
this._options = false;
});
}
_handleConfigName() {
if (this._isLoading()) { return; }
this._rename = true;
}
_handleConfigOwner() {
if (this._isLoading()) { return; }
this._owner = true;
}
_handleConfigDescription() {
if (this._isLoading()) { return; }
this._description = true;
}
_handleConfigOptions() {
if (this._isLoading()) { return; }
this._options = true;
}
_computeHeaderClass(configChanged) {
return configChanged ? 'edited' : '';
}
_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;
});
}
_computeGroupDisabled(owner, admin, groupIsInternal) {
return !(groupIsInternal && (admin || owner));
}
_getGroupUUID(id) {
if (!id) return;
return id.match(INTERNAL_GROUP_REGEX) ? id : decodeURIComponent(id);
}
}
customElements.define(GrGroup.is, GrGroup);