Skip to content

Commit

Permalink
feat: validate new project name (redhat-developer#237)
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish committed Jan 30, 2024
1 parent 590ff1d commit 3766572
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ private void doActionPerformed(final ApplicationsRootNode rootNode, final Point
throw new RuntimeException(e);
}
}, SwingUtils.EXECUTOR_BACKGROUND)
.handleAsync((ClusterProjects, error) -> {
.handleAsync((clusterProjects, error) -> {
if (error != null) {
return null;
}
ChangeActiveProjectDialog dialog = openActiveProjectDialog(ClusterProjects.isOpenShift, ClusterProjects.current, ClusterProjects.all, location, project);
ChangeActiveProjectDialog dialog = openActiveProjectDialog(clusterProjects.isOpenShift, clusterProjects.current, clusterProjects.all, location, project);
if (dialog.isOK()) {
return new ChangeActiveProjectOperation(dialog.getActiveProject(), odo);
} else if (dialog.isCreateNewProject()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@
import org.jboss.tools.intellij.openshift.actions.ActionUtils;
import org.jboss.tools.intellij.openshift.actions.NotificationUtils;
import org.jboss.tools.intellij.openshift.actions.cluster.LoggedInClusterAction;
import org.jboss.tools.intellij.openshift.telemetry.TelemetryService;
import org.jboss.tools.intellij.openshift.tree.application.ApplicationsRootNode;
import org.jboss.tools.intellij.openshift.ui.SwingUtils;
import org.jboss.tools.intellij.openshift.ui.project.CreateNewProjectDialog;
import org.jboss.tools.intellij.openshift.utils.odo.Odo;
import org.jetbrains.annotations.NotNull;

import java.awt.Point;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import static org.jboss.tools.intellij.openshift.actions.ActionUtils.runWithProgress;
Expand All @@ -40,35 +46,69 @@ public static void execute(ApplicationsRootNode rootNode) {
return;
}
CreateProjectAction action = ActionUtils.createAction(CreateProjectAction.class.getName());
action.doActionPerformed(rootNode, odo, rootNode.getProject());
action.doActionPerformed(null, odo, rootNode.getProject());
}

@Override
public void actionPerformedOnSelectedObject(AnActionEvent anActionEvent, Object selected, @NotNull Odo odo) {
ApplicationsRootNode clusterNode = (ApplicationsRootNode) selected;
doActionPerformed(clusterNode, odo, getEventProject(anActionEvent));
Point location = ActionUtils.getLocation(anActionEvent);
doActionPerformed(location, odo, getEventProject(anActionEvent));
}

private void doActionPerformed(ApplicationsRootNode clusterNode, Odo odo, Project project) {
String projectName = Messages.showInputDialog("Project name", "New Project", Messages.getQuestionIcon());
if ((projectName == null) || projectName.trim().isEmpty()) {
sendTelemetryResults(TelemetryResult.ABORTED);
return;
}
runWithProgress((ProgressIndicator progress) -> {
try {
Notification notif = NotificationUtils.notifyInformation("Create Project", "Creating project " + projectName);
odo.createProject(projectName);
notif.expire();
NotificationUtils.notifyInformation("Create Project", "Project " + projectName + " successfully created");
clusterNode.getStructure().fireModified(clusterNode);
private void doActionPerformed(final Point location, final Odo odo, Project project) {
runWithProgress((ProgressIndicator progress) ->
CompletableFuture
.supplyAsync(() -> {
try {
return odo.getNamespaces();
} catch (IOException e) {
NotificationUtils.notifyError("Create New Project", "Could not get projects: " + e.getMessage());
sendTelemetryError(e.getMessage());
throw new CompletionException(e);
}
}, SwingUtils.EXECUTOR_BACKGROUND)
.handleAsync((allProjects, error) -> {
if (error != null) {
return null;
}
CreateNewProjectDialog dialog = openCreateProjectDialog(allProjects, location, project);
if (dialog.isOK()) {
return dialog.getNewProject();
} else {
sendTelemetryResults(TelemetryService.TelemetryResult.ABORTED);
return null;
}
}
, SwingUtils.EXECUTOR_UI)
.whenCompleteAsync((newProject, error) -> {
if (error != null
|| newProject == null) {
return;
}
createProject(newProject, odo);
}, SwingUtils.EXECUTOR_BACKGROUND),
"Create Active Project...",
project);
}

private void createProject(String newProject, Odo odo) {
Notification notification = NotificationUtils.notifyInformation("Create Project", "Creating project " + newProject);
try {
odo.createProject(newProject);
notification.expire();
NotificationUtils.notifyInformation("Create Project", "Project " + newProject + " successfully created");
sendTelemetryResults(TelemetryResult.SUCCESS);
} catch (IOException | CompletionException e) {
notification.expire();
sendTelemetryError(e);
UIHelper.executeInUI(() -> Messages.showErrorDialog("Error: " + e.getLocalizedMessage(), "Create Project"));
}
},
"Create Project...",
project);
}

private CreateNewProjectDialog openCreateProjectDialog(List<String> allProjects, Point location, Project project) {
CreateNewProjectDialog dialog = new CreateNewProjectDialog(project, allProjects, location);
dialog.show();
return dialog;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.intellij.openshift.ui;

import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.PopupBorder;
import org.jetbrains.annotations.Nullable;

import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;
import java.awt.Point;
import java.awt.Window;

import static org.jboss.tools.intellij.openshift.ui.SwingUtils.locationOrMouseLocation;

public abstract class BaseDialog extends DialogWrapper {

private final Point location;

protected BaseDialog(@Nullable Project project, Point location) {
super(project, false);
this.location = location;
init();
}

@Override
protected void init() {
super.init();
Window dialogWindow = getPeer().getWindow();
JRootPane rootPane = ((RootPaneContainer) dialogWindow).getRootPane();
registerShortcuts(rootPane);
setBorders(rootPane);
setLocation(locationOrMouseLocation(location));
}

private void registerShortcuts(JRootPane rootPane) {
AnAction escape = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_ESCAPE);
DumbAwareAction.create(e -> closeImmediately())
.registerCustomShortcutSet(
escape == null ? CommonShortcuts.ESCAPE : escape.getShortcutSet(),
rootPane,
myDisposable);
}

private void setBorders(JRootPane rootPane) {
rootPane.setBorder(PopupBorder.Factory.create(true, true));
rootPane.setWindowDecorationStyle(JRootPane.NONE);
}

protected void closeImmediately() {
if (isVisible()) {
doCancelAction();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.MouseInfo;
import java.awt.Point;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -140,4 +142,11 @@ public static void setMovable(JRootPane rootPane, JComponent... movableComponent
component -> component.addMouseListener(windowMoveListener));
}

public static Point locationOrMouseLocation(Point location) {
if (location == null) {
location = MouseInfo.getPointerInfo().getLocation();
}
return location;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,39 @@
******************************************************************************/
package org.jboss.tools.intellij.openshift.ui.project;

import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentValidator;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.PopupBorder;
import com.intellij.ui.TextFieldWithAutoCompletion;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.textCompletion.TextFieldWithCompletion;
import com.intellij.util.ui.JBUI;
import net.miginfocom.swing.MigLayout;
import org.jboss.tools.intellij.openshift.ui.BaseDialog;
import org.jboss.tools.intellij.openshift.ui.SwingUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;
import javax.swing.SwingConstants;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Collection;
import java.util.function.Supplier;

public class ChangeActiveProjectDialog extends DialogWrapper {
public class ChangeActiveProjectDialog extends BaseDialog {

private static final String WIDTH = "300";
private final Project project;
private final String kind;
private final String currentProject;
private final Collection<String> allProjects;
private final Point location;
private TextFieldWithCompletion activeProjectTextField;

private String activeProject;
Expand All @@ -66,48 +55,21 @@ public ChangeActiveProjectDialog(
String currentProject,
Collection<String> allProjects,
Point location) {
super(project, false);
super(project, location);
this.project = project;
this.kind = kind;
this.currentProject = currentProject;
this.allProjects = allProjects;
this.location = location;
init();
}

@Override
protected void init() {
super.init();
Window dialogWindow = getPeer().getWindow();
JRootPane rootPane = ((RootPaneContainer) dialogWindow).getRootPane();
registerShortcuts(rootPane);
setOKButtonText("Change");
setBorders(rootPane);
setLocation(location);
setTitle("Change Active " + kind);
}

@Override
public void setLocation(Point location) {
if (location == null) {
location = MouseInfo.getPointerInfo().getLocation();
}
super.setLocation(location);
}

private void registerShortcuts(JRootPane rootPane) {
AnAction escape = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_ESCAPE);
DumbAwareAction.create(e -> closeImmediately())
.registerCustomShortcutSet(escape == null ?
CommonShortcuts.ESCAPE
: escape.getShortcutSet(), rootPane, myDisposable);
}

private void setBorders(JRootPane rootPane) {
rootPane.setBorder(PopupBorder.Factory.create(true, true));
rootPane.setWindowDecorationStyle(JRootPane.NONE);
}

@Override
protected @Nullable JComponent createCenterPanel() {
JComponent panel = new JPanel(new MigLayout(
Expand Down Expand Up @@ -156,12 +118,6 @@ private TextFieldWithAutoCompletionListProvider<String> onLookup(Collection<Stri
};
}

private void closeImmediately() {
if (isVisible()) {
doCancelAction();
}
}

@Override
protected void doOKAction() {
super.doOKAction();
Expand Down
Loading

0 comments on commit 3766572

Please sign in to comment.