Skip to content

Commit

Permalink
initial version of the custom admin ui (#626)
Browse files Browse the repository at this point in the history
* initial version of the custom admin ui

Signed-off-by: Erik Jan de Wit <[email protected]>

* PR review fixes

Signed-off-by: Erik Jan de Wit <[email protected]>

---------

Signed-off-by: Erik Jan de Wit <[email protected]>
  • Loading branch information
edewit authored Jan 28, 2025
1 parent c23f8d0 commit f4c5df7
Show file tree
Hide file tree
Showing 21 changed files with 3,573 additions and 0 deletions.
28 changes: 28 additions & 0 deletions extension/extend-admin-console-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Custom Keycloak Admin UI

This is a template to build a custom Keycloak Account UI using the [Keycloak Admin UI](https://npmjs.com/package/@keycloak/keycloak-admin-ui) package.

## Getting started

To use HMR (Hot module replacement) in development, run the following command:

```bash
pnpm i
pnpm run dev
```
Then start the Keycloak server:

```bash
pnpm run start-keycloak
```

open the admin-console in your browser (http://localhost:8080/), you will see the custom UI.

## Build

To build the application for production, run the following command:

```bash
mvn install
```
This will create a "jar" file in the `target` directory that you can deploy to your Keycloak server by copying it to the `providers` directory.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"themes": [
{
"name": "my-admin",
"types": [
"admin"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<!doctype html>
<html lang="${locale}">
<head>
<meta charset="utf-8">
<base href="${resourceUrl}/">
<link rel="icon" type="${properties.favIconType!'image/svg+xml'}" href="${resourceUrl}${properties.favIcon!'/favicon.svg'}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="${properties.description!'The Admin Console is a web-based interface for managing keycloak.'}">
<title>${properties.title!'Admin Management'}</title>
<style>
.keycloak__loading-container {
height: 100vh;
width: 100%;
background-color: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 0;
}
#loading-text {
font-size: 20px;
font-weight: 600;
}
.loader {
width: 48px;
height: 48px;
border: 5px solid #FFF;
border-bottom-color: #06c;
border-radius: 50%;
display: inline-block;
box-sizing: border-box;
animation: rotation 1s linear infinite;
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<script type="importmap">
{
"imports": {
"react": "${resourceCommonUrl}/vendor/react/react.production.min.js",
"react/jsx-runtime": "${resourceCommonUrl}/vendor/react/react-jsx-runtime.production.min.js",
"react-dom": "${resourceCommonUrl}/vendor/react-dom/react-dom.production.min.js"
}
}
</script>
<#if devServerUrl?has_content>
<script type="module">
import { injectIntoGlobalHook } from "${devServerUrl}/@react-refresh";
injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;
</script>
<script type="module">
import { inject } from "${devServerUrl}/@vite-plugin-checker-runtime";
inject({
overlayConfig: {},
base: "/",
});
</script>
<script type="module" src="${devServerUrl}/@vite/client"></script>
<script type="module" src="${devServerUrl}/src/main.tsx"></script>
</#if>
<#if entryStyles?has_content>
<#list entryStyles as style>
<link rel="stylesheet" href="${resourceUrl}/${style}">
</#list>
</#if>
<#if properties.styles?has_content>
<#list properties.styles?split(' ') as style>
<link rel="stylesheet" href="${resourceUrl}/${style}">
</#list>
</#if>
<#if entryScript?has_content>
<script type="module" src="${resourceUrl}/${entryScript}"></script>
</#if>
<#if properties.scripts?has_content>
<#list properties.scripts?split(' ') as script>
<script type="module" src="${resourceUrl}/${script}"></script>
</#list>
</#if>
<#if entryImports?has_content>
<#list entryImports as import>
<link rel="modulepreload" href="${resourceUrl}/${import}">
</#list>
</#if>
</head>
<body>
<div id="app">
<div class="keycloak__loading-container">
<span class="loader" role="progressbar" aria-valuetext="Loading...">
</span>
<div>
<p id="loading-text">Loading the account console</p>
</div>
</div>
</div>
<noscript>JavaScript is required to use the Account Console.</noscript>
<script id="environment" type="application/json">
{
"authUrl": "${authUrl}",
"authServerUrl": "${authServerUrl}",
"realm": "${realm.name}",
"clientId": "${clientId}",
"resourceUrl": "${resourceUrl}",
"logo": "${properties.logo!""}",
"logoUrl": "${properties.logoUrl!""}",
"baseUrl": "${baseUrl}",
"locale": "${locale}",
"referrerName": "${referrerName!""}",
"referrerUrl": "${referrer_uri!""}",
"features": {
"isRegistrationEmailAsUsername": ${realm.registrationEmailAsUsername?c},
"isEditUserNameAllowed": ${realm.editUsernameAllowed?c},
"isInternationalizationEnabled": ${realm.isInternationalizationEnabled()?c},
"isLinkedAccountsEnabled": ${realm.identityFederationEnabled?c},
"isMyResourcesEnabled": ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
"deleteAccountAllowed": ${deleteAccountAllowed?c},
"updateEmailFeatureEnabled": ${updateEmailFeatureEnabled?c},
"updateEmailActionEnabled": ${updateEmailActionEnabled?c},
"isViewGroupsEnabled": ${isViewGroupsEnabled?c},
"isOid4VciEnabled": ${isOid4VciEnabled?c}
}
}
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cancel=Cancelled
myPage=My page
myPage.save.success=Personal info saved
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
parent=keycloak.v2
deprecatedMode=false
36 changes: 36 additions & 0 deletions extension/extend-admin-console-node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"start-keycloak": "node ./start-server.js --account-dev"
},
"dependencies": {
"@keycloak/keycloak-ui-shared": "^26.0.7",
"@patternfly/react-core": "5.0.0",
"i18next": "^23.14.0",
"i18next-http-backend": "^2.6.0",
"keycloak-js": "^26.0.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.3",
"react-router-dom": "^6.26.1"
},
"devDependencies": {
"@keycloak/keycloak-admin-client": "^26.0.7",
"@octokit/rest": "^20.1.1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react-swc": "^3.7.0",
"gunzip-maybe": "^1.4.2",
"tar-fs": "^3.0.6",
"typescript": "^5.5.4",
"vite": "^5.4.1",
"vite-plugin-checker": "^0.6.4"
},
"packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228"
}
Loading

0 comments on commit f4c5df7

Please sign in to comment.