Convert files to typescript

The change converts the following files to typescript:

* elements/admin/gr-repo-commands/gr-repo-commands.ts

Change-Id: I5ee229c0ad26332e1946a039ae42015f85b1f009
This commit is contained in:
Ben Rohlfs
2020-09-14 22:11:35 +02:00
parent dc03ea6681
commit bc2a26d82f
4 changed files with 166 additions and 97 deletions

View File

@@ -132,8 +132,10 @@ export class GrCreateChangeDialog extends GestureEventListeners(
this.canCreate = !!branch && !!subject;
}
handleCreateChange() {
if (!this.repoName || !this.branch || !this.subject) return;
handleCreateChange(): Promise<void> {
if (!this.repoName || !this.branch || !this.subject) {
return Promise.resolve();
}
const isPrivate = this.$.privateChangeCheckBox.checked;
const isWip = true;
return this.$.restAPI

View File

@@ -14,108 +14,146 @@
* 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 '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js';
import '../../plugins/gr-endpoint-param/gr-endpoint-param.js';
import '../../shared/gr-dialog/gr-dialog.js';
import '../../shared/gr-overlay/gr-overlay.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-create-change-dialog/gr-create-change-dialog.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-repo-commands_html.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import '../../../styles/gr-form-styles';
import '../../../styles/gr-subpage-styles';
import '../../../styles/shared-styles';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../../plugins/gr-endpoint-param/gr-endpoint-param';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-overlay/gr-overlay';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
import '../gr-create-change-dialog/gr-create-change-dialog';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-repo-commands_html';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {customElement, property} from '@polymer/decorators';
import {
ErrorCallback,
RestApiService,
} from '../../../services/services/gr-rest-api/gr-rest-api';
import {
BranchName,
ConfigInfo,
PatchSetNum,
RepoName,
} from '../../../types/common';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {GrCreateChangeDialog} from '../gr-create-change-dialog/gr-create-change-dialog';
const GC_MESSAGE = 'Garbage collection completed successfully.';
const CONFIG_BRANCH = 'refs/meta/config';
const CONFIG_BRANCH = 'refs/meta/config' as BranchName;
const CONFIG_PATH = 'project.config';
const EDIT_CONFIG_SUBJECT = 'Edit Repo Config';
const INITIAL_PATCHSET = 1;
const INITIAL_PATCHSET = 1 as PatchSetNum;
const CREATE_CHANGE_FAILED_MESSAGE = 'Failed to create change.';
const CREATE_CHANGE_SUCCEEDED_MESSAGE = 'Navigating to change';
/**
* @extends PolymerElement
*/
class GrRepoCommands extends GestureEventListeners(
LegacyElementMixin(PolymerElement)) {
static get template() { return htmlTemplate; }
export interface GrRepoCommands {
$: {
restAPI: RestApiService & Element;
createChangeOverlay: GrOverlay;
createNewChangeModal: GrCreateChangeDialog;
};
}
static get is() { return 'gr-repo-commands'; }
static get properties() {
return {
params: Object,
repo: String,
_loading: {
type: Boolean,
value: true,
},
/** @type {?} */
_repoConfig: Object,
_canCreate: Boolean,
// states
_creatingChange: Boolean,
_editingConfig: Boolean,
_runningGC: Boolean,
};
@customElement('gr-repo-commands')
export class GrRepoCommands extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
) {
static get template() {
return htmlTemplate;
}
// This is a required property. Without `repo` being set the component is not
// useful. Thus using !.
@property({type: String})
repo!: RepoName;
@property({type: Boolean})
_loading = true;
@property({type: Object})
_repoConfig?: ConfigInfo;
@property({type: Boolean})
_canCreate = false;
@property({type: Boolean})
_creatingChange = false;
@property({type: Boolean})
_editingConfig = false;
@property({type: Boolean})
_runningGC = false;
/** @override */
attached() {
super.attached();
this._loadRepo();
this.dispatchEvent(new CustomEvent('title-change', {
detail: {title: 'Repo Commands'},
composed: true, bubbles: true,
}));
this.dispatchEvent(
new CustomEvent('title-change', {
detail: {title: 'Repo Commands'},
composed: true,
bubbles: true,
})
);
}
_loadRepo() {
if (!this.repo) { return Promise.resolve(); }
const errFn = response => {
this.dispatchEvent(new CustomEvent('page-error', {
detail: {response},
composed: true, bubbles: true,
}));
const errFn: ErrorCallback = response => {
// Do not process the error, if the component is not attached to the DOM
// anymore, which at least in tests can happen.
if (!this.isConnected) return;
this.dispatchEvent(
new CustomEvent('page-error', {
detail: {response},
composed: true,
bubbles: true,
})
);
};
return this.$.restAPI.getProjectConfig(this.repo, errFn)
.then(config => {
if (!config) { return Promise.resolve(); }
this._repoConfig = config;
this._loading = false;
});
this.$.restAPI.getProjectConfig(this.repo, errFn).then(config => {
if (!config) return;
// Do not process the response, if the component is not attached to the
// DOM anymore, which at least in tests can happen.
if (!this.isConnected) return;
this._repoConfig = config;
this._loading = false;
});
}
_computeLoadingClass(loading) {
_computeLoadingClass(loading: boolean) {
return loading ? 'loading' : '';
}
_isLoading() {
return this._loading || this._loading === undefined;
return this._loading;
}
_handleRunningGC() {
this._runningGC = true;
return this.$.restAPI.runRepoGC(this.repo).then(response => {
if (response.status === 200) {
this.dispatchEvent(new CustomEvent(
'show-alert',
{detail: {message: GC_MESSAGE}, bubbles: true, composed: true}));
}
})
.finally(() => {
this._runningGC = false;
});
return this.$.restAPI
.runRepoGC(this.repo)
.then(response => {
if (response?.status === 200) {
this.dispatchEvent(
new CustomEvent('show-alert', {
detail: {message: GC_MESSAGE},
bubbles: true,
composed: true,
})
);
}
})
.finally(() => {
this._runningGC = false;
});
}
_createNewChange() {
@@ -124,10 +162,9 @@ class GrRepoCommands extends GestureEventListeners(
_handleCreateChange() {
this._creatingChange = true;
this.$.createNewChangeModal.handleCreateChange()
.finally(() => {
this._creatingChange = false;
});
this.$.createNewChangeModal.handleCreateChange().finally(() => {
this._creatingChange = false;
});
this._handleCloseCreateChange();
}
@@ -135,24 +172,47 @@ class GrRepoCommands extends GestureEventListeners(
this.$.createChangeOverlay.close();
}
/**
* Returns a Promise for testing.
*/
_handleEditRepoConfig() {
this._editingConfig = true;
return this.$.restAPI.createChange(this.repo, CONFIG_BRANCH,
EDIT_CONFIG_SUBJECT, undefined, false, true).then(change => {
const message = change ?
CREATE_CHANGE_SUCCEEDED_MESSAGE :
CREATE_CHANGE_FAILED_MESSAGE;
this.dispatchEvent(new CustomEvent('show-alert',
{detail: {message}, bubbles: true, composed: true}));
if (!change) { return; }
return this.$.restAPI
.createChange(
this.repo,
CONFIG_BRANCH,
EDIT_CONFIG_SUBJECT,
undefined,
false,
true
)
.then(change => {
const message = change
? CREATE_CHANGE_SUCCEEDED_MESSAGE
: CREATE_CHANGE_FAILED_MESSAGE;
this.dispatchEvent(
new CustomEvent('show-alert', {
detail: {message},
bubbles: true,
composed: true,
})
);
if (!change) {
return;
}
GerritNav.navigateToRelativeUrl(GerritNav.getEditUrlForDiff(
change, CONFIG_PATH, INITIAL_PATCHSET));
})
.finally(() => {
this._editingConfig = false;
});
GerritNav.navigateToRelativeUrl(
GerritNav.getEditUrlForDiff(change, CONFIG_PATH, INITIAL_PATCHSET)
);
})
.finally(() => {
this._editingConfig = false;
});
}
}
customElements.define(GrRepoCommands.is, GrRepoCommands);
declare global {
interface HTMLElementTagNameMap {
'gr-repo-commands': GrRepoCommands;
}
}

View File

@@ -28,10 +28,11 @@ suite('gr-repo-commands tests', () => {
setup(() => {
element = basicFixture.instantiate();
repoStub = sinon.stub(
element.$.restAPI,
'getProjectConfig')
.callsFake(() => Promise.resolve({}));
// Note that this probably does not achieve what it is supposed to, because
// getProjectConfig() is called as soon as the element is attached, so
// stubbing it here has not effect anymore.
repoStub = sinon.stub(element.$.restAPI, 'getProjectConfig')
.returns(Promise.resolve({}));
});
suite('create new change dialog', () => {
@@ -72,6 +73,7 @@ suite('gr-repo-commands tests', () => {
sinon.stub(GerritNav, 'navigateToRelativeUrl');
handleSpy = sinon.spy(element, '_handleEditRepoConfig');
alertStub = sinon.stub();
element.repo = 'test';
element.addEventListener('show-alert', alertStub);
});

View File

@@ -645,4 +645,9 @@ export interface RestApiService {
groupName: GroupId,
includedGroup: GroupId
): Promise<Response>;
runRepoGC(
repo: RepoName,
errFn?: ErrorCallback
): Promise<Response | undefined>;
}