index.ftl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>${msg("accountManagementTitle")}</title>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  7. <meta name="robots" content="noindex, nofollow">
  8. <meta name="viewport" content="width=device-width, initial-scale=1">
  9. <script>
  10. <#if properties.developmentMode?has_content && properties.developmentMode == "true">
  11. var developmentMode = true;
  12. var reactRuntime = 'react.development.js';
  13. var reactDOMRuntime = 'react-dom.development.js';
  14. var reactRouterRuntime = 'react-router-dom.js';
  15. <#else>
  16. var developmentMode = false;
  17. var reactRuntime = 'react.production.min.js';
  18. var reactDOMRuntime = 'react-dom.production.min.js';
  19. var reactRouterRuntime = 'react-router-dom.min.js';
  20. </#if>
  21. var authUrl = '${authUrl}';
  22. var baseUrl = '${baseUrl}';
  23. var realm = '${realm.name}';
  24. var resourceUrl = '${resourceUrl}';
  25. var isReactLoading = false;
  26. <#if properties.logo?has_content>
  27. var brandImg = resourceUrl + '${properties.logo}';
  28. <#else>
  29. var brandImg = resourceUrl + '/public/logo.svg';
  30. </#if>
  31. <#if properties.logoUrl?has_content>
  32. var brandUrl = '${properties.logoUrl}';
  33. <#else>
  34. var brandUrl = baseUrl;
  35. </#if>
  36. var features = {
  37. isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
  38. isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
  39. isInternationalizationEnabled : ${realm.isInternationalizationEnabled()?c},
  40. isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
  41. isEventsEnabled : ${isEventsEnabled?c},
  42. isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
  43. isTotpConfigured : ${isTotpConfigured?c},
  44. deleteAccountAllowed : ${deleteAccountAllowed?c}
  45. }
  46. var availableLocales = [];
  47. <#list supportedLocales as locale, label>
  48. availableLocales.push({locale : '${locale}', label : '${label}'});
  49. </#list>
  50. <#if referrer??>
  51. var referrer = '${referrer}';
  52. var referrerName = '${referrerName}';
  53. var referrerUri = '${referrer_uri}'.replace('&amp;', '&');
  54. </#if>
  55. <#if msg??>
  56. var locale = '${locale}';
  57. var l18nMsg = JSON.parse('${msgJSON?no_esc}');
  58. <#else>
  59. var locale = 'en';
  60. var l18Msg = {};
  61. </#if>
  62. </script>
  63. <#if properties.favIcon?has_content>
  64. <link rel="icon" href="${resourceUrl}${properties.favIcon}" type="image/x-icon"/>
  65. <#else>
  66. <link rel="icon" href="${resourceUrl}/public/favicon.ico" type="image/x-icon"/>
  67. </#if>
  68. <script src="${authUrl}js/keycloak.js"></script>
  69. <#if properties.developmentMode?has_content && properties.developmentMode == "true">
  70. <!-- Don't use this in production: -->
  71. <script src="${resourceUrl}/node_modules/react/umd/react.development.js" crossorigin></script>
  72. <script src="${resourceUrl}/node_modules/react-dom/umd/react-dom.development.js" crossorigin></script>
  73. <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
  74. </#if>
  75. <#if properties.extensions?has_content>
  76. <#list properties.extensions?split(' ') as script>
  77. <#if properties.developmentMode?has_content && properties.developmentMode == "true">
  78. <script type="text/babel" src="${resourceUrl}/${script}"></script>
  79. <#else>
  80. <script type="text/javascript" src="${resourceUrl}/${script}"></script>
  81. </#if>
  82. </#list>
  83. </#if>
  84. <#if properties.scripts?has_content>
  85. <#list properties.scripts?split(' ') as script>
  86. <script type="text/javascript" src="${resourceUrl}/${script}"></script>
  87. </#list>
  88. </#if>
  89. <script>
  90. var content = <#include "resources/content.json"/>
  91. </script>
  92. <#if properties.styles?has_content>
  93. <#list properties.styles?split(' ') as style>
  94. <link href="${resourceUrl}/${style}" rel="stylesheet"/>
  95. </#list>
  96. </#if>
  97. <link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/base.css"/>
  98. <link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/app.css"/>
  99. <link href="${resourceUrl}/public/layout.css" rel="stylesheet"/>
  100. </head>
  101. <body>
  102. <script>
  103. var keycloak = Keycloak({
  104. authServerUrl: authUrl,
  105. realm: realm,
  106. clientId: 'account-console'
  107. });
  108. keycloak.init({onLoad: 'check-sso', pkceMethod: 'S256', promiseType: 'native'}).then((authenticated) => {
  109. isReactLoading = true;
  110. toggleReact();
  111. if (!keycloak.authenticated) {
  112. document.getElementById("landingSignInButton").style.display='inline';
  113. document.getElementById("landingSignInLink").style.display='inline';
  114. } else {
  115. document.getElementById("landingSignOutButton").style.display='inline';
  116. document.getElementById("landingSignOutLink").style.display='inline';
  117. document.getElementById("landingLoggedInUser").innerHTML = loggedInUserName('${msg("unknownUser")}', '${msg("fullName")}');
  118. }
  119. loadjs("/Main.js");
  120. }).catch(() => {
  121. alert('failed to initialize keycloak');
  122. });
  123. </script>
  124. <div id="main_react_container" style="display:none;height:100%"></div>
  125. <div id="spinner_screen" style="display:block; height:100%">
  126. <div style="width: 320px; height: 328px; text-align: center; position: absolute; top:0; bottom: 0; left: 0; right: 0; margin: auto;">
  127. <#if properties.logo?has_content>
  128. <img src="${resourceUrl}${properties.logo}" alt="Logo" class="brand">
  129. <#else>
  130. <img src="${resourceUrl}/public/logo.svg" alt="Logo" class="brand">
  131. </#if>
  132. <p>${msg("loadingMessage")}</p>
  133. <div >
  134. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
  135. <path d="M10 50A40 40 0 0 0 90 50A40 42 0 0 1 10 50" fill="#5DBCD2" stroke="none" transform="rotate(16.3145 50 51)">
  136. <animateTransform attributeName="transform" type="rotate" dur="1s" repeatCount="indefinite" keyTimes="0;1" values="0 50 51;360 50 51"></animateTransform>
  137. </path>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. <div id="welcomeScreen" style="display:none;height:100%">
  144. <div class="pf-c-page" id="page-layout-default-nav">
  145. <header role="banner" class="pf-c-page__header">
  146. <div class="pf-c-page__header-brand">
  147. <#if properties.logoUrl?has_content>
  148. <a id="landingLogo" class="pf-c-page__header-brand-link" href="${properties.logoUrl}">
  149. <#else>
  150. <a id="landingLogo" class="pf-c-page__header-brand-link" href="${baseUrl}">
  151. </#if>
  152. <#if properties.logo?has_content>
  153. <img class="pf-c-brand brand" src="${resourceUrl}${properties.logo}" alt="Logo">
  154. <#else>
  155. <img class="pf-c-brand brand" src="${resourceUrl}/public/logo.svg" alt="Logo">
  156. </#if>
  157. </a>
  158. </div>
  159. <div class="pf-c-page__header-tools">
  160. <#if referrer?has_content && referrer_uri?has_content>
  161. <div class="pf-c-page__header-tools-group pf-m-icons">
  162. <a id="landingReferrerLink" href="${referrer_uri}" id="referrer" tabindex="0"><span class="pf-icon pf-icon-arrow"></span>${msg("backTo",referrerName)}</a>
  163. </div>
  164. </#if>
  165. <div class="pf-c-page__header-tools-group pf-m-icons">
  166. <button id="landingSignInButton" tabindex="0" style="display:none" onclick="keycloak.login();" class="pf-c-button pf-m-primary" type="button">${msg("doSignIn")}</button>
  167. <button id="landingSignOutButton" tabindex="0" style="display:none" onclick="keycloak.logout();" class="pf-c-button pf-m-primary" type="button">${msg("doSignOut")}</button>
  168. </div>
  169. <!-- Kebab for mobile -->
  170. <div class="pf-c-page__header-tools-group">
  171. <div id="landingMobileKebab" class="pf-c-dropdown pf-m-mobile" onclick="toggleMobileDropdown();"> <!-- pf-m-expanded -->
  172. <button aria-label="Actions" tabindex="0" id="landingMobileKebabButton" class="pf-c-dropdown__toggle pf-m-plain" type="button" aria-expanded="true" aria-haspopup="true">
  173. <svg fill="currentColor" height="1em" width="1em" viewBox="0 0 192 512" aria-hidden="true" role="img" style="vertical-align: -0.125em;"><path d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z" transform=""></path></svg>
  174. </button>
  175. <ul id="landingMobileDropdown" aria-labelledby="landingMobileKebabButton" class="pf-c-dropdown__menu pf-m-align-right" role="menu" style="display:none">
  176. <#if referrer?has_content && referrer_uri?has_content>
  177. <li role="none">
  178. <a id="landingMobileReferrerLink" href="${referrer_uri}" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("backTo",referrerName)}</a>
  179. </li>
  180. </#if>
  181. <li id="landingSignInLink" role="none" style="display:none">
  182. <a onclick="keycloak.login();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doLogIn")}</a>
  183. </li>
  184. <li id="landingSignOutLink" role="none" style="display:none">
  185. <a onclick="keycloak.logout();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doSignOut")}</a>
  186. </li>
  187. </ul>
  188. </div>
  189. </div>
  190. <span id="landingLoggedInUser"></span>
  191. </div> <!-- end header tools -->
  192. </header>
  193. <main role="main" class="pf-c-page__main">
  194. <section class="pf-c-page__main-section pf-m-light">
  195. <div class="pf-c-content" id="landingWelcomeMessage">
  196. <h1>${msg("accountManagementWelcomeMessage")}</h1>
  197. </div>
  198. </section>
  199. <section class="pf-c-page__main-section">
  200. <div class="pf-l-gallery pf-m-gutter">
  201. <#assign content=theme.apply("content.json")?eval>
  202. <#list content as item>
  203. <div class="pf-l-gallery__item pf-c-card" id="landing-${item.id}">
  204. <div>
  205. <div class="pf-c-card__header pf-c-content">
  206. <h2>
  207. <#if item.icon??>
  208. <i class="pf-icon ${item.icon}"></i>&nbsp;
  209. <#elseif item.iconSvg??>
  210. <img src="${item.iconSvg}" alt="icon"/>&nbsp;
  211. </#if>
  212. ${msg(item.label)}
  213. </h2>
  214. <#if item.descriptionLabel??>
  215. <p>${msg(item.descriptionLabel)}</p>
  216. </#if>
  217. </div>
  218. <div class="pf-c-card__body pf-c-content">
  219. <#if item.content??>
  220. <#list item.content as sub>
  221. <div id="landing-${sub.id}">
  222. <a onclick="toggleReact(); window.location.hash='${sub.path}'">${msg(sub.label)}</a>
  223. </div>
  224. </#list>
  225. <#else>
  226. <a id="landing-${item.id}" onclick="toggleReact(); window.location.hash = '${item.path}'">${msg(item.label)}</a>
  227. </#if>
  228. </div>
  229. </div>
  230. </div>
  231. </#list>
  232. </div>
  233. </section>
  234. </main>
  235. </div>
  236. </div>
  237. <script>
  238. const removeHidden = (content) => {
  239. content.forEach(c => {
  240. if (c.hidden && eval(c.hidden)) {
  241. document.getElementById('landing-' + c.id).remove();
  242. }
  243. if (c.content) removeHidden(c.content);
  244. });
  245. }
  246. removeHidden(content);
  247. </script>
  248. </body>
  249. </html>