Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@
<artifactId>vaadin-testbench</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.flowingcode.vaadin.test</groupId>
<artifactId>testbench-rpc</artifactId>
<version>1.5.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.flowingcode.vaadin.addons.demo</groupId>
<artifactId>commons-demo</artifactId>
Expand Down Expand Up @@ -445,7 +451,8 @@
<exclude>**/test/*</exclude>
<exclude>**/it/*</exclude>
<exclude>**/DemoView.class</exclude>
<exclude>**/DemoLayout.class</exclude>
<exclude>**/DemoLayout.class</exclude>
<exclude>**/AppShellConfiguratorImpl.class</exclude>
</excludes>
</configuration>
</execution>
Expand All @@ -459,7 +466,7 @@
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<vaadin.version>25.0.0</vaadin.version>
<vaadin.version>25.0.6</vaadin.version>
<jetty.version>11.0.26</jetty.version>
</properties>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,17 @@ public void removeRouterLayoutContent(HasElement oldContent) {
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
setOpened(true);
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].replaceChildren())");
this.getElement().executeJs(
LoginOverlayUtils.getLoginFormWrapperScript(
"""
formWrapper.querySelectorAll('[slot="form"], [slot="submit"], [slot="forgot-password"]').forEach(c => c.remove());
"""));
this.getElement().appendChild(content.getElement());
content.getElement().setAttribute("slot", "form");
this.content
.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].appendChild(this))");
this.content.getElement().executeJs(
LoginOverlayUtils.getLoginFormWrapperScript(
"""
formWrapper.appendChild(this);
"""));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*-
* #%L
* Extended Login Add-on
* %%
* Copyright (C) 2023 - 2026 Flowing Code
* %%
* 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.
* #L%
*/
package com.flowingcode.vaadin.addons.extendedlogin;

/**
* Utility class for LoginOverlay.
*/
class LoginOverlayUtils {

private LoginOverlayUtils() {
// Utility class
}

/**
* Generates a JavaScript snippet that finds the overlay wrapper element.
* Handles both Vaadin 24 and Vaadin 25+ compatibility.
*
* @param action the JavaScript code to execute on the overlay wrapper
* @return the complete JavaScript string with the overlay wrapper lookup and
* the provided action
*/
static String getOverlayWrapperScript(String action) {
return """
setTimeout(() => {
var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper');
if (!overlayWrapper) {
var loginOverlay = document.querySelector('vaadin-login-overlay');
if (loginOverlay && loginOverlay.shadowRoot) {
overlayWrapper = loginOverlay.shadowRoot
.querySelector('vaadin-login-overlay-wrapper');
}
}
if (!overlayWrapper) return;
%s
});
""".formatted(action);
}

/**
* Generates a JavaScript snippet that finds the form element. Handles both
* Vaadin 24 and Vaadin 25+ compatibility.
*
* @param action the JavaScript code to execute on the form
* @return the complete JavaScript string with the form lookup and the provided
* action
*/
static String getFormWrapperScript(String action) {
return """
setTimeout(() => {
var overlayFormWrapper = document.getElementById('vaadinLoginOverlayWrapper');
if (!overlayFormWrapper) {
overlayFormWrapper = document.querySelector('vaadin-login-overlay');
}
if (!overlayFormWrapper) return;
var form = overlayFormWrapper.querySelector('form');
if (form) {
%s
}
});
""".formatted(action);
}

/**
* Generates a JavaScript snippet that finds the form wrapper containing form
* elements. Handles both Vaadin 24 and Vaadin 25+ compatibility.
*
* @param action the JavaScript code to execute on the form wrapper
* @return the complete JavaScript string with the form wrapper lookup and the
* provided action
*/
static String getLoginFormWrapperScript(String action) {
return """
setTimeout(() => {
var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper');
if (!overlayWrapper) {
var loginOverlay = document.querySelector('vaadin-login-overlay');
if (loginOverlay && loginOverlay.shadowRoot) {
overlayWrapper = loginOverlay.shadowRoot
.querySelector('vaadin-login-overlay-wrapper');
}
}
if (!overlayWrapper) return;
var formWrapper = overlayWrapper.querySelector('vaadin-login-form-wrapper');
if (!formWrapper) return;
%s
});
""".formatted(action);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,49 +28,104 @@
*/
public interface ReplaceableLoginOverlay extends HasElement {

/**
* Replaces the contents of the login form with the provided elements. Clears
* existing form
* contents and appends the provided elements.
*
* @param withElement the elements to add to the form
*/
default void replaceFormComponents(HasElement... withElement) {
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].getElementsByTagName('form')[0].replaceChildren())");
this.getElement().executeJs(LoginOverlayUtils.getFormWrapperScript("form.replaceChildren();"));

for (HasElement we : withElement) {
getElement().appendChild(we.getElement());
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].getElementsByTagName('form')[0].appendChild($0))",
we.getElement());
.executeJs(LoginOverlayUtils.getFormWrapperScript("form.appendChild($0);"), we.getElement());
}
}

