blob: c04df74f57759081633668577722b9afb88d069d [file] [log] [blame]
// 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';
Polymer({
is: 'gr-edit-controls',
properties: {
change: Object,
/**
* TODO(kaspern): by default, the RESTORE action should be hidden in the
* file-list as it is a per-file action only. Remove this default value
* when the Actions dictionary is moved to a shared constants file and
* use the hiddenActions property in the parent component.
*/
hiddenActions: {
type: Array,
value() { return [GrEditConstants.Actions.RESTORE.id]; },
},
_actions: {
type: Array,
value() { return Object.values(GrEditConstants.Actions); },
},
_path: {
type: String,
value: '',
},
_newPath: {
type: String,
value: '',
},
_query: {
type: Function,
value() {
return this._queryFiles.bind(this);
},
},
},
behaviors: [
Gerrit.PatchSetBehavior,
],
_handleTap(e) {
e.preventDefault();
const action = Polymer.dom(e).localTarget.id;
switch (action) {
case GrEditConstants.Actions.EDIT.id:
this.openEditDialog();
return;
case GrEditConstants.Actions.DELETE.id:
this.openDeleteDialog();
return;
case GrEditConstants.Actions.RENAME.id:
this.openRenameDialog();
return;
case GrEditConstants.Actions.RESTORE.id:
this.openRestoreDialog();
return;
}
},
openEditDialog(opt_path) {
if (opt_path) { this._path = opt_path; }
return this._showDialog(this.$.editDialog);
},
openDeleteDialog(opt_path) {
if (opt_path) { this._path = opt_path; }
return this._showDialog(this.$.deleteDialog);
},
openRenameDialog(opt_path) {
if (opt_path) { this._path = opt_path; }
return this._showDialog(this.$.renameDialog);
},
openRestoreDialog(opt_path) {
if (opt_path) { this._path = opt_path; }
return this._showDialog(this.$.restoreDialog);
},
/**
* Given a path string, checks that it is a valid file path.
* @param {string} path
* @return {boolean}
*/
_isValidPath(path) {
// Double negation needed for strict boolean return type.
return !!path.length && !path.endsWith('/');
},
_computeRenameDisabled(path, newPath) {
return this._isValidPath(path) && this._isValidPath(newPath);
},
/**
* Given a dom event, gets the dialog that lies along this event path.
* @param {!Event} e
* @return {!Element}
*/
_getDialogFromEvent(e) {
return Polymer.dom(e).path.find(element => {
if (!element.classList) { return false; }
return element.classList.contains('dialog');
});
},
_showDialog(dialog) {
return this.$.overlay.open().then(() => {
dialog.classList.toggle('invisible', false);
const autocomplete = dialog.querySelector('gr-autocomplete');
if (autocomplete) { autocomplete.focus(); }
this.async(() => { this.$.overlay.center(); }, 1);
});
},
_closeDialog(dialog, clearInputs) {
if (clearInputs) {
// Dialog may have autocompletes and plain inputs -- as these have
// different properties representing their bound text, it is easier to
// just make two separate queries.
dialog.querySelectorAll('gr-autocomplete')
.forEach(input => { input.text = ''; });
dialog.querySelectorAll('input')
.forEach(input => { input.bindValue = ''; });
}
dialog.classList.toggle('invisible', true);
return this.$.overlay.close();
},
_handleDialogCancel(e) {
this._closeDialog(this._getDialogFromEvent(e));
},
_handleEditConfirm(e) {
const url = Gerrit.Nav.getEditUrlForDiff(this.change, this._path);
Gerrit.Nav.navigateToRelativeUrl(url);
this._closeDialog(this._getDialogFromEvent(e), true);
},
_handleDeleteConfirm(e) {
this.$.restAPI.deleteFileInChangeEdit(this.change._number, this._path)
.then(res => {
if (!res.ok) { return; }
this._closeDialog(this._getDialogFromEvent(e), true);
Gerrit.Nav.navigateToChange(this.change);
});
},
_handleRestoreConfirm(e) {
this.$.restAPI.restoreFileInChangeEdit(this.change._number, this._path)
.then(res => {
if (!res.ok) { return; }
this._closeDialog(this._getDialogFromEvent(e), true);
Gerrit.Nav.navigateToChange(this.change);
});
},
_handleRenameConfirm(e) {
return this.$.restAPI.renameFileInChangeEdit(this.change._number,
this._path, this._newPath).then(res => {
if (!res.ok) { return; }
this._closeDialog(this._getDialogFromEvent(e), true);
Gerrit.Nav.navigateToChange(this.change);
});
},
_queryFiles(input) {
return this.$.restAPI.queryChangeFiles(this.change._number,
this.EDIT_NAME, input).then(res => res.map(file => {
return {name: file};
}));
},
_computeIsInvisible(id, hiddenActions) {
return hiddenActions.includes(id) ? 'invisible' : '';
},
});
})();