KEYCLOAK-7123: l10n dropdowns (#5170)
* KEYCLOAK-7196: Add kc_locale to keycloak.js * KEYCLOAK-7123: Localization dropdowns * Update keycloak-service to latest keycloak.js
This commit is contained in:
parent
fe2ae6ec68
commit
35154db50f
8 changed files with 577 additions and 534 deletions
|
@ -89,9 +89,7 @@ public class AccountConsole {
|
|||
|
||||
map.put("authUrl", session.getContext().getContextPath());
|
||||
map.put("baseUrl", session.getContext().getContextPath() + "/realms/" + realm.getName() + "/account");
|
||||
map.put("realm", realm.getName());
|
||||
map.put("isRegistrationEmailAsUsername", realm.isRegistrationEmailAsUsername());
|
||||
map.put("isEditUserNameAllowed", realm.isEditUsernameAllowed());
|
||||
map.put("realm", realm);
|
||||
map.put("resourceUrl", Urls.themeRoot(baseUri).getPath() + "/account/" + theme.getName());
|
||||
map.put("resourceVersion", Version.RESOURCES_VERSION);
|
||||
|
||||
|
@ -108,7 +106,7 @@ public class AccountConsole {
|
|||
Properties messages = theme.getMessages(locale);
|
||||
map.put("msg", new MessageFormatterMethod(locale, messages));
|
||||
map.put("msgJSON", messagesToJsonString(messages));
|
||||
|
||||
map.put("supportedLocales", supportedLocales(messages));
|
||||
map.put("properties", theme.getProperties());
|
||||
|
||||
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
|
||||
|
@ -119,6 +117,15 @@ public class AccountConsole {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, String> supportedLocales(Properties messages) throws IOException {
|
||||
Map<String, String> supportedLocales = new HashMap<>();
|
||||
for (String l : realm.getSupportedLocales()) {
|
||||
String label = messages.getProperty("locale_" + l, l);
|
||||
supportedLocales.put(l, label);
|
||||
}
|
||||
return supportedLocales;
|
||||
}
|
||||
|
||||
private String messagesToJsonString(Properties props) {
|
||||
if (props == null) return "";
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ doLogOutAllSessions=Log out all sessions
|
|||
doRemove=Remove
|
||||
doAdd=Add
|
||||
doSignOut=Sign Out
|
||||
doLogIn=Log In
|
||||
|
||||
editAccountHtmlTitle=Edit Account
|
||||
personalInfoHtmlTitle=Personal Info
|
||||
|
@ -210,18 +211,18 @@ permissionRequestion=Permission Requestion
|
|||
permission=Permission
|
||||
shares=share(s)
|
||||
|
||||
locale_ca=Catal\u00E0
|
||||
locale_ca=Catal\u00e0
|
||||
locale_de=Deutsch
|
||||
locale_en=English
|
||||
locale_es=Espa\u00F1ol
|
||||
locale_es=Espa\u00f1ol
|
||||
locale_fr=Fran\u00e7ais
|
||||
locale_it=Italian
|
||||
locale_ja=\u65E5\u672C\u8A9E
|
||||
locale_ja=\u65e5\u672c\u8a9e
|
||||
locale_nl=Nederlands
|
||||
locale_no=Norsk
|
||||
locale_lt=Lietuvi\u0173
|
||||
locale_pt-BR=Portugu\u00EAs (Brasil)
|
||||
locale_ru=\u0420\u0443\u0441\u0441\u043A\u0438\u0439
|
||||
locale_sk=Sloven\u010Dina
|
||||
locale_pt-BR=Portugu\u00eas (Brasil)
|
||||
locale_ru=\u0420\u0443\u0441\u0441\u043a\u0438\u0439
|
||||
locale_sk=Sloven\u010dina
|
||||
locale_sv=Svenska
|
||||
locale_zh-CN=\u4e2d\u6587\u7b80\u4f53
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
<script>
|
||||
var authUrl = '${authUrl}';
|
||||
var baseUrl = '${baseUrl}';
|
||||
var realm = '${realm}';
|
||||
var realm = '${realm.name}';
|
||||
var resourceUrl = '${resourceUrl}';
|
||||
var isRegistrationEmailAsUsername = ${isRegistrationEmailAsUsername?c};
|
||||
var isEditUserNameAllowed = ${isEditUserNameAllowed?c};
|
||||
var isRegistrationEmailAsUsername = ${realm.registrationEmailAsUsername?c};
|
||||
var isEditUserNameAllowed = ${realm.editUsernameAllowed?c};
|
||||
var isInternationalizationEnabled = ${realm.internationalizationEnabled?c};
|
||||
|
||||
var availableLocales = [];
|
||||
<#list supportedLocales as locale, label>
|
||||
availableLocales.push({locale : '${locale}', label : '${label}'});
|
||||
</#list>
|
||||
|
||||
<#if referrer??>
|
||||
var referrer = '${referrer}';
|
||||
|
@ -67,7 +73,7 @@
|
|||
<script src="${authUrl}/js/keycloak.js"></script>
|
||||
|
||||
<script>
|
||||
var keycloak = Keycloak('${authUrl}/realms/${realm}/account/keycloak.json');
|
||||
var keycloak = Keycloak('${authUrl}/realms/${realm.name}/account/keycloak.json');
|
||||
keycloak.init({onLoad: 'check-sso'}).success(function(authenticated) {
|
||||
var loadjs = function (url,loadListener) {
|
||||
const script = document.createElement("script");
|
||||
|
@ -128,27 +134,15 @@
|
|||
we are unable to localize the button's message. Not sure what to do about that yet.
|
||||
-->
|
||||
<ul class="nav navbar-nav navbar-right navbar-iconic">
|
||||
<li><button id="signInButton" style="visibility:hidden" onclick="keycloak.login();" class="btn btn-primary btn-lg btn-sign" type="button">Log In</button></li>
|
||||
<li><button id="signInButton" style="visibility:hidden" onclick="keycloak.login();" class="btn btn-primary btn-lg btn-sign" type="button">${msg("doLogIn")}</button></li>
|
||||
<li class="dropdown">
|
||||
<a href="#0" class="dropdown-toggle nav-item-iconic" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
${msg("locale_en")} <span class="caret"></span>
|
||||
${msg("locale_" + locale)} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><a href="#">${msg("locale_ca")}</a></li>
|
||||
<li><a href="#">${msg("locale_de")}</a></li>
|
||||
<li><a href="#">${msg("locale_en")}</a></li>
|
||||
<li><a href="#">${msg("locale_es")}</a></li>
|
||||
<li><a href="#">${msg("locale_fr")}</a></li>
|
||||
<li><a href="#">${msg("locale_it")}</a></li>
|
||||
<li><a href="#">${msg("locale_ja")}</a></li>
|
||||
<li><a href="#">${msg("locale_nl")}</a></li>
|
||||
<li><a href="#">${msg("locale_no")}</a></li>
|
||||
<li><a href="#">${msg("locale_lt")}</a></li>
|
||||
<li><a href="#">${msg("locale_pt-BR")}</a></li>
|
||||
<li><a href="#">${msg("locale_ru")}</a></li>
|
||||
<li><a href="#">${msg("locale_sk")}</a></li>
|
||||
<li><a href="#">${msg("locale_sv")}</a></li>
|
||||
<li><a href="#">${msg("locale_zh-CN")}</a></li>
|
||||
<#list supportedLocales as locale, label>
|
||||
<li><a href="${baseUrl}/?kc_locale=${locale}">${label}</a></li>
|
||||
</#list>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2017 Andy Hanson
|
||||
* Copyright 2017 Brett Epps <https://github.com/eppsilon>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
|
@ -29,7 +29,7 @@ export = Keycloak;
|
|||
declare function Keycloak(config?: string|{}): Keycloak.KeycloakInstance;
|
||||
|
||||
declare namespace Keycloak {
|
||||
type KeycloakAdapterName = 'cordova'|'default';
|
||||
type KeycloakAdapterName = 'cordova'|'default' | any;
|
||||
type KeycloakOnLoad = 'login-required'|'check-sso';
|
||||
type KeycloakResponseMode = 'query'|'fragment';
|
||||
type KeycloakResponseType = 'code'|'id_token token'|'code id_token token';
|
||||
|
@ -39,6 +39,15 @@ declare namespace Keycloak {
|
|||
/**
|
||||
* @private Undocumented.
|
||||
*/
|
||||
useNonce?: boolean;
|
||||
|
||||
/**
|
||||
* Allows to use different adapter:
|
||||
*
|
||||
* - {string} default - using browser api for redirects
|
||||
* - {string} cordova - using cordova plugins
|
||||
* - {function} - allows to provide custom function as adapter.
|
||||
*/
|
||||
adapter?: KeycloakAdapterName;
|
||||
|
||||
/**
|
||||
|
@ -78,7 +87,7 @@ declare namespace Keycloak {
|
|||
* Set the interval to check login state (in seconds).
|
||||
* @default 5
|
||||
*/
|
||||
checkLoginIframeInterval?: boolean;
|
||||
checkLoginIframeInterval?: number;
|
||||
|
||||
/**
|
||||
* Set the OpenID Connect response mode to send to Keycloak upon login.
|
||||
|
@ -141,9 +150,17 @@ declare namespace Keycloak {
|
|||
idpHint?: string;
|
||||
|
||||
/**
|
||||
* Specifies the desired locale for the UI.
|
||||
* Sets the 'ui_locales' query param in compliance with section 3.1.2.1
|
||||
* of the OIDC 1.0 specification.
|
||||
*/
|
||||
locale?: string;
|
||||
|
||||
/**
|
||||
* Specifies the desired Keycloak locale for the UI. This differs from
|
||||
* the locale param in that it tells the Keycloak server to set a cookie and update
|
||||
* the user's profile to a new preferred locale.
|
||||
*/
|
||||
kcLocale?: string;
|
||||
}
|
||||
|
||||
type KeycloakPromiseCallback<T> = (result: T) => void;
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
adapter = loadAdapter('cordova');
|
||||
} else if (initOptions && initOptions.adapter === 'default') {
|
||||
adapter = loadAdapter();
|
||||
} else if (initOptions && typeof initOptions.adapter === "object") {
|
||||
adapter = initOptions.adapter;
|
||||
} else {
|
||||
if (window.Cordova || window.cordova) {
|
||||
adapter = loadAdapter('cordova');
|
||||
|
@ -281,6 +283,10 @@
|
|||
url += '&ui_locales=' + encodeURIComponent(options.locale);
|
||||
}
|
||||
|
||||
if (options && options.kcLocale) {
|
||||
url += '&kc_locale=' + encodeURIComponent(options.kcLocale);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
|
@ -464,6 +470,10 @@
|
|||
} else {
|
||||
console.warn('[KEYCLOAK] Failed to refresh token');
|
||||
|
||||
if (req.status == 400) {
|
||||
kc.clearToken();
|
||||
}
|
||||
|
||||
kc.onAuthRefreshError && kc.onAuthRefreshError();
|
||||
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
|
||||
p.setError(true);
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
|
||||
<li><a href="#" (click)="logout()">{{'doSignOut' | translate}}</a></li>
|
||||
<li class="dropdown-submenu pull-left">
|
||||
<a class="test" tabindex="-1" href="#">Change language</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li *ngFor="let locale of availableLocales" (click)="changeLocale(locale.locale)"><a tabindex="-1" href="#">{{ locale.label }}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -24,6 +24,7 @@ declare const resourceUrl: string;
|
|||
declare const baseUrl: string;
|
||||
declare const referrer: string;
|
||||
declare const referrer_uri: string;
|
||||
declare const availableLocales: Array<Object>;
|
||||
|
||||
@Component({
|
||||
selector: 'app-top-nav',
|
||||
|
@ -34,10 +35,13 @@ export class TopNavComponent implements OnInit {
|
|||
@Input() showSideNav: String;
|
||||
|
||||
public resourceUrl: string = resourceUrl;
|
||||
public availableLocales: Array<Object> = availableLocales;
|
||||
|
||||
private referrer: Referrer;
|
||||
|
||||
constructor(private keycloakService: KeycloakService, translateUtil: TranslateUtil, private respSvc: ResponsivenessService) {
|
||||
constructor(private keycloakService: KeycloakService,
|
||||
translateUtil: TranslateUtil,
|
||||
private respSvc: ResponsivenessService) {
|
||||
this.referrer = new Referrer(translateUtil);
|
||||
}
|
||||
|
||||
|
@ -52,4 +56,8 @@ export class TopNavComponent implements OnInit {
|
|||
this.keycloakService.logout(baseUrl);
|
||||
}
|
||||
|
||||
private changeLocale(newLocale: string) {
|
||||
this.keycloakService.login({kcLocale: newLocale });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue