getOpenedDialogs() {
}
/**
+ * Returns the most recently opened component {@link Dialog} created via
+ * {@link Dialogs}. For views shown as dialogs (e.g. {@code InputDialog}) use
+ * {@link #getLastOpenedViewDialog()}.
+ *
* @return the most recent opened {@link DialogInfo} or {@code null} if no opened dialogs
*/
@Nullable
public static DialogInfo getLastOpenedDialog() {
return applicationContext.getBean(OpenedDialogs.class).getLastDialog();
}
+
+ /**
+ * Returns an immutable list of {@link View}s shown as dialogs (i.e. opened in {@link OpenMode#DIALOG}),
+ * in the order they were opened. This includes any lookup or detail view opened as a dialog, as well as
+ * the framework {@code InputDialog}.
+ *
+ * Example of the order in which view dialogs are stored:
+ *
+ * - first opened view dialog has index {@code 0}
+ * - second opened view dialog has index {@code 1}
+ * - last opened view dialog has index {@code openedViewDialogs.size() - 1}
+ *
+ *
+ * For component dialogs created via {@link Dialogs} (message, option, background-task and side
+ * dialogs) use {@link #getOpenedDialogs()} instead.
+ *
+ * @return immutable list of {@link View}s shown as dialogs, in order of opening
+ */
+ public static List> getOpenedViewDialogs() {
+ return applicationContext.getBean(OpenedDialogWindows.class).getDialogs();
+ }
+
+ /**
+ * Returns the most recently opened {@link View} shown as a dialog, i.e. the topmost view opened in
+ * {@link OpenMode#DIALOG} (a lookup or detail view, a custom view, etc.). Usage example:
+ *
+ * // open a view as a dialog (e.g. via DialogWindows or OpenMode.DIALOG), then:
+ * CustomerDetailView view = UiTestUtils.getLastOpenedViewDialog();
+ *
+ *
+ * Note: the framework {@code InputDialog} is also a view dialog and can be obtained the same way.
+ *
+ * @param expected type of the view
+ * @return the most recently opened view dialog, or {@code null} if there are no opened view dialogs
+ */
+ @SuppressWarnings("unchecked")
+ @Nullable
+ public static > T getLastOpenedViewDialog() {
+ return (T) applicationContext.getBean(OpenedDialogWindows.class)
+ .getCurrentDialog()
+ .orElse(null);
+ }
}
diff --git a/jmix-flowui/flowui/src/test/java/dialog/ViewDialogTest.java b/jmix-flowui/flowui/src/test/java/dialog/ViewDialogTest.java
new file mode 100644
index 0000000000..3b93b78f66
--- /dev/null
+++ b/jmix-flowui/flowui/src/test/java/dialog/ViewDialogTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2026 Haulmont.
+ *
+ * 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 dialog;
+
+import dialog.view.DialogsTestView;
+import io.jmix.flowui.app.inputdialog.InputDialog;
+import io.jmix.flowui.testassist.FlowuiTestAssistConfiguration;
+import io.jmix.flowui.testassist.UiTest;
+import io.jmix.flowui.testassist.UiTestUtils;
+import io.jmix.flowui.view.View;
+import io.jmix.flowui.view.navigation.ViewNavigationSupport;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import test_support.FlowuiTestConfiguration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Verifies that views shown as dialogs (e.g. {@code InputDialog}) are reported through the view-dialog
+ * accessors of {@link UiTestUtils} and are kept separate from component dialogs.
+ */
+@UiTest(viewBasePackages = {"io.jmix.flowui.app.inputdialog","dialog.view"})
+@SpringBootTest(classes = {FlowuiTestConfiguration.class, FlowuiTestAssistConfiguration.class})
+public class ViewDialogTest {
+
+ @Autowired
+ ViewNavigationSupport navigationSupport;
+
+ @Test
+ @DisplayName("InputDialog is reported as a view dialog, not as a component dialog")
+ public void inputDialogIsReportedAsViewDialogTest() {
+ // Navigate to DialogsTestView
+ DialogsTestView view = navigateToDialogsTestView();
+
+ // Open an InputDialog (a view shown as a dialog)
+ view.openInputDialog();
+
+ // It is available through the view-dialog accessors
+ View> lastViewDialog = UiTestUtils.getLastOpenedViewDialog();
+ assertNotNull(lastViewDialog);
+ assertInstanceOf(InputDialog.class, lastViewDialog);
+ assertEquals(1, UiTestUtils.getOpenedViewDialogs().size());
+ assertSame(lastViewDialog, UiTestUtils.getOpenedViewDialogs().get(0));
+
+ // ...and it is not reported as a component dialog
+ assertNull(UiTestUtils.getLastOpenedDialog());
+ assertTrue(UiTestUtils.getOpenedDialogs().isEmpty());
+ }
+
+ protected > T navigateToDialogsTestView() {
+ //noinspection unchecked
+ navigationSupport.navigate((Class) DialogsTestView.class);
+ return UiTestUtils.getCurrentView();
+ }
+}
diff --git a/jmix-flowui/flowui/src/test/java/dialog/view/DialogsTestView.java b/jmix-flowui/flowui/src/test/java/dialog/view/DialogsTestView.java
index d4b00e0a37..1f9093e130 100644
--- a/jmix-flowui/flowui/src/test/java/dialog/view/DialogsTestView.java
+++ b/jmix-flowui/flowui/src/test/java/dialog/view/DialogsTestView.java
@@ -19,6 +19,7 @@
import com.vaadin.flow.router.Route;
import io.jmix.flowui.Dialogs;
import io.jmix.flowui.action.DialogAction;
+import io.jmix.flowui.app.inputdialog.InputParameter;
import io.jmix.flowui.view.StandardView;
import io.jmix.flowui.view.ViewController;
import org.springframework.beans.factory.annotation.Autowired;
@@ -50,4 +51,10 @@ public void openOptionDialog() {
)
.open();
}
+
+ public void openInputDialog() {
+ dialogs.createInputDialog(this)
+ .withParameter(InputParameter.stringParameter("name"))
+ .open();
+ }
}