KEYCLOAK-12936 only change the locale in the AccountPage.
This commit is contained in:
parent
fd9c4e9228
commit
db8cb63565
15 changed files with 79 additions and 277 deletions
|
@ -19,12 +19,12 @@ package org.keycloak.testsuite.ui.account2;
|
||||||
|
|
||||||
import org.jboss.arquillian.graphene.page.Page;
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.ui.account2.page.PersonalInfoPage;
|
import org.keycloak.testsuite.ui.account2.page.PersonalInfoPage;
|
||||||
import org.keycloak.testsuite.ui.account2.page.WelcomeScreen;
|
import org.keycloak.testsuite.ui.account2.page.WelcomeScreen;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -36,7 +36,6 @@ import static org.junit.Assert.assertEquals;
|
||||||
/**
|
/**
|
||||||
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
||||||
*/
|
*/
|
||||||
@Ignore // TODO remove this once KEYCLOAK-12936 is resolved
|
|
||||||
public class InternationalizationTest extends AbstractAccountTest {
|
public class InternationalizationTest extends AbstractAccountTest {
|
||||||
@Page
|
@Page
|
||||||
private WelcomeScreen welcomeScreen;
|
private WelcomeScreen welcomeScreen;
|
||||||
|
@ -53,20 +52,6 @@ public class InternationalizationTest extends AbstractAccountTest {
|
||||||
@Before
|
@Before
|
||||||
public void beforeI18nTest() {
|
public void beforeI18nTest() {
|
||||||
assertTestUserLocale(null);
|
assertTestUserLocale(null);
|
||||||
assertEquals(DEFAULT_LOCALE_NAME, welcomeScreen.header().getCurrentLocaleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void welcomeScreenTest() {
|
|
||||||
welcomeScreen.header().selectLocale(CUSTOM_LOCALE);
|
|
||||||
assertCustomLocaleWelcomeScreen();
|
|
||||||
|
|
||||||
// check if selected locale is preserved
|
|
||||||
welcomeScreen.clickPersonalInfoLink();
|
|
||||||
assertCustomLocaleLoginPage();
|
|
||||||
loginToAccount();
|
|
||||||
assertTestUserLocale(CUSTOM_LOCALE);
|
|
||||||
assertCustomLocalePersonalInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -74,8 +59,10 @@ public class InternationalizationTest extends AbstractAccountTest {
|
||||||
personalInfoPage.navigateTo();
|
personalInfoPage.navigateTo();
|
||||||
loginToAccount();
|
loginToAccount();
|
||||||
assertTestUserLocale(null);
|
assertTestUserLocale(null);
|
||||||
assertEquals(DEFAULT_LOCALE_NAME, personalInfoPage.header().getCurrentLocaleName());
|
personalInfoPage.selectLocale(CUSTOM_LOCALE);
|
||||||
personalInfoPage.header().selectLocale(CUSTOM_LOCALE);
|
personalInfoPage.clickSave(false);
|
||||||
|
WaitUtils.waitForPageToLoad();
|
||||||
|
|
||||||
assertTestUserLocale(CUSTOM_LOCALE);
|
assertTestUserLocale(CUSTOM_LOCALE);
|
||||||
assertCustomLocalePersonalInfo();
|
assertCustomLocalePersonalInfo();
|
||||||
|
|
||||||
|
@ -95,13 +82,11 @@ public class InternationalizationTest extends AbstractAccountTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void userAttributeTest() {
|
public void userAttributeTest() {
|
||||||
testUser.setAttributes(singletonMap(UserModel.LOCALE, singletonList(CUSTOM_LOCALE)));
|
testUser.setAttributes(singletonMap(UserModel.LOCALE, singletonList(CUSTOM_LOCALE)));
|
||||||
testUserResource().update(testUser);
|
testUserResource().update(testUser);
|
||||||
|
|
||||||
welcomeScreen.navigateTo();
|
welcomeScreen.navigateTo();
|
||||||
assertEquals(DEFAULT_LOCALE_NAME, welcomeScreen.header().getCurrentLocaleName());
|
|
||||||
welcomeScreen.clickPersonalInfoLink();
|
welcomeScreen.clickPersonalInfoLink();
|
||||||
assertEquals(DEFAULT_LOCALE_NAME, loginPage.localeDropdown().getSelected());
|
assertEquals(DEFAULT_LOCALE_NAME, loginPage.localeDropdown().getSelected());
|
||||||
loginToAccount();
|
loginToAccount();
|
||||||
|
@ -109,14 +94,10 @@ public class InternationalizationTest extends AbstractAccountTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCustomLocaleWelcomeScreen() {
|
private void assertCustomLocaleWelcomeScreen() {
|
||||||
welcomeScreen.header().assertLocaleVisible(true);
|
|
||||||
assertEquals(CUSTOM_LOCALE_NAME, welcomeScreen.header().getCurrentLocaleName());
|
|
||||||
assertEquals("Vítejte v Keycloaku", welcomeScreen.getWelcomeMessage());
|
assertEquals("Vítejte v Keycloaku", welcomeScreen.getWelcomeMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCustomLocalePersonalInfo() {
|
private void assertCustomLocalePersonalInfo() {
|
||||||
personalInfoPage.header().assertLocaleVisible(true);
|
|
||||||
assertEquals(CUSTOM_LOCALE_NAME, personalInfoPage.header().getCurrentLocaleName());
|
|
||||||
assertEquals("Osobní údaje", personalInfoPage.getPageTitle());
|
assertEquals("Osobní údaje", personalInfoPage.getPageTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +107,7 @@ public class InternationalizationTest extends AbstractAccountTest {
|
||||||
|
|
||||||
private void assertTestUserLocale(String expectedLocale) {
|
private void assertTestUserLocale(String expectedLocale) {
|
||||||
String actualLocale = null;
|
String actualLocale = null;
|
||||||
List <String> userLocales = null;
|
List <String> userLocales;
|
||||||
Map<String, List<String>> userAttributes = testUserResource().toRepresentation().getAttributes();
|
Map<String, List<String>> userAttributes = testUserResource().toRepresentation().getAttributes();
|
||||||
|
|
||||||
if (userAttributes != null) {
|
if (userAttributes != null) {
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package org.keycloak.testsuite.ui.account2;
|
package org.keycloak.testsuite.ui.account2;
|
||||||
|
|
||||||
import org.jboss.arquillian.graphene.page.Page;
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -123,31 +122,6 @@ public class ReferrerTest extends AbstractAccountTest {
|
||||||
testReferrer(personalInfoPage.header(), false);
|
testReferrer(personalInfoPage.header(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that i18n and referrer work well together
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Ignore // TODO remove this once KEYCLOAK-12936 is resolved
|
|
||||||
public void i18nTest() {
|
|
||||||
RealmRepresentation realm = testRealmResource().toRepresentation();
|
|
||||||
configureInternationalizationForRealm(realm);
|
|
||||||
testRealmResource().update(realm);
|
|
||||||
testContext.setTestRealmReps(Collections.emptyList()); // a small hack; we want realm re-import after this test
|
|
||||||
|
|
||||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl());
|
|
||||||
welcomeScreen.header().assertReferrerLinkVisible(true);
|
|
||||||
welcomeScreen.header().selectLocale(CUSTOM_LOCALE);
|
|
||||||
welcomeScreen.header().assertReferrerLinkVisible(true);
|
|
||||||
|
|
||||||
welcomeScreen.clickPersonalInfoLink();
|
|
||||||
assertEquals(CUSTOM_LOCALE_NAME, loginPage.localeDropdown().getSelected());
|
|
||||||
loginToAccount();
|
|
||||||
personalInfoPage.header().assertReferrerLinkVisible(true);
|
|
||||||
personalInfoPage.header().selectLocale(DEFAULT_LOCALE);
|
|
||||||
assertEquals(DEFAULT_LOCALE_NAME, personalInfoPage.header().getCurrentLocaleName());
|
|
||||||
testReferrer(personalInfoPage.header(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testReferrer(AbstractHeader header, boolean expectReferrerVisible) {
|
private void testReferrer(AbstractHeader header, boolean expectReferrerVisible) {
|
||||||
if (expectReferrerVisible) {
|
if (expectReferrerVisible) {
|
||||||
assertEquals(REFERRER_LINK_TEXT, header.getReferrerLinkText());
|
assertEquals(REFERRER_LINK_TEXT, header.getReferrerLinkText());
|
||||||
|
|
|
@ -43,7 +43,6 @@ public class WelcomeScreenTest extends AbstractAccountTest {
|
||||||
public void loginLogoutTest() {
|
public void loginLogoutTest() {
|
||||||
accountWelcomeScreen.assertCurrent();
|
accountWelcomeScreen.assertCurrent();
|
||||||
accountWelcomeScreen.header().assertLogoutBtnVisible(false);
|
accountWelcomeScreen.header().assertLogoutBtnVisible(false);
|
||||||
accountWelcomeScreen.header().assertLocaleVisible(false);
|
|
||||||
|
|
||||||
// login
|
// login
|
||||||
accountWelcomeScreen.header().clickLoginBtn();
|
accountWelcomeScreen.header().clickLoginBtn();
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.testsuite.ui.account2.page;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.openqa.selenium.WebElement;
|
import org.openqa.selenium.WebElement;
|
||||||
import org.openqa.selenium.support.FindBy;
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
import static org.keycloak.testsuite.util.UIAssert.assertElementDisabled;
|
import static org.keycloak.testsuite.util.UIAssert.assertElementDisabled;
|
||||||
import static org.keycloak.testsuite.util.UIAssert.assertInputElementValid;
|
import static org.keycloak.testsuite.util.UIAssert.assertInputElementValid;
|
||||||
|
@ -38,6 +39,8 @@ public class PersonalInfoPage extends AbstractLoggedInPage {
|
||||||
private WebElement firstName;
|
private WebElement firstName;
|
||||||
@FindBy(id = "last-name")
|
@FindBy(id = "last-name")
|
||||||
private WebElement lastName;
|
private WebElement lastName;
|
||||||
|
@FindBy(id = "locale-select")
|
||||||
|
private Select localeSelector;
|
||||||
@FindBy(id = "save-btn")
|
@FindBy(id = "save-btn")
|
||||||
private WebElement saveBtn;
|
private WebElement saveBtn;
|
||||||
@FindBy(id = "cancel-btn")
|
@FindBy(id = "cancel-btn")
|
||||||
|
@ -105,8 +108,14 @@ public class PersonalInfoPage extends AbstractLoggedInPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clickSave() {
|
public void clickSave() {
|
||||||
|
clickSave(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clickSave(boolean assertAlert) {
|
||||||
saveBtn.click();
|
saveBtn.click();
|
||||||
alert().assertIsDisplayed();
|
if (assertAlert) {
|
||||||
|
alert().assertIsDisplayed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clickCancel() {
|
public void clickCancel() {
|
||||||
|
@ -126,4 +135,8 @@ public class PersonalInfoPage extends AbstractLoggedInPage {
|
||||||
&& user.getFirstName().equals(getFirstName())
|
&& user.getFirstName().equals(getFirstName())
|
||||||
&& user.getLastName().equals(getLastName());
|
&& user.getLastName().equals(getLastName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void selectLocale(String customLocale) {
|
||||||
|
localeSelector.selectByValue(customLocale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,36 +60,8 @@ public abstract class AbstractHeader extends AbstractFragmentWithMobileLayout {
|
||||||
return getToolsBtnText(getReferrerLink());
|
return getToolsBtnText(getReferrerLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectLocale(String locale) {
|
|
||||||
if (isMobileLayout()) {
|
|
||||||
clickMobileKebab();
|
|
||||||
}
|
|
||||||
getLocaleBtn().click();
|
|
||||||
clickLink(getLocaleDropdown().findElement(By.id(getLocaleElementIdPrefix() + locale)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurrentLocaleName() {
|
|
||||||
if (!isMobileLayout()) {
|
|
||||||
return getTextFromElement(getLocaleBtn());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clickMobileKebab();
|
|
||||||
String ret = getTextFromElement(getLocaleBtn());
|
|
||||||
clickMobileKebab(); // hide the dropdown again
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertLocaleVisible(boolean expected) {
|
|
||||||
assertToolsBtnVisible(expected, getLocaleBtn());
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void clickMobileKebab();
|
public abstract void clickMobileKebab();
|
||||||
|
|
||||||
protected abstract WebElement getLocaleBtn();
|
|
||||||
|
|
||||||
protected abstract WebElement getLocaleDropdown();
|
|
||||||
|
|
||||||
protected abstract WebElement getLogoutBtn ();
|
protected abstract WebElement getLogoutBtn ();
|
||||||
|
|
||||||
protected abstract WebElement getReferrerLink();
|
protected abstract WebElement getReferrerLink();
|
||||||
|
|
|
@ -54,16 +54,6 @@ public class LoggedInPageHeader extends AbstractHeader {
|
||||||
clickLink(mobileKebab);
|
clickLink(mobileKebab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WebElement getLocaleBtn() {
|
|
||||||
return isMobileLayout() ? localeBtnMobile : localeBtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WebElement getLocaleDropdown() {
|
|
||||||
return isMobileLayout() ? localeDropdownMobile : localeDropdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WebElement getLogoutBtn() {
|
protected WebElement getLogoutBtn() {
|
||||||
return isMobileLayout() ? logoutBtnMobile : logoutBtn;
|
return isMobileLayout() ? logoutBtnMobile : logoutBtn;
|
||||||
|
|
|
@ -41,11 +41,6 @@ public class WelcomeScreenHeader extends AbstractHeader {
|
||||||
@FindBy(id = "landing-mobile-local-toggle")
|
@FindBy(id = "landing-mobile-local-toggle")
|
||||||
private WebElement localeBtnMobile;
|
private WebElement localeBtnMobile;
|
||||||
|
|
||||||
@FindBy(id = "landing-locale-dropdown-list")
|
|
||||||
private WebElement localeDropdown;
|
|
||||||
@FindBy(id = "landingMobileDropdown") // the mobile locale menu is integrated with the generic mobile menu
|
|
||||||
private WebElement localeDropdownMobile;
|
|
||||||
|
|
||||||
@FindBy(id = "landingReferrerLink")
|
@FindBy(id = "landingReferrerLink")
|
||||||
private WebElement referrerLink;
|
private WebElement referrerLink;
|
||||||
@FindBy(id = "landingMobileReferrerLink")
|
@FindBy(id = "landingMobileReferrerLink")
|
||||||
|
@ -67,16 +62,6 @@ public class WelcomeScreenHeader extends AbstractHeader {
|
||||||
assertToolsBtnVisible(expected, isMobileLayout() ? loginBtnMobile : loginBtn);
|
assertToolsBtnVisible(expected, isMobileLayout() ? loginBtnMobile : loginBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WebElement getLocaleBtn() {
|
|
||||||
return isMobileLayout() ? localeBtnMobile : localeBtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WebElement getLocaleDropdown() {
|
|
||||||
return isMobileLayout() ? localeDropdownMobile : localeDropdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WebElement getLogoutBtn() {
|
protected WebElement getLogoutBtn() {
|
||||||
return isMobileLayout() ? logoutBtnMobile : logoutBtn;
|
return isMobileLayout() ? logoutBtnMobile : logoutBtn;
|
||||||
|
|
|
@ -216,6 +216,10 @@
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/FormHelperText.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/FormHelperText.js</include>
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/Form.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/Form.js</include>
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/index.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Form/index.js</include>
|
||||||
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/FormSelect/index.js</include>
|
||||||
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/FormSelect/FormSelect.js</include>
|
||||||
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/FormSelect/FormSelectOption.js</include>
|
||||||
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/FormSelect/FormSelectOptionGroup.js</include>
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxBody.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxBody.js</include>
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxCloseButton.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxCloseButton.js</include>
|
||||||
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxFooter.js</include>
|
<include>**/node_modules/@patternfly/react-core/dist/umd/components/Modal/ModalBoxFooter.js</include>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
var features = {
|
var features = {
|
||||||
isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
|
isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
|
||||||
isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
|
isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
|
||||||
isInternationalizationEnabled : false,
|
isInternationalizationEnabled : ${realm.isInternationalizationEnabled()?c},
|
||||||
isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
|
isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
|
||||||
isEventsEnabled : ${isEventsEnabled?c},
|
isEventsEnabled : ${isEventsEnabled?c},
|
||||||
isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
|
isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
|
||||||
|
|
|
@ -11,6 +11,7 @@ remove=Remove
|
||||||
update=Update
|
update=Update
|
||||||
loadingMessage=Account Console loading ...
|
loadingMessage=Account Console loading ...
|
||||||
|
|
||||||
|
selectLocale=Select a locale
|
||||||
# Device Activity Page
|
# Device Activity Page
|
||||||
signedInDevices=Signed In Devices
|
signedInDevices=Signed In Devices
|
||||||
signedInDevicesExplanation=Sign out any device that is unfamiliar.
|
signedInDevicesExplanation=Sign out any device that is unfamiliar.
|
||||||
|
|
|
@ -53,60 +53,6 @@ var loadPatternFly = function () {
|
||||||
patternFlyHasLoaded = true;
|
patternFlyHasLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var toggleLocaleDropdown = function () {
|
|
||||||
var localeDropdownList = document.getElementById("landing-locale-dropdown-list");
|
|
||||||
if (localeDropdownList.hasAttribute("hidden")) {
|
|
||||||
localeDropdownList.removeAttribute("hidden");
|
|
||||||
document.getElementById("landing-locale-dropdown-button").setAttribute("aria-expanded", true);
|
|
||||||
} else {
|
|
||||||
localeDropdownList.setAttribute("hidden", true);
|
|
||||||
document.getElementById("landing-locale-dropdown-button").setAttribute("aria-expanded", false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleMobileDropdown = function () {
|
|
||||||
var mobileDropdown = document.getElementById("landingMobileDropdown");
|
|
||||||
var mobileKebab = document.getElementById("landingMobileKebab");
|
|
||||||
var mobileKebabButton = document.getElementById("landingMobileKebabButton");
|
|
||||||
if (mobileDropdown.style.display === 'none') {
|
|
||||||
mobileDropdown.style.display = 'block';
|
|
||||||
mobileKebab.classList.add("pf-m-expanded");
|
|
||||||
mobileKebabButton.setAttribute("aria-expanded", "true");
|
|
||||||
} else {
|
|
||||||
mobileDropdown.style.display = 'none';
|
|
||||||
mobileKebab.classList.remove("pf-m-expanded");
|
|
||||||
mobileKebabButton.setAttribute("aria-expanded", "false");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleMobileChooseLocale = function() {
|
|
||||||
var mobileLocaleSelectedIcon = document.getElementById("landingMobileLocaleSelectedIcon");
|
|
||||||
var isDropdownClosed = mobileLocaleSelectedIcon.classList.contains("fa-angle-right");
|
|
||||||
var mobileLocaleSeparator = document.getElementById("landingMobileLocaleSeparator");
|
|
||||||
|
|
||||||
if (isDropdownClosed) {
|
|
||||||
mobileLocaleSelectedIcon.classList.remove("fa-angle-right");
|
|
||||||
mobileLocaleSelectedIcon.classList.add("fa-angle-down");
|
|
||||||
mobileLocaleSeparator.style.display = 'block';
|
|
||||||
} else {
|
|
||||||
mobileLocaleSelectedIcon.classList.add("fa-angle-right");
|
|
||||||
mobileLocaleSelectedIcon.classList.remove("fa-angle-down");
|
|
||||||
mobileLocaleSeparator.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i=0; i < availableLocales.length; i++) {
|
|
||||||
if (locale === availableLocales[i].locale) continue; // don't unhide current locale
|
|
||||||
var mobileLocaleSelection = document.getElementById("landing-mobile-locale-" + availableLocales[i].locale);
|
|
||||||
if (isDropdownClosed) {
|
|
||||||
mobileLocaleSelection.style.display= 'inline';
|
|
||||||
} else {
|
|
||||||
mobileLocaleSelection.style.display= 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleMobileDropdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadjs = function (url, loadListener) {
|
var loadjs = function (url, loadListener) {
|
||||||
const script = document.createElement("script");
|
const script = document.createElement("script");
|
||||||
script.src = resourceUrl + url;
|
script.src = resourceUrl + url;
|
||||||
|
|
|
@ -21,7 +21,6 @@ import {Dropdown, KebabToggle, Toolbar, ToolbarGroup, ToolbarItem} from '@patter
|
||||||
import {ReferrerDropdownItem} from './widgets/ReferrerDropdownItem';
|
import {ReferrerDropdownItem} from './widgets/ReferrerDropdownItem';
|
||||||
import {ReferrerLink} from './widgets/ReferrerLink';
|
import {ReferrerLink} from './widgets/ReferrerLink';
|
||||||
import {Features} from './widgets/features';
|
import {Features} from './widgets/features';
|
||||||
import {LocaleNav,LocaleDropdown} from './widgets/LocaleSelectors';
|
|
||||||
import {LogoutButton,LogoutDropdownItem} from './widgets/Logout';
|
import {LogoutButton,LogoutDropdownItem} from './widgets/Logout';
|
||||||
|
|
||||||
declare const referrerName: string;
|
declare const referrerName: string;
|
||||||
|
@ -54,10 +53,6 @@ export class PageToolbar extends React.Component<PageToolbarProps, PageToolbarSt
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features.isInternationalizationEnabled) {
|
|
||||||
kebabDropdownItems.push(<LocaleNav key='kebabLocaleNav'/>);
|
|
||||||
}
|
|
||||||
|
|
||||||
kebabDropdownItems.push(<LogoutDropdownItem key='LogoutDropdownItem'/>);
|
kebabDropdownItems.push(<LogoutDropdownItem key='LogoutDropdownItem'/>);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -71,12 +66,6 @@ export class PageToolbar extends React.Component<PageToolbarProps, PageToolbarSt
|
||||||
}
|
}
|
||||||
|
|
||||||
<ToolbarGroup key='secondGroup'>
|
<ToolbarGroup key='secondGroup'>
|
||||||
{features.isInternationalizationEnabled &&
|
|
||||||
<ToolbarItem className="pf-m-icons" key='locale'>
|
|
||||||
<LocaleDropdown/>
|
|
||||||
</ToolbarItem>
|
|
||||||
}
|
|
||||||
|
|
||||||
<ToolbarItem className="pf-m-icons" key='logout'>
|
<ToolbarItem className="pf-m-icons" key='logout'>
|
||||||
<LogoutButton/>
|
<LogoutButton/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
|
|
|
@ -23,8 +23,10 @@ import { Features } from '../../widgets/features';
|
||||||
import { Msg } from '../../widgets/Msg';
|
import { Msg } from '../../widgets/Msg';
|
||||||
import { ContentPage } from '../ContentPage';
|
import { ContentPage } from '../ContentPage';
|
||||||
import { ContentAlert } from '../ContentAlert';
|
import { ContentAlert } from '../ContentAlert';
|
||||||
|
import { LocaleSelector } from '../../widgets/LocaleSelectors';
|
||||||
|
|
||||||
declare const features: Features;
|
declare const features: Features;
|
||||||
|
declare const locale: string;
|
||||||
|
|
||||||
interface AccountPageProps {
|
interface AccountPageProps {
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,7 @@ interface FormFields {
|
||||||
readonly firstName?: string;
|
readonly firstName?: string;
|
||||||
readonly lastName?: string;
|
readonly lastName?: string;
|
||||||
readonly email?: string;
|
readonly email?: string;
|
||||||
|
attributes?: { locale?: [string] };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AccountPageState {
|
interface AccountPageState {
|
||||||
|
@ -58,7 +61,8 @@ export class AccountPage extends React.Component<AccountPageProps, AccountPageSt
|
||||||
username: '',
|
username: '',
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
email: ''
|
email: '',
|
||||||
|
attributes: {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +77,12 @@ export class AccountPage extends React.Component<AccountPageProps, AccountPageSt
|
||||||
AccountServiceClient.Instance.doGet("/")
|
AccountServiceClient.Instance.doGet("/")
|
||||||
.then((response: AxiosResponse<FormFields>) => {
|
.then((response: AxiosResponse<FormFields>) => {
|
||||||
this.setState(this.DEFAULT_STATE);
|
this.setState(this.DEFAULT_STATE);
|
||||||
this.setState({...{ formFields: response.data }});
|
const formFields = response.data;
|
||||||
|
if (!formFields.attributes || !formFields.attributes.locale) {
|
||||||
|
formFields.attributes = { locale: [locale] };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({...{ formFields: formFields }});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +109,9 @@ export class AccountPage extends React.Component<AccountPageProps, AccountPageSt
|
||||||
AccountServiceClient.Instance.doPost("/", { data: reqData })
|
AccountServiceClient.Instance.doPost("/", { data: reqData })
|
||||||
.then(() => { // to use response, say ((response: AxiosResponse<FormFields>) => {
|
.then(() => { // to use response, say ((response: AxiosResponse<FormFields>) => {
|
||||||
ContentAlert.success('accountUpdatedMessage');
|
ContentAlert.success('accountUpdatedMessage');
|
||||||
|
if (locale !== this.state.formFields.attributes!.locale![0]) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
|
@ -187,6 +199,19 @@ export class AccountPage extends React.Component<AccountPageProps, AccountPageSt
|
||||||
>
|
>
|
||||||
</TextInput>
|
</TextInput>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
{features.isInternationalizationEnabled && <FormGroup
|
||||||
|
label={Msg.localize('selectLocale')}
|
||||||
|
isRequired
|
||||||
|
fieldId="locale"
|
||||||
|
>
|
||||||
|
<LocaleSelector id="locale-selector"
|
||||||
|
value={fields.attributes!.locale || ''}
|
||||||
|
onChange={value => this.setState({
|
||||||
|
errors: this.state.errors,
|
||||||
|
formFields: { ...this.state.formFields, attributes: { ...this.state.formFields.attributes, locale: [value] }}
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</FormGroup>}
|
||||||
<ActionGroup>
|
<ActionGroup>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|
|
@ -13,122 +13,45 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {withRouter, RouteComponentProps} from 'react-router-dom';
|
|
||||||
|
|
||||||
import {Msg} from './Msg';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dropdown,
|
FormSelect,
|
||||||
DropdownItem,
|
FormSelectOption,
|
||||||
DropdownToggle,
|
FormSelectProps
|
||||||
Nav,
|
|
||||||
NavExpandable,
|
|
||||||
NavItem,
|
|
||||||
NavList
|
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
|
import { Msg } from './Msg';
|
||||||
declare const locale: string;
|
|
||||||
declare const baseUrl: string;
|
|
||||||
declare const referrer: string;
|
|
||||||
declare const referrerUri: string;
|
|
||||||
|
|
||||||
interface AvailableLocale {
|
interface AvailableLocale {
|
||||||
locale: string;
|
locale: string;
|
||||||
label: string;
|
label: string;
|
||||||
};
|
};
|
||||||
declare const availableLocales: [AvailableLocale];
|
declare const availableLocales: [AvailableLocale];
|
||||||
// remove entry for current locale
|
|
||||||
const availLocales = availableLocales.filter((availableLocale: AvailableLocale) => availableLocale.locale !== locale);
|
|
||||||
|
|
||||||
let referrerFragment = '';
|
interface LocaleSelectorProps extends FormSelectProps { }
|
||||||
if ((typeof referrer !== 'undefined') &&
|
interface LocaleSelectorState { }
|
||||||
(typeof referrerUri !== 'undefined')) {
|
export class LocaleSelector extends React.Component<LocaleSelectorProps, LocaleSelectorState> {
|
||||||
referrerFragment = '&referrer=' + referrer + '&referrer_uri=' + encodeURIComponent(referrerUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LocaleKebabItemProps extends RouteComponentProps {}
|
constructor(props: LocaleSelectorProps) {
|
||||||
interface LocaleKebabItemState {activeGroup: string; activeItem: string}
|
|
||||||
class LocaleKebabItem extends React.Component<LocaleKebabItemProps, LocaleKebabItemState> {
|
|
||||||
public constructor(props: LocaleKebabItemProps) {
|
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
|
||||||
activeGroup: 'locale-group',
|
|
||||||
activeItem: ''
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
const appPath = this.props.location.pathname;
|
|
||||||
const localeNavItems = availLocales.map((availableLocale: AvailableLocale) => {
|
|
||||||
const url = baseUrl + '?kc_locale=' + availableLocale.locale + referrerFragment + '#' + appPath;
|
|
||||||
return (<NavItem
|
|
||||||
id={`mobile-locale-${availableLocale.locale}`}
|
|
||||||
key={availableLocale.locale}
|
|
||||||
to={url}>
|
|
||||||
{availableLocale.label}
|
|
||||||
</NavItem> );
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Nav>
|
<FormSelect
|
||||||
<NavList>
|
id="locale-select"
|
||||||
<NavExpandable id="mobile-locale" title={Msg.localize('locale_' + locale)} isActive={false} groupId="locale-group">
|
value={this.props.value}
|
||||||
{localeNavItems}
|
onChange={(value, event) => { if (this.props.onChange) this.props.onChange(value, event) }}
|
||||||
</NavExpandable>
|
aria-label={Msg.localize('selectLocale')}
|
||||||
</NavList>
|
>
|
||||||
</Nav>
|
{availableLocales.map((locale, index) =>
|
||||||
|
<FormSelectOption
|
||||||
|
key={index}
|
||||||
|
value={locale.locale}
|
||||||
|
label={locale.label}
|
||||||
|
/>)
|
||||||
|
}
|
||||||
|
</FormSelect>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
interface LocaleDropdownComponentProps extends RouteComponentProps {}
|
|
||||||
interface LocaleDropdownComponentState {isDropdownOpen: boolean}
|
|
||||||
class LocaleDropdownComponent extends React.Component<LocaleDropdownComponentProps, LocaleDropdownComponentState> {
|
|
||||||
public constructor(props: LocaleDropdownComponentProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {isDropdownOpen: false};
|
|
||||||
}
|
|
||||||
|
|
||||||
private onDropdownToggle = (isDropdownOpen: boolean) => {
|
|
||||||
this.setState({
|
|
||||||
isDropdownOpen
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private onDropdownSelect = () => {
|
|
||||||
this.setState({
|
|
||||||
isDropdownOpen: !this.state.isDropdownOpen
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
|
||||||
const appPath = this.props.location.pathname;
|
|
||||||
const localeDropdownItems = availLocales.map((availableLocale: AvailableLocale) => {
|
|
||||||
const url = baseUrl + '?kc_locale=' + availableLocale.locale + referrerFragment + '#' + appPath;
|
|
||||||
return (<DropdownItem
|
|
||||||
id={`locale-${availableLocale.locale}`}
|
|
||||||
key={availableLocale.locale}
|
|
||||||
href={url}>
|
|
||||||
{availableLocale.label}
|
|
||||||
</DropdownItem> );
|
|
||||||
});
|
|
||||||
|
|
||||||
if (localeDropdownItems.length < 2) return (<React.Fragment/>);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dropdown
|
|
||||||
isPlain
|
|
||||||
position="right"
|
|
||||||
onSelect={this.onDropdownSelect}
|
|
||||||
isOpen={this.state.isDropdownOpen}
|
|
||||||
toggle={<DropdownToggle id="locale-dropdown-toggle" onToggle={this.onDropdownToggle}><Msg msgKey={'locale_' + locale}/></DropdownToggle>}
|
|
||||||
dropdownItems={localeDropdownItems}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LocaleDropdown = withRouter(LocaleDropdownComponent);
|
|
||||||
export const LocaleNav = withRouter(LocaleKebabItem);
|
|
|
@ -105,7 +105,7 @@
|
||||||
'./Expandable': '@empty', //'./Expandable/index.js',
|
'./Expandable': '@empty', //'./Expandable/index.js',
|
||||||
'./Form': './Form/index.js',
|
'./Form': './Form/index.js',
|
||||||
'./FormGroup': './FormGroup/index.js',
|
'./FormGroup': './FormGroup/index.js',
|
||||||
'./FormSelect': '@empty', //'./FormSelect/index.js',
|
'./FormSelect': './FormSelect/index.js',
|
||||||
'./InputGroup': '@empty', //'./InputGroup/index.js',
|
'./InputGroup': '@empty', //'./InputGroup/index.js',
|
||||||
'./Label': '@empty', //'./Label/index.js',
|
'./Label': '@empty', //'./Label/index.js',
|
||||||
'./List': '@empty', //'./List/index.js',
|
'./List': '@empty', //'./List/index.js',
|
||||||
|
|
Loading…
Reference in a new issue