blob: b8960e85eff05a98f3c029481f5d9f6ccab1b19f [file] [log] [blame]
/**
* @license
* Copyright (C) 2016 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 '../../../scripts/bundled-polymer.js';
import '@polymer/iron-input/iron-input.js';
import '../../shared/gr-autocomplete/gr-autocomplete.js';
import '../../shared/gr-button/gr-button.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../../../styles/gr-form-styles.js';
import '../../../styles/shared-styles.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.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-watched-projects-editor_html.js';
const NOTIFICATION_TYPES = [
{name: 'Changes', key: 'notify_new_changes'},
{name: 'Patches', key: 'notify_new_patch_sets'},
{name: 'Comments', key: 'notify_all_comments'},
{name: 'Submits', key: 'notify_submitted_changes'},
{name: 'Abandons', key: 'notify_abandoned_changes'},
];
/** @extends Polymer.Element */
class GrWatchedProjectsEditor extends GestureEventListeners(
LegacyElementMixin(
PolymerElement)) {
static get template() { return htmlTemplate; }
static get is() { return 'gr-watched-projects-editor'; }
static get properties() {
return {
hasUnsavedChanges: {
type: Boolean,
value: false,
notify: true,
},
_projects: Array,
_projectsToRemove: {
type: Array,
value() { return []; },
},
_query: {
type: Function,
value() {
return this._getProjectSuggestions.bind(this);
},
},
};
}
loadData() {
return this.$.restAPI.getWatchedProjects().then(projs => {
this._projects = projs;
});
}
save() {
let deletePromise;
if (this._projectsToRemove.length) {
deletePromise = this.$.restAPI.deleteWatchedProjects(
this._projectsToRemove);
} else {
deletePromise = Promise.resolve();
}
return deletePromise
.then(() => this.$.restAPI.saveWatchedProjects(this._projects))
.then(projects => {
this._projects = projects;
this._projectsToRemove = [];
this.hasUnsavedChanges = false;
});
}
_getTypes() {
return NOTIFICATION_TYPES;
}
_getTypeCount() {
return this._getTypes().length;
}
_computeCheckboxChecked(project, key) {
return project.hasOwnProperty(key);
}
_getProjectSuggestions(input) {
return this.$.restAPI.getSuggestedProjects(input)
.then(response => {
const projects = [];
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
projects.push({
name: key,
value: response[key],
});
}
return projects;
});
}
_handleRemoveProject(e) {
const el = dom(e).localTarget;
const index = parseInt(el.getAttribute('data-index'), 10);
const project = this._projects[index];
this.splice('_projects', index, 1);
this.push('_projectsToRemove', project);
this.hasUnsavedChanges = true;
}
_canAddProject(project, text, filter) {
if ((!project || !project.id) && !text) { return false; }
// This will only be used if not using the auto complete
if (!project && text) { return true; }
// Check if the project with filter is already in the list. Compare
// filters using == to coalesce null and undefined.
for (let i = 0; i < this._projects.length; i++) {
if (this._projects[i].project === project.id &&
this._projects[i].filter == filter) {
return false;
}
}
return true;
}
_getNewProjectIndex(name, filter) {
let i;
for (i = 0; i < this._projects.length; i++) {
if (this._projects[i].project > name ||
(this._projects[i].project === name &&
this._projects[i].filter > filter)) {
break;
}
}
return i;
}
_handleAddProject() {
const newProject = this.$.newProject.value;
const newProjectName = this.$.newProject.text;
const filter = this.$.newFilter.value || null;
if (!this._canAddProject(newProject, newProjectName, filter)) { return; }
const insertIndex = this._getNewProjectIndex(newProjectName, filter);
this.splice('_projects', insertIndex, 0, {
project: newProjectName,
filter,
_is_local: true,
});
this.$.newProject.clear();
this.$.newFilter.bindValue = '';
this.hasUnsavedChanges = true;
}
_handleCheckboxChange(e) {
const el = dom(e).localTarget;
const index = parseInt(el.getAttribute('data-index'), 10);
const key = el.getAttribute('data-key');
const checked = el.checked;
this.set(['_projects', index, key], !!checked);
this.hasUnsavedChanges = true;
}
_handleNotifCellClick(e) {
const checkbox = dom(e.target).querySelector('input');
if (checkbox) { checkbox.click(); }
}
}
customElements.define(GrWatchedProjectsEditor.is, GrWatchedProjectsEditor);