Merge changes I49159738,I0358f77a
* changes:
Convert gr-create-group-dialog to lit
Convert gr-create-group-dialog_test.js to typescript
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.ts b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.ts
index ea70d7e..83063a1 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.ts
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.ts
@@ -185,4 +185,8 @@
computeLoadingClass(loading: boolean) {
return loading ? 'loading' : '';
}
+
+ _handleHasNewGroupName() {
+ this._hasNewGroupName = !!this.$.createNewModal.name;
+ }
}
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_html.ts b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_html.ts
index 91863a9..fdde399 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_html.ts
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_html.ts
@@ -70,8 +70,8 @@
<div class="header" slot="header">Create Group</div>
<div class="main" slot="main">
<gr-create-group-dialog
- has-new-group-name="{{_hasNewGroupName}}"
id="createNewModal"
+ on-has-new-group-name="_handleHasNewGroupName"
></gr-create-group-dialog>
</div>
</gr-dialog>
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.ts b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.ts
index 180e60a..ce07804 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.ts
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.ts
@@ -17,61 +17,95 @@
import '@polymer/iron-input/iron-input';
import '../../../styles/gr-form-styles';
import '../../../styles/shared-styles';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {htmlTemplate} from './gr-create-group-dialog_html';
import {encodeURL, getBaseUrl} from '../../../utils/url-util';
import {page} from '../../../utils/page-wrapper-utils';
-import {customElement, property, observe} from '@polymer/decorators';
import {GroupName} from '../../../types/common';
import {appContext} from '../../../services/app-context';
-
-@customElement('gr-create-group-dialog')
-export class GrCreateGroupDialog extends PolymerElement {
- static get template() {
- return htmlTemplate;
- }
-
- @property({type: Boolean, notify: true})
- hasNewGroupName = false;
-
- @property({type: String})
- _name: GroupName | '' = '';
-
- @property({type: Boolean})
- _groupCreated = false;
-
- private readonly restApiService = appContext.restApiService;
-
- _computeGroupUrl(groupId: string) {
- return getBaseUrl() + '/admin/groups/' + encodeURL(groupId, true);
- }
-
- @observe('_name')
- _updateGroupName(name: string) {
- this.hasNewGroupName = !!name;
- }
-
- override focus() {
- this.shadowRoot?.querySelector('input')?.focus();
- }
-
- handleCreateGroup() {
- const name = this._name as GroupName;
- return this.restApiService.createGroup({name}).then(groupRegistered => {
- if (groupRegistered.status !== 201) {
- return;
- }
- this._groupCreated = true;
- return this.restApiService.getGroupConfig(name).then(group => {
- // TODO(TS): should group always defined ?
- page.show(this._computeGroupUrl(String(group!.group_id!)));
- });
- });
- }
-}
+import {formStyles} from '../../../styles/gr-form-styles';
+import {sharedStyles} from '../../../styles/shared-styles';
+import {LitElement, PropertyValues, css, html} from 'lit';
+import {customElement, query, property} from 'lit/decorators';
+import {BindValueChangeEvent} from '../../../types/events';
+import {fireEvent} from '../../../utils/event-util';
declare global {
interface HTMLElementTagNameMap {
'gr-create-group-dialog': GrCreateGroupDialog;
}
}
+
+@customElement('gr-create-group-dialog')
+export class GrCreateGroupDialog extends LitElement {
+ @query('input') private input!: HTMLInputElement;
+
+ @property({type: String})
+ name: GroupName | '' = '';
+
+ private readonly restApiService = appContext.restApiService;
+
+ static override get styles() {
+ return [
+ formStyles,
+ sharedStyles,
+ css`
+ :host {
+ display: inline-block;
+ }
+ input {
+ width: 20em;
+ }
+ `,
+ ];
+ }
+
+ override render() {
+ return html`
+ <div class="gr-form-styles">
+ <div id="form">
+ <section>
+ <span class="title">Group name</span>
+ <iron-input
+ .bindValue=${this.name}
+ @bind-value-changed=${this.handleGroupNameBindValueChanged}
+ >
+ <input />
+ </iron-input>
+ </section>
+ </div>
+ </div>
+ `;
+ }
+
+ override updated(changedProperties: PropertyValues) {
+ if (changedProperties.has('name')) {
+ this.updateGroupName();
+ }
+ }
+
+ private updateGroupName() {
+ fireEvent(this, 'has-new-group-name');
+ }
+
+ private computeGroupUrl(groupId: string) {
+ return getBaseUrl() + '/admin/groups/' + encodeURL(groupId, true);
+ }
+
+ override focus() {
+ this.input.focus();
+ }
+
+ handleCreateGroup() {
+ const name = this.name as GroupName;
+ return this.restApiService.createGroup({name}).then(groupRegistered => {
+ if (groupRegistered.status !== 201) return;
+ return this.restApiService.getGroupConfig(name).then(group => {
+ if (!group) return;
+ page.show(this.computeGroupUrl(String(group.group_id!)));
+ });
+ });
+ }
+
+ private handleGroupNameBindValueChanged(e: BindValueChangeEvent) {
+ this.name = e.detail.value as GroupName;
+ }
+}
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_html.ts b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_html.ts
deleted file mode 100644
index daf8780..0000000
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_html.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 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 {html} from '@polymer/polymer/lib/utils/html-tag';
-
-export const htmlTemplate = html`
- <style include="shared-styles">
- /* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
- </style>
- <style include="gr-form-styles">
- :host {
- display: inline-block;
- }
- input {
- width: 20em;
- }
- </style>
- <div class="gr-form-styles">
- <div id="form">
- <section>
- <span class="title">Group name</span>
- <iron-input bind-value="{{_name}}">
- <input is="iron-input" bind-value="{{_name}}" />
- </iron-input>
- </section>
- </div>
- </div>
-`;
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js
deleted file mode 100644
index 321f069..0000000
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @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 '../../../test/common-test-setup-karma.js';
-import './gr-create-group-dialog.js';
-import {page} from '../../../utils/page-wrapper-utils.js';
-import {stubRestApi} from '../../../test/test-utils.js';
-
-const basicFixture = fixtureFromElement('gr-create-group-dialog');
-
-suite('gr-create-group-dialog tests', () => {
- let element;
-
- const GROUP_NAME = 'test-group';
-
- setup(() => {
- element = basicFixture.instantiate();
- });
-
- test('name is updated correctly', async () => {
- assert.isFalse(element.hasNewGroupName);
-
- const inputEl = element.root.querySelector('iron-input');
- inputEl.bindValue = GROUP_NAME;
-
- await new Promise(resolve => setTimeout(resolve));
- assert.isTrue(element.hasNewGroupName);
- assert.deepEqual(element._name, GROUP_NAME);
- });
-
- test('test for redirecting to group on successful creation', async () => {
- stubRestApi('createGroup').returns(Promise.resolve({status: 201}));
- stubRestApi('getGroupConfig').returns(Promise.resolve({group_id: 551}));
-
- const showStub = sinon.stub(page, 'show');
- await element.handleCreateGroup();
- assert.isTrue(showStub.calledWith('/admin/groups/551'));
- });
-
- test('test for unsuccessful group creation', async () => {
- stubRestApi('createGroup').returns(Promise.resolve({status: 409}));
- stubRestApi('getGroupConfig').returns(Promise.resolve({group_id: 551}));
-
- const showStub = sinon.stub(page, 'show');
- await element.handleCreateGroup();
- assert.isFalse(showStub.called);
- });
-});
-
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.ts b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.ts
new file mode 100644
index 0000000..f84c76c
--- /dev/null
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.ts
@@ -0,0 +1,82 @@
+/**
+ * @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 '../../../test/common-test-setup-karma';
+import './gr-create-group-dialog';
+import {GrCreateGroupDialog} from './gr-create-group-dialog';
+import {page} from '../../../utils/page-wrapper-utils';
+import {
+ mockPromise,
+ queryAndAssert,
+ stubRestApi,
+} from '../../../test/test-utils';
+import {IronInputElement} from '@polymer/iron-input';
+import {GroupId} from '../../../types/common';
+
+const basicFixture = fixtureFromElement('gr-create-group-dialog');
+
+suite('gr-create-group-dialog tests', () => {
+ let element: GrCreateGroupDialog;
+
+ const GROUP_NAME = 'test-group';
+
+ setup(async () => {
+ element = basicFixture.instantiate();
+ await element.updateComplete;
+ });
+
+ test('name is updated correctly', async () => {
+ const promise = mockPromise();
+ element.addEventListener('has-new-group-name', () => {
+ promise.resolve();
+ });
+
+ const inputEl = queryAndAssert<IronInputElement>(element, 'iron-input');
+ inputEl.bindValue = GROUP_NAME;
+ inputEl.dispatchEvent(new Event('input', {bubbles: true, composed: true}));
+
+ await promise;
+
+ assert.deepEqual(element.name, GROUP_NAME);
+ });
+
+ test('test for redirecting to group on successful creation', async () => {
+ stubRestApi('createGroup').returns(
+ Promise.resolve({status: 201} as Response)
+ );
+ stubRestApi('getGroupConfig').returns(
+ Promise.resolve({id: 'testId551' as GroupId, group_id: 551})
+ );
+
+ const showStub = sinon.stub(page, 'show');
+ await element.handleCreateGroup();
+ assert.isTrue(showStub.calledWith('/admin/groups/551'));
+ });
+
+ test('test for unsuccessful group creation', async () => {
+ stubRestApi('createGroup').returns(
+ Promise.resolve({status: 409} as Response)
+ );
+ stubRestApi('getGroupConfig').returns(
+ Promise.resolve({id: 'testId551' as GroupId, group_id: 551})
+ );
+
+ const showStub = sinon.stub(page, 'show');
+ await element.handleCreateGroup();
+ assert.isFalse(showStub.called);
+ });
+});