Merge "Handle labels not existing in the target system"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
index b996657..f23cef1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
@@ -68,7 +68,7 @@
case HTTP_LDAP:
case CLIENT_SSL_CERT_LDAP:
case LDAP:
- return createAccountByLdapAndAddSshKeys(api, acc, a);
+ return createAccountByLdapAndAddSshKeys(api, acc);
default:
throw new NoSuchAccountException(String.format("User %s not found",
acc.username));
@@ -84,7 +84,7 @@
}
private Account.Id createAccountByLdapAndAddSshKeys(RemoteApi api,
- AccountInfo acc, AccountState a)
+ AccountInfo acc)
throws NoSuchAccountException, BadRequestException, IOException,
OrmException {
if (!acc.username.matches(Account.USER_NAME_PATTERN)) {
@@ -96,7 +96,7 @@
AuthRequest req = AuthRequest.forUser(acc.username);
req.setSkipAuthentication(true);
Account.Id id = accountManager.authenticate(req).getAccountId();
- addSshKeys(api, acc, a);
+ addSshKeys(api, acc);
return id;
} catch (AccountException e) {
throw new NoSuchAccountException(
@@ -104,9 +104,10 @@
}
}
- private void addSshKeys(RemoteApi api, AccountInfo acc, AccountState a) throws
+ private void addSshKeys(RemoteApi api, AccountInfo acc) throws
BadRequestException, IOException, OrmException {
List<SshKeyInfo> sshKeys = api.getSshKeys(acc.username);
+ AccountState a = accountCache.getByUsername(acc.username);
db.get().accountSshKeys().upsert(toAccountSshKey(a, sshKeys));
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
index e40fc5e..f3bf629 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
@@ -15,12 +15,10 @@
package com.googlesource.gerrit.plugins.importer;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
-import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.change.HashtagsUtil;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
@@ -39,7 +37,7 @@
}
private final HashtagsUtil hashtagsUtil;
- private final IdentifiedUser.GenericFactory genericUserFactory;
+ private final CurrentUser currentUser;
private final ChangeControl.GenericFactory changeControlFactory;
private final Change change;
private final ChangeInfo changeInfo;
@@ -47,7 +45,7 @@
@Inject
AddHashtagsStep(HashtagsUtil hashtagsUtil,
- IdentifiedUser.GenericFactory genericUserFactory,
+ CurrentUser currentUser,
ChangeControl.GenericFactory changeControlFactory,
@Assisted Change change,
@Assisted ChangeInfo changeInfo,
@@ -55,14 +53,14 @@
this.hashtagsUtil = hashtagsUtil;
this.change = change;
this.changeInfo = changeInfo;
- this.genericUserFactory = genericUserFactory;
+ this.currentUser = currentUser;
this.changeControlFactory = changeControlFactory;
this.resume = resume;
}
void add() throws IllegalArgumentException, AuthException, IOException,
ValidationException, OrmException, NoSuchChangeException {
- ChangeControl ctrl = control(change, changeInfo.owner);
+ ChangeControl ctrl = changeControlFactory.controlFor(change, currentUser);
if (resume) {
HashtagsInput input = new HashtagsInput();
@@ -74,15 +72,4 @@
input.add = new HashSet<>(changeInfo.hashtags);
hashtagsUtil.setHashtags(ctrl, input, false, false);
}
-
- private ChangeControl control(Change change, AccountInfo acc)
- throws NoSuchChangeException {
- return control(change, new Account.Id(acc._accountId));
- }
-
- private ChangeControl control(Change change, Account.Id id)
- throws NoSuchChangeException {
- return changeControlFactory.controlFor(change,
- genericUserFactory.create(id));
- }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
index 7cb35ac..81363e7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
@@ -15,12 +15,21 @@
package com.googlesource.gerrit.plugins.importer;
import com.google.gerrit.extensions.annotations.PluginData;
+import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.CapabilityControl;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.importer.CompleteProjectImport.Input;
@@ -67,4 +76,57 @@
throw new ResourceConflictException("failed to lock project for delete");
}
}
+
+ public static class OnProjects implements
+ RestModifyView<ProjectResource, Input>, UiAction<ProjectResource> {
+ private final ProjectsCollection projectsCollection;
+ private final CompleteProjectImport completeProjectImport;
+ private final Provider<CurrentUser> currentUserProvider;
+ private final String pluginName;
+
+ @Inject
+ public OnProjects(ProjectsCollection projectsCollection,
+ CompleteProjectImport completeProjectImport,
+ Provider<CurrentUser> currentUserProvider,
+ @PluginName String pluginName) {
+ this.projectsCollection = projectsCollection;
+ this.completeProjectImport = completeProjectImport;
+ this.currentUserProvider = currentUserProvider;
+ this.pluginName = pluginName;
+ }
+
+ @Override
+ public Response<?> apply(ProjectResource rsrc, Input input)
+ throws ResourceNotFoundException, ResourceConflictException {
+ ImportProjectResource projectResource =
+ projectsCollection.parse(new ConfigResource(),
+ IdString.fromDecoded(rsrc.getName()));
+ return completeProjectImport.apply(projectResource, input);
+ }
+
+ @Override
+ public UiAction.Description getDescription(ProjectResource rsrc) {
+ UiAction.Description desc = new UiAction.Description()
+ .setLabel("Complete Import...")
+ .setTitle("Complete the project import."
+ + " After completion, resume is not possible anymore.");
+
+ try {
+ projectsCollection.parse(new ConfigResource(),
+ IdString.fromDecoded(rsrc.getName()));
+ desc.setVisible(canCompleteImport(rsrc));
+ } catch (ResourceNotFoundException e) {
+ desc.setVisible(false);
+ }
+
+ return desc;
+ }
+
+ private boolean canCompleteImport(ProjectResource rsrc) {
+ CapabilityControl ctl = currentUserProvider.get().getCapabilities();
+ return ctl.canAdministrateServer()
+ || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
+ && rsrc.getControl().isOwner());
+ }
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
index 7a5bdfc..7b6edf0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
@@ -29,6 +29,8 @@
.toInstance(new JavaScriptPlugin("resume-copy-project.js"));
DynamicSet.bind(binder(), WebUiPlugin.class)
.toInstance(new JavaScriptPlugin("resume-project-import.js"));
+ DynamicSet.bind(binder(), WebUiPlugin.class)
+ .toInstance(new JavaScriptPlugin("complete-project-import.js"));
DynamicSet.bind(binder(), WebUiPlugin.class)
.toInstance(new GwtPlugin("importer"));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
index 76fefdd..74b8eb0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
@@ -97,6 +97,7 @@
private final Project.NameKey targetProject;
private Project.NameKey srcProject;
private Project.NameKey parent;
+ private boolean force;
private Writer err;
@@ -146,9 +147,10 @@
}
}
- public Response<String> resume(String user, String pass, File importStatus)
- throws RestApiException, OrmException, IOException, ValidationException,
- GitAPIException, NoSuchChangeException, NoSuchAccountException {
+ public Response<String> resume(String user, String pass, boolean force,
+ File importStatus) throws RestApiException, OrmException, IOException,
+ ValidationException, GitAPIException, NoSuchChangeException,
+ NoSuchAccountException {
LockFile lockFile = lockForImport();
try {
ImportProjectInfo info = ImportJson.parse(importStatus);
@@ -160,6 +162,8 @@
input.name = info.name;
input.parent = info.parent;
+ this.force = force;
+
return apply(lockFile, input, info);
} finally {
lockFile.unlock();
@@ -189,7 +193,7 @@
gitFetchStep.fetch(input.user, input.pass, repo, pm);
configProjectStep.configure(targetProject, parent, pm);
replayChangesFactory.create(input.from, input.user, input.pass, repo,
- srcProject, targetProject, resume, pm).replay();
+ srcProject, targetProject, force, resume, pm).replay();
} finally {
repo.close();
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ListImportedProjects.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ListImportedProjects.java
index 7ba24db..1ac50be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ListImportedProjects.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ListImportedProjects.java
@@ -16,6 +16,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
+import com.google.common.io.Files;
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.RestReadView;
@@ -26,8 +27,10 @@
import org.kohsuke.args4j.Option;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Locale;
import java.util.Map;
@Singleton
@@ -59,14 +62,16 @@
return importedProjects;
}
- private File[] listImportFiles() {
- match = Strings.nullToEmpty(match);
-
- return lockRoot.listFiles(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return !name.endsWith(".lock") && name.toLowerCase().contains(match);
+ private Collection<File> listImportFiles() {
+ match = Strings.nullToEmpty(match).toLowerCase(Locale.ENGLISH);
+ Collection<File> importFiles = new HashSet<>();
+ for (File f : Files.fileTreeTraverser().preOrderTraversal(lockRoot)) {
+ if (f.isFile()
+ && !f.getName().endsWith(".lock")
+ && f.getName().toLowerCase(Locale.ENGLISH).contains(match)) {
+ importFiles.add(f);
}
- });
+ }
+ return importFiles;
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
index d703aa8..0a121be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
@@ -52,6 +52,7 @@
put(PROJECT_KIND, "copy").to(CopyProject.class);
put(PROJECT_KIND, "copy.resume").to(ResumeCopyProject.class);
put(PROJECT_KIND, "import.resume").to(ResumeProjectImport.OnProjects.class);
+ post(PROJECT_KIND, "delete").to(CompleteProjectImport.OnProjects.class);
child(CONFIG_KIND, "groups").to(GroupsCollection.class);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java b/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
index 3322095..55de14d 100755
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
@@ -14,6 +14,8 @@
package com.googlesource.gerrit.plugins.importer;
+import static com.google.gerrit.extensions.restapi.Url.encode;
+
import com.google.common.collect.Iterables;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -44,6 +46,7 @@
public ProjectInfo getProject(String projectName) throws IOException,
BadRequestException {
+ projectName = encode(projectName);
String endPoint = "/projects/" + projectName;
try (RestResponse r = checkedGet(endPoint)) {
return newGson().fromJson(r.getReader(),
@@ -81,6 +84,7 @@
public GroupInfo getGroup(String groupName) throws IOException,
BadRequestException {
+ groupName = encode(groupName);
String endPoint = "/groups/" + groupName + "/detail";
try (RestResponse r = checkedGet(endPoint)) {
return newGson().fromJson(r.getReader(),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
index e32d1ec..bffae8c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -53,7 +53,8 @@
Repository repo,
@Assisted("srcProject") Project.NameKey srcProject,
@Assisted("targetProject") Project.NameKey targetProject,
- boolean resume,
+ @Assisted("force") boolean force,
+ @Assisted("resume") boolean resume,
ProgressMonitor pm);
}
@@ -72,6 +73,7 @@
private final Repository repo;
private final Project.NameKey srcProject;
private final Project.NameKey targetProject;
+ private final boolean force;
private final boolean resume;
private final ProgressMonitor pm;
@@ -93,7 +95,8 @@
@Assisted Repository repo,
@Assisted("srcProject") Project.NameKey srcProject,
@Assisted("targetProject") Project.NameKey targetProject,
- @Assisted boolean resume,
+ @Assisted("force") boolean force,
+ @Assisted("resume") boolean resume,
@Assisted ProgressMonitor pm) {
this.replayRevisionsFactory = replayRevisionsFactory;
this.replayInlineCommentsFactory = replayInlineCommentsFactory;
@@ -110,6 +113,7 @@
this.repo = repo;
this.srcProject = srcProject;
this.targetProject = targetProject;
+ this.force = force;
this.resume = resume;
this.pm = pm;
}
@@ -147,7 +151,7 @@
change = createChange(c);
} else {
resumeChange = true;
- if (change.getLastUpdatedOn().equals(c.updated)) {
+ if (!force && change.getLastUpdatedOn().equals(c.updated)) {
// change was not modified since last import
return;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
index 4aa3d05..5dfb115 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
@@ -35,6 +35,9 @@
usage = "password of remote user")
private String pass;
+ @Option(name = "--force", usage = "Whether the resume should be done forcefully.")
+ private boolean force;
+
@Option(name = "--quiet", usage = "suppress progress messages")
private boolean quiet;
@@ -58,6 +61,7 @@
ResumeProjectImport.Input input = new ResumeProjectImport.Input();
input.user = user;
input.pass = pass;
+ input.force = force;
resume.apply(rsrc, input);
} catch (RestApiException e) {
throw die(e.getMessage());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
index 521be04..ad172d4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
@@ -50,6 +50,7 @@
public static class Input {
public String user;
public String pass;
+ public boolean force;
}
private final ImportProject.Factory importProjectFactory;
@@ -74,7 +75,8 @@
ImportProject importer = importProjectFactory.create(rsrc.getName());
importer.setErr(err);
- return importer.resume(input.user, input.pass, rsrc.getImportStatus());
+ return importer.resume(input.user, input.pass, input.force,
+ rsrc.getImportStatus());
}
public static class OnProjects implements
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ProjectImportsScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ProjectImportsScreen.java
index d031708..874bb35 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ProjectImportsScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ProjectImportsScreen.java
@@ -21,11 +21,8 @@
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.Label;
diff --git a/src/main/resources/Documentation/cmd-resume-project.md b/src/main/resources/Documentation/cmd-resume-project.md
index 8221c5f..f5c7ebd 100644
--- a/src/main/resources/Documentation/cmd-resume-project.md
+++ b/src/main/resources/Documentation/cmd-resume-project.md
@@ -11,6 +11,7 @@
ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ resume-project \
--user <USER> | -u <USER> \
--pass - | <PASS> \
+ [--force] \
[--quiet] \
<NAME>
```
@@ -38,6 +39,11 @@
`--user`
: User on remote system.
+`--force`
+: Whether the resume should be done forcefully. On resume with force
+ changes that have the same last modified timestamp in the source
+ and target system are resumed, otherwise they will be skipped.
+
`--quiet`
: Suppress progress messages.
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index 380e584..5655414 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -41,9 +41,6 @@
Lists the imported projects.
-As result a map is returned that maps the project name to
-[ImportProjectInfo](#import-project-info) entity.
-
Caller must be a member of a group that is granted the 'Import'
capability (provided by this plugin) or the 'Administrate Server'
capability.
@@ -58,6 +55,9 @@
GET /config/server/@PLUGIN@~projects/?match=my HTTP/1.0
```
+As result a map is returned that maps the project name to
+[ImportProjectInfo](#import-project-info) entity.
+
#### Response
```
@@ -196,7 +196,7 @@
}
```
-### <a id="complete-project-import"> Resume Project Import
+### <a id="complete-project-import"> Complete Project Import
_DELETE /config/server/@PLUGIN@~projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)_
Mark a project import as completed.
@@ -272,6 +272,9 @@
* _user_: User on remote system.
* _pass_: Password of remote user.
+* _force_: Whether the resume should be done forcefully. On resume with
+force changes that have the same last modified timestamp in the source
+and target system are resumed, otherwise they will be skipped.
SEE ALSO
diff --git a/src/main/resources/Documentation/rest-api-projects.md b/src/main/resources/Documentation/rest-api-projects.md
index ebc443f..252b33d 100644
--- a/src/main/resources/Documentation/rest-api-projects.md
+++ b/src/main/resources/Documentation/rest-api-projects.md
@@ -73,6 +73,25 @@
}
```
+### <a id="complete-project-import"> Complete Project Import
+_POST /projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~delete)_
+
+Mark a project import as completed.
+
+Once a project import is completed it cannot be resumed any more.
+
+#### Request
+
+```
+ POST /projects/myProject/@PLUGIN@~delete HTTP/1.0
+```
+
+#### Response
+
+```
+ HTTP/1.1 204 No Content
+```
+
<a id="json-entities">JSON Entities
-----------------------------------
diff --git a/src/main/resources/static/complete-project-import.js b/src/main/resources/static/complete-project-import.js
new file mode 100644
index 0000000..059dc46
--- /dev/null
+++ b/src/main/resources/static/complete-project-import.js
@@ -0,0 +1,38 @@
+// 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.
+
+Gerrit.install(function(self) {
+ function onCompleteProjectImport(c) {
+ var b = c.button('Complete',
+ {onclick: function(){
+ c.call(
+ {},
+ function(r) {
+ c.hide();
+ window.alert('Import for project "'
+ + c.project
+ + '" was completed."'),
+ Gerrit.go('/admin/projects/' + c.project);
+ });
+ }});
+ c.popup(c.div(
+ c.msg('Complete import for project "'
+ + c.project
+ + '" ?'),
+ c.br(),
+ c.br(),
+ b));
+ }
+ self.onAction('project', 'delete', onCompleteProjectImport);
+ });
diff --git a/src/main/resources/static/resume-project-import.js b/src/main/resources/static/resume-project-import.js
index eaf752d..fdca63c 100644
--- a/src/main/resources/static/resume-project-import.js
+++ b/src/main/resources/static/resume-project-import.js
@@ -17,10 +17,11 @@
var u = c.textfield();
var p = c.textfield();
p.type = 'password';
+ var f = c.checkbox();
var b = c.button('Resume',
{onclick: function(){
c.call(
- {user: u.value, pass: p.value},
+ {user: u.value, pass: p.value, force: f.checked},
function(r) {
c.hide();
window.alert('Import for project "'
@@ -38,6 +39,8 @@
c.br(),
c.prependLabel('Password:', p),
c.br(),
+ c.label(f, 'Force Resume'),
+ c.br(),
c.br(),
b));
}