Allow to resume project imports from import list screen

For each import listed on the import list screen there is now a button
to resume the project import.

Change-Id: Ief2821605a44924b1b77374a9d40a90d19318267
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectListScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectListScreen.java
index 54f1880..56b152d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectListScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectListScreen.java
@@ -19,8 +19,11 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.FlexTable;
 import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
 import com.google.gwt.user.client.ui.VerticalPanel;
@@ -55,7 +58,7 @@
   }
 
   private void display(NativeMap<ImportProjectInfo> map) {
-    int columns = 4;
+    int columns = 5;
     FlexTable t = new FlexTable();
     t.setStyleName("importer-importProjectTable");
     FlexCellFormatter fmt = t.getFlexCellFormatter();
@@ -69,9 +72,10 @@
     t.setText(0, 1, "From");
     t.setText(0, 2, "Last Import By");
     t.setText(0, 3, "Last Import At");
+    t.setText(0, 4, "Actions");
 
     int row = 1;
-    for (String project : map.keySet()) {
+    for (final String project : map.keySet()) {
       ImportProjectInfo info = map.get(project);
 
       for (int c = 0; c < columns; c++) {
@@ -96,6 +100,13 @@
         t.setText(row, 3, "N/A");
       }
 
+      t.setWidget(row, 4, new Button("Resume...", new ClickHandler() {
+        @Override
+        public void onClick(ClickEvent event) {
+          (new ResumeImportDialog(project)).center();
+        }
+      }));
+
       row++;
     }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
index c24c2c3..f65ae5c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
@@ -14,25 +14,22 @@
 
 package com.googlesource.gerrit.plugins.importer.client;
 
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.addPasswordTextBox;
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.addTextBox;
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.getValue;
+
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
 import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.DialogBox;
 import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Image;
 import com.google.gwt.user.client.ui.Label;
 import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.PasswordTextBox;
 import com.google.gwt.user.client.ui.TextBox;
 import com.google.gwt.user.client.ui.VerticalPanel;
 
@@ -55,13 +52,13 @@
   ImportProjectScreen() {
     setStyleName("importer-import-panel");
 
-    fromTxt = addTextBox("From*", "URL of the remote system from where the project should be imported");
-    srcNameTxt = addTextBox("Project Name in Source*", "name of project in source system");
-    targetNameTxt = addTextBox("Target Project Name", "name of project in target system"
+    fromTxt = addTextBox(this, "From*", "URL of the remote system from where the project should be imported");
+    srcNameTxt = addTextBox(this, "Project Name in Source*", "name of project in source system");
+    targetNameTxt = addTextBox(this, "Target Project Name", "name of project in target system"
         + " (if not specified it is assumed to be the same name as in the source system)");
-    userTxt = addTextBox("Remote User*", "user on remote system");
-    passTxt = addPasswordTextBox("Password*", "password of remote user");
-    parentTxt = addTextBox("Parent", "name of parent project in target system"
+    userTxt = addTextBox(this, "Remote User*", "user on remote system");
+    passTxt = addPasswordTextBox(this, "Password*", "password of remote user");
+    parentTxt = addTextBox(this, "Parent", "name of parent project in target system"
         + "(if not specified it is assumed to be the same parent as in the source system)");
 
     HorizontalPanel buttons = new HorizontalPanel();
@@ -83,77 +80,6 @@
     importButton.setEnabled(false);
   }
 
-  private TextBox addTextBox(String label, String infoMsg) {
-    return addTextBox(label, infoMsg, false);
-  }
-
-  private TextBox addPasswordTextBox(String label, String infoMsg) {
-    return addTextBox(label, infoMsg, true);
-  }
-
-  private TextBox addTextBox(String label, String infoMsg, boolean isPassword) {
-    HorizontalPanel hp = new HorizontalPanel();
-    hp.add(new Label(label));
-    Image info = new Image(ImporterPlugin.RESOURCES.info());
-    info.setTitle(infoMsg);
-    hp.add(info);
-    hp.add(new Label(":"));
-
-    Panel p = new VerticalPanel();
-    p.add(hp);
-    TextBox tb = createTextBox(isPassword);
-    p.add(tb);
-    add(p);
-    return tb;
-  }
-
-  private static TextBox createTextBox(boolean isPassword) {
-    TextBox tb;
-    if (isPassword) {
-      tb = new PasswordTextBox() {
-        @Override
-        public void onBrowserEvent(Event event) {
-          super.onBrowserEvent(event);
-          handlePaste(this, event);
-        }
-      };
-    } else {
-      tb = new TextBox() {
-        @Override
-        public void onBrowserEvent(Event event) {
-          super.onBrowserEvent(event);
-          handlePaste(this, event);
-        }
-      };
-    }
-    tb.addKeyPressHandler(new KeyPressHandler() {
-      @Override
-      public void onKeyPress(KeyPressEvent event) {
-        event.stopPropagation();
-      }
-    });
-    tb.sinkEvents(Event.ONPASTE);
-    tb.setVisibleLength(40);
-    return tb;
-  }
-
-  private static void handlePaste(final TextBox tb, Event event) {
-    if (event.getTypeInt() == Event.ONPASTE) {
-      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-        @Override
-        public void execute() {
-          if (getValue(tb).length() != 0) {
-            tb.setEnabled(true);
-          }
-        }
-      });
-    }
-  }
-
-  private static String getValue(TextBox tb) {
-    return tb.getValue().trim();
-  }
-
   private void doImport() {
     final String targetName = getValue(targetNameTxt).length() == 0
         ? getValue(srcNameTxt) : getValue(targetNameTxt);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
new file mode 100644
index 0000000..73488f4
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
@@ -0,0 +1,129 @@
+// Copyright (C) 2015 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.
+
+package com.googlesource.gerrit.plugins.importer.client;
+
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.addPasswordTextBox;
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.addTextBox;
+import static com.googlesource.gerrit.plugins.importer.client.TextBoxUtil.getValue;
+
+import com.google.gerrit.plugin.client.Plugin;
+import com.google.gerrit.plugin.client.rpc.RestApi;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwtexpui.globalkey.client.GlobalKey;
+import com.google.gwtexpui.user.client.AutoCenterDialogBox;
+
+public class ResumeImportDialog extends AutoCenterDialogBox {
+
+  private final Button cancelButton;
+  private final Button resumeButton;
+  private final TextBox userTxt;
+  private final TextBox passTxt;
+
+  public ResumeImportDialog(final String project) {
+    super(/* auto hide */false, /* modal */true);
+    setGlassEnabled(true);
+    setText("Resume Project Import");
+
+    FlowPanel buttons = new FlowPanel();
+
+    resumeButton = new Button();
+    resumeButton.setText("Resume");
+    resumeButton.addClickHandler(new ClickHandler() {
+      @Override
+      public void onClick(ClickEvent event) {
+        hide();
+
+        ResumeImportProjectInput in = ResumeImportProjectInput.create();
+        in.user(getValue(userTxt));
+        in.pass(getValue(passTxt));
+
+        new RestApi("config").id("server")
+            .view(Plugin.get().getName(), "projects").id(project)
+            .view("resume").put(in, new AsyncCallback<JavaScriptObject>() {
+              @Override
+              public void onSuccess(JavaScriptObject result) {
+                Plugin.get().go("/admin/projects/" + project);
+
+                final DialogBox successDialog = new DialogBox();
+                successDialog.setText("Resume Project Import");
+                successDialog.setAnimationEnabled(true);
+
+                Panel p = new VerticalPanel();
+                p.setStyleName("importer-message-panel");
+                p.add(new Label("The project import was resumed."));
+                Button okButton = new Button("OK");
+                okButton.addClickHandler(new ClickHandler() {
+                  public void onClick(ClickEvent event) {
+                    successDialog.hide();
+                  }
+                });
+
+                p.add(okButton);
+                successDialog.add(p);
+
+                successDialog.center();
+                successDialog.show();
+              }
+
+              @Override
+              public void onFailure(Throwable caught) {
+              }
+            });
+      }
+    });
+    buttons.add(resumeButton);
+
+    cancelButton = new Button();
+    cancelButton.addStyleName("importer-cancel-button");
+    cancelButton.setText("Cancel");
+    cancelButton.addClickHandler(new ClickHandler() {
+      @Override
+      public void onClick(ClickEvent event) {
+        hide();
+      }
+    });
+    buttons.add(cancelButton);
+
+    FlowPanel center = new FlowPanel();
+    Label msg = new Label("Resume import of project '" + project + "'");
+    msg.addStyleName("importer-resume-message");
+    center.add(msg);
+
+    userTxt = addTextBox(center, "Remote User*", "user on remote system");
+    passTxt = addPasswordTextBox(center, "Password*", "password of remote user");
+
+    center.add(buttons);
+    add(center);
+
+    setWidget(center);
+  }
+
+  @Override
+  public void center() {
+    super.center();
+    GlobalKey.dialog(this);
+    cancelButton.setFocus(true);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportProjectInput.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportProjectInput.java
new file mode 100644
index 0000000..1635882
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportProjectInput.java
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 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.
+
+package com.googlesource.gerrit.plugins.importer.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public class ResumeImportProjectInput extends JavaScriptObject {
+  final native void user(String u) /*-{ this.user = u; }-*/;
+  final native void pass(String p) /*-{ this.pass = p; }-*/;
+
+  static ResumeImportProjectInput create() {
+    return (ResumeImportProjectInput) createObject();
+  }
+
+  protected ResumeImportProjectInput() {
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/TextBoxUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/TextBoxUtil.java
new file mode 100644
index 0000000..81d56c8
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/TextBoxUtil.java
@@ -0,0 +1,101 @@
+// Copyright (C) 2015 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.
+
+package com.googlesource.gerrit.plugins.importer.client;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.PasswordTextBox;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+public class TextBoxUtil {
+  public static TextBox addTextBox(Panel p, String label, String infoMsg) {
+    return addTextBox(p, label, infoMsg, false);
+  }
+
+  public static TextBox addPasswordTextBox(Panel p, String label, String infoMsg) {
+    return addTextBox(p, label, infoMsg, true);
+  }
+
+  public static TextBox addTextBox(Panel p, String label, String infoMsg, boolean isPassword) {
+    HorizontalPanel hp = new HorizontalPanel();
+    hp.add(new Label(label));
+    Image info = new Image(ImporterPlugin.RESOURCES.info());
+    info.setTitle(infoMsg);
+    hp.add(info);
+    hp.add(new Label(":"));
+
+    Panel vp = new VerticalPanel();
+    vp.add(hp);
+    TextBox tb = createTextBox(isPassword);
+    vp.add(tb);
+    p.add(vp);
+    return tb;
+  }
+
+  private static TextBox createTextBox(boolean isPassword) {
+    TextBox tb;
+    if (isPassword) {
+      tb = new PasswordTextBox() {
+        @Override
+        public void onBrowserEvent(Event event) {
+          super.onBrowserEvent(event);
+          handlePaste(this, event);
+        }
+      };
+    } else {
+      tb = new TextBox() {
+        @Override
+        public void onBrowserEvent(Event event) {
+          super.onBrowserEvent(event);
+          handlePaste(this, event);
+        }
+      };
+    }
+    tb.addKeyPressHandler(new KeyPressHandler() {
+      @Override
+      public void onKeyPress(KeyPressEvent event) {
+        event.stopPropagation();
+      }
+    });
+    tb.sinkEvents(Event.ONPASTE);
+    tb.setVisibleLength(40);
+    return tb;
+  }
+
+  private static void handlePaste(final TextBox tb, Event event) {
+    if (event.getTypeInt() == Event.ONPASTE) {
+      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+        @Override
+        public void execute() {
+          if (getValue(tb).length() != 0) {
+            tb.setEnabled(true);
+          }
+        }
+      });
+    }
+  }
+
+  public static String getValue(TextBox tb) {
+    return tb.getValue().trim();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/public/importer.css b/src/main/java/com/googlesource/gerrit/plugins/importer/public/importer.css
index 7731558..9ec691e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/public/importer.css
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/public/importer.css
@@ -53,3 +53,11 @@
   vertical-align: middle;
   height: 20px;
 }
+
+.importer-cancel-button {
+  margin-left: 150px;
+}
+
+.importer-resume-message {
+  margin-bottom: 10px;
+}