Convert gr-confirm-move-dialog to lit

Release-Notes: skip
Change-Id: Ic8d5ec5ee670fdc3c7a95661609ce51c667e59fb
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.ts
index 77a993c..482efd6 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.ts
@@ -14,29 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import '../../../styles/shared-styles';
-import '../../shared/gr-autocomplete/gr-autocomplete';
-import '../../shared/gr-dialog/gr-dialog';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {customElement, property} from '@polymer/decorators';
+import {css, html, LitElement} from 'lit';
+import {customElement, property} from 'lit/decorators';
+import {sharedStyles} from '../../../styles/shared-styles';
 import {BranchName, RepoName} from '../../../types/common';
 import {getAppContext} from '../../../services/app-context';
-import {GrTypedAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';
+import '../../shared/gr-autocomplete/gr-autocomplete';
+import '../../shared/gr-dialog/gr-dialog';
+import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
 import {addShortcut, Key, Modifier} from '../../../utils/dom-util';
-import {html} from '@polymer/polymer/lib/utils/html-tag';
 
 const SUGGESTIONS_LIMIT = 15;
 
-// This is used to make sure 'branch'
-// can be typed as BranchName.
-export interface GrConfirmMoveDialog {
-  $: {
-    branchInput: GrTypedAutocomplete<BranchName>;
-  };
-}
-
 @customElement('gr-confirm-move-dialog')
-export class GrConfirmMoveDialog extends PolymerElement {
+export class GrConfirmMoveDialog extends LitElement {
   /**
    * Fired when the confirm button is pressed.
    *
@@ -58,9 +49,6 @@
   @property({type: String})
   project?: RepoName;
 
-  @property({type: Object})
-  _query?: (input: string) => Promise<{name: BranchName}[]>;
-
   /** Called in disconnectedCallback. */
   private cleanups: (() => void)[] = [];
 
@@ -74,26 +62,22 @@
     super.connectedCallback();
     this.cleanups.push(
       addShortcut(this, {key: Key.ENTER, modifiers: [Modifier.CTRL_KEY]}, e =>
-        this._handleConfirmTap(e)
+        this.handleConfirmTap(e)
       )
     );
     this.cleanups.push(
       addShortcut(this, {key: Key.ENTER, modifiers: [Modifier.META_KEY]}, e =>
-        this._handleConfirmTap(e)
+        this.handleConfirmTap(e)
       )
     );
   }
 
   private readonly restApiService = getAppContext().restApiService;
 
-  constructor() {
-    super();
-    this._query = (text: string) => this._getProjectBranchesSuggestions(text);
-  }
-
-  static get template() {
-    return html`
-      <style include="shared-styles">
+  static override get styles() {
+    return [
+      sharedStyles,
+      css`
         :host {
           display: block;
           width: 30em;
@@ -121,11 +105,16 @@
         .warning {
           color: var(--error-text-color);
         }
-      </style>
+      `,
+    ];
+  }
+
+  override render() {
+    return html`
       <gr-dialog
         confirm-label="Move Change"
-        on-confirm="_handleConfirmTap"
-        on-cancel="_handleCancelTap"
+        @confirm=${(e: Event) => this.handleConfirmTap(e)}
+        @cancel=${(e: Event) => this.handleCancelTap(e)}
       >
         <div class="header" slot="header">Move Change to Another Branch</div>
         <div class="main" slot="main">
@@ -135,8 +124,8 @@
           <label for="branchInput"> Move change to branch </label>
           <gr-autocomplete
             id="branchInput"
-            text="{{branch}}"
-            query="[[_query]]"
+            .text=${this.branch}
+            .query=${(text: string) => this.getProjectBranchesSuggestions(text)}
             placeholder="Destination branch"
           >
           </gr-autocomplete>
@@ -145,16 +134,16 @@
             id="messageInput"
             class="message"
             autocomplete="on"
-            rows="4"
-            max-rows="15"
-            bind-value="{{message}}"
+            .rows=${4}
+            .maxRows=${15}
+            .bindValue=${this.message}
           ></iron-autogrow-textarea>
         </div>
       </gr-dialog>
     `;
   }
 
-  _handleConfirmTap(e: Event) {
+  private handleConfirmTap(e: Event) {
     e.preventDefault();
     e.stopPropagation();
     this.dispatchEvent(
@@ -165,7 +154,7 @@
     );
   }
 
-  _handleCancelTap(e: Event) {
+  private handleCancelTap(e: Event) {
     e.preventDefault();
     e.stopPropagation();
     this.dispatchEvent(
@@ -176,7 +165,7 @@
     );
   }
 
-  _getProjectBranchesSuggestions(input: string) {
+  private getProjectBranchesSuggestions(input: string) {
     if (!this.project) return Promise.reject(new Error('Missing project'));
     if (input.startsWith('refs/heads/')) {
       input = input.substring('refs/heads/'.length);
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.ts
index ea5d320..af75b48 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.ts
@@ -18,15 +18,15 @@
 import '../../../test/common-test-setup-karma';
 import './gr-confirm-move-dialog';
 import {GrConfirmMoveDialog} from './gr-confirm-move-dialog';
-import {stubRestApi} from '../../../test/test-utils';
+import {queryAndAssert, stubRestApi} from '../../../test/test-utils';
 import {BranchName, GitRef, RepoName} from '../../../types/common';
-
-const basicFixture = fixtureFromElement('gr-confirm-move-dialog');
+import {fixture, html} from '@open-wc/testing-helpers';
+import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';
 
 suite('gr-confirm-move-dialog tests', () => {
   let element: GrConfirmMoveDialog;
 
-  setup(() => {
+  setup(async () => {
     stubRestApi('getRepoBranches').callsFake((input: string) => {
       if (input.startsWith('test')) {
         return Promise.resolve([
@@ -40,35 +40,70 @@
         return Promise.resolve([]);
       }
     });
-    element = basicFixture.instantiate();
-    element.project = 'test-repo' as RepoName;
+    element = await fixture(
+      html`<gr-confirm-move-dialog
+        .project=${'test-repo' as RepoName}
+      ></gr-confirm-move-dialog>`
+    );
   });
 
-  test('with updated commit message', () => {
+  test('render', async () => {
+    expect(element).shadowDom.to.equal(/* HTML */ `
+      <gr-dialog confirm-label="Move Change" role="dialog">
+        <div class="header" slot="header">Move Change to Another Branch</div>
+        <div class="main" slot="main">
+          <p class="warning">
+            Warning: moving a change will not change its parents.
+          </p>
+          <label for="branchInput"> Move change to branch </label>
+          <gr-autocomplete id="branchInput" placeholder="Destination branch">
+          </gr-autocomplete>
+          <label for="messageInput"> Move Change Message </label>
+          <iron-autogrow-textarea
+            aria-disabled="false"
+            id="messageInput"
+            class="message"
+            autocomplete="on"
+          ></iron-autogrow-textarea>
+        </div>
+      </gr-dialog>
+    `);
+  });
+
+  test('with updated commit message', async () => {
     element.branch = 'master' as BranchName;
     const myNewMessage = 'updated commit message';
     element.message = myNewMessage;
-    flush();
+    await element.updateComplete;
+
     assert.equal(element.message, myNewMessage);
   });
 
-  test('_getProjectBranchesSuggestions empty', async () => {
-    const branches = await element._getProjectBranchesSuggestions(
-      'nonexistent'
+  test('suggestions empty', async () => {
+    const autoComplete = queryAndAssert<GrAutocomplete>(
+      element,
+      'gr-autocomplete'
     );
+    const branches = await autoComplete.query!('nonexistent');
     assert.equal(branches.length, 0);
   });
 
-  test('_getProjectBranchesSuggestions non-empty', async () => {
-    const branches = await element._getProjectBranchesSuggestions(
-      'test-branch'
+  test('suggestions non-empty', async () => {
+    const autoComplete = queryAndAssert<GrAutocomplete>(
+      element,
+      'gr-autocomplete'
     );
+    const branches = await autoComplete.query!('test-branch');
     assert.equal(branches.length, 1);
     assert.equal(branches[0].name, 'test-branch');
   });
 
-  test('_getProjectBranchesSuggestions input empty string', async () => {
-    const branches = await element._getProjectBranchesSuggestions('');
+  test('suggestions input empty string', async () => {
+    const autoComplete = queryAndAssert<GrAutocomplete>(
+      element,
+      'gr-autocomplete'
+    );
+    const branches = await autoComplete.query!('');
     assert.equal(branches.length, 0);
   });
 });