/**
* Replaces the header/brand component of the login overlay. Clears the brand
* section and appends
* the provided element.
*
* @param withElement the element to set as the new brand/header
*/
default void replaceHeaderComponent(HasElement withElement) {
getElement().appendChild(withElement.getElement());

this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').shadowRoot.querySelector('[part=\"brand\"]').replaceChildren())");
LoginOverlayUtils.getOverlayWrapperScript(
"""
var brand = overlayWrapper.shadowRoot ? overlayWrapper.shadowRoot.querySelector('[part="brand"]') : overlayWrapper.querySelector('[part="brand"]');
if (brand) {
brand.replaceChildren();
}
"""));

this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').shadowRoot.querySelector('[part=\"brand\"]').appendChild($0))",
LoginOverlayUtils.getOverlayWrapperScript(
"""
var brand = overlayWrapper.shadowRoot ? overlayWrapper.shadowRoot.querySelector('[part="brand"]') : overlayWrapper.querySelector('[part="brand"]');
if (brand) {
brand.appendChild($0);
}
"""),
withElement);
}

/**
* Removes the forgot password link from the login form.
*/
default void removeForgotPassword() {
this.getElement()
.executeJs(
LoginOverlayUtils.getLoginFormWrapperScript(
"""
var forgotPassword = formWrapper.querySelector('[slot="forgot-password"]');
if (forgotPassword) {
forgotPassword.remove();
}
"""));
}

/**
* Replaces the forgot password component in the login overlay. Clears the
* forgot password section
* and appends the provided element.
*
* @param withElement the element to set as the new forgot password component
*
*/
default void replaceForgotPassword(HasElement withElement) {
withElement.getElement().setAttribute("slot", "forgot-password");
getElement().appendChild(withElement.getElement());
this.removeForgotPassword();
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].querySelector('[slot=\\\"forgot-password\\\"]').remove())");
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].appendChild($0))",
LoginOverlayUtils.getLoginFormWrapperScript(
"""
formWrapper.appendChild($0);
"""),
withElement);
}

/**
* Removes the default submit button.
* Removes the default submit button.
*/
default void removeSubmitButton() {
this.getElement()
.executeJs(
"setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].querySelector('[slot=\"submit\"]').remove())");
this.getElement()
.executeJs(
LoginOverlayUtils.getLoginFormWrapperScript(
"""
var submitButton = formWrapper.querySelector('[slot="submit"]');
if (submitButton) {
submitButton.remove();
}
"""));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*-
* #%L
* Extended Login Add-on
* %%
* Copyright (C) 2023 - 2026 Flowing Code
* %%
* 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.
* #L%
*/
package com.flowingcode.vaadin.addons;

import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.theme.Theme;

@Theme
public class AppShellConfiguratorImpl implements AppShellConfigurator {

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@

@DemoSource(
"/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java")
//#if vaadin eq 0
@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles.css",
caption = "extended-login-styles.css", condition = "vaadin eq 24")
@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css",
caption = "extended-login-styles-v25.css", condition = "vaadin ge 25")
//#endif
@PageTitle("Extended Login Overlay Demo")
@SuppressWarnings("serial")
@Route(value = "extended-login/login-overlay-demo", layout = ExtendedLoginDemoView.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@

@DemoSource("/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java")
@DemoSource("/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java")
//#if vaadin eq 0
@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles.css",
caption = "extended-login-styles.css", condition = "vaadin eq 24")
@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css",
caption = "extended-login-styles-v25.css", condition = "vaadin ge 25")
//#endif
@PageTitle("Login Layout Demo")
@SuppressWarnings("serial")
@Route(value = "extended-login/login-layout-demo", layout = ExtendedLoginDemoView.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
package com.flowingcode.vaadin.addons.extendedlogin;

import com.flowingcode.vaadin.addons.extendedlogin.it.ServerVersionCallables;
import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dependency.CssImport;
Expand All @@ -39,9 +41,14 @@
*/
@SuppressWarnings("serial")
@Route(value = "extended-login/login-overlay")
@CssImport("./styles/extended-login-styles.css") // hide-source
//#if vaadin eq 24
@CssImport("./styles/extended-login-styles.css")
//#else
@CssImport("./styles/extended-login-styles-v25.css")
//#endif
@Ignore
public class TestExtendedLoginOverlayView extends Div {
// show-source public class TestExtendedLoginOverlayView extends Div {

Check warning on line 50 in src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This block of commented-out lines of code should be removed.

See more on https://sonarcloud.io/project/issues?id=FlowingCode_ExtendedLoginAddon&issues=AZzErky_TBjk2HgQEnEF&open=AZzErky_TBjk2HgQEnEF&pullRequest=27
public class TestExtendedLoginOverlayView extends Div implements ServerVersionCallables { //hide-source

public TestExtendedLoginOverlayView() {
ExtendedLoginOverlay elo = new ExtendedLoginOverlay();
Expand All @@ -60,4 +67,13 @@
elo.setOpened(true);
add(elo);
}

//#if vaadin eq 0
@Override
@ClientCallable
public int getMajorVersion() {
return com.vaadin.flow.server.Version.getMajorVersion();
}
//#endif

}
Loading