feat: initial commit
@@ -0,0 +1,293 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${msg("accountManagementTitle")}</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<script>
|
||||
<#if properties.developmentMode?has_content && properties.developmentMode == "true">
|
||||
var developmentMode = true;
|
||||
var reactRuntime = 'react.development.js';
|
||||
var reactDOMRuntime = 'react-dom.development.js';
|
||||
var reactRouterRuntime = 'react-router-dom.js';
|
||||
<#else>
|
||||
var developmentMode = false;
|
||||
var reactRuntime = 'react.production.min.js';
|
||||
var reactDOMRuntime = 'react-dom.production.min.js';
|
||||
var reactRouterRuntime = 'react-router-dom.min.js';
|
||||
</#if>
|
||||
var authUrl = '${authUrl}';
|
||||
var baseUrl = '${baseUrl}';
|
||||
var realm = '${realm.name}';
|
||||
var resourceUrl = '${resourceUrl}';
|
||||
var isReactLoading = false;
|
||||
|
||||
<#if properties.logo?has_content>
|
||||
var brandImg = resourceUrl + '${properties.logo}';
|
||||
<#else>
|
||||
var brandImg = resourceUrl + '/public/logo.svg';
|
||||
</#if>
|
||||
|
||||
<#if properties.logoUrl?has_content>
|
||||
var brandUrl = '${properties.logoUrl}';
|
||||
<#else>
|
||||
var brandUrl = baseUrl;
|
||||
</#if>
|
||||
|
||||
var features = {
|
||||
isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
|
||||
isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
|
||||
isInternationalizationEnabled : ${realm.isInternationalizationEnabled()?c},
|
||||
isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
|
||||
isEventsEnabled : ${isEventsEnabled?c},
|
||||
isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
|
||||
isTotpConfigured : ${isTotpConfigured?c},
|
||||
deleteAccountAllowed : ${deleteAccountAllowed?c}
|
||||
}
|
||||
|
||||
var availableLocales = [];
|
||||
<#list supportedLocales as locale, label>
|
||||
availableLocales.push({locale : '${locale}', label : '${label}'});
|
||||
</#list>
|
||||
|
||||
<#if referrer??>
|
||||
var referrer = '${referrer}';
|
||||
var referrerName = '${referrerName}';
|
||||
var referrerUri = '${referrer_uri}'.replace('&', '&');
|
||||
</#if>
|
||||
|
||||
<#if msg??>
|
||||
var locale = '${locale}';
|
||||
<#outputformat "JavaScript">
|
||||
var l18nMsg = JSON.parse('${msgJSON?js_string}');
|
||||
</#outputformat>
|
||||
<#else>
|
||||
var locale = 'en';
|
||||
var l18Msg = {};
|
||||
</#if>
|
||||
</script>
|
||||
|
||||
<#if properties.favIcon?has_content>
|
||||
<link rel="icon" href="${resourceUrl}${properties.favIcon}" type="image/x-icon"/>
|
||||
<#else>
|
||||
<link rel="icon" href="${resourceUrl}/public/favicon.ico" type="image/x-icon"/>
|
||||
</#if>
|
||||
|
||||
<script src="${authUrl}js/keycloak.js"></script>
|
||||
|
||||
<#if properties.developmentMode?has_content && properties.developmentMode == "true">
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="${resourceUrl}/node_modules/react/umd/react.development.js" crossorigin></script>
|
||||
<script src="${resourceUrl}/node_modules/react-dom/umd/react-dom.development.js" crossorigin></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
|
||||
</#if>
|
||||
|
||||
<#if properties.extensions?has_content>
|
||||
<#list properties.extensions?split(' ') as script>
|
||||
<#if properties.developmentMode?has_content && properties.developmentMode == "true">
|
||||
<script type="text/babel" src="${resourceUrl}/${script}"></script>
|
||||
<#else>
|
||||
<script type="text/javascript" src="${resourceUrl}/${script}"></script>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
<#if properties.scripts?has_content>
|
||||
<#list properties.scripts?split(' ') as script>
|
||||
<script type="text/javascript" src="${resourceUrl}/${script}"></script>
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
<script>
|
||||
var content = <#include "resources/content.json"/>
|
||||
</script>
|
||||
|
||||
<#if properties.styles?has_content>
|
||||
<#list properties.styles?split(' ') as style>
|
||||
<link href="${resourceUrl}/${style}" rel="stylesheet"/>
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/base.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/app.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/patternfly/patternfly-addons.css"/>
|
||||
<link href="${resourceUrl}/public/layout.css" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var keycloak = Keycloak({
|
||||
authServerUrl: authUrl,
|
||||
realm: realm,
|
||||
clientId: 'account-console'
|
||||
});
|
||||
keycloak.init({onLoad: 'check-sso', pkceMethod: 'S256', promiseType: 'native'}).then((authenticated) => {
|
||||
isReactLoading = true;
|
||||
toggleReact();
|
||||
if (!keycloak.authenticated) {
|
||||
document.getElementById("landingSignInButton").style.display='inline';
|
||||
document.getElementById("landingSignInLink").style.display='inline';
|
||||
} else {
|
||||
document.getElementById("landingSignOutButton").style.display='inline';
|
||||
document.getElementById("landingSignOutLink").style.display='inline';
|
||||
document.getElementById("landingLoggedInUser").innerHTML = loggedInUserName('${msg("unknownUser")}', '${msg("fullName")}');
|
||||
}
|
||||
|
||||
loadjs("/Main.js");
|
||||
}).catch(() => {
|
||||
alert('failed to initialize keycloak');
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="main_react_container" style="display:none;height:100%"></div>
|
||||
|
||||
<div id="spinner_screen" style="display:block; height:100%">
|
||||
<div style="width: 320px; height: 328px; text-align: center; position: absolute; top:0; bottom: 0; left: 0; right: 0; margin: auto;">
|
||||
<#if properties.logo?has_content>
|
||||
<img src="${resourceUrl}${properties.logo}" alt="Logo" class="brand">
|
||||
<#else>
|
||||
<img src="${resourceUrl}/public/logo.svg" alt="Logo" class="brand">
|
||||
</#if>
|
||||
<p>${msg("loadingMessage")}</p>
|
||||
<div>
|
||||
<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">
|
||||
<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)">
|
||||
<animateTransform attributeName="transform" type="rotate" dur="1s" repeatCount="indefinite" keyTimes="0;1" values="0 50 51;360 50 51"></animateTransform>
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="welcomeScreen" style="display:none;height:100%">
|
||||
<div class="pf-c-page" id="page-layout-default-nav">
|
||||
<header role="banner" class="pf-c-page__header">
|
||||
<div class="pf-c-page__header-brand">
|
||||
<#if properties.logoUrl?has_content>
|
||||
<a id="landingLogo" class="pf-c-page__header-brand-link" href="${properties.logoUrl}">
|
||||
<#else>
|
||||
<a id="landingLogo" class="pf-c-page__header-brand-link" href="${baseUrl}">
|
||||
</#if>
|
||||
<#if properties.logo?has_content>
|
||||
<img class="pf-c-brand brand" src="${resourceUrl}${properties.logo}" alt="Logo">
|
||||
<#else>
|
||||
<img class="pf-c-brand brand" src="${resourceUrl}/public/logo.svg" alt="Logo">
|
||||
</#if>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pf-c-page__header-tools">
|
||||
<#if referrer?has_content && referrer_uri?has_content>
|
||||
<div class="pf-c-page__header-tools-group pf-m-icons pf-u-display-none pf-u-display-flex-on-md">
|
||||
<a id="landingReferrerLink" href="${referrer_uri}" class="pf-c-button pf-m-link" tabindex="0">
|
||||
<span class="pf-c-button__icon pf-m-start">
|
||||
<i class="pf-icon pf-icon-arrow" aria-hidden="true"></i>
|
||||
</span>
|
||||
${msg("backToAdminConsole")}
|
||||
</a>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<div class="pf-c-page__header-tools-group pf-m-icons pf-u-display-none pf-u-display-flex-on-md pf-u-mr-md">
|
||||
<button id="landingSignInButton" tabindex="0" style="display:none" onclick="keycloak.login();" class="pf-c-button pf-m-primary" type="button">${msg("doSignIn")}</button>
|
||||
<button id="landingSignOutButton" tabindex="0" style="display:none" onclick="keycloak.logout();" class="pf-c-button pf-m-primary" type="button">${msg("doSignOut")}</button>
|
||||
</div>
|
||||
|
||||
<!-- Kebab for mobile -->
|
||||
<div class="pf-c-page__header-tools-group pf-u-display-none-on-md">
|
||||
<div id="landingMobileKebab" class="pf-c-dropdown pf-m-mobile" onclick="toggleMobileDropdown();"> <!-- pf-m-expanded -->
|
||||
<button aria-label="Actions" tabindex="0" id="landingMobileKebabButton" class="pf-c-dropdown__toggle pf-m-plain" type="button" aria-expanded="true" aria-haspopup="true">
|
||||
<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>
|
||||
</button>
|
||||
<ul id="landingMobileDropdown" aria-labelledby="landingMobileKebabButton" class="pf-c-dropdown__menu pf-m-align-right" role="menu" style="display:none">
|
||||
<#if referrer?has_content && referrer_uri?has_content>
|
||||
<li role="none">
|
||||
<a id="landingMobileReferrerLink" href="${referrer_uri}" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("backToAdminConsole")}</a>
|
||||
</li>
|
||||
</#if>
|
||||
|
||||
<li id="landingSignInLink" role="none" style="display:none">
|
||||
<a onclick="keycloak.login();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doLogIn")}</a>
|
||||
</li>
|
||||
<li id="landingSignOutLink" role="none" style="display:none">
|
||||
<a onclick="keycloak.logout();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doSignOut")}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span id="landingLoggedInUser"></span>
|
||||
|
||||
</div> <!-- end header tools -->
|
||||
</header>
|
||||
|
||||
<main role="main" class="pf-c-page__main">
|
||||
<section class="pf-c-page__main-section pf-m-limit-width pf-m-light pf-m-shadow-bottom">
|
||||
<div class="pf-c-page__main-body">
|
||||
<div class="pf-c-content" id="landingWelcomeMessage">
|
||||
<h1>${msg("accountManagementWelcomeMessage")}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="pf-c-page__main-section pf-m-limit-width pf-m-overflow-scroll">
|
||||
<div class="pf-c-page__main-body">
|
||||
<div class="pf-l-gallery pf-m-gutter">
|
||||
<#assign content=theme.apply("content.json")?eval>
|
||||
<#list content as item>
|
||||
<div class="pf-l-gallery__item" id="landing-${item.id}">
|
||||
<div class="pf-c-card pf-m-full-height">
|
||||
<div>
|
||||
<div class="pf-c-card__title pf-c-content">
|
||||
<h2 class="pf-u-display-flex pf-u-w-100 pf-u-flex-direction-column">
|
||||
<#if item.icon??>
|
||||
<i class="pf-icon ${item.icon}"></i>
|
||||
<#elseif item.iconSvg??>
|
||||
<img src="${item.iconSvg}" alt="icon"/>
|
||||
</#if>
|
||||
${msg(item.label)}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<#if item.descriptionLabel??>
|
||||
<p class="pf-u-mb-md">${msg(item.descriptionLabel)}</p>
|
||||
</#if>
|
||||
<#if item.content??>
|
||||
<#list item.content as sub>
|
||||
<div id="landing-${sub.id}">
|
||||
<a onclick="toggleReact(); window.location.hash='${sub.path}'">${msg(sub.label)}</a>
|
||||
</div>
|
||||
</#list>
|
||||
<#else>
|
||||
<a id="landing-${item.id}" onclick="toggleReact(); window.location.hash = '${item.path}'">${msg(item.label)}</a>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#list>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const removeHidden = (content) => {
|
||||
content.forEach(c => {
|
||||
if (c.hidden && eval(c.hidden)) {
|
||||
document.getElementById('landing-' + c.id).remove();
|
||||
}
|
||||
if (c.content) removeHidden(c.content);
|
||||
});
|
||||
}
|
||||
removeHidden(content);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1,122 @@
|
||||
# Put new messages for Account Console Here
|
||||
# Feel free to use any existing messages from the base theme
|
||||
pageNotFound=Seite nicht gefunden
|
||||
forbidden=Verboten
|
||||
needAccessRights=Sie haben keine Zugriffsrechte auf diese Anfrage. Wenden Sie sich an Ihren Administrator.
|
||||
invalidRoute={0} ist keine valide Route.
|
||||
actionRequiresIDP=Diese Aktion erfordert eine Umleitung zu Ihrem Identit\u00E4tsanbieter.
|
||||
actionNotDefined=Keine Aktion festgelegt
|
||||
continue=Fortfahren
|
||||
refreshPage=Aktualisiere die Seite
|
||||
done=Fertig
|
||||
cancel=Abbrechen
|
||||
remove=Entfernen
|
||||
update=Aktualisieren
|
||||
status=Status
|
||||
loadingMessage=Accountkonsole l\u00E4dt ...
|
||||
unknownUser=Unbekannter Nutzer
|
||||
fullName={0} {1}
|
||||
|
||||
selectLocale=Sprache ausw\u00E4hlen
|
||||
doSignIn=Anmelden
|
||||
|
||||
# Device Activity Page
|
||||
signedInDevices=Angemeldete Ger\u00E4te
|
||||
signedInDevicesExplanation=Melde ein unbekanntes Ger\u00E4t ab.
|
||||
signOutWarning=Session abmelden?
|
||||
signOutAllDevices=Alle Ger\u00E4te abmelden
|
||||
signOutAllDevicesWarning=Diese Aktion meldet alle Ger\u00E4te ab, die sich bei Ihrem Konto angemeldet haben, einschlie\u00DFlich des aktuellen Ger\u00E4ts, das Sie verwenden.
|
||||
recentlyUsedDevices=K\u00FCrzlich verwendete Ger\u00E4te
|
||||
recentlyUsedDevicesExplanation=Ger\u00E4te die im letzten Monat verwendet wurden, aber derzeit nicht angemeldet sind.
|
||||
lastAccess=Letzter Zugriff
|
||||
unknownOperatingSystem=Unbekanntes Betriebssystem
|
||||
currentDevice=Aktuelles Ger\u00E4t
|
||||
currentSession=Aktuelle Sitzung
|
||||
signedOutSession=Abgemeldet {0}/{1}
|
||||
lastAccessedOn=Zuletzt zugegriffen am
|
||||
clients=Clients
|
||||
startedAt=Gestartet am
|
||||
expiresAt=L\u00E4uft ab am
|
||||
ipAddress=IP Adresse
|
||||
|
||||
# Resources Page
|
||||
resourceName=Ressourcenname
|
||||
nextPage=N\u00E4chste
|
||||
previousPage=Vorherige
|
||||
firstPage=Erste Seite
|
||||
resourceSharedWith=Ressource ist freigegeben mit {0}
|
||||
and=\ und {0} anderen Nutzern
|
||||
add=Hinzuf\u00FCgen
|
||||
share=Freigeben
|
||||
edit=Editieren
|
||||
close=Schlie\u00DFen
|
||||
unShare=Alle Freigaben aufheben
|
||||
shareSuccess=Ressource erfolgreich freigegeben.
|
||||
unShareSuccess=Freigabe erfolgreich aufgehoben.
|
||||
updateSuccess=Ressource erfolgreich aktualisiert.
|
||||
resourceAlreadyShared=Ressource ist bereits an diesen Nutzer freigegeben.
|
||||
resourceNotShared=Diese Ressource ist nicht freigegeben.
|
||||
permissionRequests=Zugriffsanfragen
|
||||
permissions=Zugriffsrechte
|
||||
unShareAllConfirm=Wollen Sie wirklich alle Freigaben aufheben?
|
||||
userNotFound=Kein Nutzer mit dem Namen oder E-Mail gefunden {0}
|
||||
|
||||
# Linked Accounts Page
|
||||
linkedAccountsTitle=Verbundene Konten
|
||||
linkedAccountsIntroMessage=Verwalten Sie Anmeldungen \u00FCber Konten von Drittanbietern.
|
||||
linkedLoginProviders=Verbundene Login Anbieter
|
||||
unlinkedLoginProviders=Getrennte Login Anbieter
|
||||
linkedEmpty=Keine verbundenen Anbieter
|
||||
unlinkedEmpty=Keine getrennten Anbieter
|
||||
socialLogin=Social Login
|
||||
systemDefined=Systemdefiniert
|
||||
link=Account verbinden
|
||||
unLink=Account trennen
|
||||
|
||||
# Signing In Page
|
||||
signingIn=Anmeldung
|
||||
signingInSubMessage=Konfigurieren Sie die Anmeldem\u00F6glichkeiten.
|
||||
credentialCreatedAt=Erstellt
|
||||
successRemovedMessage={0} wurde entfernt.
|
||||
stopUsingCred={0} nicht mehr verwenden?
|
||||
removeCred={0} entfernen
|
||||
setUpNew={0} einrichten
|
||||
notSetUp={0} ist nicht eingerichtet.
|
||||
two-factor=Zwei-Faktor Authentifizierung
|
||||
passwordless=Kennwortlos
|
||||
unknown=Unbekannt
|
||||
password-display-name=Passwort
|
||||
password-help-text=Mit einem Passwort anmelden.
|
||||
password=Mein Passwort
|
||||
otp-display-name=Authenticator-Anwendung
|
||||
otp-help-text=Geben Sie einen Verifizierungscode aus der Authenticator-Anwendung ein.
|
||||
webauthn-display-name=Security-Token
|
||||
webauthn-help-text=Verwenden Sie Ihr Security-Token zur Anmeldung.
|
||||
webauthn-passwordless-display-name=Security-Token
|
||||
webauthn-passwordless-help-text=Verwenden Sie Ihr Security-Token zur kennwortlosen Anmeldung.
|
||||
basic-authentication=Standardauthentifizierung
|
||||
invalidRequestMessage=Ung\u00FCltige Anfrage
|
||||
|
||||
# Applications page
|
||||
applicationsPageTitle=Anwendungen
|
||||
internalApp=Intern
|
||||
thirdPartyApp=Drittanbieter
|
||||
offlineAccess=Offline Zugriff
|
||||
inUse=In Benutzung
|
||||
notInUse=Nicht in Benutzung
|
||||
applicationDetails=Anwendungsdetails
|
||||
client=Client
|
||||
description=Beschreibung
|
||||
baseUrl=URL
|
||||
accessGrantedOn=Zugriff gew\u00E4hrt am
|
||||
removeButton=Zugriff entfernen
|
||||
removeModalTitle=Zugriff entfernen
|
||||
removeModalMessage=Dadurch wird die aktuell gew\u00E4hrte Zugriffsberechtigung f\u00FCr {0} entfernt. Sie m\u00FCssen den Zugriff erneut gew\u00E4hren, wenn Sie diese Anwendung verwenden m\u00F6chten.
|
||||
confirmButton=Best\u00E4tigen
|
||||
infoMessage=Indem Sie auf "Zugriff entfernen" klicken, entfernen Sie gew\u00E4hrte Berechtigungen dieser Anwendung. Diese Anwendung wird Ihre Informationen nicht mehr verwenden.
|
||||
|
||||
#Delete Account page
|
||||
doDelete=L\u00F6schen
|
||||
deleteAccountSummary=Wenn Sie Ihr Konto l\u00F6schen, werden alle Ihre Daten gel\u00F6scht und Sie werden sofort abgemeldet.
|
||||
deleteAccount=Konto l\u00F6schen
|
||||
deleteAccountWarning=Dies ist unwiderruflich. Alle Ihre Daten werden dauerhaft gel\u00F6scht und k\u00F6nnen nicht wiederhergestellt werden.
|
||||
@@ -0,0 +1,164 @@
|
||||
# Put new messages for Account Console Here
|
||||
# Feel free to use any existing messages from the base theme
|
||||
pageNotFound=Page not found
|
||||
forbidden=Forbidden
|
||||
needAccessRights=You do not have access rights to this request. Contact your administrator.
|
||||
invalidRoute={0} is not a valid route.
|
||||
actionRequiresIDP=This action requires redirection to your identity provider.
|
||||
actionNotDefined=No action defined
|
||||
continue=Continue
|
||||
refreshPage=Refresh the page
|
||||
refresh=Refresh
|
||||
done=Done
|
||||
cancel=Cancel
|
||||
remove=Remove
|
||||
update=Update
|
||||
loadingMessage=Account Console loading ...
|
||||
unknownUser=Anonymous
|
||||
fullName={0} {1}
|
||||
allFieldsRequired=All fields are required.
|
||||
|
||||
selectLocale=Select a locale
|
||||
doSignIn=Sign in
|
||||
|
||||
backToAdminConsole=Back to admin console
|
||||
accountManagementWelcomeMessage=Welcome to Keycloak account management
|
||||
|
||||
# Personal info page
|
||||
personalInfoHtmlTitle=Personal info
|
||||
|
||||
# Device activity page
|
||||
signedInDevices=Signed in devices
|
||||
signedInDevicesExplanation=Sign out of any unfamiliar devices.
|
||||
signOutWarning=Sign out the session?
|
||||
signOutAllDevices=Sign out all devices
|
||||
signOutAllDevicesWarning=This action will sign out all the devices that have signed in to your account, including the current device you are using.
|
||||
recentlyUsedDevices=Recently used devices
|
||||
recentlyUsedDevicesExplanation=Devices used in the last month, but not currently logged in.
|
||||
lastAccess=Last access
|
||||
unknownOperatingSystem=Unknown operating system
|
||||
currentDevice=Current device
|
||||
currentSession=Current session
|
||||
signedOutSession=Signed out {0}/{1}
|
||||
lastAccessedOn=Last accessed
|
||||
clients=Clients
|
||||
started=Started
|
||||
expires=Expires
|
||||
ipAddress=IP address
|
||||
|
||||
# Resources page
|
||||
resourceName=Resource name
|
||||
nextPage=Next
|
||||
previousPage=Previous
|
||||
firstPage=First page
|
||||
resourceSharedWith=Resource is shared with {0}
|
||||
and=\ and {0} other users
|
||||
add=Add
|
||||
share=Share
|
||||
shareWith=Share with
|
||||
edit=Edit
|
||||
close=Close
|
||||
unShare=Unshare all
|
||||
shareSuccess=Resource successfully shared.
|
||||
unShareSuccess=Resource successfully un-shared.
|
||||
updateSuccess=Resource successfully updated.
|
||||
resourceAlreadyShared=Resource is already shared with this user.
|
||||
resourceNotShared=This resource is not shared.
|
||||
permissionRequests=Permission requests
|
||||
permissions=Permissions
|
||||
selectPermissions=Select the permissions
|
||||
unShareAllConfirm=Are you sure you want to completely remove all shares?
|
||||
userNotFound=No user found with name or email {0}
|
||||
|
||||
# Linked accounts page
|
||||
linkedAccountsTitle=Linked accounts
|
||||
linkedAccountsIntroMessage=Manage logins through third-party accounts.
|
||||
linkedLoginProviders=Linked login providers
|
||||
unlinkedLoginProviders=Unlinked login providers
|
||||
linkedEmpty=No linked providers
|
||||
unlinkedEmpty=No unlinked providers
|
||||
socialLogin=Social login
|
||||
systemDefined=System defined
|
||||
link=Link account
|
||||
unLink=Unlink account
|
||||
|
||||
# Signing in page
|
||||
signingIn=Signing in
|
||||
signingInSubMessage=Configure ways to sign in.
|
||||
credentialCreatedAt=Created
|
||||
successRemovedMessage={0} was removed.
|
||||
stopUsingCred=Stop using {0}?
|
||||
changePassword=Change password
|
||||
removeCred=Remove {0}
|
||||
setUpNew=Set up {0}
|
||||
removeCredAriaLabel=Remove credential
|
||||
updateCredAriaLabel=Update credential
|
||||
notSetUp={0} is not set up.
|
||||
two-factor=Two-factor authentication
|
||||
passwordless=Passwordless
|
||||
unknown=Unknown
|
||||
password-display-name=Password
|
||||
password-help-text=Log in by entering your password.
|
||||
password=My password
|
||||
otp-display-name=authenticator application
|
||||
otp-help-text=Enter a verification code from authenticator application.
|
||||
recovery-authn-code=My recovery authentication codes
|
||||
recovery-authn-codes-display-name=Recovery authentication codes
|
||||
recovery-authn-codes-help-text=These codes can be used to regain your access in case your other 2FA means are not available.
|
||||
recovery-codes-number-used={0} recovery codes used
|
||||
recovery-codes-number-remaining={0} recovery codes remaining
|
||||
recovery-codes-generate-new-codes=Generate new codes to ensure access to your account
|
||||
webauthn-display-name=Security key
|
||||
webauthn-help-text=Use your security key to sign in.
|
||||
webauthn-passwordless-display-name=Security key
|
||||
webauthn-passwordless-help-text=Use your security key for passwordless sign in.
|
||||
basic-authentication=Basic authentication
|
||||
invalidRequestMessage=Invalid request
|
||||
|
||||
# Applications page
|
||||
applicationsPageTitle=Applications
|
||||
internalApp=Internal
|
||||
thirdPartyApp=Third-party
|
||||
offlineAccess=Offline access
|
||||
inUse=In use
|
||||
notInUse=Not in use
|
||||
applicationDetails=Application details
|
||||
client=Client
|
||||
description=Description
|
||||
baseUrl=URL
|
||||
accessGrantedOn=Access granted on
|
||||
removeButton=Remove access
|
||||
removeModalTitle=Remove access
|
||||
removeModalMessage=This will remove the currently granted access permission for {0}. You will need to grant access again if you want to use this app.
|
||||
confirmButton=Confirm
|
||||
infoMessage=By clicking 'Remove Access', you will remove granted permissions of this application. This application will no longer use your information.
|
||||
termsOfService=Terms of service
|
||||
policy=Privacy policy
|
||||
applicationType=Application type
|
||||
status=Status
|
||||
|
||||
#Delete account page
|
||||
doDelete=Delete
|
||||
deleteAccountSummary=Deleting your account will erase all your data and log you out immediately.
|
||||
deleteAccount=Delete account
|
||||
deleteAccountWarning=This is irreversible. All your data will be permanently destroyed, and irretrievable.
|
||||
|
||||
error-invalid-value=''{0}'' has invalid value.
|
||||
error-invalid-blank=Please specify value of ''{0}''.
|
||||
error-empty=Please specify value of ''{0}''.
|
||||
error-invalid-length=''{0}'' must have a length between {1} and {2}.
|
||||
error-invalid-length-too-short=''{0}'' must have minimal length of {1}.
|
||||
error-invalid-length-too-long=''{0}'' must have maximal length of {2}.
|
||||
error-invalid-email=Invalid email address.
|
||||
error-invalid-number=''{0}'' is invalid number.
|
||||
error-number-out-of-range=''{0}'' must be a number between {1} and {2}.
|
||||
error-number-out-of-range-too-small=''{0}'' must have minimal value of {1}.
|
||||
error-number-out-of-range-too-big=''{0}'' must have maximal value of {2}.
|
||||
error-pattern-no-match=''{0}'' doesn''t match required format.
|
||||
error-invalid-uri=''{0}'' is invalid URL.
|
||||
error-invalid-uri-scheme=''{0}'' has invalid URL scheme.
|
||||
error-invalid-uri-fragment=''{0}'' is invalid URL fragment.
|
||||
error-user-attribute-required=Please specify ''{0}''.
|
||||
error-invalid-date=''{0}'' is invalid date.
|
||||
error-username-invalid-character=''{0}'' contains invalid character.
|
||||
error-person-name-invalid-character='{0}' contains invalid character.
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1,42 @@
|
||||
fullName={0} {1}
|
||||
loadingMessage=Gestion du compte en cours de chargement ...
|
||||
|
||||
# Personal informations page
|
||||
selectLocale=Choisissez une langue
|
||||
|
||||
# Authentication page
|
||||
signingIn=Authentification
|
||||
signingInSubMessage=Configurez les m\u00e9thodes d''authentification.
|
||||
basic-authentication=Authentification de Base
|
||||
password-display-name=Mot de passe
|
||||
password-help-text=Authentifiez-vous en saisissant votre mot de passe
|
||||
credentialCreatedAt=Cr\u00e9\u00e9 le
|
||||
two-factor=Authentification \u00e0 Deux Facteurs
|
||||
passwordless=Authentification Sans Mot de Passe
|
||||
otp-display-name=Application d''authentification
|
||||
otp-help-text=Entrez un code de v\u00e9rification \u00e0 usage unique fourni par l''application d''authentification.
|
||||
webauthn-display-name=Cl\u00e9 de S\u00e9curit\u00e9
|
||||
webauthn-help-text=Utilisez votre cl\u00e9 de s\u00e9curit\u00e9 pour vous authentifier.
|
||||
webauthn-passwordless-display-name=Cl\u00e9 de S\u00e9curit\u00e9
|
||||
webauthn-passwordless-help-text=Utilisez votre cl\u00e9 de s\u00e9curit\u00e9 pour une authentification sans mot de passe.
|
||||
notSetUp={0} non configur\u00e9(e).
|
||||
remove=Supprimer
|
||||
refreshPage=Rafra\u00eechir la page
|
||||
client_security-admin-console=Console d''administration de la s\u00e9curit\u00e9
|
||||
client_account-console=Console de gestion du compte
|
||||
|
||||
|
||||
# Device Activity page
|
||||
signedInDevices=Appareils Connect\u00e9s
|
||||
signedInDevicesExplanation=D\u00e9connectez les appareils que vous ne reconnaissez pas.
|
||||
currentSession=Session Courante
|
||||
lastAccessedOn=Dernier acc\u00e8s le
|
||||
startedAt=D\u00e9marr\u00e9(e) le
|
||||
expiresAt=Expire le
|
||||
|
||||
# Applications page
|
||||
internalApp=Interne
|
||||
thirdPartyApp=Tierce
|
||||
inUse=Utilis\u00e9(e)
|
||||
notInUse=Non utilis\u00e9(e)
|
||||
setUpNew=Configurer {0}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1,121 @@
|
||||
# Put new messages for Account Console Here
|
||||
# Feel free to use any existing messages from the base theme
|
||||
pageNotFound=P\u00e1gina N\u00e3o Encontrada
|
||||
forbidden=Proibido
|
||||
needAccessRights=Voc\u00ea n\u00e3o tem as permiss\u00f5es de acesso para esta solicita\u00e7\u00e3o. Entre em contato com um administrador.
|
||||
invalidRoute={0} n\u00e3o \u00e9 uma rota v\u00e1lida.
|
||||
actionRequiresIDP=Esta a\u00e7\u00e3o requer uma redire\u00e7\u00e3o do seu provedor de identidades.
|
||||
actionNotDefined=Nenhuma a\u00e7\u00e3o definida
|
||||
continue=Continuar
|
||||
refreshPage=Atualizar p\u00e1gina
|
||||
done=Pronto
|
||||
cancel=Cancelar
|
||||
remove=Remover
|
||||
update=Atualizar
|
||||
loadingMessage=Carregando console de conta...
|
||||
unknownUser=An\u00f4nimo
|
||||
fullName={0} {1}
|
||||
|
||||
selectLocale=Selecionar l\u00edngua
|
||||
doSignIn=Entrar
|
||||
|
||||
# Device Activity Page
|
||||
signedInDevices=Dispositivos autenticados
|
||||
signedInDevicesExplanation=Saia de qualquer dispositivo que n\u00e3o reconhe\u00e7a.
|
||||
signOutWarning=Finalizar todas as sess\u00f5es?
|
||||
signOutAllDevices=Finalizar Sess\u00e3o em Todos os Dispositivos
|
||||
signOutAllDevicesWarning=Esta a\u00e7\u00e3o ir\u00e1 finalizar a sess\u00e3o de todos os dispositivos logados na sua conta, incluindo o dispositivo que est\u00e1 sendo utilizado atualmente.
|
||||
recentlyUsedDevices=Dispositivos Utilizados Recentemente
|
||||
recentlyUsedDevicesExplanation=Dispositivos utilizados no \u00faltimo m\u00eas, mas sem sess\u00e3o ativa atualmente.
|
||||
lastAccess=\u00daltimo Acesso
|
||||
unknownOperatingSystem=Sistema Operacional Desconhecido
|
||||
currentDevice=Dispositivo Atual
|
||||
currentSession=Sess\u00e3o Atual
|
||||
signedOutSession=Deslogado {0}/{1}
|
||||
lastAccessedOn=\u00daltimo acesso em
|
||||
clients=Clientes
|
||||
startedAt=Iniciado em
|
||||
expiresAt=Expira em
|
||||
ipAddress=Endere\u00e7o IP
|
||||
|
||||
# Resources Page
|
||||
resourceName=Nome do Recurso
|
||||
nextPage=Avan\u00e7ar
|
||||
previousPage=Voltar
|
||||
firstPage=Primeira P\u00e1gina
|
||||
resourceSharedWith=O recurso \u00e9 compartilhado com {0}
|
||||
and=\ e {0} outros usu\u00e1rios
|
||||
add=Adicionar
|
||||
share=Compartilhar
|
||||
edit=Editar
|
||||
close=Fechar
|
||||
unShare=Descompartilhar tudo
|
||||
shareSuccess=O recurso foi compartilhado com sucesso.
|
||||
unShareSuccess=O recurso foi descompartilhado com sucesso.
|
||||
updateSuccess=O recurso foi atualizado com sucesso.
|
||||
resourceAlreadyShared=O recurso j\u00e1 foi compartilhado com este usu\u00e1rio.
|
||||
resourceNotShared=O recurso n\u00e3o foi compartilhado.
|
||||
permissionRequests=Pedidos de permiss\u00e3o
|
||||
permissions=Permiss\u00f5es
|
||||
unShareAllConfirm=Tem certeza de que quer remover todos os compartilhamentos?
|
||||
userNotFound=Usu\u00e1rio com o nome ou e-mail {0} n\u00e3o foi encontrado
|
||||
|
||||
# Linked Accounts Page
|
||||
linkedAccountsTitle=Contas conectadas
|
||||
linkedAccountsIntroMessage=Gerenciar acessos por contas de outras aplica\u00e7\u00f5es.
|
||||
linkedLoginProviders=Provedores de Acesso Conectados
|
||||
unlinkedLoginProviders=Provedores de Acesso N\u00e3o-Conectados
|
||||
linkedEmpty=Nenhum Provedor Conectado
|
||||
unlinkedEmpty=Nenhum Provedor N\u00e3o-Conectado
|
||||
socialLogin=Login Social
|
||||
systemDefined=Definido pelo Sistema
|
||||
link=Conectar Conta
|
||||
unLink=Desconectar Conta
|
||||
|
||||
# Signing In Page
|
||||
signingIn=Entrando na Conta
|
||||
signingInSubMessage=Configure maneiras de entrar na conta.
|
||||
credentialCreatedAt=Criada em
|
||||
successRemovedMessage={0} removida com sucesso.
|
||||
stopUsingCred=Para de usar {0}?
|
||||
removeCred=Remover {0}
|
||||
setUpNew=Configurar {0}
|
||||
notSetUp={0} n\u00e3o est\u00e1 configurada.
|
||||
two-factor=Autentica\u00e7\u00e3o de Dois Fatores
|
||||
passwordless=Sem Senha
|
||||
unknown=Desconhecida
|
||||
password-display-name=Senha
|
||||
password-help-text=Entre inserindo a sua senha.
|
||||
password=Minha Senha
|
||||
otp-display-name=App Autenticador
|
||||
otp-help-text=Insira o c\u00f3digo de verifica\u00e7\u00e3o do app autenticador.
|
||||
webauthn-display-name=Chave de Seguran\u00e7a
|
||||
webauthn-help-text=Use a sua chave de seguran\u00e7a para entrar.
|
||||
webauthn-passwordless-display-name=Chave de Seguran\u00e7a
|
||||
webauthn-passwordless-help-text=Use a sua chave de seguran\u00e7a para entrar sem senha.
|
||||
basic-authentication=Autentica\u00e7\u00e3o B\u00e1sica
|
||||
invalidRequestMessage=Solicita\u00e7\u00e3o Inv\u00e1lida
|
||||
|
||||
# Applications page
|
||||
applicationsPageTitle=Aplica\u00e7\u00f5es
|
||||
internalApp=Interna
|
||||
thirdPartyApp=De Terceiros
|
||||
offlineAccess=Acesso Offline
|
||||
inUse=Em uso
|
||||
notInUse=N\u00e3o utilizado
|
||||
applicationDetails=Detalhes da Aplica\u00e7\u00e3o
|
||||
client=Cliente
|
||||
description=Descri\u00e7\u00e3o
|
||||
baseUrl=URL
|
||||
accessGrantedOn=Acesso concedido em
|
||||
removeButton=Remover acesso
|
||||
removeModalTitle=Remover Acesso
|
||||
removeModalMessage=Isto ir\u00e1 remover a permiss\u00e3o atual de acesso concedido para {0}. Voc\u00ea precisar\u00e1 repetir o processo de concess\u00e3o se for utilizar o app novamente.
|
||||
confirmButton=Confirmar
|
||||
infoMessage=Ao clicar em 'Remover Acesso', voc\u00ea ir\u00e1 remover as permiss\u00f5es concedidas a esta aplica\u00e7\u00e3o. Ela n\u00e3o poder\u00e1 mais utilizar as suas informa\u00e7\u00f5es.
|
||||
|
||||
#Delete Account page
|
||||
doDelete=Apagar
|
||||
deleteAccountSummary=Apagar a sua conta ir\u00e1 remover todos os seus dados e finalizar a sess\u00e3o imediatamente.
|
||||
deleteAccount=Apagar Conta
|
||||
deleteAccountWarning=Esta a\u00e7\u00e3o \u00e9 irrevers\u00edvel. Todos os seus dados ser\u00e3o apagados permanentemente e n\u00e3o poder\u00e3o ser recuperados.
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1 @@
|
||||
fullName={0} {1}
|
||||
@@ -0,0 +1,75 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import { PageNav } from "./PageNav.js";
|
||||
import { PageHeaderTool } from "./PageHeaderTool.js";
|
||||
import { makeRoutes } from "./ContentPages.js";
|
||||
import { Brand, Page, PageHeader, PageSidebar } from "../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { KeycloakContext } from "./keycloak-service/KeycloakContext.js";
|
||||
;
|
||||
export class App extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
this.context = context;
|
||||
toggleReact();
|
||||
}
|
||||
|
||||
render() {
|
||||
toggleReact(); // check login
|
||||
|
||||
if (!this.context.authenticated() && !isWelcomePage()) {
|
||||
this.context.login();
|
||||
}
|
||||
|
||||
const username = /*#__PURE__*/React.createElement("span", {
|
||||
style: {
|
||||
marginLeft: '10px'
|
||||
},
|
||||
id: "loggedInUser"
|
||||
}, loggedInUserName());
|
||||
const Header = /*#__PURE__*/React.createElement(PageHeader, {
|
||||
logo: /*#__PURE__*/React.createElement("a", {
|
||||
id: "brandLink",
|
||||
href: brandUrl
|
||||
}, /*#__PURE__*/React.createElement(Brand, {
|
||||
src: brandImg,
|
||||
alt: "Logo",
|
||||
className: "brand"
|
||||
})),
|
||||
headerTools: /*#__PURE__*/React.createElement(PageHeaderTool, null),
|
||||
showNavToggle: true
|
||||
});
|
||||
const Sidebar = /*#__PURE__*/React.createElement(PageSidebar, {
|
||||
nav: /*#__PURE__*/React.createElement(PageNav, null)
|
||||
});
|
||||
return /*#__PURE__*/React.createElement(Page, {
|
||||
header: Header,
|
||||
sidebar: Sidebar,
|
||||
isManagedSidebar: true
|
||||
}, makeRoutes());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(App, "contextType", KeycloakContext);
|
||||
|
||||
;
|
||||
//# sourceMappingURL=App.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/app/App.tsx"],"names":["React","PageNav","PageHeaderTool","makeRoutes","Brand","Page","PageHeader","PageSidebar","KeycloakContext","App","Component","constructor","props","context","toggleReact","render","authenticated","isWelcomePage","login","username","marginLeft","loggedInUserName","Header","brandUrl","brandImg","Sidebar"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AAIA,SAAQC,OAAR;AACA,SAAQC,cAAR;AACA,SAAQC,UAAR;AAEA,SACIC,KADJ,EAEIC,IAFJ,EAGIC,UAHJ,EAIIC,WAJJ;AAOA,SAASC,eAAT;AAS4B;AAC5B,OAAO,MAAMC,GAAN,SAAkBT,KAAK,CAACU,SAAxB,CAA4C;AAIxCC,EAAAA,WAAW,CAACC,KAAD,EAAkBC,OAAlB,EAAsE;AACpF,UAAMD,KAAN;;AADoF;;AAEpF,SAAKC,OAAL,GAAeA,OAAf;AACAC,IAAAA,WAAW;AACd;;AAEMC,EAAAA,MAAM,GAAoB;AAC7BD,IAAAA,WAAW,GADkB,CAG7B;;AACA,QAAI,CAAC,KAAKD,OAAL,CAAcG,aAAd,EAAD,IAAkC,CAACC,aAAa,EAApD,EAAwD;AACpD,WAAKJ,OAAL,CAAcK,KAAd;AACH;;AAED,UAAMC,QAAQ,gBACV;AAAM,MAAA,KAAK,EAAE;AAACC,QAAAA,UAAU,EAAE;AAAb,OAAb;AAAmC,MAAA,EAAE,EAAC;AAAtC,OAAsDC,gBAAgB,EAAtE,CADJ;AAIA,UAAMC,MAAM,gBACR,oBAAC,UAAD;AACI,MAAA,IAAI,eAAE;AAAG,QAAA,EAAE,EAAC,WAAN;AAAkB,QAAA,IAAI,EAAEC;AAAxB,sBAAkC,oBAAC,KAAD;AAAO,QAAA,GAAG,EAAEC,QAAZ;AAAsB,QAAA,GAAG,EAAC,MAA1B;AAAiC,QAAA,SAAS,EAAC;AAA3C,QAAlC,CADV;AAEI,MAAA,WAAW,eAAE,oBAAC,cAAD,OAFjB;AAGI,MAAA,aAAa;AAHjB,MADJ;AAQA,UAAMC,OAAO,gBAAG,oBAAC,WAAD;AAAa,MAAA,GAAG,eAAE,oBAAC,OAAD;AAAlB,MAAhB;AAEA,wBACI,oBAAC,IAAD;AAAM,MAAA,MAAM,EAAEH,MAAd;AAAsB,MAAA,OAAO,EAAEG,OAA/B;AAAwC,MAAA,gBAAgB;AAAxD,OACKtB,UAAU,EADf,CADJ;AAKH;;AArC8C;;gBAAtCM,G,iBACYD,e;;AAqCxB","sourcesContent":["/*\n * Copyright 2018 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as React from 'react';\n\nimport {KeycloakService} from './keycloak-service/keycloak.service';\n\nimport {PageNav} from './PageNav';\nimport {PageHeaderTool} from './PageHeaderTool';\nimport {makeRoutes} from './ContentPages';\n\nimport {\n Brand,\n Page,\n PageHeader,\n PageSidebar\n} from '@patternfly/react-core';\n\nimport { KeycloakContext } from './keycloak-service/KeycloakContext';\n\ndeclare function toggleReact(): void;\ndeclare function isWelcomePage(): boolean;\ndeclare function loggedInUserName(): string;\n\ndeclare const brandImg: string;\ndeclare const brandUrl: string;\n\nexport interface AppProps {};\nexport class App extends React.Component<AppProps> {\n static contextType = KeycloakContext;\n context: React.ContextType<typeof KeycloakContext>;\n\n public constructor(props: AppProps, context: React.ContextType<typeof KeycloakContext>) {\n super(props);\n this.context = context;\n toggleReact();\n }\n\n public render(): React.ReactNode {\n toggleReact();\n\n // check login\n if (!this.context!.authenticated() && !isWelcomePage()) {\n this.context!.login();\n }\n\n const username = (\n <span style={{marginLeft: '10px'}} id=\"loggedInUser\">{loggedInUserName()}</span>\n );\n\n const Header = (\n <PageHeader\n logo={<a id=\"brandLink\" href={brandUrl}><Brand src={brandImg} alt=\"Logo\" className=\"brand\"/></a>}\n headerTools={<PageHeaderTool/>}\n showNavToggle\n />\n );\n\n const Sidebar = <PageSidebar nav={<PageNav/>} />;\n\n return (\n <Page header={Header} sidebar={Sidebar} isManagedSidebar>\n {makeRoutes()}\n </Page>\n );\n }\n};\n"],"file":"App.js"}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import { Route, Switch } from "../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { NavItem, NavExpandable } from "../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { Msg } from "./widgets/Msg.js";
|
||||
import { PageNotFound } from "./content/page-not-found/PageNotFound.js";
|
||||
import { ForbiddenPage } from "./content/forbidden-page/ForbiddenPage.js";
|
||||
;
|
||||
export function isModulePageDef(item) {
|
||||
return item.modulePath !== undefined;
|
||||
}
|
||||
export function isExpansion(contentItem) {
|
||||
return contentItem.content !== undefined;
|
||||
}
|
||||
|
||||
function groupId(group) {
|
||||
return 'grp-' + group;
|
||||
}
|
||||
|
||||
function itemId(group, item) {
|
||||
return 'grp-' + group + '_itm-' + item;
|
||||
}
|
||||
|
||||
function isChildOf(parent, child) {
|
||||
for (var item of parent.content) {
|
||||
if (isExpansion(item) && isChildOf(item, child)) return true;
|
||||
if (parent.groupId === child.groupId) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function createNavItems(activePage, contentParam, groupNum) {
|
||||
if (typeof content === 'undefined') return /*#__PURE__*/React.createElement(React.Fragment, null);
|
||||
const links = contentParam.map(item => {
|
||||
const navLinkId = `nav-link-${item.id}`;
|
||||
|
||||
if (isExpansion(item)) {
|
||||
return /*#__PURE__*/React.createElement(NavExpandable, {
|
||||
id: navLinkId,
|
||||
groupId: item.groupId,
|
||||
key: item.groupId,
|
||||
title: Msg.localize(item.label, item.labelParams),
|
||||
isExpanded: isChildOf(item, activePage)
|
||||
}, createNavItems(activePage, item.content, groupNum + 1));
|
||||
} else {
|
||||
const page = item;
|
||||
return /*#__PURE__*/React.createElement(NavItem, {
|
||||
id: navLinkId,
|
||||
groupId: item.groupId,
|
||||
itemId: item.itemId,
|
||||
key: item.itemId,
|
||||
to: '#/' + page.path,
|
||||
isActive: activePage.itemId === item.itemId,
|
||||
type: "button"
|
||||
}, Msg.localize(page.label, page.labelParams));
|
||||
}
|
||||
});
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, links);
|
||||
}
|
||||
|
||||
export function makeNavItems(activePage) {
|
||||
console.log({
|
||||
activePage
|
||||
});
|
||||
return createNavItems(activePage, content, 0);
|
||||
}
|
||||
|
||||
function setIds(contentParam, groupNum) {
|
||||
if (typeof contentParam === 'undefined') return groupNum;
|
||||
let expansionGroupNum = groupNum;
|
||||
|
||||
for (let i = 0; i < contentParam.length; i++) {
|
||||
const item = contentParam[i];
|
||||
|
||||
if (isExpansion(item)) {
|
||||
item.itemId = itemId(groupNum, i);
|
||||
expansionGroupNum = expansionGroupNum + 1;
|
||||
item.groupId = groupId(expansionGroupNum);
|
||||
expansionGroupNum = setIds(item.content, expansionGroupNum);
|
||||
console.log('currentGroup=' + expansionGroupNum);
|
||||
} else {
|
||||
item.groupId = groupId(groupNum);
|
||||
item.itemId = itemId(groupNum, i);
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
return expansionGroupNum;
|
||||
}
|
||||
|
||||
export function initGroupAndItemIds() {
|
||||
setIds(content, 0);
|
||||
console.log({
|
||||
content
|
||||
});
|
||||
} // get rid of Expansions and put all PageDef items into a single array
|
||||
|
||||
export function flattenContent(pageDefs) {
|
||||
const flat = [];
|
||||
|
||||
for (let item of pageDefs) {
|
||||
if (isExpansion(item)) {
|
||||
flat.push(...flattenContent(item.content));
|
||||
} else {
|
||||
flat.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return flat;
|
||||
}
|
||||
export function makeRoutes() {
|
||||
if (typeof content === 'undefined') return /*#__PURE__*/React.createElement("span", null);
|
||||
const pageDefs = flattenContent(content);
|
||||
const routes = pageDefs.map(page => {
|
||||
if (isModulePageDef(page)) {
|
||||
const node = React.createElement(page.module[page.componentName], {
|
||||
'pageDef': page
|
||||
});
|
||||
return /*#__PURE__*/React.createElement(Route, {
|
||||
key: page.itemId,
|
||||
path: '/' + page.path,
|
||||
exact: true,
|
||||
render: () => node
|
||||
});
|
||||
} else {
|
||||
const pageDef = page;
|
||||
return /*#__PURE__*/React.createElement(Route, {
|
||||
key: page.itemId,
|
||||
path: '/' + page.path,
|
||||
exact: true,
|
||||
component: pageDef.component
|
||||
});
|
||||
}
|
||||
});
|
||||
return /*#__PURE__*/React.createElement(Switch, null, routes, /*#__PURE__*/React.createElement(Route, {
|
||||
path: "/forbidden",
|
||||
component: ForbiddenPage
|
||||
}), /*#__PURE__*/React.createElement(Route, {
|
||||
component: PageNotFound
|
||||
}));
|
||||
}
|
||||
//# sourceMappingURL=ContentPages.js.map
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import * as ReactDOM from "../../common/keycloak/web_modules/react-dom.js";
|
||||
import { HashRouter } from "../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { App } from "./App.js";
|
||||
import { flattenContent, initGroupAndItemIds, isExpansion, isModulePageDef } from "./ContentPages.js";
|
||||
import { KeycloakService } from "./keycloak-service/keycloak.service.js";
|
||||
import { KeycloakContext } from "./keycloak-service/KeycloakContext.js";
|
||||
import { AccountServiceClient } from "./account-service/account.service.js";
|
||||
import { AccountServiceContext } from "./account-service/AccountServiceContext.js";
|
||||
export class Main extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
isReactLoading = false;
|
||||
toggleReact();
|
||||
}
|
||||
|
||||
render() {
|
||||
const keycloakService = new KeycloakService(keycloak);
|
||||
return /*#__PURE__*/React.createElement(HashRouter, null, /*#__PURE__*/React.createElement(KeycloakContext.Provider, {
|
||||
value: keycloakService
|
||||
}, /*#__PURE__*/React.createElement(AccountServiceContext.Provider, {
|
||||
value: new AccountServiceClient(keycloakService)
|
||||
}, /*#__PURE__*/React.createElement(App, null))));
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
const e = React.createElement;
|
||||
|
||||
function removeHidden(items) {
|
||||
const visible = [];
|
||||
|
||||
for (let item of items) {
|
||||
if (item.hidden && eval(item.hidden)) continue;
|
||||
|
||||
if (isExpansion(item)) {
|
||||
visible.push(item);
|
||||
item.content = removeHidden(item.content);
|
||||
|
||||
if (item.content.length === 0) {
|
||||
visible.pop(); // remove empty expansion
|
||||
}
|
||||
} else {
|
||||
visible.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return visible;
|
||||
}
|
||||
|
||||
content = removeHidden(content);
|
||||
initGroupAndItemIds();
|
||||
|
||||
function loadModule(modulePage) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log('loading: ' + resourceUrl + modulePage.modulePath);
|
||||
import(resourceUrl + modulePage.modulePath).then(module => {
|
||||
modulePage.module = module;
|
||||
resolve(modulePage);
|
||||
}).catch(error => {
|
||||
console.warn('Unable to load ' + modulePage.label + ' because ' + error.message);
|
||||
reject(modulePage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
;
|
||||
const moduleLoaders = [];
|
||||
flattenContent(content).forEach(item => {
|
||||
if (isModulePageDef(item)) {
|
||||
moduleLoaders.push(loadModule(item));
|
||||
}
|
||||
}); // load content modules and start
|
||||
|
||||
Promise.all(moduleLoaders).then(() => {
|
||||
const domContainer = document.querySelector('#main_react_container');
|
||||
ReactDOM.render(e(Main), domContainer);
|
||||
});
|
||||
//# sourceMappingURL=Main.js.map
|
||||
@@ -0,0 +1,23 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import { PageHeaderTools } from "../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { ReferrerLink } from "./widgets/ReferrerLink.js";
|
||||
import { LogoutButton } from "./widgets/Logout.js";
|
||||
export class PageHeaderTool extends React.Component {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
_defineProperty(this, "hasReferrer", typeof referrerName !== 'undefined');
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(PageHeaderTools, null, this.hasReferrer && /*#__PURE__*/React.createElement("div", {
|
||||
className: "pf-c-page__header-tools-group"
|
||||
}, /*#__PURE__*/React.createElement(ReferrerLink, null)), /*#__PURE__*/React.createElement("div", {
|
||||
className: "pf-c-page__header-tools-group"
|
||||
}, /*#__PURE__*/React.createElement(LogoutButton, null)));
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=PageHeaderTool.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/app/PageHeaderTool.tsx"],"names":["React","PageHeaderTools","ReferrerLink","LogoutButton","PageHeaderTool","Component","referrerName","render","hasReferrer"],"mappings":";;AAAA,OAAO,KAAKA,KAAZ;AAEA,SAAQC,eAAR;AACA,SAAQC,YAAR;AACA,SAAQC,YAAR;AAIA,OAAO,MAAMC,cAAN,SAA6BJ,KAAK,CAACK,SAAnC,CAA6C;AAAA;AAAA;;AAAA,yCACjB,OAAOC,YAAP,KAAwB,WADP;AAAA;;AAGzCC,EAAAA,MAAM,GAAoB;AAC7B,wBACI,oBAAC,eAAD,QACK,KAAKC,WAAL,iBACG;AAAK,MAAA,SAAS,EAAC;AAAf,oBACI,oBAAC,YAAD,OADJ,CAFR,eAOI;AAAK,MAAA,SAAS,EAAC;AAAf,oBACI,oBAAC,YAAD,OADJ,CAPJ,CADJ;AAaH;;AAjB+C","sourcesContent":["import * as React from 'react';\n\nimport {PageHeaderTools} from '@patternfly/react-core';\nimport {ReferrerLink} from './widgets/ReferrerLink';\nimport {LogoutButton} from './widgets/Logout';\n\ndeclare const referrerName: string;\n\nexport class PageHeaderTool extends React.Component {\n private hasReferrer: boolean = typeof referrerName !== 'undefined';\n\n public render(): React.ReactNode {\n return (\n <PageHeaderTools>\n {this.hasReferrer &&\n <div className=\"pf-c-page__header-tools-group\">\n <ReferrerLink/>\n </div>\n }\n\n <div className=\"pf-c-page__header-tools-group\">\n <LogoutButton/>\n </div>\n </PageHeaderTools>\n );\n }\n}\n"],"file":"PageHeaderTool.js"}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import { withRouter } from "../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { Nav, NavList } from "../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { makeNavItems, flattenContent } from "./ContentPages.js";
|
||||
|
||||
class PageNavigation extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
findActiveItem() {
|
||||
const currentPath = this.props.location.pathname;
|
||||
const items = flattenContent(content);
|
||||
const firstItem = items[0];
|
||||
|
||||
for (let item of items) {
|
||||
const itemPath = '/' + item.path;
|
||||
|
||||
if (itemPath === currentPath) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
return firstItem;
|
||||
}
|
||||
|
||||
render() {
|
||||
const activeItem = this.findActiveItem();
|
||||
return /*#__PURE__*/React.createElement(Nav, null, /*#__PURE__*/React.createElement(NavList, null, makeNavItems(activeItem)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const PageNav = withRouter(PageNavigation);
|
||||
//# sourceMappingURL=PageNav.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/app/PageNav.tsx"],"names":["React","withRouter","Nav","NavList","makeNavItems","flattenContent","PageNavigation","Component","constructor","props","findActiveItem","currentPath","location","pathname","items","content","firstItem","item","itemPath","path","render","activeItem","PageNav"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AACA,SAAQC,UAAR;AACA,SAAQC,GAAR,EAAaC,OAAb;AAEA,SAAQC,YAAR,EAAsBC,cAAtB;;AAQA,MAAMC,cAAN,SAA6BN,KAAK,CAACO,SAAnC,CAAyE;AAE9DC,EAAAA,WAAW,CAACC,KAAD,EAAsB;AACpC,UAAMA,KAAN;AACH;;AAEOC,EAAAA,cAAc,GAAY;AAC9B,UAAMC,WAAmB,GAAG,KAAKF,KAAL,CAAWG,QAAX,CAAoBC,QAAhD;AACA,UAAMC,KAAgB,GAAGT,cAAc,CAACU,OAAD,CAAvC;AACA,UAAMC,SAAS,GAAGF,KAAK,CAAC,CAAD,CAAvB;;AACA,SAAK,IAAIG,IAAT,IAAiBH,KAAjB,EAAwB;AACpB,YAAMI,QAAgB,GAAG,MAAMD,IAAI,CAACE,IAApC;;AACA,UAAID,QAAQ,KAAKP,WAAjB,EAA8B;AAC1B,eAAOM,IAAP;AACH;AACJ;;AAAA;AAED,WAAOD,SAAP;AACH;;AAEMI,EAAAA,MAAM,GAAoB;AAC7B,UAAMC,UAAmB,GAAG,KAAKX,cAAL,EAA5B;AACA,wBACI,oBAAC,GAAD,qBACI,oBAAC,OAAD,QACKN,YAAY,CAACiB,UAAD,CADjB,CADJ,CADJ;AAOH;;AA7BoE;;AAgCzE,OAAO,MAAMC,OAAO,GAAGrB,UAAU,CAACK,cAAD,CAA1B","sourcesContent":["/*\n * Copyright 2019 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as React from 'react';\nimport {withRouter, RouteComponentProps} from 'react-router-dom';\nimport {Nav, NavList} from '@patternfly/react-core';\n\nimport {makeNavItems, flattenContent, ContentItem, PageDef} from './ContentPages';\n\ndeclare const content: ContentItem[];\n\nexport interface PageNavProps extends RouteComponentProps {}\n\nexport interface PageNavState {}\n\nclass PageNavigation extends React.Component<PageNavProps, PageNavState> {\n\n public constructor(props: PageNavProps) {\n super(props);\n }\n\n private findActiveItem(): PageDef {\n const currentPath: string = this.props.location.pathname;\n const items: PageDef[] = flattenContent(content);\n const firstItem = items[0];\n for (let item of items) {\n const itemPath: string = '/' + item.path;\n if (itemPath === currentPath) {\n return item;\n }\n };\n\n return firstItem;\n }\n\n public render(): React.ReactNode {\n const activeItem: PageDef = this.findActiveItem();\n return (\n <Nav>\n <NavList>\n {makeNavItems(activeItem)}\n </NavList>\n </Nav>\n );\n }\n}\n\nexport const PageNav = withRouter(PageNavigation);\n"],"file":"PageNav.js"}
|
||||
@@ -0,0 +1,60 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../common/keycloak/web_modules/react.js";
|
||||
import { Toolbar, ToolbarGroup, ToolbarItem } from "../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { ReferrerLink } from "./widgets/ReferrerLink.js";
|
||||
import { LogoutButton } from "./widgets/Logout.js";
|
||||
export class PageToolbar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "hasReferrer", typeof referrerName !== 'undefined');
|
||||
|
||||
_defineProperty(this, "onKebabDropdownToggle", isKebabDropdownOpen => {
|
||||
this.setState({
|
||||
isKebabDropdownOpen
|
||||
});
|
||||
});
|
||||
|
||||
this.state = {
|
||||
isKebabDropdownOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(Toolbar, null, this.hasReferrer && /*#__PURE__*/React.createElement(ToolbarGroup, {
|
||||
key: "referrerGroup",
|
||||
alignment: {
|
||||
default: "alignRight"
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(ToolbarItem, {
|
||||
className: "pf-m-icons",
|
||||
key: "referrer"
|
||||
}, /*#__PURE__*/React.createElement(ReferrerLink, null))), /*#__PURE__*/React.createElement(ToolbarGroup, {
|
||||
key: "secondGroup",
|
||||
alignment: {
|
||||
default: "alignRight"
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(ToolbarItem, {
|
||||
className: "pf-m-icons",
|
||||
key: "logout"
|
||||
}, /*#__PURE__*/React.createElement(LogoutButton, null))));
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=PageToolbar.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/app/PageToolbar.tsx"],"names":["React","Toolbar","ToolbarGroup","ToolbarItem","ReferrerLink","LogoutButton","PageToolbar","Component","constructor","props","referrerName","isKebabDropdownOpen","setState","state","render","hasReferrer","default"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AAEA,SAA+BC,OAA/B,EAAwCC,YAAxC,EAAsDC,WAAtD;AAGA,SAAQC,YAAR;AAEA,SAAQC,YAAR;AAOA,OAAO,MAAMC,WAAN,SAA0BN,KAAK,CAACO,SAAhC,CAA8E;AAG1EC,EAAAA,WAAW,CAACC,KAAD,EAA0B;AACxC,UAAMA,KAAN;;AADwC,yCAFb,OAAOC,YAAP,KAAwB,WAEX;;AAAA,mDAQXC,mBAAD,IAAkC;AAC9D,WAAKC,QAAL,CAAc;AACVD,QAAAA;AADU,OAAd;AAGH,KAZ2C;;AAGxC,SAAKE,KAAL,GAAa;AACTF,MAAAA,mBAAmB,EAAE;AADZ,KAAb;AAGH;;AAQMG,EAAAA,MAAM,GAAoB;AAC7B,wBACI,oBAAC,OAAD,QACK,KAAKC,WAAL,iBACG,oBAAC,YAAD;AAAc,MAAA,GAAG,EAAC,eAAlB;AAAkC,MAAA,SAAS,EAAE;AAACC,QAAAA,OAAO,EAAC;AAAT;AAA7C,oBACI,oBAAC,WAAD;AAAa,MAAA,SAAS,EAAC,YAAvB;AAAoC,MAAA,GAAG,EAAC;AAAxC,oBACI,oBAAC,YAAD,OADJ,CADJ,CAFR,eASI,oBAAC,YAAD;AAAc,MAAA,GAAG,EAAC,aAAlB;AAAgC,MAAA,SAAS,EAAE;AAACA,QAAAA,OAAO,EAAC;AAAT;AAA3C,oBACI,oBAAC,WAAD;AAAa,MAAA,SAAS,EAAC,YAAvB;AAAoC,MAAA,GAAG,EAAC;AAAxC,oBACI,oBAAC,YAAD,OADJ,CADJ,CATJ,CADJ;AAiBH;;AAnCgF","sourcesContent":["/*\n * Copyright 2019 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as React from 'react';\n\nimport {Dropdown, KebabToggle, Toolbar, ToolbarGroup, ToolbarItem} from '@patternfly/react-core';\n\nimport {ReferrerDropdownItem} from './widgets/ReferrerDropdownItem';\nimport {ReferrerLink} from './widgets/ReferrerLink';\nimport {Features} from './widgets/features';\nimport {LogoutButton,LogoutDropdownItem} from './widgets/Logout';\n\ndeclare const referrerName: string;\ndeclare const features: Features;\n\ninterface PageToolbarProps {}\ninterface PageToolbarState {isKebabDropdownOpen: boolean}\nexport class PageToolbar extends React.Component<PageToolbarProps, PageToolbarState> {\n private hasReferrer: boolean = typeof referrerName !== 'undefined';\n\n public constructor(props: PageToolbarProps) {\n super(props);\n\n this.state = {\n isKebabDropdownOpen: false,\n };\n }\n\n private onKebabDropdownToggle = (isKebabDropdownOpen: boolean) => {\n this.setState({\n isKebabDropdownOpen\n });\n };\n\n public render(): React.ReactNode {\n return (\n <Toolbar>\n {this.hasReferrer &&\n <ToolbarGroup key='referrerGroup' alignment={{default:\"alignRight\"}}>\n <ToolbarItem className=\"pf-m-icons\" key='referrer'>\n <ReferrerLink/>\n </ToolbarItem>\n </ToolbarGroup>\n }\n\n <ToolbarGroup key='secondGroup' alignment={{default:\"alignRight\"}}>\n <ToolbarItem className=\"pf-m-icons\" key='logout'>\n <LogoutButton/>\n </ToolbarItem>\n </ToolbarGroup>\n </Toolbar>\n );\n }\n}\n"],"file":"PageToolbar.js"}
|
||||
@@ -0,0 +1,3 @@
|
||||
import * as React from "../../../common/keycloak/web_modules/react.js";
|
||||
export const AccountServiceContext = React.createContext(undefined);
|
||||
//# sourceMappingURL=AccountServiceContext.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/account-service/AccountServiceContext.tsx"],"names":["React","AccountServiceContext","createContext","undefined"],"mappings":"AAAA,OAAO,KAAKA,KAAZ;AAGA,OAAO,MAAMC,qBAAqB,GAAGD,KAAK,CAACE,aAAN,CAAsDC,SAAtD,CAA9B","sourcesContent":["import * as React from 'react';\nimport { AccountServiceClient } from './account.service';\n\nexport const AccountServiceContext = React.createContext<AccountServiceClient | undefined>(undefined);"],"file":"AccountServiceContext.js"}
|
||||
@@ -0,0 +1,149 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import { ContentAlert } from "../content/ContentAlert.js";
|
||||
export class AccountServiceError extends Error {
|
||||
constructor(response) {
|
||||
super(response.statusText);
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
|
||||
*/
|
||||
|
||||
export class AccountServiceClient {
|
||||
constructor(keycloakService) {
|
||||
_defineProperty(this, "kcSvc", void 0);
|
||||
|
||||
_defineProperty(this, "accountUrl", void 0);
|
||||
|
||||
this.kcSvc = keycloakService;
|
||||
this.accountUrl = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/account';
|
||||
}
|
||||
|
||||
async doGet(endpoint, config) {
|
||||
return this.doRequest(endpoint, { ...config,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
async doDelete(endpoint, config) {
|
||||
return this.doRequest(endpoint, { ...config,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
async doPost(endpoint, body, config) {
|
||||
return this.doRequest(endpoint, { ...config,
|
||||
body: JSON.stringify(body),
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
async doPut(endpoint, body, config) {
|
||||
return this.doRequest(endpoint, { ...config,
|
||||
body: JSON.stringify(body),
|
||||
method: 'put'
|
||||
});
|
||||
}
|
||||
|
||||
async doRequest(endpoint, config) {
|
||||
const response = await fetch(this.makeUrl(endpoint, config).toString(), await this.makeConfig(config));
|
||||
|
||||
try {
|
||||
response.data = await response.json();
|
||||
} catch (e) {} // ignore. Might be empty
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
this.handleError(response);
|
||||
throw new AccountServiceError(response);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
handleError(response) {
|
||||
if (response !== null && response.status === 401) {
|
||||
if (this.kcSvc.authenticated() && !this.kcSvc.audiencePresent()) {
|
||||
// authenticated and the audience is not present => not allowed
|
||||
window.location.href = baseUrl + '#/forbidden';
|
||||
} else {
|
||||
// session timed out?
|
||||
this.kcSvc.login();
|
||||
}
|
||||
}
|
||||
|
||||
if (response !== null && response.status === 403) {
|
||||
window.location.href = baseUrl + '#/forbidden';
|
||||
}
|
||||
|
||||
if (response !== null && response.data != null) {
|
||||
if (response.data['errors'] != null) {
|
||||
for (let err of response.data['errors']) ContentAlert.danger(err['errorMessage'], err['params']);
|
||||
} else {
|
||||
ContentAlert.danger(`${response.statusText}: ${response.data['errorMessage'] ? response.data['errorMessage'] : ''} ${response.data['error'] ? response.data['error'] : ''}`);
|
||||
}
|
||||
|
||||
;
|
||||
} else {
|
||||
ContentAlert.danger(response.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
makeUrl(endpoint, config) {
|
||||
if (endpoint.startsWith('http')) return new URL(endpoint);
|
||||
const url = new URL(this.accountUrl + endpoint); // add request params
|
||||
|
||||
if (config && config.hasOwnProperty('params')) {
|
||||
const params = config.params || {};
|
||||
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
makeConfig(config = {}) {
|
||||
return new Promise(resolve => {
|
||||
this.kcSvc.getToken().then(token => {
|
||||
resolve({ ...config,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...config.headers,
|
||||
Authorization: 'Bearer ' + token
|
||||
}
|
||||
});
|
||||
}).catch(() => {
|
||||
this.kcSvc.login();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
window.addEventListener("unhandledrejection", event => {
|
||||
event.promise.catch(error => {
|
||||
if (error instanceof AccountServiceError) {
|
||||
// We already handled the error. Ignore unhandled rejection.
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=account.service.js.map
|
||||
@@ -0,0 +1,60 @@
|
||||
[
|
||||
{
|
||||
"id": "personal-info",
|
||||
"path": "personal-info",
|
||||
"icon": "pf-icon-user",
|
||||
"label": "personalInfoSidebarTitle",
|
||||
"descriptionLabel": "personalInfoIntroMessage",
|
||||
"modulePath": "/content/account-page/AccountPage.js",
|
||||
"componentName": "AccountPage"
|
||||
},
|
||||
{
|
||||
"id": "security",
|
||||
"icon": "pf-icon-security",
|
||||
"label": "accountSecuritySidebarTitle",
|
||||
"descriptionLabel": "accountSecurityIntroMessage",
|
||||
"content": [
|
||||
{
|
||||
"id": "signingin",
|
||||
"path": "security/signingin",
|
||||
"label": "signingInSidebarTitle",
|
||||
"modulePath": "/content/signingin-page/SigningInPage.js",
|
||||
"componentName": "SigningInPage"
|
||||
},
|
||||
{
|
||||
"id": "device-activity",
|
||||
"path": "security/device-activity",
|
||||
"label": "deviceActivitySidebarTitle",
|
||||
"modulePath": "/content/device-activity-page/DeviceActivityPage.js",
|
||||
"componentName": "DeviceActivityPage"
|
||||
},
|
||||
{
|
||||
"id": "linked-accounts",
|
||||
"path": "security/linked-accounts",
|
||||
"label": "linkedAccountsSidebarTitle",
|
||||
"modulePath": "/content/linked-accounts-page/LinkedAccountsPage.js",
|
||||
"componentName": "LinkedAccountsPage",
|
||||
"hidden": "!features.isLinkedAccountsEnabled"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "applications",
|
||||
"icon": "pf-icon-applications",
|
||||
"path": "applications",
|
||||
"label": "applications",
|
||||
"descriptionLabel": "applicationsIntroMessage",
|
||||
"modulePath": "/content/applications-page/ApplicationsPage.js",
|
||||
"componentName": "ApplicationsPage"
|
||||
},
|
||||
{
|
||||
"id": "resources",
|
||||
"icon": "pf-icon-repository",
|
||||
"path": "resources",
|
||||
"label": "resources",
|
||||
"descriptionLabel": "resourceIntroMessage",
|
||||
"modulePath": "/content/my-resources-page/MyResourcesPage.js",
|
||||
"componentName": "MyResourcesPage",
|
||||
"hidden": "!features.isMyResourcesEnabled"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,113 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../common/keycloak/web_modules/react.js";
|
||||
import { Alert, AlertActionCloseButton, AlertGroup, AlertVariant } from "../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { Msg } from "../widgets/Msg.js";
|
||||
export class ContentAlert extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "hideAlert", key => {
|
||||
this.setState({
|
||||
alerts: [...this.state.alerts.filter(el => el.key !== key)]
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "getUniqueId", () => new Date().getTime());
|
||||
|
||||
_defineProperty(this, "postAlert", (variant, message, params) => {
|
||||
const alerts = this.state.alerts;
|
||||
const key = this.getUniqueId();
|
||||
alerts.push({
|
||||
key,
|
||||
message: Msg.localize(message, params),
|
||||
variant
|
||||
});
|
||||
this.setState({
|
||||
alerts
|
||||
});
|
||||
|
||||
if (variant !== AlertVariant.danger) {
|
||||
setTimeout(() => this.hideAlert(key), 8000);
|
||||
}
|
||||
});
|
||||
|
||||
this.state = {
|
||||
alerts: []
|
||||
};
|
||||
ContentAlert.instance = this;
|
||||
}
|
||||
/**
|
||||
* @param message A literal text message or localization key.
|
||||
*/
|
||||
|
||||
|
||||
static success(message, params) {
|
||||
ContentAlert.instance.postAlert(AlertVariant.success, message, params);
|
||||
}
|
||||
/**
|
||||
* @param message A literal text message or localization key.
|
||||
*/
|
||||
|
||||
|
||||
static danger(message, params) {
|
||||
ContentAlert.instance.postAlert(AlertVariant.danger, message, params);
|
||||
}
|
||||
/**
|
||||
* @param message A literal text message or localization key.
|
||||
*/
|
||||
|
||||
|
||||
static warning(message, params) {
|
||||
ContentAlert.instance.postAlert(AlertVariant.warning, message, params);
|
||||
}
|
||||
/**
|
||||
* @param message A literal text message or localization key.
|
||||
*/
|
||||
|
||||
|
||||
static info(message, params) {
|
||||
ContentAlert.instance.postAlert(AlertVariant.info, message, params);
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(AlertGroup, {
|
||||
isToast: true,
|
||||
"aria-live": "assertive"
|
||||
}, this.state.alerts.map(({
|
||||
key,
|
||||
variant,
|
||||
message
|
||||
}) => /*#__PURE__*/React.createElement(Alert, {
|
||||
"aria-details": message,
|
||||
isLiveRegion: true,
|
||||
variant: variant,
|
||||
title: message,
|
||||
actionClose: /*#__PURE__*/React.createElement(AlertActionCloseButton, {
|
||||
title: message,
|
||||
variantLabel: `${variant} alert`,
|
||||
onClose: () => this.hideAlert(key)
|
||||
}),
|
||||
key: key
|
||||
})));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(ContentAlert, "instance", void 0);
|
||||
//# sourceMappingURL=ContentAlert.js.map
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../common/keycloak/web_modules/react.js";
|
||||
import { Button, Text, Title, Tooltip, PageSection, TextContent, PageSectionVariants, SplitItem, Split } from "../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { SyncAltIcon } from "../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { Msg } from "../widgets/Msg.js";
|
||||
import { ContentAlert } from "./ContentAlert.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2019 Red Hat Inc.
|
||||
*/
|
||||
export class ContentPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ContentAlert, null), /*#__PURE__*/React.createElement(PageSection, {
|
||||
variant: PageSectionVariants.light,
|
||||
className: "pf-u-pb-xs"
|
||||
}, /*#__PURE__*/React.createElement(Split, null, /*#__PURE__*/React.createElement(SplitItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement(TextContent, null, /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h1",
|
||||
size: "2xl",
|
||||
className: "pf-u-mb-xl"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: this.props.title
|
||||
})), this.props.introMessage && /*#__PURE__*/React.createElement(Text, {
|
||||
component: "p"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: this.props.introMessage
|
||||
})))), this.props.onRefresh && /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(Tooltip, {
|
||||
content: /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "refreshPage"
|
||||
})
|
||||
}, /*#__PURE__*/React.createElement(Button, {
|
||||
"aria-label": Msg.localize('refreshPage'),
|
||||
id: "refresh-page",
|
||||
variant: "link",
|
||||
onClick: this.props.onRefresh,
|
||||
icon: /*#__PURE__*/React.createElement(SyncAltIcon, null)
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "refresh"
|
||||
})))))), this.props.children);
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
//# sourceMappingURL=ContentPage.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/content/ContentPage.tsx"],"names":["React","Button","Text","Title","Tooltip","PageSection","TextContent","PageSectionVariants","SplitItem","Split","SyncAltIcon","Msg","ContentAlert","ContentPage","Component","constructor","props","render","light","title","introMessage","onRefresh","localize","children"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AACA,SAAQC,MAAR,EAAgCC,IAAhC,EAAsCC,KAAtC,EAA6CC,OAA7C,EAAwFC,WAAxF,EAAqGC,WAArG,EAAkHC,mBAAlH,EAAuIC,SAAvI,EAAkJC,KAAlJ;AACA,SAAkBC,WAAlB;AAEA,SAAQC,GAAR;AACA,SAAQC,YAAR;;AASA;AACA;AACA;AACA,OAAO,MAAMC,WAAN,SAA0Bb,KAAK,CAACc,SAAhC,CAA4D;AAExDC,EAAAA,WAAW,CAACC,KAAD,EAA0B;AACxC,UAAMA,KAAN;AACH;;AAEMC,EAAAA,MAAM,GAAoB;AAC7B,wBACI,oBAAC,KAAD,CAAO,QAAP,qBACA,oBAAC,YAAD,OADA,eAGA,oBAAC,WAAD;AAAa,MAAA,OAAO,EAAEV,mBAAmB,CAACW,KAA1C;AAAiD,MAAA,SAAS,EAAC;AAA3D,oBACE,oBAAC,KAAD,qBACE,oBAAC,SAAD;AAAW,MAAA,QAAQ;AAAnB,oBACE,oBAAC,WAAD,qBACE,oBAAC,KAAD;AAAO,MAAA,YAAY,EAAC,IAApB;AAAyB,MAAA,IAAI,EAAC,KAA9B;AAAoC,MAAA,SAAS,EAAC;AAA9C,oBACE,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAE,KAAKF,KAAL,CAAWG;AAAxB,MADF,CADF,EAIG,KAAKH,KAAL,CAAWI,YAAX,iBACC,oBAAC,IAAD;AAAM,MAAA,SAAS,EAAC;AAAhB,oBACE,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAE,KAAKJ,KAAL,CAAWI;AAAxB,MADF,CALJ,CADF,CADF,EAaG,KAAKJ,KAAL,CAAWK,SAAX,iBACC,oBAAC,SAAD,qBACE,oBAAC,OAAD;AAAS,MAAA,OAAO,eAAE,oBAAC,GAAD;AAAK,QAAA,MAAM,EAAC;AAAZ;AAAlB,oBACE,oBAAC,MAAD;AACE,oBAAYV,GAAG,CAACW,QAAJ,CAAa,aAAb,CADd;AAEE,MAAA,EAAE,EAAC,cAFL;AAGE,MAAA,OAAO,EAAC,MAHV;AAIE,MAAA,OAAO,EAAE,KAAKN,KAAL,CAAWK,SAJtB;AAKE,MAAA,IAAI,eAAE,oBAAC,WAAD;AALR,oBAOE,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC;AAAZ,MAPF,CADF,CADF,CAdJ,CADF,CAHA,EAkCC,KAAKL,KAAL,CAAWO,QAlCZ,CADJ;AAsCH;;AA7C8D;AA8ClE","sourcesContent":["/*\n * Copyright 2019 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as React from 'react';\nimport {Button, Grid, GridItem, Text, Title, Tooltip, Card, CardBody, Stack, StackItem, PageSection, TextContent, PageSectionVariants, SplitItem, Split} from '@patternfly/react-core';\nimport {RedoIcon, SyncAltIcon} from '@patternfly/react-icons';\n\nimport {Msg} from '../widgets/Msg';\nimport {ContentAlert} from './ContentAlert';\n\ninterface ContentPageProps {\n title: string; // Literal title or key into message bundle\n introMessage?: string; // Literal message or key into message bundle\n onRefresh?: () => void;\n children: React.ReactNode;\n}\n\n/**\n * @author Stan Silvert ssilvert@redhat.com (C) 2019 Red Hat Inc.\n */\nexport class ContentPage extends React.Component<ContentPageProps> {\n\n public constructor(props: ContentPageProps) {\n super(props);\n }\n\n public render(): React.ReactNode {\n return (\n <React.Fragment>\n <ContentAlert />\n\n <PageSection variant={PageSectionVariants.light} className=\"pf-u-pb-xs\">\n <Split>\n <SplitItem isFilled>\n <TextContent>\n <Title headingLevel=\"h1\" size=\"2xl\" className=\"pf-u-mb-xl\">\n <Msg msgKey={this.props.title} />\n </Title>\n {this.props.introMessage && (\n <Text component=\"p\">\n <Msg msgKey={this.props.introMessage} />\n </Text>\n )}\n </TextContent>\n </SplitItem>\n {this.props.onRefresh && (\n <SplitItem>\n <Tooltip content={<Msg msgKey=\"refreshPage\" />}>\n <Button\n aria-label={Msg.localize('refreshPage')}\n id=\"refresh-page\"\n variant=\"link\"\n onClick={this.props.onRefresh}\n icon={<SyncAltIcon />}\n >\n <Msg msgKey=\"refresh\" />\n </Button>\n </Tooltip>\n </SplitItem>\n )}\n </Split>\n </PageSection>\n {this.props.children}\n </React.Fragment>\n );\n }\n};\n"],"file":"ContentPage.js"}
|
||||
@@ -0,0 +1,276 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { ActionGroup, Button, Form, FormGroup, TextInput, Grid, GridItem, ExpandableSection, ValidatedOptions, PageSection, PageSectionVariants, Text, TextVariants, TextContent } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
import { LocaleSelector } from "../../widgets/LocaleSelectors.js";
|
||||
import { KeycloakContext } from "../../keycloak-service/KeycloakContext.js";
|
||||
import { AIACommand } from "../../util/AIACommand.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
|
||||
*/
|
||||
export class AccountPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "isRegistrationEmailAsUsername", features.isRegistrationEmailAsUsername);
|
||||
|
||||
_defineProperty(this, "isEditUserNameAllowed", features.isEditUserNameAllowed);
|
||||
|
||||
_defineProperty(this, "isDeleteAccountAllowed", features.deleteAccountAllowed);
|
||||
|
||||
_defineProperty(this, "DEFAULT_STATE", {
|
||||
errors: {
|
||||
username: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: ''
|
||||
},
|
||||
formFields: {
|
||||
username: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
attributes: {}
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "state", this.DEFAULT_STATE);
|
||||
|
||||
_defineProperty(this, "handleCancel", () => {
|
||||
this.fetchPersonalInfo();
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleChange", (value, event) => {
|
||||
const target = event.currentTarget;
|
||||
const name = target.name;
|
||||
this.setState({
|
||||
errors: { ...this.state.errors,
|
||||
[name]: target.validationMessage
|
||||
},
|
||||
formFields: { ...this.state.formFields,
|
||||
[name]: value
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleSubmit", event => {
|
||||
event.preventDefault();
|
||||
const form = event.target;
|
||||
const isValid = form.checkValidity();
|
||||
|
||||
if (isValid) {
|
||||
const reqData = { ...this.state.formFields
|
||||
};
|
||||
this.context.doPost("/", reqData).then(() => {
|
||||
ContentAlert.success('accountUpdatedMessage');
|
||||
|
||||
if (locale !== this.state.formFields.attributes.locale[0]) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const formData = new FormData(form);
|
||||
const validationMessages = Array.from(formData.keys()).reduce((acc, key) => {
|
||||
acc[key] = form.elements[key].validationMessage;
|
||||
return acc;
|
||||
}, {});
|
||||
this.setState({
|
||||
errors: { ...validationMessages
|
||||
},
|
||||
formFields: this.state.formFields
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleDelete", keycloak => {
|
||||
new AIACommand(keycloak, "delete_account").execute();
|
||||
});
|
||||
|
||||
_defineProperty(this, "UsernameInput", () => /*#__PURE__*/React.createElement(TextInput, {
|
||||
isRequired: true,
|
||||
type: "text",
|
||||
id: "user-name",
|
||||
name: "username",
|
||||
maxLength: 254,
|
||||
value: this.state.formFields.username,
|
||||
onChange: this.handleChange,
|
||||
validated: this.state.errors.username !== '' ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}));
|
||||
|
||||
_defineProperty(this, "RestrictedUsernameInput", () => /*#__PURE__*/React.createElement(TextInput, {
|
||||
isReadOnly: true,
|
||||
type: "text",
|
||||
id: "user-name",
|
||||
name: "username",
|
||||
value: this.state.formFields.username
|
||||
}));
|
||||
|
||||
this.context = context;
|
||||
this.fetchPersonalInfo();
|
||||
}
|
||||
|
||||
fetchPersonalInfo() {
|
||||
this.context.doGet("/").then(response => {
|
||||
this.setState(this.DEFAULT_STATE);
|
||||
const formFields = response.data;
|
||||
|
||||
if (!formFields.attributes) {
|
||||
formFields.attributes = {
|
||||
locale: [locale]
|
||||
};
|
||||
} else if (!formFields.attributes.locale) {
|
||||
formFields.attributes.locale = [locale];
|
||||
}
|
||||
|
||||
this.setState({ ...{
|
||||
formFields: formFields
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const fields = this.state.formFields;
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: "personalInfoHtmlTitle",
|
||||
introMessage: "personalSubMessage"
|
||||
}, /*#__PURE__*/React.createElement(PageSection, {
|
||||
isFilled: true,
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(TextContent, {
|
||||
className: "pf-u-mb-lg"
|
||||
}, /*#__PURE__*/React.createElement(Text, {
|
||||
component: TextVariants.small
|
||||
}, Msg.localize('allFieldsRequired'))), /*#__PURE__*/React.createElement(Form, {
|
||||
onSubmit: event => this.handleSubmit(event),
|
||||
className: "personal-info-form"
|
||||
}, !this.isRegistrationEmailAsUsername && /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: Msg.localize("username"),
|
||||
fieldId: "user-name",
|
||||
helperTextInvalid: this.state.errors.username,
|
||||
validated: this.state.errors.username !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}, this.isEditUserNameAllowed && /*#__PURE__*/React.createElement(this.UsernameInput, null), !this.isEditUserNameAllowed && /*#__PURE__*/React.createElement(this.RestrictedUsernameInput, null)), /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: Msg.localize("email"),
|
||||
fieldId: "email-address",
|
||||
helperTextInvalid: this.state.errors.email,
|
||||
validated: this.state.errors.email !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}, /*#__PURE__*/React.createElement(TextInput, {
|
||||
isRequired: true,
|
||||
type: "email",
|
||||
id: "email-address",
|
||||
name: "email",
|
||||
maxLength: 254,
|
||||
value: fields.email,
|
||||
onChange: this.handleChange,
|
||||
validated: this.state.errors.email !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
})), /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: Msg.localize("firstName"),
|
||||
fieldId: "first-name",
|
||||
helperTextInvalid: this.state.errors.firstName,
|
||||
validated: this.state.errors.firstName !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}, /*#__PURE__*/React.createElement(TextInput, {
|
||||
isRequired: true,
|
||||
type: "text",
|
||||
id: "first-name",
|
||||
name: "firstName",
|
||||
maxLength: 254,
|
||||
value: fields.firstName,
|
||||
onChange: this.handleChange,
|
||||
validated: this.state.errors.firstName !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
})), /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: Msg.localize("lastName"),
|
||||
fieldId: "last-name",
|
||||
helperTextInvalid: this.state.errors.lastName,
|
||||
validated: this.state.errors.lastName !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}, /*#__PURE__*/React.createElement(TextInput, {
|
||||
isRequired: true,
|
||||
type: "text",
|
||||
id: "last-name",
|
||||
name: "lastName",
|
||||
maxLength: 254,
|
||||
value: fields.lastName,
|
||||
onChange: this.handleChange,
|
||||
validated: this.state.errors.lastName !== "" ? ValidatedOptions.error : ValidatedOptions.default
|
||||
})), features.isInternationalizationEnabled && /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: Msg.localize("selectLocale"),
|
||||
isRequired: true,
|
||||
fieldId: "locale"
|
||||
}, /*#__PURE__*/React.createElement(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]
|
||||
}
|
||||
}
|
||||
})
|
||||
})), /*#__PURE__*/React.createElement(ActionGroup, null, /*#__PURE__*/React.createElement(Button, {
|
||||
type: "submit",
|
||||
id: "save-btn",
|
||||
variant: "primary",
|
||||
isDisabled: Object.values(this.state.errors).filter(e => e !== "").length !== 0
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "doSave"
|
||||
})), /*#__PURE__*/React.createElement(Button, {
|
||||
id: "cancel-btn",
|
||||
variant: "link",
|
||||
onClick: this.handleCancel
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "doCancel"
|
||||
})))), this.isDeleteAccountAllowed && /*#__PURE__*/React.createElement("div", {
|
||||
id: "delete-account",
|
||||
style: {
|
||||
marginTop: "30px"
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(ExpandableSection, {
|
||||
toggleText: "Delete Account"
|
||||
}, /*#__PURE__*/React.createElement(Grid, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(GridItem, {
|
||||
span: 6
|
||||
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "deleteAccountWarning"
|
||||
}))), /*#__PURE__*/React.createElement(GridItem, {
|
||||
span: 4
|
||||
}, /*#__PURE__*/React.createElement(KeycloakContext.Consumer, null, keycloak => /*#__PURE__*/React.createElement(Button, {
|
||||
id: "delete-account-btn",
|
||||
variant: "danger",
|
||||
onClick: () => this.handleDelete(keycloak),
|
||||
className: "delete-button"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "doDelete"
|
||||
})))), /*#__PURE__*/React.createElement(GridItem, {
|
||||
span: 2
|
||||
}))))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(AccountPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
//# sourceMappingURL=AccountPage.js.map
|
||||
@@ -0,0 +1,70 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { withRouter } from "../../../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { AIACommand } from "../../util/AIACommand.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { Title, Button, EmptyState, EmptyStateVariant, EmptyStateIcon, EmptyStateBody, TitleSizes } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { PassportIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { KeycloakContext } from "../../keycloak-service/KeycloakContext.js"; // Note: This class demonstrates two features of the ContentPages framework:
|
||||
// 1) The PageDef is available as a React property.
|
||||
// 2) You can add additional custom properties to the PageDef. In this case,
|
||||
// we add a value called kcAction in content.js and access it by extending the
|
||||
// PageDef interface.
|
||||
|
||||
/**
|
||||
* @author Stan Silvert
|
||||
*/
|
||||
class ApplicationInitiatedActionPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "handleClick", keycloak => {
|
||||
new AIACommand(keycloak, this.props.pageDef.kcAction).execute();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(EmptyState, {
|
||||
variant: EmptyStateVariant.full
|
||||
}, /*#__PURE__*/React.createElement(EmptyStateIcon, {
|
||||
icon: PassportIcon
|
||||
}), /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h5",
|
||||
size: TitleSizes.lg
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: this.props.pageDef.label,
|
||||
params: this.props.pageDef.labelParams
|
||||
})), /*#__PURE__*/React.createElement(EmptyStateBody, null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "actionRequiresIDP"
|
||||
})), /*#__PURE__*/React.createElement(KeycloakContext.Consumer, null, keycloak => /*#__PURE__*/React.createElement(Button, {
|
||||
variant: "primary",
|
||||
onClick: () => this.handleClick(keycloak),
|
||||
target: "_blank"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "continue"
|
||||
}))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
; // Note that the class name is not exported above. To get access to the router,
|
||||
// we use withRouter() and export a different name.
|
||||
|
||||
export const AppInitiatedActionPage = withRouter(ApplicationInitiatedActionPage);
|
||||
//# sourceMappingURL=AppInitiatedActionPage.js.map
|
||||
@@ -0,0 +1,184 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { DataList, DataListItem, DataListItemRow, DataListCell, DataListToggle, DataListContent, DataListItemCells, DescriptionList, DescriptionListTerm, DescriptionListGroup, DescriptionListDescription, Grid, GridItem, Button, PageSection, PageSectionVariants, Stack } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { InfoAltIcon, CheckIcon, ExternalLinkAltIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { ContinueCancelModal } from "../../widgets/ContinueCancelModal.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
export class ApplicationsPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "removeConsent", clientId => {
|
||||
this.context.doDelete("/applications/" + clientId + "/consent").then(() => {
|
||||
this.fetchApplications();
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "onToggle", row => {
|
||||
const newIsRowOpen = this.state.isRowOpen;
|
||||
newIsRowOpen[row] = !newIsRowOpen[row];
|
||||
this.setState({
|
||||
isRowOpen: newIsRowOpen
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
isRowOpen: [],
|
||||
applications: []
|
||||
};
|
||||
this.fetchApplications();
|
||||
}
|
||||
|
||||
fetchApplications() {
|
||||
this.context.doGet("/applications").then(response => {
|
||||
const applications = response.data || [];
|
||||
this.setState({
|
||||
isRowOpen: new Array(applications.length).fill(false),
|
||||
applications: applications
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
elementId(item, application) {
|
||||
return `application-${item}-${application.clientId}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: Msg.localize('applicationsPageTitle'),
|
||||
introMessage: "Manage your application permissions."
|
||||
}, /*#__PURE__*/React.createElement(PageSection, {
|
||||
isFilled: true,
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(Stack, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(DataList, {
|
||||
id: "applications-list",
|
||||
"aria-label": Msg.localize('applicationsPageTitle')
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
id: "applications-list-header",
|
||||
"aria-labelledby": "Columns names"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, "// invisible toggle allows headings to line up properly", /*#__PURE__*/React.createElement("span", {
|
||||
style: {
|
||||
visibility: 'hidden',
|
||||
height: 55
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(DataListToggle, {
|
||||
isExpanded: false,
|
||||
id: "applications-list-header-invisible-toggle",
|
||||
"aria-controls": "hidden"
|
||||
})), /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "applications-list-client-id-header",
|
||||
width: 2,
|
||||
className: "pf-u-pt-md"
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "applicationName"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "applications-list-app-type-header",
|
||||
width: 2,
|
||||
className: "pf-u-pt-md"
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "applicationType"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "applications-list-status",
|
||||
width: 2,
|
||||
className: "pf-u-pt-md"
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "status"
|
||||
})))]
|
||||
}))), this.state.applications.map((application, appIndex) => {
|
||||
return /*#__PURE__*/React.createElement(DataListItem, {
|
||||
id: this.elementId("client-id", application),
|
||||
key: 'application-' + appIndex,
|
||||
"aria-labelledby": "applications-list",
|
||||
isExpanded: this.state.isRowOpen[appIndex]
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
className: "pf-u-align-items-center"
|
||||
}, /*#__PURE__*/React.createElement(DataListToggle, {
|
||||
onClick: () => this.onToggle(appIndex),
|
||||
isExpanded: this.state.isRowOpen[appIndex],
|
||||
id: this.elementId('toggle', application),
|
||||
"aria-controls": this.elementId("expandable", application)
|
||||
}), /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
className: "pf-u-align-items-center",
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: this.elementId('name', application),
|
||||
width: 2,
|
||||
key: 'app-' + appIndex
|
||||
}, /*#__PURE__*/React.createElement(Button, {
|
||||
className: "pf-u-pl-0 title-case",
|
||||
component: "a",
|
||||
variant: "link",
|
||||
onClick: () => window.open(application.effectiveUrl)
|
||||
}, application.clientName || application.clientId, " ", /*#__PURE__*/React.createElement(ExternalLinkAltIcon, null))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: this.elementId('internal', application),
|
||||
width: 2,
|
||||
key: 'internal-' + appIndex
|
||||
}, application.userConsentRequired ? Msg.localize('thirdPartyApp') : Msg.localize('internalApp'), application.offlineAccess ? ', ' + Msg.localize('offlineAccess') : ''), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: this.elementId('status', application),
|
||||
width: 2,
|
||||
key: 'status-' + appIndex
|
||||
}, application.inUse ? Msg.localize('inUse') : Msg.localize('notInUse'))]
|
||||
})), /*#__PURE__*/React.createElement(DataListContent, {
|
||||
className: "pf-u-pl-35xl",
|
||||
hasNoPadding: false,
|
||||
"aria-label": Msg.localize('applicationDetails'),
|
||||
id: this.elementId("expandable", application),
|
||||
isHidden: !this.state.isRowOpen[appIndex]
|
||||
}, /*#__PURE__*/React.createElement(DescriptionList, null, /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('client')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, application.clientId)), application.description && /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('description')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, application.description)), application.effectiveUrl && /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, "URL"), /*#__PURE__*/React.createElement(DescriptionListDescription, null, application.effectiveUrl.split('"'))), application.consent && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, "Has access to"), application.consent.grantedScopes.map((scope, scopeIndex) => {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||||
key: 'scope-' + scopeIndex
|
||||
}, /*#__PURE__*/React.createElement(DescriptionListDescription, null, /*#__PURE__*/React.createElement(CheckIcon, null), " ", scope.name));
|
||||
})), /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('accessGrantedOn') + ': '), /*#__PURE__*/React.createElement(DescriptionListDescription, null, new Intl.DateTimeFormat(locale, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric'
|
||||
}).format(application.consent.createDate))))), (application.consent || application.offlineAccess) && /*#__PURE__*/React.createElement(Grid, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement("hr", null), /*#__PURE__*/React.createElement(GridItem, null, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
buttonTitle: Msg.localize('removeButton') // required
|
||||
,
|
||||
buttonVariant: "secondary" // defaults to 'primary'
|
||||
,
|
||||
modalTitle: Msg.localize('removeModalTitle') // required
|
||||
,
|
||||
modalMessage: Msg.localize('removeModalMessage', [application.clientId]),
|
||||
modalContinueButtonLabel: Msg.localize('confirmButton') // defaults to 'Continue'
|
||||
,
|
||||
onContinue: () => this.removeConsent(application.clientId) // required
|
||||
|
||||
}))), /*#__PURE__*/React.createElement(GridItem, null, /*#__PURE__*/React.createElement(InfoAltIcon, null), " ", Msg.localize('infoMessage')))));
|
||||
})))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(ApplicationsPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
//# sourceMappingURL=ApplicationsPage.js.map
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
export class AuthenticatorPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("h2", null, "Hello Authenticator Page"));
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
//# sourceMappingURL=AuthenticatorPage.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/app/content/authenticator-page/AuthenticatorPage.tsx"],"names":["React","AuthenticatorPage","Component","constructor","props","render"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AAKA,OAAO,MAAMC,iBAAN,SAAgCD,KAAK,CAACE,SAAtC,CAAwE;AAEpEC,EAAAA,WAAW,CAACC,KAAD,EAAgC;AAC9C,UAAMA,KAAN;AACH;;AAEMC,EAAAA,MAAM,GAAoB;AAC7B,wBACI,8CACE,2DADF,CADJ;AAKH;;AAZ0E;AAa9E","sourcesContent":["/* \n * Copyright 2018 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as React from 'react';\n \nexport interface AuthenticatorPageProps {\n}\n \nexport class AuthenticatorPage extends React.Component<AuthenticatorPageProps> {\n \n public constructor(props: AuthenticatorPageProps) {\n super(props);\n }\n\n public render(): React.ReactNode {\n return (\n <div>\n <h2>Hello Authenticator Page</h2>\n </div>\n );\n }\n};"],"file":"AuthenticatorPage.js"}
|
||||
@@ -0,0 +1,238 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import TimeUtil from "../../util/TimeUtil.js";
|
||||
import { Button, DataList, DataListItem, DataListItemRow, DataListContent, DescriptionList, DescriptionListTerm, DescriptionListDescription, DescriptionListGroup, Grid, GridItem, Label, PageSection, PageSectionVariants, Title, Tooltip, SplitItem, Split } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { DesktopIcon, MobileAltIcon, SyncAltIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContinueCancelModal } from "../../widgets/ContinueCancelModal.js";
|
||||
import { KeycloakContext } from "../../keycloak-service/KeycloakContext.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2019 Red Hat Inc.
|
||||
*/
|
||||
export class DeviceActivityPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "signOutAll", keycloakService => {
|
||||
this.context.doDelete("/sessions").then(() => {
|
||||
keycloakService.logout();
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "signOutSession", (device, session) => {
|
||||
this.context.doDelete("/sessions/" + session.id).then(() => {
|
||||
this.fetchDevices();
|
||||
ContentAlert.success('signedOutSession', [session.browser, device.os]);
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
devices: []
|
||||
};
|
||||
this.fetchDevices();
|
||||
}
|
||||
|
||||
fetchDevices() {
|
||||
this.context.doGet("/sessions/devices").then(response => {
|
||||
console.log({
|
||||
response
|
||||
});
|
||||
let devices = this.moveCurrentToTop(response.data);
|
||||
this.setState({
|
||||
devices: devices
|
||||
});
|
||||
});
|
||||
} // current device and session should display at the top of their respective lists
|
||||
|
||||
|
||||
moveCurrentToTop(devices) {
|
||||
let currentDevice = devices[0];
|
||||
devices.forEach((device, index) => {
|
||||
if (device.current) {
|
||||
currentDevice = device;
|
||||
devices.splice(index, 1);
|
||||
devices.unshift(device);
|
||||
}
|
||||
});
|
||||
currentDevice.sessions.forEach((session, index) => {
|
||||
if (session.current) {
|
||||
const currentSession = currentDevice.sessions.splice(index, 1);
|
||||
currentDevice.sessions.unshift(currentSession[0]);
|
||||
}
|
||||
});
|
||||
return devices;
|
||||
}
|
||||
|
||||
time(time) {
|
||||
return TimeUtil.format(time * 1000);
|
||||
}
|
||||
|
||||
elementId(item, session, element = 'session') {
|
||||
return `${element}-${session.id.substring(0, 7)}-${item}`;
|
||||
}
|
||||
|
||||
findDeviceTypeIcon(session, device) {
|
||||
const deviceType = device.mobile;
|
||||
if (deviceType === true) return /*#__PURE__*/React.createElement(MobileAltIcon, {
|
||||
id: this.elementId('icon-mobile', session, 'device')
|
||||
});
|
||||
return /*#__PURE__*/React.createElement(DesktopIcon, {
|
||||
id: this.elementId('icon-desktop', session, 'device')
|
||||
});
|
||||
}
|
||||
|
||||
findOS(device) {
|
||||
if (device.os.toLowerCase().includes('unknown')) return Msg.localize('unknownOperatingSystem');
|
||||
return device.os;
|
||||
}
|
||||
|
||||
findOSVersion(device) {
|
||||
if (device.osVersion.toLowerCase().includes('unknown')) return '';
|
||||
return device.osVersion;
|
||||
}
|
||||
|
||||
makeClientsString(clients) {
|
||||
let clientsString = "";
|
||||
clients.forEach((client, index) => {
|
||||
let clientName;
|
||||
|
||||
if (client.hasOwnProperty('clientName') && client.clientName !== undefined && client.clientName !== '') {
|
||||
clientName = Msg.localize(client.clientName);
|
||||
} else {
|
||||
clientName = client.clientId;
|
||||
}
|
||||
|
||||
clientsString += clientName;
|
||||
if (clients.length > index + 1) clientsString += ', ';
|
||||
});
|
||||
return clientsString;
|
||||
}
|
||||
|
||||
isShowSignOutAll(devices) {
|
||||
if (devices.length === 0) return false;
|
||||
if (devices.length > 1) return true;
|
||||
if (devices[0].sessions.length > 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: "device-activity",
|
||||
introMessage: "signedInDevicesExplanation"
|
||||
}, /*#__PURE__*/React.createElement(PageSection, {
|
||||
isFilled: true,
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(Split, {
|
||||
hasGutter: true,
|
||||
className: "pf-u-mb-lg"
|
||||
}, /*#__PURE__*/React.createElement(SplitItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
id: "signedInDevicesTitle",
|
||||
className: "pf-c-content"
|
||||
}, /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h2",
|
||||
size: "xl"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "signedInDevices"
|
||||
})))), /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(Tooltip, {
|
||||
content: /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "refreshPage"
|
||||
})
|
||||
}, /*#__PURE__*/React.createElement(Button, {
|
||||
"aria-describedby": "refresh page",
|
||||
id: "refresh-page",
|
||||
variant: "link",
|
||||
onClick: this.fetchDevices.bind(this),
|
||||
icon: /*#__PURE__*/React.createElement(SyncAltIcon, null)
|
||||
}, "Refresh"))), /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(KeycloakContext.Consumer, null, keycloak => this.isShowSignOutAll(this.state.devices) && /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
buttonTitle: "signOutAllDevices",
|
||||
buttonId: "sign-out-all",
|
||||
modalTitle: "signOutAllDevices",
|
||||
modalMessage: "signOutAllDevicesWarning",
|
||||
onContinue: () => this.signOutAll(keycloak)
|
||||
})))), /*#__PURE__*/React.createElement(DataList, {
|
||||
className: "signed-in-device-list",
|
||||
"aria-label": Msg.localize('signedInDevices')
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
"aria-labelledby": "sessions",
|
||||
id: "device-activity-sessions"
|
||||
}, this.state.devices.map((device, deviceIndex) => {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, device.sessions.map((session, sessionIndex) => {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||||
key: 'device-' + deviceIndex + '-session-' + sessionIndex
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListContent, {
|
||||
"aria-label": "device-sessions-content",
|
||||
isHidden: false,
|
||||
className: "pf-u-flex-grow-1"
|
||||
}, /*#__PURE__*/React.createElement(Grid, {
|
||||
className: "signed-in-device-grid",
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(GridItem, {
|
||||
className: "device-icon",
|
||||
span: 1,
|
||||
rowSpan: 2
|
||||
}, /*#__PURE__*/React.createElement("span", null, this.findDeviceTypeIcon(session, device))), /*#__PURE__*/React.createElement(GridItem, {
|
||||
sm: 8,
|
||||
md: 9,
|
||||
span: 10
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
id: this.elementId('browser', session),
|
||||
className: "pf-u-mr-md"
|
||||
}, this.findOS(device), " ", this.findOSVersion(device), " / ", session.browser), session.current && /*#__PURE__*/React.createElement(Label, {
|
||||
color: "green"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "currentSession"
|
||||
}))), /*#__PURE__*/React.createElement(GridItem, {
|
||||
className: "pf-u-text-align-right",
|
||||
sm: 3,
|
||||
md: 2,
|
||||
span: 1
|
||||
}, !session.current && /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
buttonTitle: "doSignOut",
|
||||
buttonId: this.elementId('sign-out', session),
|
||||
modalTitle: "doSignOut",
|
||||
buttonVariant: "secondary",
|
||||
modalMessage: "signOutWarning",
|
||||
onContinue: () => this.signOutSession(device, session)
|
||||
})), /*#__PURE__*/React.createElement(GridItem, {
|
||||
span: 11
|
||||
}, /*#__PURE__*/React.createElement(DescriptionList, {
|
||||
columnModifier: {
|
||||
sm: '2Col',
|
||||
lg: '3Col'
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('ipAddress')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, session.ipAddress)), /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('lastAccessedOn')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, this.time(session.lastAccess))), /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('clients')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, this.makeClientsString(session.clients))), /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('started')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, this.time(session.started))), /*#__PURE__*/React.createElement(DescriptionListGroup, null, /*#__PURE__*/React.createElement(DescriptionListTerm, null, Msg.localize('expires')), /*#__PURE__*/React.createElement(DescriptionListDescription, null, this.time(session.expires)))))))));
|
||||
}));
|
||||
})))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(DeviceActivityPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
//# sourceMappingURL=DeviceActivityPage.js.map
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { WarningTriangleIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import EmptyMessageState from "../../widgets/EmptyMessageState.js";
|
||||
export class ForbiddenPage extends React.Component {
|
||||
constructor() {
|
||||
super({});
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(EmptyMessageState, {
|
||||
icon: WarningTriangleIcon,
|
||||
messageKey: "forbidden"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "needAccessRights"
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
//# sourceMappingURL=ForbiddenPage.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/app/content/forbidden-page/ForbiddenPage.tsx"],"names":["React","WarningTriangleIcon","Msg","EmptyMessageState","ForbiddenPage","Component","constructor","render"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,KAAKA,KAAZ;AAEA,SAASC,mBAAT;AACA,SAAQC,GAAR;AACA,OAAOC,iBAAP;AAGA,OAAO,MAAMC,aAAN,SAA4BJ,KAAK,CAACK,SAAlC,CAA4C;AAExCC,EAAAA,WAAW,GAAG;AACjB,UAAM,EAAN;AACH;;AAEMC,EAAAA,MAAM,GAAoB;AAC7B,wBACI,oBAAC,iBAAD;AAAmB,MAAA,IAAI,EAAEN,mBAAzB;AAA8C,MAAA,UAAU,EAAC;AAAzD,oBACI,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC;AAAZ,MADJ,CADJ;AAKH;;AAZ8C;AAalD","sourcesContent":["/*\n * Copyright 2020 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport * as React from 'react';\n\nimport { WarningTriangleIcon } from '@patternfly/react-icons';\nimport {Msg} from '../../widgets/Msg';\nimport EmptyMessageState from '../../widgets/EmptyMessageState';\n\n\nexport class ForbiddenPage extends React.Component {\n\n public constructor() {\n super({});\n }\n\n public render(): React.ReactNode {\n return (\n <EmptyMessageState icon={WarningTriangleIcon} messageKey=\"forbidden\">\n <Msg msgKey=\"needAccessRights\"/>\n </EmptyMessageState>\n );\n }\n};\n"],"file":"ForbiddenPage.js"}
|
||||
@@ -0,0 +1,261 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { withRouter } from "../../../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { Button, DataList, DataListAction, DataListItemCells, DataListCell, DataListItemRow, Label, PageSection, PageSectionVariants, Split, SplitItem, Stack, StackItem, Title, DataListItem } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { BitbucketIcon, CubeIcon, GitlabIcon, LinkIcon, PaypalIcon, UnlinkIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { createRedirect } from "../../util/RedirectUri.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert
|
||||
*/
|
||||
class LinkedAccountsPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
linkedAccounts: [],
|
||||
unLinkedAccounts: []
|
||||
};
|
||||
this.getLinkedAccounts();
|
||||
}
|
||||
|
||||
getLinkedAccounts() {
|
||||
this.context.doGet("/linked-accounts").then(response => {
|
||||
console.log({
|
||||
response
|
||||
});
|
||||
const linkedAccounts = response.data.filter(account => account.connected);
|
||||
const unLinkedAccounts = response.data.filter(account => !account.connected);
|
||||
this.setState({
|
||||
linkedAccounts: linkedAccounts,
|
||||
unLinkedAccounts: unLinkedAccounts
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
unLinkAccount(account) {
|
||||
const url = '/linked-accounts/' + account.providerName;
|
||||
this.context.doDelete(url).then(response => {
|
||||
console.log({
|
||||
response
|
||||
});
|
||||
this.getLinkedAccounts();
|
||||
});
|
||||
}
|
||||
|
||||
linkAccount(account) {
|
||||
const url = '/linked-accounts/' + account.providerName;
|
||||
const redirectUri = createRedirect(this.props.location.pathname);
|
||||
this.context.doGet(url, {
|
||||
params: {
|
||||
providerId: account.providerName,
|
||||
redirectUri
|
||||
}
|
||||
}).then(response => {
|
||||
console.log({
|
||||
response
|
||||
});
|
||||
window.location.href = response.data.accountLinkUri;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: Msg.localize('linkedAccountsTitle'),
|
||||
introMessage: Msg.localize('linkedAccountsIntroMessage')
|
||||
}, /*#__PURE__*/React.createElement(PageSection, {
|
||||
isFilled: true,
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(Stack, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(StackItem, null, /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h2",
|
||||
className: "pf-u-mb-lg",
|
||||
size: "xl"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "linkedLoginProviders"
|
||||
})), /*#__PURE__*/React.createElement(DataList, {
|
||||
id: "linked-idps",
|
||||
"aria-label": Msg.localize('linkedLoginProviders')
|
||||
}, this.makeRows(this.state.linkedAccounts, true))), /*#__PURE__*/React.createElement(StackItem, null, /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h2",
|
||||
className: "pf-u-mt-xl pf-u-mb-lg",
|
||||
size: "xl"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "unlinkedLoginProviders"
|
||||
})), /*#__PURE__*/React.createElement(DataList, {
|
||||
id: "unlinked-idps",
|
||||
"aria-label": Msg.localize('unlinkedLoginProviders')
|
||||
}, this.makeRows(this.state.unLinkedAccounts, false))))));
|
||||
}
|
||||
|
||||
emptyRow(isLinked) {
|
||||
let isEmptyMessage = '';
|
||||
|
||||
if (isLinked) {
|
||||
isEmptyMessage = Msg.localize('linkedEmpty');
|
||||
} else {
|
||||
isEmptyMessage = Msg.localize('unlinkedEmpty');
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: "emptyItem",
|
||||
"aria-labelledby": Msg.localize('isEmptyMessage')
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
key: "emptyRow"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "empty"
|
||||
}, isEmptyMessage)]
|
||||
})));
|
||||
}
|
||||
|
||||
makeRows(accounts, isLinked) {
|
||||
if (accounts.length === 0) {
|
||||
return this.emptyRow(isLinked);
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, " ", accounts.map(account => /*#__PURE__*/React.createElement(DataListItem, {
|
||||
id: `${account.providerAlias}-idp`,
|
||||
key: account.providerName,
|
||||
"aria-labelledby": Msg.localize('linkedAccountsTitle')
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
key: account.providerName
|
||||
}, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "idp"
|
||||
}, /*#__PURE__*/React.createElement(Split, null, /*#__PURE__*/React.createElement(SplitItem, {
|
||||
className: "pf-u-mr-sm"
|
||||
}, this.findIcon(account)), /*#__PURE__*/React.createElement(SplitItem, {
|
||||
className: "pf-u-my-xs",
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
id: `${account.providerAlias}-idp-name`
|
||||
}, account.displayName)))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "label"
|
||||
}, /*#__PURE__*/React.createElement(Split, null, /*#__PURE__*/React.createElement(SplitItem, {
|
||||
className: "pf-u-my-xs",
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
id: `${account.providerAlias}-idp-label`
|
||||
}, this.label(account))))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "username",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement(Split, null, /*#__PURE__*/React.createElement(SplitItem, {
|
||||
className: "pf-u-my-xs",
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
id: `${account.providerAlias}-idp-username`
|
||||
}, account.linkedUsername))))]
|
||||
}), /*#__PURE__*/React.createElement(DataListAction, {
|
||||
"aria-labelledby": Msg.localize('link'),
|
||||
"aria-label": Msg.localize('unLink'),
|
||||
id: "setPasswordAction"
|
||||
}, isLinked && /*#__PURE__*/React.createElement(Button, {
|
||||
id: `${account.providerAlias}-idp-unlink`,
|
||||
variant: "link",
|
||||
onClick: () => this.unLinkAccount(account)
|
||||
}, /*#__PURE__*/React.createElement(UnlinkIcon, {
|
||||
size: "sm"
|
||||
}), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "unLink"
|
||||
})), !isLinked && /*#__PURE__*/React.createElement(Button, {
|
||||
id: `${account.providerAlias}-idp-link`,
|
||||
variant: "link",
|
||||
onClick: () => this.linkAccount(account)
|
||||
}, /*#__PURE__*/React.createElement(LinkIcon, {
|
||||
size: "sm"
|
||||
}), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "link"
|
||||
})))))), " ");
|
||||
}
|
||||
|
||||
label(account) {
|
||||
if (account.social) {
|
||||
return /*#__PURE__*/React.createElement(Label, {
|
||||
color: "blue"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "socialLogin"
|
||||
}));
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(Label, {
|
||||
color: "green"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "systemDefined"
|
||||
}));
|
||||
}
|
||||
|
||||
findIcon(account) {
|
||||
const socialIconId = `${account.providerAlias}-idp-icon-social`;
|
||||
console.log(account);
|
||||
|
||||
switch (true) {
|
||||
case account.providerName.toLowerCase().includes('bitbucket'):
|
||||
return /*#__PURE__*/React.createElement(BitbucketIcon, {
|
||||
id: socialIconId,
|
||||
size: "lg"
|
||||
});
|
||||
|
||||
case account.providerName.toLowerCase().includes('openshift'):
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "idp-icon-social",
|
||||
id: "openshift-idp-icon-social"
|
||||
});
|
||||
|
||||
case account.providerName.toLowerCase().includes('gitlab'):
|
||||
return /*#__PURE__*/React.createElement(GitlabIcon, {
|
||||
id: socialIconId,
|
||||
size: "lg"
|
||||
});
|
||||
|
||||
case account.providerName.toLowerCase().includes('paypal'):
|
||||
return /*#__PURE__*/React.createElement(PaypalIcon, {
|
||||
id: socialIconId,
|
||||
size: "lg"
|
||||
});
|
||||
|
||||
case account.providerName !== '' && account.social:
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "idp-icon-social",
|
||||
id: socialIconId
|
||||
});
|
||||
|
||||
default:
|
||||
return /*#__PURE__*/React.createElement(CubeIcon, {
|
||||
id: `${account.providerAlias}-idp-icon-default`,
|
||||
size: "lg"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(LinkedAccountsPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
const LinkedAccountsPagewithRouter = withRouter(LinkedAccountsPage);
|
||||
export { LinkedAccountsPagewithRouter as LinkedAccountsPage };
|
||||
//# sourceMappingURL=LinkedAccountsPage.js.map
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
export class AbstractResourcesTable extends React.Component {
|
||||
hasPermissions(row) {
|
||||
return this.state.permissions.has(row) && this.state.permissions.get(row).length > 0;
|
||||
}
|
||||
|
||||
firstUser(row) {
|
||||
if (!this.hasPermissions(row)) return 'ERROR!!!!'; // should never happen
|
||||
|
||||
return this.state.permissions.get(row)[0].username;
|
||||
}
|
||||
|
||||
numOthers(row) {
|
||||
if (!this.hasPermissions(row)) return -1; // should never happen
|
||||
|
||||
return this.state.permissions.get(row).length - 1;
|
||||
}
|
||||
|
||||
sharedWithUsersMessage(row) {
|
||||
if (!this.hasPermissions(row)) return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "resourceNotShared"
|
||||
}));
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "resourceSharedWith"
|
||||
}, /*#__PURE__*/React.createElement("strong", null, this.firstUser(row))), this.numOthers(row) > 0 && /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "and"
|
||||
}, /*#__PURE__*/React.createElement("strong", null, this.numOthers(row))), ".");
|
||||
}
|
||||
|
||||
getClientName(client) {
|
||||
if (client.hasOwnProperty('name') && client.name !== null && client.name !== '') {
|
||||
return Msg.localize(client.name);
|
||||
} else {
|
||||
return client.clientId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=AbstractResourceTable.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/app/content/my-resources-page/AbstractResourceTable.tsx"],"names":["React","Msg","AbstractResourcesTable","Component","hasPermissions","row","state","permissions","has","get","length","firstUser","username","numOthers","sharedWithUsersMessage","getClientName","client","hasOwnProperty","name","localize","clientId"],"mappings":"AAAA,OAAO,KAAKA,KAAZ;AAEA,SAASC,GAAT;AAUA,OAAO,MAAeC,sBAAf,SAA6EF,KAAK,CAACG,SAAnF,CAAqH;AAEhHC,EAAAA,cAAc,CAACC,GAAD,EAAuB;AAC7C,WAAQ,KAAKC,KAAL,CAAWC,WAAX,CAAuBC,GAAvB,CAA2BH,GAA3B,CAAD,IAAsC,KAAKC,KAAL,CAAWC,WAAX,CAAuBE,GAAvB,CAA2BJ,GAA3B,EAAiCK,MAAjC,GAA0C,CAAvF;AACD;;AAEOC,EAAAA,SAAS,CAACN,GAAD,EAAsB;AACrC,QAAI,CAAC,KAAKD,cAAL,CAAoBC,GAApB,CAAL,EAA+B,OAAO,WAAP,CADM,CACc;;AAEnD,WAAO,KAAKC,KAAL,CAAWC,WAAX,CAAuBE,GAAvB,CAA2BJ,GAA3B,EAAiC,CAAjC,EAAoCO,QAA3C;AACD;;AAESC,EAAAA,SAAS,CAACR,GAAD,EAAsB;AACvC,QAAI,CAAC,KAAKD,cAAL,CAAoBC,GAApB,CAAL,EAA+B,OAAO,CAAC,CAAR,CADQ,CACG;;AAE1C,WAAO,KAAKC,KAAL,CAAWC,WAAX,CAAuBE,GAAvB,CAA2BJ,GAA3B,EAAiCK,MAAjC,GAA0C,CAAjD;AACD;;AAEMI,EAAAA,sBAAsB,CAACT,GAAD,EAA+B;AAC1D,QAAI,CAAC,KAAKD,cAAL,CAAoBC,GAApB,CAAL,EAA+B,oBAAQ,oBAAC,KAAD,CAAO,QAAP,qBAAgB,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC;AAAZ,MAAhB,CAAR;AAE/B,wBACE,oBAAC,KAAD,CAAO,QAAP,qBACE,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC;AAAZ,oBACE,oCAAS,KAAKM,SAAL,CAAeN,GAAf,CAAT,CADF,CADF,EAIG,KAAKQ,SAAL,CAAeR,GAAf,IAAsB,CAAtB,iBAA2B,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC;AAAZ,oBAC1B,oCAAS,KAAKQ,SAAL,CAAeR,GAAf,CAAT,CAD0B,CAJ9B,MADF;AAUD;;AAESU,EAAAA,aAAa,CAACC,MAAD,EAAyB;AAC9C,QAAIA,MAAM,CAACC,cAAP,CAAsB,MAAtB,KAAiCD,MAAM,CAACE,IAAP,KAAgB,IAAjD,IAAyDF,MAAM,CAACE,IAAP,KAAgB,EAA7E,EAAiF;AAC/E,aAAOjB,GAAG,CAACkB,QAAJ,CAAaH,MAAM,CAACE,IAApB,CAAP;AACD,KAFD,MAEO;AACL,aAAOF,MAAM,CAACI,QAAd;AACD;AACF;;AAvCyH","sourcesContent":["import * as React from 'react';\nimport { Permission, PaginatedResources, Client } from './resource-model';\nimport { Msg } from '../../widgets/Msg';\n\nexport interface ResourcesTableProps {\n resources: PaginatedResources;\n}\n\nexport interface ResourcesTableState {\n permissions: Map<number, Permission[]>;\n}\n\nexport abstract class AbstractResourcesTable<S extends ResourcesTableState> extends React.Component<ResourcesTableProps, S> {\n\n protected hasPermissions(row: number): boolean {\n return (this.state.permissions.has(row)) && (this.state.permissions.get(row)!.length > 0);\n }\n\n private firstUser(row: number): string {\n if (!this.hasPermissions(row)) return 'ERROR!!!!'; // should never happen\n\n return this.state.permissions.get(row)![0].username;\n }\n\n protected numOthers(row: number): number {\n if (!this.hasPermissions(row)) return -1; // should never happen\n\n return this.state.permissions.get(row)!.length - 1;\n }\n\n public sharedWithUsersMessage(row: number): React.ReactNode {\n if (!this.hasPermissions(row)) return (<React.Fragment><Msg msgKey='resourceNotShared' /></React.Fragment>);\n\n return (\n <React.Fragment>\n <Msg msgKey='resourceSharedWith'>\n <strong>{this.firstUser(row)}</strong>\n </Msg>\n {this.numOthers(row) > 0 && <Msg msgKey='and'>\n <strong>{this.numOthers(row)}</strong>\n </Msg>}.\n </React.Fragment>\n );\n }\n\n protected getClientName(client: Client): string {\n if (client.hasOwnProperty('name') && client.name !== null && client.name !== '') {\n return Msg.localize(client.name!);\n } else {\n return client.clientId;\n }\n }\n}\n"],"file":"AbstractResourceTable.js"}
|
||||
@@ -0,0 +1,120 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { Button, Modal, Form, FormGroup, TextInput, InputGroup, ModalVariant } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { OkIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { Scope } from "./resource-model.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
import { PermissionSelect } from "./PermissionSelect.js";
|
||||
export class EditTheResource extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "handleToggleDialog", () => {
|
||||
if (this.state.isOpen) {
|
||||
this.setState({
|
||||
isOpen: false
|
||||
});
|
||||
this.props.onClose();
|
||||
} else {
|
||||
this.clearState();
|
||||
this.setState({
|
||||
isOpen: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "updateChanged", row => {
|
||||
const changed = this.state.changed;
|
||||
changed[row] = !changed[row];
|
||||
this.setState({
|
||||
changed
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
changed: [],
|
||||
isOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
clearState() {
|
||||
this.setState({});
|
||||
}
|
||||
|
||||
async savePermission(permission) {
|
||||
await this.context.doPut(`/resources/${this.props.resource._id}/permissions`, [permission]);
|
||||
ContentAlert.success(Msg.localize('updateSuccess'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children(this.handleToggleDialog), /*#__PURE__*/React.createElement(Modal, {
|
||||
title: 'Edit the resource - ' + this.props.resource.name,
|
||||
variant: ModalVariant.large,
|
||||
isOpen: this.state.isOpen,
|
||||
onClose: this.handleToggleDialog,
|
||||
actions: [/*#__PURE__*/React.createElement(Button, {
|
||||
key: "done",
|
||||
variant: "link",
|
||||
id: "done",
|
||||
onClick: this.handleToggleDialog
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "done"
|
||||
}))]
|
||||
}, /*#__PURE__*/React.createElement(Form, {
|
||||
isHorizontal: true
|
||||
}, this.props.permissions.map((p, row) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FormGroup, {
|
||||
fieldId: `username-${row}`,
|
||||
label: Msg.localize('User')
|
||||
}, /*#__PURE__*/React.createElement(TextInput, {
|
||||
id: `username-${row}`,
|
||||
type: "text",
|
||||
value: p.username,
|
||||
isDisabled: true
|
||||
})), /*#__PURE__*/React.createElement(FormGroup, {
|
||||
fieldId: `permissions-${row}`,
|
||||
label: Msg.localize('permissions'),
|
||||
isRequired: true
|
||||
}, /*#__PURE__*/React.createElement(InputGroup, null, /*#__PURE__*/React.createElement(PermissionSelect, {
|
||||
scopes: this.props.resource.scopes,
|
||||
selected: p.scopes.map(s => new Scope(s)),
|
||||
direction: row === this.props.permissions.length - 1 ? "up" : "down",
|
||||
onSelect: selection => {
|
||||
p.scopes = selection.map(s => s.name);
|
||||
this.updateChanged(row);
|
||||
}
|
||||
}), /*#__PURE__*/React.createElement(Button, {
|
||||
id: `save-${row}`,
|
||||
isDisabled: !this.state.changed[row],
|
||||
onClick: () => this.savePermission(p)
|
||||
}, /*#__PURE__*/React.createElement(OkIcon, null)))), /*#__PURE__*/React.createElement("hr", null))))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(EditTheResource, "defaultProps", {
|
||||
permissions: []
|
||||
});
|
||||
|
||||
_defineProperty(EditTheResource, "contextType", AccountServiceContext);
|
||||
//# sourceMappingURL=EditTheResource.js.map
|
||||
@@ -0,0 +1,284 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import parse from "../../util/ParseLink.js";
|
||||
import { Button, Level, LevelItem, PageSection, PageSectionVariants, Stack, StackItem, Tab, Tabs, TextInput } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Scope } from "./resource-model.js";
|
||||
import { ResourcesTable } from "./ResourcesTable.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { SharedResourcesTable } from "./SharedResourcesTable.js";
|
||||
const MY_RESOURCES_TAB = 0;
|
||||
const SHARED_WITH_ME_TAB = 1;
|
||||
export class MyResourcesPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "first", 0);
|
||||
|
||||
_defineProperty(this, "max", 5);
|
||||
|
||||
_defineProperty(this, "makeScopeObj", scope => {
|
||||
return new Scope(scope.name, scope.displayName);
|
||||
});
|
||||
|
||||
_defineProperty(this, "fetchPermissionRequests", () => {
|
||||
this.state.myResources.data.forEach(resource => {
|
||||
this.fetchShareRequests(resource);
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "fetchPending", async () => {
|
||||
const response = await this.context.doGet(`/resources/pending-requests`);
|
||||
const resources = response.data || [];
|
||||
resources.forEach(pendingRequest => {
|
||||
this.state.sharedWithMe.data.forEach(resource => {
|
||||
if (resource._id === pendingRequest._id) {
|
||||
resource.shareRequests = [{
|
||||
username: 'me',
|
||||
scopes: pendingRequest.scopes
|
||||
}];
|
||||
this.forceUpdate();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleFilterRequest", value => {
|
||||
this.setState({
|
||||
nameFilter: value
|
||||
});
|
||||
this.fetchFilteredResources({
|
||||
name: value
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleFirstPageClick", () => {
|
||||
this.fetchInitialResources();
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleNextClick", () => {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
this.fetchResources(this.state.sharedWithMe.nextUrl);
|
||||
} else {
|
||||
this.fetchResources(this.state.myResources.nextUrl);
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handlePreviousClick", () => {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
this.fetchResources(this.state.sharedWithMe.prevUrl);
|
||||
} else {
|
||||
this.fetchResources(this.state.myResources.prevUrl);
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleTabClick", (event, tabIndex) => {
|
||||
if (this.state.activeTabKey === tabIndex) return;
|
||||
this.setState({
|
||||
nameFilter: '',
|
||||
activeTabKey: tabIndex
|
||||
}, () => {
|
||||
this.fetchInitialResources();
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
activeTabKey: MY_RESOURCES_TAB,
|
||||
nameFilter: '',
|
||||
isModalOpen: false,
|
||||
myResources: {
|
||||
nextUrl: '',
|
||||
prevUrl: '',
|
||||
data: []
|
||||
},
|
||||
sharedWithMe: {
|
||||
nextUrl: '',
|
||||
prevUrl: '',
|
||||
data: []
|
||||
}
|
||||
};
|
||||
this.fetchInitialResources();
|
||||
}
|
||||
|
||||
isSharedWithMeTab() {
|
||||
return this.state.activeTabKey === SHARED_WITH_ME_TAB;
|
||||
}
|
||||
|
||||
hasNext() {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
return this.state.sharedWithMe.nextUrl !== null && this.state.sharedWithMe.nextUrl !== '';
|
||||
} else {
|
||||
return this.state.myResources.nextUrl !== null && this.state.myResources.nextUrl !== '';
|
||||
}
|
||||
}
|
||||
|
||||
hasPrevious() {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
return this.state.sharedWithMe.prevUrl !== null && this.state.sharedWithMe.prevUrl !== '';
|
||||
} else {
|
||||
return this.state.myResources.prevUrl !== null && this.state.myResources.prevUrl !== '';
|
||||
}
|
||||
}
|
||||
|
||||
fetchInitialResources() {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
this.fetchResources("/resources/shared-with-me");
|
||||
} else {
|
||||
this.fetchResources("/resources", {
|
||||
first: this.first,
|
||||
max: this.max
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fetchFilteredResources(params) {
|
||||
if (this.isSharedWithMeTab()) {
|
||||
this.fetchResources("/resources/shared-with-me", params);
|
||||
} else {
|
||||
this.fetchResources("/resources", { ...params,
|
||||
first: this.first,
|
||||
max: this.max
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fetchResources(url, extraParams) {
|
||||
this.context.doGet(url, {
|
||||
params: extraParams
|
||||
}).then(response => {
|
||||
const resources = response.data || [];
|
||||
resources.forEach(resource => resource.shareRequests = []); // serialize the Scope objects from JSON so that toString() will work.
|
||||
|
||||
resources.forEach(resource => resource.scopes = resource.scopes.map(this.makeScopeObj));
|
||||
|
||||
if (this.isSharedWithMeTab()) {
|
||||
this.setState({
|
||||
sharedWithMe: this.parseResourceResponse(response)
|
||||
}, this.fetchPending);
|
||||
} else {
|
||||
this.setState({
|
||||
myResources: this.parseResourceResponse(response)
|
||||
}, this.fetchPermissionRequests);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fetchShareRequests(resource) {
|
||||
this.context.doGet('/resources/' + resource._id + '/permissions/requests').then(response => {
|
||||
resource.shareRequests = response.data || [];
|
||||
|
||||
if (resource.shareRequests.length > 0) {
|
||||
this.forceUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
parseResourceResponse(response) {
|
||||
const links = response.headers.get('link') || undefined;
|
||||
const parsed = parse(links);
|
||||
let next = '';
|
||||
let prev = '';
|
||||
|
||||
if (parsed !== null) {
|
||||
if (parsed.next) next = parsed.next;
|
||||
if (parsed.prev) prev = parsed.prev;
|
||||
}
|
||||
|
||||
const resources = response.data || [];
|
||||
return {
|
||||
nextUrl: next,
|
||||
prevUrl: prev,
|
||||
data: resources
|
||||
};
|
||||
}
|
||||
|
||||
makeTab(eventKey, title, resources, sharedResourcesTab) {
|
||||
return /*#__PURE__*/React.createElement(Tab, {
|
||||
id: title,
|
||||
eventKey: eventKey,
|
||||
title: Msg.localize(title)
|
||||
}, /*#__PURE__*/React.createElement(Stack, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("span", null)), /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement(Level, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(LevelItem, null, /*#__PURE__*/React.createElement(TextInput, {
|
||||
value: this.state.nameFilter,
|
||||
onChange: this.handleFilterRequest,
|
||||
id: 'filter-' + title,
|
||||
type: "text",
|
||||
placeholder: Msg.localize('filterByName'),
|
||||
iconVariant: "search"
|
||||
})))), /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, !sharedResourcesTab && /*#__PURE__*/React.createElement(ResourcesTable, {
|
||||
resources: resources
|
||||
}), sharedResourcesTab && /*#__PURE__*/React.createElement(SharedResourcesTable, {
|
||||
resources: resources
|
||||
}))));
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: "resources",
|
||||
onRefresh: this.fetchInitialResources.bind(this)
|
||||
}, /*#__PURE__*/React.createElement(PageSection, {
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(Tabs, {
|
||||
activeKey: this.state.activeTabKey,
|
||||
onSelect: this.handleTabClick
|
||||
}, this.makeTab(0, 'myResources', this.state.myResources, false), this.makeTab(1, 'sharedwithMe', this.state.sharedWithMe, true)), /*#__PURE__*/React.createElement(Level, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(LevelItem, null, this.hasPrevious() && /*#__PURE__*/React.createElement(Button, {
|
||||
onClick: this.handlePreviousClick
|
||||
}, "<", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "previousPage"
|
||||
}))), /*#__PURE__*/React.createElement(LevelItem, null, this.hasPrevious() && /*#__PURE__*/React.createElement(Button, {
|
||||
onClick: this.handleFirstPageClick
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "firstPage"
|
||||
}))), /*#__PURE__*/React.createElement(LevelItem, null, this.hasNext() && /*#__PURE__*/React.createElement(Button, {
|
||||
onClick: this.handleNextClick
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "nextPage"
|
||||
}), ">")))));
|
||||
}
|
||||
|
||||
clearNextPrev() {
|
||||
const newMyResources = this.state.myResources;
|
||||
newMyResources.nextUrl = '';
|
||||
newMyResources.prevUrl = '';
|
||||
this.setState({
|
||||
myResources: newMyResources
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(MyResourcesPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
//# sourceMappingURL=MyResourcesPage.js.map
|
||||
@@ -0,0 +1,151 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { Button, Modal, Text, Badge, DataListItem, DataList, TextVariants, DataListItemRow, DataListItemCells, DataListCell, Chip, Split, SplitItem, ModalVariant } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { UserCheckIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
export class PermissionRequest extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "handleApprove", async (shareRequest, index) => {
|
||||
this.handle(shareRequest.username, shareRequest.scopes, true);
|
||||
this.props.resource.shareRequests.splice(index, 1);
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleDeny", async (shareRequest, index) => {
|
||||
this.handle(shareRequest.username, shareRequest.scopes);
|
||||
this.props.resource.shareRequests.splice(index, 1);
|
||||
});
|
||||
|
||||
_defineProperty(this, "handle", async (username, scopes, approve = false) => {
|
||||
const id = this.props.resource._id;
|
||||
this.handleToggleDialog();
|
||||
const permissionsRequest = await this.context.doGet(`/resources/${id}/permissions`);
|
||||
const permissions = permissionsRequest.data || [];
|
||||
const foundPermission = permissions.find(p => p.username === username);
|
||||
const userScopes = foundPermission ? foundPermission.scopes : [];
|
||||
|
||||
if (approve) {
|
||||
userScopes.push(...scopes);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.context.doPut(`/resources/${id}/permissions`, [{
|
||||
username: username,
|
||||
scopes: userScopes
|
||||
}]);
|
||||
ContentAlert.success(Msg.localize('shareSuccess'));
|
||||
this.props.onClose();
|
||||
} catch (e) {
|
||||
console.error('Could not update permissions', e.error);
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleToggleDialog", () => {
|
||||
this.setState({
|
||||
isOpen: !this.state.isOpen
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
isOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const id = `shareRequest-${this.props.resource.name.replace(/\s/, '-')}`;
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
||||
id: id,
|
||||
variant: "link",
|
||||
onClick: this.handleToggleDialog
|
||||
}, /*#__PURE__*/React.createElement(UserCheckIcon, {
|
||||
size: "lg"
|
||||
}), /*#__PURE__*/React.createElement(Badge, null, this.props.resource.shareRequests.length)), /*#__PURE__*/React.createElement(Modal, {
|
||||
id: `modal-${id}`,
|
||||
title: Msg.localize('permissionRequests') + ' - ' + this.props.resource.name,
|
||||
variant: ModalVariant.large,
|
||||
isOpen: this.state.isOpen,
|
||||
onClose: this.handleToggleDialog,
|
||||
actions: [/*#__PURE__*/React.createElement(Button, {
|
||||
id: `close-${id}`,
|
||||
key: "close",
|
||||
variant: "link",
|
||||
onClick: this.handleToggleDialog
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "close"
|
||||
}))]
|
||||
}, /*#__PURE__*/React.createElement(DataList, {
|
||||
"aria-label": Msg.localize('permissionRequests')
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "permissions-name-header",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("strong", null, "Requestor")), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "permissions-requested-header",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "permissionRequests"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "permission-request-header",
|
||||
width: 5
|
||||
})]
|
||||
})), this.props.resource.shareRequests.map((shareRequest, i) => /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: i,
|
||||
"aria-labelledby": "requestor"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: `requestor${i}`,
|
||||
key: `requestor${i}`
|
||||
}, /*#__PURE__*/React.createElement("span", null, shareRequest.firstName, " ", shareRequest.lastName, " ", shareRequest.lastName ? '' : shareRequest.username), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Text, {
|
||||
component: TextVariants.small
|
||||
}, shareRequest.email)), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: `permissions${i}`,
|
||||
key: `permissions${i}`
|
||||
}, shareRequest.scopes.map((scope, j) => /*#__PURE__*/React.createElement(Chip, {
|
||||
key: j,
|
||||
isReadOnly: true
|
||||
}, scope))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: `actions${i}`
|
||||
}, /*#__PURE__*/React.createElement(Split, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(Button, {
|
||||
id: `accept-${i}-${id}`,
|
||||
onClick: () => this.handleApprove(shareRequest, i)
|
||||
}, "Accept")), /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(Button, {
|
||||
id: `deny-${i}-${id}`,
|
||||
variant: "danger",
|
||||
onClick: () => this.handleDeny(shareRequest, i)
|
||||
}, "Deny"))))]
|
||||
})))))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(PermissionRequest, "defaultProps", {
|
||||
permissions: [],
|
||||
row: 0
|
||||
});
|
||||
|
||||
_defineProperty(PermissionRequest, "contextType", AccountServiceContext);
|
||||
//# sourceMappingURL=PermissionRequest.js.map
|
||||
@@ -0,0 +1,103 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { Select, SelectOption, SelectVariant } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
|
||||
class ScopeValue {
|
||||
constructor(value) {
|
||||
_defineProperty(this, "value", void 0);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.displayName ? this.value.displayName : this.value.name;
|
||||
}
|
||||
|
||||
compareTo(selectOption) {
|
||||
return selectOption.name === this.value.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class PermissionSelect extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "onSelect", (_event, selection) => {
|
||||
const {
|
||||
selected
|
||||
} = this.state;
|
||||
const {
|
||||
onSelect
|
||||
} = this.props;
|
||||
|
||||
if (selected.includes(selection)) {
|
||||
this.setState(prevState => ({
|
||||
selected: prevState.selected.filter(item => item !== selection)
|
||||
}), () => onSelect(this.state.selected.map(sv => sv.value)));
|
||||
} else {
|
||||
this.setState(prevState => ({
|
||||
selected: [...prevState.selected, selection]
|
||||
}), () => onSelect(this.state.selected.map(sv => sv.value)));
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "onToggle", isExpanded => {
|
||||
this.setState({
|
||||
isExpanded
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "clearSelection", () => {
|
||||
this.setState({
|
||||
selected: [],
|
||||
isExpanded: false
|
||||
});
|
||||
this.props.onSelect([]);
|
||||
});
|
||||
|
||||
let values = [];
|
||||
|
||||
if (this.props.selected) {
|
||||
values = this.props.selected.map(s => new ScopeValue(s));
|
||||
}
|
||||
|
||||
this.state = {
|
||||
isExpanded: false,
|
||||
selected: values,
|
||||
scopes: this.props.scopes.map((option, index) => /*#__PURE__*/React.createElement(SelectOption, {
|
||||
key: index,
|
||||
value: values.find(s => s.compareTo(option)) || new ScopeValue(option)
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
isExpanded,
|
||||
selected
|
||||
} = this.state;
|
||||
const titleId = 'permission-id';
|
||||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
|
||||
id: titleId,
|
||||
hidden: true
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "selectPermissions"
|
||||
})), /*#__PURE__*/React.createElement(Select, {
|
||||
direction: this.props.direction || 'down',
|
||||
variant: SelectVariant.typeaheadMulti,
|
||||
typeAheadAriaLabel: Msg.localize("selectPermissions"),
|
||||
onToggle: this.onToggle,
|
||||
onSelect: this.onSelect,
|
||||
onClear: this.clearSelection,
|
||||
selections: selected,
|
||||
isOpen: isExpanded,
|
||||
"aria-labelledby": titleId,
|
||||
placeholderText: Msg.localize("selectPermissions")
|
||||
}, this.state.scopes));
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=PermissionSelect.js.map
|
||||
@@ -0,0 +1,313 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { DataList, DataListItem, DataListItemRow, DataListCell, DataListToggle, DataListContent, DataListItemCells, Level, LevelItem, Button, DataListAction, Dropdown, DropdownPosition, DropdownItem, KebabToggle } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { Remove2Icon, RepositoryIcon, ShareAltIcon, EditAltIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { PermissionRequest } from "./PermissionRequest.js";
|
||||
import { ShareTheResource } from "./ShareTheResource.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { AbstractResourcesTable } from "./AbstractResourceTable.js";
|
||||
import { EditTheResource } from "./EditTheResource.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
import EmptyMessageState from "../../widgets/EmptyMessageState.js";
|
||||
import { ContinueCancelModal } from "../../widgets/ContinueCancelModal.js";
|
||||
export class ResourcesTable extends AbstractResourcesTable {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "onToggle", row => {
|
||||
const newIsRowOpen = this.state.isRowOpen;
|
||||
newIsRowOpen[row] = !newIsRowOpen[row];
|
||||
if (newIsRowOpen[row]) this.fetchPermissions(this.props.resources.data[row], row);
|
||||
this.setState({
|
||||
isRowOpen: newIsRowOpen
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "onContextToggle", (row, isOpen) => {
|
||||
if (this.state.isModalActive) return;
|
||||
const data = this.props.resources.data;
|
||||
const contextOpen = this.state.contextOpen;
|
||||
contextOpen[row] = isOpen;
|
||||
|
||||
if (isOpen) {
|
||||
const index = row > data.length ? row - data.length - 1 : row;
|
||||
this.fetchPermissions(data[index], index);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
contextOpen
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
isRowOpen: [],
|
||||
contextOpen: [],
|
||||
isModalActive: false,
|
||||
permissions: new Map()
|
||||
};
|
||||
}
|
||||
|
||||
fetchPermissions(resource, row) {
|
||||
this.context.doGet(`/resources/${resource._id}/permissions`).then(response => {
|
||||
const newPermissions = new Map(this.state.permissions);
|
||||
newPermissions.set(row, response.data || []);
|
||||
this.setState({
|
||||
permissions: newPermissions
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
removeShare(resource, row) {
|
||||
const permissions = this.state.permissions.get(row).map(a => ({
|
||||
username: a.username,
|
||||
scopes: []
|
||||
}));
|
||||
return this.context.doPut(`/resources/${resource._id}/permissions`, permissions).then(() => {
|
||||
ContentAlert.success(Msg.localize('unShareSuccess'));
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.resources.data.length === 0) {
|
||||
return /*#__PURE__*/React.createElement(EmptyMessageState, {
|
||||
icon: RepositoryIcon,
|
||||
messageKey: "notHaveAnyResource"
|
||||
});
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(DataList, {
|
||||
"aria-label": Msg.localize('resources'),
|
||||
id: "resourcesList"
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: "resource-header",
|
||||
"aria-labelledby": "resource-header"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, "// invisible toggle allows headings to line up properly", /*#__PURE__*/React.createElement("span", {
|
||||
style: {
|
||||
visibility: 'hidden'
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(DataListToggle, {
|
||||
isExpanded: false,
|
||||
id: "resource-header-invisible-toggle",
|
||||
"aria-controls": "ex-expand1"
|
||||
})), /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "resource-name-header",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "resourceName"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "application-name-header",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "application"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "permission-request-header",
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "permissionRequests"
|
||||
})))]
|
||||
}))), this.props.resources.data.map((resource, row) => /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: 'resource-' + row,
|
||||
"aria-labelledby": resource.name,
|
||||
isExpanded: this.state.isRowOpen[row]
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListToggle, {
|
||||
onClick: () => this.onToggle(row),
|
||||
isExpanded: this.state.isRowOpen[row],
|
||||
id: 'resourceToggle-' + row,
|
||||
"aria-controls": "ex-expand1"
|
||||
}), /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: 'resourceName-' + row,
|
||||
key: 'resourceName-' + row,
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: resource.name
|
||||
})), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: 'resourceClient-' + row,
|
||||
key: 'resourceClient-' + row,
|
||||
width: 5
|
||||
}, /*#__PURE__*/React.createElement("a", {
|
||||
href: resource.client.baseUrl
|
||||
}, this.getClientName(resource.client))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: 'resourceRequests-' + row,
|
||||
key: 'permissionRequests-' + row,
|
||||
width: 5
|
||||
}, resource.shareRequests.length > 0 && /*#__PURE__*/React.createElement(PermissionRequest, {
|
||||
resource: resource,
|
||||
onClose: () => this.fetchPermissions(resource, row)
|
||||
}))]
|
||||
}), /*#__PURE__*/React.createElement(DataListAction, {
|
||||
visibility: {
|
||||
lg: 'hidden'
|
||||
},
|
||||
"aria-labelledby": "check-action-item3 check-action-action3",
|
||||
id: "check-action-action3",
|
||||
"aria-label": "Actions"
|
||||
}, /*#__PURE__*/React.createElement(Dropdown, {
|
||||
isPlain: true,
|
||||
position: DropdownPosition.right,
|
||||
onSelect: () => this.setState({
|
||||
isModalActive: true
|
||||
}),
|
||||
toggle: /*#__PURE__*/React.createElement(KebabToggle, {
|
||||
onToggle: isOpen => this.onContextToggle(row + this.props.resources.data.length + 1, isOpen)
|
||||
}),
|
||||
isOpen: this.state.contextOpen[row + this.props.resources.data.length + 1],
|
||||
dropdownItems: [/*#__PURE__*/React.createElement(ShareTheResource, {
|
||||
resource: resource,
|
||||
permissions: this.state.permissions.get(row),
|
||||
sharedWithUsersMsg: this.sharedWithUsersMessage(row),
|
||||
onClose: () => {
|
||||
this.setState({
|
||||
isModalActive: false
|
||||
}, () => {
|
||||
this.onContextToggle(row + this.props.resources.data.length + 1, false);
|
||||
this.fetchPermissions(resource, row + this.props.resources.data.length + 1);
|
||||
});
|
||||
}
|
||||
}, toggle => /*#__PURE__*/React.createElement(DropdownItem, {
|
||||
id: 'mob-share-' + row,
|
||||
key: "mob-share",
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(ShareAltIcon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "share"
|
||||
}))), /*#__PURE__*/React.createElement(EditTheResource, {
|
||||
resource: resource,
|
||||
permissions: this.state.permissions.get(row),
|
||||
onClose: () => {
|
||||
this.setState({
|
||||
isModalActive: false
|
||||
}, () => {
|
||||
this.onContextToggle(row + this.props.resources.data.length + 1, false);
|
||||
this.fetchPermissions(resource, row + this.props.resources.data.length + 1);
|
||||
});
|
||||
}
|
||||
}, toggle => /*#__PURE__*/React.createElement(DropdownItem, {
|
||||
id: 'mob-edit-' + row,
|
||||
key: "mob-edit",
|
||||
isDisabled: this.numOthers(row) < 0,
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(EditAltIcon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "edit"
|
||||
}))), /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
render: toggle => /*#__PURE__*/React.createElement(DropdownItem, {
|
||||
id: 'mob-remove-' + row,
|
||||
key: "mob-remove",
|
||||
isDisabled: this.numOthers(row) < 0,
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(Remove2Icon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "unShare"
|
||||
})),
|
||||
modalTitle: "unShare",
|
||||
modalMessage: "unShareAllConfirm",
|
||||
onClose: () => this.setState({
|
||||
isModalActive: false
|
||||
}, () => {
|
||||
this.onContextToggle(row + this.props.resources.data.length + 1, false);
|
||||
}),
|
||||
onContinue: () => this.removeShare(resource, row).then(() => this.fetchPermissions(resource, row + this.props.resources.data.length + 1))
|
||||
})]
|
||||
})), /*#__PURE__*/React.createElement(DataListAction, {
|
||||
id: `actions-${row}`,
|
||||
visibility: {
|
||||
default: 'hidden',
|
||||
lg: 'visible'
|
||||
},
|
||||
"aria-labelledby": "Row actions",
|
||||
"aria-label": "Actions"
|
||||
}, /*#__PURE__*/React.createElement(ShareTheResource, {
|
||||
resource: resource,
|
||||
permissions: this.state.permissions.get(row),
|
||||
sharedWithUsersMsg: this.sharedWithUsersMessage(row),
|
||||
onClose: () => this.fetchPermissions(resource, row)
|
||||
}, toggle => /*#__PURE__*/React.createElement(Button, {
|
||||
id: `share-${row}`,
|
||||
variant: "link",
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(ShareAltIcon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "share"
|
||||
}))), /*#__PURE__*/React.createElement(Dropdown, {
|
||||
id: `action-menu-${row}`,
|
||||
isPlain: true,
|
||||
position: DropdownPosition.right,
|
||||
toggle: /*#__PURE__*/React.createElement(KebabToggle, {
|
||||
onToggle: isOpen => this.onContextToggle(row, isOpen)
|
||||
}),
|
||||
onSelect: () => this.setState({
|
||||
isModalActive: true
|
||||
}),
|
||||
isOpen: this.state.contextOpen[row],
|
||||
dropdownItems: [/*#__PURE__*/React.createElement(EditTheResource, {
|
||||
resource: resource,
|
||||
permissions: this.state.permissions.get(row),
|
||||
onClose: () => {
|
||||
this.setState({
|
||||
isModalActive: false
|
||||
}, () => {
|
||||
this.onContextToggle(row, false);
|
||||
this.fetchPermissions(resource, row);
|
||||
});
|
||||
}
|
||||
}, toggle => /*#__PURE__*/React.createElement(DropdownItem, {
|
||||
id: 'edit-' + row,
|
||||
key: "edit",
|
||||
component: "button",
|
||||
isDisabled: this.numOthers(row) < 0,
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(EditAltIcon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "edit"
|
||||
}))), /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
render: toggle => /*#__PURE__*/React.createElement(DropdownItem, {
|
||||
id: 'remove-' + row,
|
||||
key: "remove",
|
||||
component: "button",
|
||||
isDisabled: this.numOthers(row) < 0,
|
||||
onClick: toggle
|
||||
}, /*#__PURE__*/React.createElement(Remove2Icon, null), " ", /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "unShare"
|
||||
})),
|
||||
modalTitle: "unShare",
|
||||
modalMessage: "unShareAllConfirm",
|
||||
onClose: () => this.setState({
|
||||
isModalActive: false
|
||||
}, () => {
|
||||
this.onContextToggle(row, false);
|
||||
}),
|
||||
onContinue: () => this.removeShare(resource, row).then(() => this.fetchPermissions(resource, row))
|
||||
})]
|
||||
}))), /*#__PURE__*/React.createElement(DataListContent, {
|
||||
hasNoPadding: false,
|
||||
"aria-label": "Session Details",
|
||||
id: 'ex-expand' + row,
|
||||
isHidden: !this.state.isRowOpen[row]
|
||||
}, /*#__PURE__*/React.createElement(Level, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(LevelItem, null, /*#__PURE__*/React.createElement("span", null)), /*#__PURE__*/React.createElement(LevelItem, {
|
||||
id: 'shared-with-user-message-' + row
|
||||
}, this.sharedWithUsersMessage(row)), /*#__PURE__*/React.createElement(LevelItem, null, /*#__PURE__*/React.createElement("span", null)))))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(ResourcesTable, "contextType", AccountServiceContext);
|
||||
//# sourceMappingURL=ResourcesTable.js.map
|
||||
@@ -0,0 +1,222 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { Button, Chip, ChipGroup, Form, FormGroup, Gallery, GalleryItem, Modal, Stack, StackItem, TextInput, ModalVariant } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
import { PermissionSelect } from "./PermissionSelect.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2019 Red Hat Inc.
|
||||
*/
|
||||
export class ShareTheResource extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "handleAddPermission", () => {
|
||||
const rscId = this.props.resource._id;
|
||||
const newPermissions = [];
|
||||
|
||||
for (const permission of this.state.permissionsSelected) {
|
||||
newPermissions.push(permission.name);
|
||||
}
|
||||
|
||||
const permissions = [];
|
||||
|
||||
for (const username of this.state.usernames) {
|
||||
permissions.push({
|
||||
username: username,
|
||||
scopes: newPermissions
|
||||
});
|
||||
}
|
||||
|
||||
this.handleToggleDialog();
|
||||
this.context.doPut(`/resources/${rscId}/permissions`, permissions).then(() => {
|
||||
ContentAlert.success('shareSuccess');
|
||||
this.props.onClose();
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleToggleDialog", () => {
|
||||
if (this.state.isOpen) {
|
||||
this.setState({
|
||||
isOpen: false
|
||||
});
|
||||
this.props.onClose();
|
||||
} else {
|
||||
this.clearState();
|
||||
this.setState({
|
||||
isOpen: true
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleUsernameChange", username => {
|
||||
this.setState({
|
||||
usernameInput: username
|
||||
});
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleAddUsername", async () => {
|
||||
if (this.state.usernameInput !== '' && !this.state.usernames.includes(this.state.usernameInput)) {
|
||||
const response = await this.context.doGet(`/resources/${this.props.resource._id}/user`, {
|
||||
params: {
|
||||
value: this.state.usernameInput
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data && response.data.username) {
|
||||
this.setState({
|
||||
usernameInput: '',
|
||||
usernames: [...this.state.usernames, this.state.usernameInput]
|
||||
});
|
||||
} else {
|
||||
ContentAlert.info('userNotFound', [this.state.usernameInput]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleEnterKeyInAddField", event => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
this.handleAddUsername();
|
||||
}
|
||||
});
|
||||
|
||||
_defineProperty(this, "handleDeleteUsername", username => {
|
||||
const newUsernames = this.state.usernames.filter(user => user !== username);
|
||||
this.setState({
|
||||
usernames: newUsernames
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
permissionsSelected: [],
|
||||
permissionsUnSelected: this.props.resource.scopes,
|
||||
usernames: [],
|
||||
usernameInput: ''
|
||||
};
|
||||
}
|
||||
|
||||
clearState() {
|
||||
this.setState({
|
||||
permissionsSelected: [],
|
||||
permissionsUnSelected: this.props.resource.scopes,
|
||||
usernames: [],
|
||||
usernameInput: ''
|
||||
});
|
||||
}
|
||||
|
||||
isAddDisabled() {
|
||||
return this.state.usernameInput === '' || this.isAlreadyShared();
|
||||
}
|
||||
|
||||
isAlreadyShared() {
|
||||
for (let permission of this.props.permissions) {
|
||||
if (permission.username === this.state.usernameInput) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isFormInvalid() {
|
||||
return this.state.usernames.length === 0 || this.state.permissionsSelected.length === 0;
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children(this.handleToggleDialog), /*#__PURE__*/React.createElement(Modal, {
|
||||
title: 'Share the resource - ' + this.props.resource.name,
|
||||
variant: ModalVariant.large,
|
||||
isOpen: this.state.isOpen,
|
||||
onClose: this.handleToggleDialog,
|
||||
actions: [/*#__PURE__*/React.createElement(Button, {
|
||||
key: "cancel",
|
||||
variant: "link",
|
||||
onClick: this.handleToggleDialog
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "cancel"
|
||||
})), /*#__PURE__*/React.createElement(Button, {
|
||||
key: "confirm",
|
||||
variant: "primary",
|
||||
id: "done",
|
||||
onClick: this.handleAddPermission,
|
||||
isDisabled: this.isFormInvalid()
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "done"
|
||||
}))]
|
||||
}, /*#__PURE__*/React.createElement(Stack, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: "Add users to share your resource with",
|
||||
type: "string",
|
||||
helperTextInvalid: Msg.localize('resourceAlreadyShared'),
|
||||
fieldId: "username",
|
||||
isRequired: true
|
||||
}, /*#__PURE__*/React.createElement(Gallery, {
|
||||
hasGutter: true
|
||||
}, /*#__PURE__*/React.createElement(GalleryItem, null, /*#__PURE__*/React.createElement(TextInput, {
|
||||
value: this.state.usernameInput,
|
||||
id: "username",
|
||||
"aria-describedby": "username-helper",
|
||||
placeholder: "Username or email",
|
||||
onChange: this.handleUsernameChange,
|
||||
onKeyPress: this.handleEnterKeyInAddField
|
||||
})), /*#__PURE__*/React.createElement(GalleryItem, null, /*#__PURE__*/React.createElement(Button, {
|
||||
key: "add-user",
|
||||
variant: "primary",
|
||||
id: "add",
|
||||
onClick: this.handleAddUsername,
|
||||
isDisabled: this.isAddDisabled()
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "add"
|
||||
})))), /*#__PURE__*/React.createElement(ChipGroup, {
|
||||
categoryName: Msg.localize('shareWith')
|
||||
}, this.state.usernames.map(currentChip => /*#__PURE__*/React.createElement(Chip, {
|
||||
key: currentChip,
|
||||
onClick: () => this.handleDeleteUsername(currentChip)
|
||||
}, currentChip)))), /*#__PURE__*/React.createElement(FormGroup, {
|
||||
label: "",
|
||||
fieldId: "permissions-selected"
|
||||
}, /*#__PURE__*/React.createElement(PermissionSelect, {
|
||||
scopes: this.state.permissionsUnSelected,
|
||||
onSelect: selection => this.setState({
|
||||
permissionsSelected: selection
|
||||
}),
|
||||
direction: "up"
|
||||
})))), /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, /*#__PURE__*/React.createElement("br", null)), /*#__PURE__*/React.createElement(StackItem, {
|
||||
isFilled: true
|
||||
}, this.props.sharedWithUsersMsg))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(ShareTheResource, "defaultProps", {
|
||||
permissions: []
|
||||
});
|
||||
|
||||
_defineProperty(ShareTheResource, "contextType", AccountServiceContext);
|
||||
//# sourceMappingURL=ShareTheResource.js.map
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { DataList, DataListItem, DataListItemRow, DataListCell, DataListItemCells, ChipGroup, Chip } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { RepositoryIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { AbstractResourcesTable } from "./AbstractResourceTable.js";
|
||||
import EmptyMessageState from "../../widgets/EmptyMessageState.js";
|
||||
export class SharedResourcesTable extends AbstractResourcesTable {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
permissions: new Map()
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.resources.data.length === 0) {
|
||||
return /*#__PURE__*/React.createElement(EmptyMessageState, {
|
||||
icon: RepositoryIcon,
|
||||
messageKey: "noResourcesSharedWithYou"
|
||||
});
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(DataList, {
|
||||
"aria-label": Msg.localize('resources'),
|
||||
id: "sharedResourcesList"
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: "resource-header",
|
||||
"aria-labelledby": "resource-header"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "resource-name-header",
|
||||
width: 2
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "resourceName"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "application-name-header",
|
||||
width: 2
|
||||
}, /*#__PURE__*/React.createElement("strong", null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "application"
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "permission-header",
|
||||
width: 2
|
||||
}), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "requests-header",
|
||||
width: 2
|
||||
})]
|
||||
}))), this.props.resources.data.map((resource, row) => /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: 'resource-' + row,
|
||||
"aria-labelledby": resource.name
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, null, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'resourceName-' + row,
|
||||
width: 2
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: resource.name
|
||||
})), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'resourceClient-' + row,
|
||||
width: 2
|
||||
}, /*#__PURE__*/React.createElement("a", {
|
||||
href: resource.client.baseUrl
|
||||
}, this.getClientName(resource.client))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'permissions-' + row,
|
||||
width: 2
|
||||
}, resource.scopes.length > 0 && /*#__PURE__*/React.createElement(ChipGroup, {
|
||||
categoryName: Msg.localize('permissions')
|
||||
}, resource.scopes.map(scope => /*#__PURE__*/React.createElement(Chip, {
|
||||
key: scope.name,
|
||||
isReadOnly: true
|
||||
}, scope.displayName || scope.name)))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'pending-' + row,
|
||||
width: 2
|
||||
}, resource.shareRequests.length > 0 && /*#__PURE__*/React.createElement(ChipGroup, {
|
||||
categoryName: Msg.localize('pending')
|
||||
}, resource.shareRequests[0].scopes.map(scope => /*#__PURE__*/React.createElement(Chip, {
|
||||
key: scope.name,
|
||||
isReadOnly: true
|
||||
}, scope.displayName || scope.name))))]
|
||||
})))));
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=SharedResourcesTable.js.map
|
||||
@@ -0,0 +1,16 @@
|
||||
export class Scope {
|
||||
constructor(name, displayName) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
toString() {
|
||||
if (this.hasOwnProperty('displayName') && this.displayName) {
|
||||
return this.displayName;
|
||||
} else {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=resource-model.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/app/content/my-resources-page/resource-model.ts"],"names":["Scope","constructor","name","displayName","toString","hasOwnProperty"],"mappings":"AAeA,OAAO,MAAMA,KAAN,CAAY;AACVC,EAAAA,WAAW,CAAQC,IAAR,EAA6BC,WAA7B,EAAmD;AAAA,SAA3CD,IAA2C,GAA3CA,IAA2C;AAAA,SAAtBC,WAAsB,GAAtBA,WAAsB;AAAE;;AAEhEC,EAAAA,QAAQ,GAAW;AACtB,QAAI,KAAKC,cAAL,CAAoB,aAApB,KAAuC,KAAKF,WAAhD,EAA8D;AAC1D,aAAO,KAAKA,WAAZ;AACH,KAFD,MAEO;AACH,aAAO,KAAKD,IAAZ;AACH;AACJ;;AATgB","sourcesContent":["export interface Resource {\n _id: string;\n name: string;\n client: Client;\n scopes: Scope[];\n uris: string[];\n shareRequests: Permission[];\n}\n\nexport interface Client {\n baseUrl: string;\n clientId: string;\n name?: string;\n}\n\nexport class Scope {\n public constructor(public name: string, public displayName?: string) {}\n\n public toString(): string {\n if (this.hasOwnProperty('displayName') && (this.displayName)) {\n return this.displayName;\n } else {\n return this.name;\n }\n }\n}\n\nexport interface PaginatedResources {\n nextUrl: string;\n prevUrl: string;\n data: Resource[];\n}\n\nexport interface Permission {\n email?: string;\n firstName?: string;\n lastName?: string;\n scopes: Scope[] | string[]; // this should be Scope[] - fix API\n username: string;\n}\n\nexport interface Permissions {\n permissions: Permission[];\n row?: number;\n}\n"],"file":"resource-model.js"}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { WarningTriangleIcon } from "../../../../common/keycloak/web_modules/@patternfly/react-icons.js";
|
||||
import { withRouter } from "../../../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import EmptyMessageState from "../../widgets/EmptyMessageState.js";
|
||||
|
||||
class PgNotFound extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(EmptyMessageState, {
|
||||
icon: WarningTriangleIcon,
|
||||
messageKey: "pageNotFound"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "invalidRoute",
|
||||
params: [this.props.location.pathname]
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
;
|
||||
export const PageNotFound = withRouter(PgNotFound);
|
||||
//# sourceMappingURL=PageNotFound.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/app/content/page-not-found/PageNotFound.tsx"],"names":["React","WarningTriangleIcon","withRouter","Msg","EmptyMessageState","PgNotFound","Component","constructor","props","render","location","pathname","PageNotFound"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AAEA,OAAO,KAAKA,KAAZ;AAEA,SAASC,mBAAT;AACA,SAAQC,UAAR;AACA,SAAQC,GAAR;AACA,OAAOC,iBAAP;;AAIA,MAAMC,UAAN,SAAyBL,KAAK,CAACM,SAA/B,CAA4D;AAEjDC,EAAAA,WAAW,CAACC,KAAD,EAA2B;AACzC,UAAMA,KAAN;AACH;;AAEMC,EAAAA,MAAM,GAAoB;AAC7B,wBACI,oBAAC,iBAAD;AAAmB,MAAA,IAAI,EAAER,mBAAzB;AAA8C,MAAA,UAAU,EAAC;AAAzD,oBACI,oBAAC,GAAD;AAAK,MAAA,MAAM,EAAC,cAAZ;AAA2B,MAAA,MAAM,EAAE,CAAC,KAAKO,KAAL,CAAWE,QAAX,CAAoBC,QAArB;AAAnC,MADJ,CADJ;AAKH;;AAZuD;;AAa3D;AAED,OAAO,MAAMC,YAAY,GAAGV,UAAU,CAACG,UAAD,CAA/B","sourcesContent":["/*\n * To change this license header, choose License Headers in Project Properties.\n * To change this template file, choose Tools | Templates\n * and open the template in the editor.\n */\n\nimport * as React from 'react';\n\nimport { WarningTriangleIcon } from '@patternfly/react-icons';\nimport {withRouter, RouteComponentProps} from 'react-router-dom';\nimport {Msg} from '../../widgets/Msg';\nimport EmptyMessageState from '../../widgets/EmptyMessageState';\n\nexport interface PageNotFoundProps extends RouteComponentProps {}\n\nclass PgNotFound extends React.Component<PageNotFoundProps> {\n\n public constructor(props: PageNotFoundProps) {\n super(props);\n }\n\n public render(): React.ReactNode {\n return (\n <EmptyMessageState icon={WarningTriangleIcon} messageKey=\"pageNotFound\">\n <Msg msgKey=\"invalidRoute\" params={[this.props.location.pathname]} />\n </EmptyMessageState>\n );\n }\n};\n\nexport const PageNotFound = withRouter(PgNotFound);"],"file":"PageNotFound.js"}
|
||||
@@ -0,0 +1,350 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2018 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
import * as React from "../../../../common/keycloak/web_modules/react.js";
|
||||
import { withRouter } from "../../../../common/keycloak/web_modules/react-router-dom.js";
|
||||
import { Alert, Button, DataList, DataListAction, DataListItemCells, DataListCell, DataListItem, DataListItemRow, EmptyState, EmptyStateVariant, EmptyStateBody, Split, SplitItem, Title, Dropdown, DropdownPosition, KebabToggle, PageSection, PageSectionVariants } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
|
||||
import { AIACommand } from "../../util/AIACommand.js";
|
||||
import TimeUtil from "../../util/TimeUtil.js";
|
||||
import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
|
||||
import { ContinueCancelModal } from "../../widgets/ContinueCancelModal.js";
|
||||
import { Msg } from "../../widgets/Msg.js";
|
||||
import { ContentPage } from "../ContentPage.js";
|
||||
import { ContentAlert } from "../ContentAlert.js";
|
||||
import { KeycloakContext } from "../../keycloak-service/KeycloakContext.js";
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
|
||||
*/
|
||||
class SigningInPage extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
|
||||
_defineProperty(this, "context", void 0);
|
||||
|
||||
_defineProperty(this, "handleRemove", (credentialId, userLabel) => {
|
||||
this.context.doDelete("/credentials/" + credentialId).then(() => {
|
||||
this.getCredentialContainers();
|
||||
ContentAlert.success("successRemovedMessage", [userLabel]);
|
||||
});
|
||||
});
|
||||
|
||||
this.context = context;
|
||||
this.state = {
|
||||
credentialContainers: new Map()
|
||||
};
|
||||
this.getCredentialContainers();
|
||||
}
|
||||
|
||||
getCredentialContainers() {
|
||||
this.context.doGet("/credentials").then(response => {
|
||||
const allContainers = new Map();
|
||||
const containers = response.data || [];
|
||||
containers.forEach(container => {
|
||||
let categoryMap = allContainers.get(container.category);
|
||||
|
||||
if (!categoryMap) {
|
||||
categoryMap = new Map();
|
||||
allContainers.set(container.category, categoryMap);
|
||||
}
|
||||
|
||||
categoryMap.set(container.type, container);
|
||||
});
|
||||
this.setState({
|
||||
credentialContainers: allContainers
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static credElementId(credType, credId, item) {
|
||||
return `${credType}-${item}-${credId.substring(0, 8)}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return /*#__PURE__*/React.createElement(ContentPage, {
|
||||
title: "signingIn",
|
||||
introMessage: "signingInSubMessage"
|
||||
}, this.renderCategories());
|
||||
}
|
||||
|
||||
renderCategories() {
|
||||
return Array.from(this.state.credentialContainers.keys()).map(category => /*#__PURE__*/React.createElement(PageSection, {
|
||||
key: category,
|
||||
variant: PageSectionVariants.light
|
||||
}, /*#__PURE__*/React.createElement(Title, {
|
||||
id: `${category}-categ-title`,
|
||||
headingLevel: "h2",
|
||||
size: "xl"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: category
|
||||
})), this.renderTypes(category)));
|
||||
}
|
||||
|
||||
renderTypes(category) {
|
||||
let credTypeMap = this.state.credentialContainers.get(category);
|
||||
return /*#__PURE__*/React.createElement(KeycloakContext.Consumer, null, keycloak => /*#__PURE__*/React.createElement(React.Fragment, null, Array.from(credTypeMap.keys()).map((credType, index, typeArray) => [this.renderCredTypeTitle(credTypeMap.get(credType), keycloak, category), this.renderUserCredentials(credTypeMap, credType, keycloak)])));
|
||||
}
|
||||
|
||||
renderEmptyRow(type, isLast) {
|
||||
if (isLast) return; // don't put empty row at the end
|
||||
|
||||
return /*#__PURE__*/React.createElement(DataListItem, {
|
||||
"aria-labelledby": "empty-list-item-" + type
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
key: "empty-row-" + type
|
||||
}, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, null)]
|
||||
})));
|
||||
}
|
||||
|
||||
renderUserCredentials(credTypeMap, credType, keycloak) {
|
||||
const credContainer = credTypeMap.get(credType);
|
||||
const userCredentialMetadatas = credContainer.userCredentialMetadatas;
|
||||
const removeable = credContainer.removeable;
|
||||
const type = credContainer.type;
|
||||
const displayName = credContainer.displayName;
|
||||
|
||||
if (!userCredentialMetadatas || userCredentialMetadatas.length === 0) {
|
||||
const localizedDisplayName = Msg.localize(displayName);
|
||||
return /*#__PURE__*/React.createElement(DataList, {
|
||||
"aria-label": Msg.localize('notSetUp', [localizedDisplayName]),
|
||||
className: "pf-u-mb-xl"
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
key: "no-credentials-list-item",
|
||||
"aria-labelledby": Msg.localize('notSetUp', [localizedDisplayName])
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
key: "no-credentials-list-item-row",
|
||||
className: "pf-u-align-items-center"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: [/*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'no-credentials-cell-0'
|
||||
}), /*#__PURE__*/React.createElement(EmptyState, {
|
||||
id: `${type}-not-set-up`,
|
||||
key: 'no-credentials-cell-1',
|
||||
variant: EmptyStateVariant.xs
|
||||
}, /*#__PURE__*/React.createElement(EmptyStateBody, null, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "notSetUp",
|
||||
params: [localizedDisplayName]
|
||||
}))), /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: 'no-credentials-cell-2'
|
||||
})]
|
||||
}))));
|
||||
}
|
||||
|
||||
userCredentialMetadatas.forEach(credentialMetadata => {
|
||||
let credential = credentialMetadata.credential;
|
||||
if (!credential.userLabel) credential.userLabel = Msg.localize(credential.type);
|
||||
|
||||
if (credential.hasOwnProperty('createdDate') && credential.createdDate && credential.createdDate > 0) {
|
||||
credential.strCreatedDate = TimeUtil.format(credential.createdDate);
|
||||
}
|
||||
});
|
||||
let updateAIA;
|
||||
|
||||
if (credContainer.updateAction) {
|
||||
updateAIA = new AIACommand(keycloak, credContainer.updateAction);
|
||||
}
|
||||
|
||||
let maxWidth = {
|
||||
maxWidth: 689
|
||||
};
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||||
key: "userCredentialMetadatas"
|
||||
}, " ", userCredentialMetadatas.map(credentialMetadata => /*#__PURE__*/React.createElement(React.Fragment, null, credentialMetadata.infoMessage && !credentialMetadata.warningMessageTitle && !credentialMetadata.warningMessageDescription && /*#__PURE__*/React.createElement(Alert, {
|
||||
variant: "default",
|
||||
className: "pf-u-mb-md",
|
||||
isInline: true,
|
||||
isPlain: true,
|
||||
title: Msg.localize(JSON.parse(credentialMetadata.infoMessage).key, JSON.parse(credentialMetadata.infoMessage).parameters)
|
||||
}), credentialMetadata.warningMessageTitle && credentialMetadata.warningMessageDescription && /*#__PURE__*/React.createElement(Alert, {
|
||||
variant: "warning",
|
||||
className: "pf-u-mb-md",
|
||||
isInline: true,
|
||||
title: Msg.localize(JSON.parse(credentialMetadata.warningMessageTitle).key, JSON.parse(credentialMetadata.warningMessageTitle).parameters),
|
||||
style: maxWidth
|
||||
}, /*#__PURE__*/React.createElement("p", null, Msg.localize(JSON.parse(credentialMetadata.warningMessageDescription).key, JSON.parse(credentialMetadata.warningMessageDescription).parameters))), /*#__PURE__*/React.createElement(DataList, {
|
||||
"aria-label": "user credential",
|
||||
className: "pf-u-mb-xl"
|
||||
}, /*#__PURE__*/React.createElement(DataListItem, {
|
||||
id: `${SigningInPage.credElementId(type, credentialMetadata.credential.id, 'row')}`,
|
||||
key: 'credential-list-item-' + credentialMetadata.credential.id,
|
||||
"aria-labelledby": 'credential-list-item-' + credentialMetadata.credential.userLabel
|
||||
}, /*#__PURE__*/React.createElement(DataListItemRow, {
|
||||
key: 'userCredentialRow-' + credentialMetadata.credential.id,
|
||||
className: "pf-u-align-items-center"
|
||||
}, /*#__PURE__*/React.createElement(DataListItemCells, {
|
||||
dataListCells: this.credentialRowCells(credentialMetadata, type)
|
||||
}), /*#__PURE__*/React.createElement(CredentialAction, {
|
||||
credential: credentialMetadata.credential,
|
||||
removeable: removeable,
|
||||
updateAction: updateAIA,
|
||||
credRemover: this.handleRemove
|
||||
})))))), " ");
|
||||
}
|
||||
|
||||
credentialRowCells(credMetadata, type) {
|
||||
const credRowCells = [];
|
||||
const credential = credMetadata.credential;
|
||||
let maxWidth = {
|
||||
"--pf-u-max-width--MaxWidth": "300px"
|
||||
};
|
||||
credRowCells.push( /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: `${SigningInPage.credElementId(type, credential.id, 'label')}`,
|
||||
key: 'userLabel-' + credential.id,
|
||||
className: "pf-u-max-width",
|
||||
style: maxWidth
|
||||
}, credential.userLabel));
|
||||
|
||||
if (credential.strCreatedDate) {
|
||||
credRowCells.push( /*#__PURE__*/React.createElement(DataListCell, {
|
||||
id: `${SigningInPage.credElementId(type, credential.id, "created-at")}`,
|
||||
key: "created-" + credential.id
|
||||
}, /*#__PURE__*/React.createElement("strong", {
|
||||
className: "pf-u-mr-md"
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "credentialCreatedAt"
|
||||
}), " "), credential.strCreatedDate));
|
||||
credRowCells.push( /*#__PURE__*/React.createElement(DataListCell, {
|
||||
key: "spacer-" + credential.id
|
||||
}));
|
||||
}
|
||||
|
||||
return credRowCells;
|
||||
}
|
||||
|
||||
renderCredTypeTitle(credContainer, keycloak, category) {
|
||||
if (!credContainer.hasOwnProperty("helptext") && !credContainer.hasOwnProperty("createAction")) return;
|
||||
let setupAction;
|
||||
|
||||
if (credContainer.createAction) {
|
||||
setupAction = new AIACommand(keycloak, credContainer.createAction);
|
||||
}
|
||||
|
||||
const credContainerDisplayName = Msg.localize(credContainer.displayName);
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||||
key: "credTypeTitle-" + credContainer.type
|
||||
}, /*#__PURE__*/React.createElement(Split, {
|
||||
className: "pf-u-mt-lg pf-u-mb-lg"
|
||||
}, /*#__PURE__*/React.createElement(SplitItem, null, /*#__PURE__*/React.createElement(Title, {
|
||||
headingLevel: "h3",
|
||||
size: "md",
|
||||
className: "pf-u-mb-md"
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "cred-title pf-u-display-block",
|
||||
id: `${credContainer.type}-cred-title`
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: credContainer.displayName
|
||||
}))), /*#__PURE__*/React.createElement("span", {
|
||||
id: `${credContainer.type}-cred-help`
|
||||
}, credContainer.helptext && /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: credContainer.helptext
|
||||
}))), /*#__PURE__*/React.createElement(SplitItem, {
|
||||
isFilled: true
|
||||
}, credContainer.createAction && /*#__PURE__*/React.createElement("div", {
|
||||
id: "mob-setUpAction-" + credContainer.type,
|
||||
className: "pf-u-display-none-on-lg pf-u-float-right"
|
||||
}, /*#__PURE__*/React.createElement(Dropdown, {
|
||||
isPlain: true,
|
||||
position: DropdownPosition.right,
|
||||
toggle: /*#__PURE__*/React.createElement(KebabToggle, {
|
||||
onToggle: isOpen => {
|
||||
credContainer.open = isOpen;
|
||||
this.setState({
|
||||
credentialContainers: new Map(this.state.credentialContainers)
|
||||
});
|
||||
}
|
||||
}),
|
||||
isOpen: credContainer.open,
|
||||
dropdownItems: [/*#__PURE__*/React.createElement("button", {
|
||||
id: `mob-${credContainer.type}-set-up`,
|
||||
className: "pf-c-button pf-m-link",
|
||||
type: "button",
|
||||
onClick: () => setupAction.execute()
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "pf-c-button__icon"
|
||||
}, /*#__PURE__*/React.createElement("i", {
|
||||
className: "fas fa-plus-circle",
|
||||
"aria-hidden": "true"
|
||||
})), /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "setUpNew",
|
||||
params: [credContainerDisplayName]
|
||||
}))]
|
||||
})), credContainer.createAction && /*#__PURE__*/React.createElement("div", {
|
||||
id: "setUpAction-" + credContainer.type,
|
||||
className: "pf-u-display-none pf-u-display-inline-flex-on-lg pf-u-float-right"
|
||||
}, /*#__PURE__*/React.createElement("button", {
|
||||
id: `${credContainer.type}-set-up`,
|
||||
className: "pf-c-button pf-m-link",
|
||||
type: "button",
|
||||
onClick: () => setupAction.execute()
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "pf-c-button__icon"
|
||||
}, /*#__PURE__*/React.createElement("i", {
|
||||
className: "fas fa-plus-circle",
|
||||
"aria-hidden": "true"
|
||||
})), /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "setUpNew",
|
||||
params: [credContainerDisplayName]
|
||||
}))))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_defineProperty(SigningInPage, "contextType", AccountServiceContext);
|
||||
|
||||
;
|
||||
|
||||
class CredentialAction extends React.Component {
|
||||
render() {
|
||||
if (this.props.updateAction) {
|
||||
return /*#__PURE__*/React.createElement(DataListAction, {
|
||||
"aria-labelledby": Msg.localize('updateCredAriaLabel'),
|
||||
"aria-label": Msg.localize('updateCredAriaLabel'),
|
||||
id: "updateAction-" + this.props.credential.id
|
||||
}, /*#__PURE__*/React.createElement(Button, {
|
||||
variant: "secondary",
|
||||
id: `${SigningInPage.credElementId(this.props.credential.type, this.props.credential.id, "update")}`,
|
||||
onClick: () => this.props.updateAction.execute()
|
||||
}, /*#__PURE__*/React.createElement(Msg, {
|
||||
msgKey: "update"
|
||||
})));
|
||||
}
|
||||
|
||||
if (this.props.removeable) {
|
||||
const userLabel = this.props.credential.userLabel;
|
||||
return /*#__PURE__*/React.createElement(DataListAction, {
|
||||
"aria-label": Msg.localize('removeCredAriaLabel'),
|
||||
"aria-labelledby": Msg.localize('removeCredAriaLabel'),
|
||||
id: 'removeAction-' + this.props.credential.id
|
||||
}, /*#__PURE__*/React.createElement(ContinueCancelModal, {
|
||||
buttonTitle: "remove",
|
||||
buttonVariant: "danger",
|
||||
buttonId: `${SigningInPage.credElementId(this.props.credential.type, this.props.credential.id, 'remove')}`,
|
||||
modalTitle: Msg.localize('removeCred', [userLabel]),
|
||||
modalMessage: Msg.localize('stopUsingCred', [userLabel]),
|
||||
onContinue: () => this.props.credRemover(this.props.credential.id, userLabel)
|
||||
}));
|
||||
}
|
||||
|
||||
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const SigningInPageWithRouter = withRouter(SigningInPage);
|
||||
export { SigningInPageWithRouter as SigningInPage };
|
||||
//# sourceMappingURL=SigningInPage.js.map
|
||||
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.faac274b-9d49-4ba1-9ef0-610572d38128 {
|
||||
fill: #1877f2;
|
||||
}
|
||||
|
||||
.f55f6e4a-14c2-4793-a1d5-db4b028479c8 {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="b36e017a-ce19-4905-9b48-48066e87bbf5" data-name="New stuff">
|
||||
<g>
|
||||
<rect class="faac274b-9d49-4ba1-9ef0-610572d38128" width="32" height="32" rx="1.19"/>
|
||||
<path class="f55f6e4a-14c2-4793-a1d5-db4b028479c8" d="M26.93,16.07a10.93,10.93,0,1,0-12.64,10.8V19.23H11.52V16.07h2.77V13.66c0-2.74,1.63-4.26,4.13-4.26a16.32,16.32,0,0,1,2.45.22v2.69H19.49A1.58,1.58,0,0,0,17.71,14v2.05h3l-.48,3.16H17.71v7.64a10.94,10.94,0,0,0,9.22-10.8Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 730 B |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.b42551c7-a511-4544-a371-f6e3883f7abd {
|
||||
fill: #fff;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="f00b56ab-1ecb-4d94-b704-cf429e3c78a4" data-name="GitHub">
|
||||
<g>
|
||||
<rect width="32" height="32" rx="1.19"/>
|
||||
<path class="b42551c7-a511-4544-a371-f6e3883f7abd" d="M16,5.13a11.06,11.06,0,0,0-3.5,21.55c.56.1.76-.24.76-.53s0-1,0-1.88c-3.07.67-3.72-1.48-3.72-1.48a2.91,2.91,0,0,0-1.23-1.62c-1-.69.08-.67.08-.67a2.32,2.32,0,0,1,1.69,1.14,2.36,2.36,0,0,0,3.22.92,2.36,2.36,0,0,1,.7-1.48c-2.45-.28-5-1.23-5-5.47a4.29,4.29,0,0,1,1.13-3,4,4,0,0,1,.11-2.93s.93-.3,3,1.13a10.55,10.55,0,0,1,5.54,0c2.11-1.43,3-1.13,3-1.13a4,4,0,0,1,.11,2.93,4.25,4.25,0,0,1,1.13,3c0,4.25-2.58,5.18-5.05,5.46a2.62,2.62,0,0,1,.75,2.05c0,1.47,0,2.67,0,3s.2.64.76.53A11.06,11.06,0,0,0,16,5.13Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 912 B |
@@ -0,0 +1,77 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.e5ef51ce-3313-4c04-b152-23646fd2b306 {
|
||||
fill: none;
|
||||
clip-rule: evenodd;
|
||||
}
|
||||
|
||||
.ef16f3ef-fb03-4a62-9cce-d65767c17c4c {
|
||||
fill: #ededed;
|
||||
}
|
||||
|
||||
.e0f4cb03-a97e-447b-8c37-60d897bac484 {
|
||||
clip-path: url(#fe0cecb0-916b-4b9d-828f-63ec94884d2e);
|
||||
}
|
||||
|
||||
.afb39849-fc2d-48aa-a4a4-070e36b84e51 {
|
||||
fill: #3e82f1;
|
||||
}
|
||||
|
||||
.a2ee00a5-b156-4157-adc5-b40fd1ee5ebd {
|
||||
clip-path: url(#e022c77c-5a12-4caf-aaed-c796166a8562);
|
||||
}
|
||||
|
||||
.a025e47e-f997-4bd7-8964-88ada0c7c12f {
|
||||
fill: #32a753;
|
||||
}
|
||||
|
||||
.b4e7c98a-856b-4280-8aaa-b9f157cf22ea {
|
||||
clip-path: url(#b1e1e904-5b74-4ac6-8dc5-11a864f7f8ec);
|
||||
}
|
||||
|
||||
.b0bf74a2-e960-4e68-948c-0e3dfb1bcd2a {
|
||||
fill: #f9bb00;
|
||||
}
|
||||
|
||||
.ba55bfd1-dca2-4617-b45c-128fdf3bf3b4 {
|
||||
clip-path: url(#bcdf0102-4e91-4218-8945-e2893d757d6d);
|
||||
}
|
||||
|
||||
.fae83dfa-2d64-4e2a-9cd9-b00b32869370 {
|
||||
fill: #e74235;
|
||||
}
|
||||
</style>
|
||||
<clipPath id="fe0cecb0-916b-4b9d-828f-63ec94884d2e">
|
||||
<path class="e5ef51ce-3313-4c04-b152-23646fd2b306" d="M25.85,16.23a12.53,12.53,0,0,0-.18-2.06H16.2v3.89h5.41a4.58,4.58,0,0,1-2,3v2.53h3.25a9.81,9.81,0,0,0,3-7.39Zm0,0"/>
|
||||
</clipPath>
|
||||
<clipPath id="e022c77c-5a12-4caf-aaed-c796166a8562">
|
||||
<path class="e5ef51ce-3313-4c04-b152-23646fd2b306" d="M16.2,26.05a9.61,9.61,0,0,0,6.65-2.43L19.6,21.09a6.06,6.06,0,0,1-9-3.18H7.22v2.6a10,10,0,0,0,9,5.54Zm0,0"/>
|
||||
</clipPath>
|
||||
<clipPath id="b1e1e904-5b74-4ac6-8dc5-11a864f7f8ec">
|
||||
<path class="e5ef51ce-3313-4c04-b152-23646fd2b306" d="M10.58,17.91a5.86,5.86,0,0,1,0-3.82v-2.6H7.22a10,10,0,0,0,0,9l3.36-2.6Zm0,0"/>
|
||||
</clipPath>
|
||||
<clipPath id="bcdf0102-4e91-4218-8945-e2893d757d6d">
|
||||
<path class="e5ef51ce-3313-4c04-b152-23646fd2b306" d="M16.2,10A5.39,5.39,0,0,1,20,11.45l2.89-2.88A9.7,9.7,0,0,0,16.2,6a10,10,0,0,0-9,5.54l3.36,2.6A6,6,0,0,1,16.2,10Zm0,0"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="a06b7517-c1f4-49d5-aa34-cee2287c4769" data-name="Google">
|
||||
<g id="fbe0f094-aaab-4b03-a7bf-452a2c250397" data-name="Full color">
|
||||
<rect class="ef16f3ef-fb03-4a62-9cce-d65767c17c4c" width="32" height="32" rx="1.19"/>
|
||||
<g>
|
||||
<g class="e0f4cb03-a97e-447b-8c37-60d897bac484">
|
||||
<rect class="afb39849-fc2d-48aa-a4a4-070e36b84e51" x="10.62" y="8.59" width="20.81" height="20.61"/>
|
||||
</g>
|
||||
<g class="a2ee00a5-b156-4157-adc5-b40fd1ee5ebd">
|
||||
<rect class="a025e47e-f997-4bd7-8964-88ada0c7c12f" x="1.64" y="12.33" width="26.8" height="19.31"/>
|
||||
</g>
|
||||
<g class="b4e7c98a-856b-4280-8aaa-b9f157cf22ea">
|
||||
<rect class="b0bf74a2-e960-4e68-948c-0e3dfb1bcd2a" x="0.57" y="5.9" width="15.59" height="20.19"/>
|
||||
</g>
|
||||
<g class="ba55bfd1-dca2-4617-b45c-128fdf3bf3b4">
|
||||
<rect class="fae83dfa-2d64-4e2a-9cd9-b00b32869370" x="1.64" y="0.37" width="26.87" height="19.31"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.ac4e1fda-441f-45c3-89b5-eabc007f54ca {
|
||||
fill: #e1306c;
|
||||
}
|
||||
|
||||
.a7c172c4-b213-4581-937c-bb042fd94b3e {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="a864479b-0561-4117-aa66-744aa86c5250" data-name="Instagram">
|
||||
<g id="bb9ebb9e-2d15-4e72-a42a-7eff89494a26" data-name="Black and white">
|
||||
<rect class="ac4e1fda-441f-45c3-89b5-eabc007f54ca" width="32" height="32" rx="1.19"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="a7c172c4-b213-4581-937c-bb042fd94b3e" d="M16,6.09c-2.69,0-3,0-4.09.06a7.18,7.18,0,0,0-2.4.46,5,5,0,0,0-2.9,2.9,7.18,7.18,0,0,0-.46,2.4C6.1,13,6.09,13.31,6.09,16s0,3,.06,4.09a7.18,7.18,0,0,0,.46,2.4,5,5,0,0,0,2.9,2.9,7.18,7.18,0,0,0,2.4.46c1.06,0,1.4.06,4.09.06s3,0,4.09-.06a7.18,7.18,0,0,0,2.4-.46,5,5,0,0,0,2.9-2.9,7.18,7.18,0,0,0,.46-2.4c0-1.06.06-1.4.06-4.09s0-3-.06-4.09a7.18,7.18,0,0,0-.46-2.4,5,5,0,0,0-2.9-2.9,7.18,7.18,0,0,0-2.4-.46C19,6.1,18.69,6.09,16,6.09Zm0,1.79c2.65,0,3,0,4,0a5.73,5.73,0,0,1,1.84.34A3,3,0,0,1,23,9a3,3,0,0,1,.75,1.14A5.73,5.73,0,0,1,24.07,12c0,1,.05,1.35.05,4s0,3-.05,4a5.73,5.73,0,0,1-.34,1.84,3.38,3.38,0,0,1-1.89,1.89,5.73,5.73,0,0,1-1.84.34c-1,0-1.35.05-4,.05s-3,0-4-.05a5.73,5.73,0,0,1-1.84-.34A3,3,0,0,1,9,23a3,3,0,0,1-.75-1.14A5.73,5.73,0,0,1,7.93,20c0-1,0-1.35,0-4s0-3,0-4a5.73,5.73,0,0,1,.34-1.84A3,3,0,0,1,9,9a3,3,0,0,1,1.14-.75A5.73,5.73,0,0,1,12,7.93c1,0,1.35,0,4,0"/>
|
||||
<path class="a7c172c4-b213-4581-937c-bb042fd94b3e" d="M16,19.3A3.3,3.3,0,1,1,19.3,16,3.3,3.3,0,0,1,16,19.3Zm0-8.39A5.09,5.09,0,1,0,21.09,16,5.09,5.09,0,0,0,16,10.91Z"/>
|
||||
<path class="a7c172c4-b213-4581-937c-bb042fd94b3e" d="M22.48,10.71a1.19,1.19,0,1,1-1.19-1.19,1.19,1.19,0,0,1,1.19,1.19Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.a975829d-e85a-4fdc-b46a-16eba47b4e8e {
|
||||
fill: #2867b2;
|
||||
}
|
||||
|
||||
.b17912fc-cab5-4688-935b-8aa15b250003 {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="adf29cd2-f5a2-4433-a836-7d0b8cd64c5d" data-name="LinkedIn">
|
||||
<g>
|
||||
<rect class="a975829d-e85a-4fdc-b46a-16eba47b4e8e" width="32" height="32" rx="1.19"/>
|
||||
<g>
|
||||
<polygon class="b17912fc-cab5-4688-935b-8aa15b250003" points="10.47 25.5 6.46 25.5 6.46 12.59 10.47 12.59 10.47 25.5 10.47 25.5"/>
|
||||
<path class="b17912fc-cab5-4688-935b-8aa15b250003" d="M8.46,10.83A2.33,2.33,0,1,1,10.79,8.5a2.33,2.33,0,0,1-2.33,2.33Z"/>
|
||||
<path class="b17912fc-cab5-4688-935b-8aa15b250003" d="M25.5,25.5h-4V19.22c0-1.49,0-3.42-2.09-3.42S17,17.43,17,19.11V25.5H13V12.59h3.84v1.76h.06a4.21,4.21,0,0,1,3.8-2.08c4.06,0,4.81,2.67,4.81,6.15V25.5Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 951 B |
@@ -0,0 +1,34 @@
|
||||
<svg id="bf5a9f86-a166-4609-aea2-c789db71fd48" data-name="Microsoft" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.fe82c64e-6d2d-42d3-aeec-ae7ea0741e78 {
|
||||
fill: #ededed;
|
||||
}
|
||||
|
||||
.be49cf2d-e5c3-4773-b2c7-b422380b776a {
|
||||
fill: #7fba00;
|
||||
}
|
||||
|
||||
.a9f66f41-846e-499a-af6d-5503813bb401 {
|
||||
fill: #ffb900;
|
||||
}
|
||||
|
||||
.a8084a6b-0b46-4437-8e12-638c29ccbea1 {
|
||||
fill: #f25022;
|
||||
}
|
||||
|
||||
.bb872b1d-e833-4ba3-99af-3b105ed602a0 {
|
||||
fill: #00a4ef;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="e0b7e64b-db07-46e0-9f19-72b142175f6b" data-name="Full color">
|
||||
<rect class="fe82c64e-6d2d-42d3-aeec-ae7ea0741e78" width="32" height="32" rx="1.19"/>
|
||||
<g>
|
||||
<rect class="be49cf2d-e5c3-4773-b2c7-b422380b776a" x="16.47" y="6.5" width="9.03" height="9.03" rx="0.1"/>
|
||||
<rect class="a9f66f41-846e-499a-af6d-5503813bb401" x="16.47" y="16.47" width="9.03" height="9.03" rx="0.1"/>
|
||||
<rect class="a8084a6b-0b46-4437-8e12-638c29ccbea1" x="6.5" y="6.5" width="9.03" height="9.03" rx="0.1"/>
|
||||
<rect class="bb872b1d-e833-4ba3-99af-3b105ed602a0" x="6.5" y="16.47" width="9.03" height="9.03" rx="0.1"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(0.321739,0,0,0.321739,-0.234299,0.0972928)">
|
||||
<path d="M64.38,23.5C67.556,24.99 70.436,27.044 72.88,29.56L88.62,23.83C80.176,12.044 66.537,5.037 52.039,5.037C27.353,5.037 7.039,25.351 7.039,50.037C7.039,51.183 7.083,52.328 7.17,53.47L22.91,47.74C24.033,32.597 36.806,20.737 51.99,20.737C56.273,20.737 60.503,21.68 64.38,23.5" style="fill:rgb(238,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M16,58.19L1,63.63C2.371,69.099 4.744,74.267 8,78.87L23.7,73.16C19.696,69.029 16.99,63.813 15.92,58.16" style="fill:rgb(238,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M81.16,52.25C80.904,55.75 80.009,59.173 78.52,62.35C71.736,76.878 54.205,83.258 39.67,76.49C36.487,75.027 33.599,72.994 31.15,70.49L15.45,76.21C23.88,88.016 37.524,95.039 52.032,95.039C69.504,95.039 85.459,84.851 92.81,69C96.075,61.982 97.454,54.233 96.81,46.52L81.16,52.25Z" style="fill:rgb(238,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M85,33L70,38.45C72.851,43.476 74.153,49.236 73.74,55L89.44,49.29C88.992,43.63 87.486,38.104 85,33" style="fill:rgb(238,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M29.46,45.36L13.72,51.09C13.94,53.604 14.368,56.096 15,58.54L30,53.1C29.501,50.552 29.346,47.949 29.54,45.36" style="fill:rgb(204,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M99,28C97.903,25.724 96.619,23.543 95.16,21.48L79.43,27.18C81.238,29.04 82.791,31.132 84.05,33.4L99,28Z" style="fill:rgb(204,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M15.45,76.17C16.671,77.879 18.007,79.503 19.45,81.03L36.54,74.79C34.578,73.561 32.769,72.105 31.15,70.45L15.45,76.17ZM96.86,46.54L81.16,52.25C80.985,54.545 80.539,56.81 79.83,59L96.92,52.76C97.04,50.684 97.02,48.603 96.86,46.53" style="fill:rgb(204,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M29.4,48.52C29.36,47.466 29.38,46.411 29.46,45.36L13.72,51.09C13.8,52.09 13.93,53.09 14.08,54.09L29.4,48.52Z" style="fill:rgb(163,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M96.72,23.82C96.22,23.01 95.72,22.22 95.16,21.44L79.43,27.18C80.116,27.884 80.764,28.626 81.37,29.4L96.72,23.82Z" style="fill:rgb(163,0,0);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.f425009f-d653-4243-b52f-e6e7efdbf57a {
|
||||
fill: #4d4d4d;
|
||||
}
|
||||
|
||||
.bac6a0a4-fc2d-4f36-9ded-667acc6f4b52 {
|
||||
fill: #bcbbbb;
|
||||
}
|
||||
|
||||
.b9d59bf2-7616-43cd-a672-04b81955bad9 {
|
||||
fill: #f48024;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="b393dd85-54a9-4370-beab-fda62d40e5d8" data-name="StackOverflow">
|
||||
<g id="beef34ed-ad1e-45a9-8dc6-781d71c5dd19" data-name="Full color">
|
||||
<rect class="f425009f-d653-4243-b52f-e6e7efdbf57a" width="32" height="32" rx="1.19"/>
|
||||
<g>
|
||||
<polygon class="bac6a0a4-fc2d-4f36-9ded-667acc6f4b52" points="21.29 23.44 21.29 18.82 23.34 18.82 23.34 25.5 7.94 25.5 7.94 18.82 9.99 18.82 9.99 23.44 21.29 23.44"/>
|
||||
<path class="b9d59bf2-7616-43cd-a672-04b81955bad9" d="M11.53,21.9h8.22V20.36H11.53ZM19,6.5l-1.39,1,5.08,6.83,1.39-1Zm-4.21,4L21.29,16l1.08-1.28L15.85,9.22Zm-2.16,3.8,7.7,3.59L21,16.36l-7.7-3.59Zm7.18,5.53.36-1.51-8.27-1.72-.35,1.7Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<style>
|
||||
.b48eca1a-55ea-4187-8747-2a0a7c0905ff {
|
||||
fill: #1da1f2;
|
||||
}
|
||||
|
||||
.a0fa0208-710f-4171-b935-86383a49537b {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="e43e3b03-e423-44e8-9d4d-c8c1f8f88064" data-name="Twitter">
|
||||
<g>
|
||||
<rect class="b48eca1a-55ea-4187-8747-2a0a7c0905ff" width="32" height="32" rx="1.19"/>
|
||||
<path class="a0fa0208-710f-4171-b935-86383a49537b" d="M24.42,11.5c0,.18,0,.37,0,.56A12.25,12.25,0,0,1,5.58,22.37,8.72,8.72,0,0,0,12,20.59a4.3,4.3,0,0,1-4-3,4.28,4.28,0,0,0,.81.07,4.22,4.22,0,0,0,1.13-.15A4.29,4.29,0,0,1,6.43,13.3v-.05a4.4,4.4,0,0,0,2,.54A4.31,4.31,0,0,1,7,8a12.26,12.26,0,0,0,8.88,4.5,4,4,0,0,1-.11-1,4.3,4.3,0,0,1,7.44-3,8.59,8.59,0,0,0,2.73-1A4.31,4.31,0,0,1,24.09,10a8.86,8.86,0,0,0,2.47-.68,8.72,8.72,0,0,1-2.14,2.23Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 895 B |
@@ -0,0 +1,3 @@
|
||||
import * as React from "../../../common/keycloak/web_modules/react.js";
|
||||
export const KeycloakContext = React.createContext(undefined);
|
||||
//# sourceMappingURL=KeycloakContext.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/keycloak-service/KeycloakContext.tsx"],"names":["React","KeycloakContext","createContext","undefined"],"mappings":"AAAA,OAAO,KAAKA,KAAZ;AAGA,OAAO,MAAMC,eAAe,GAAGD,KAAK,CAACE,aAAN,CAAiDC,SAAjD,CAAxB","sourcesContent":["import * as React from 'react';\nimport { KeycloakService } from './keycloak.service';\n\nexport const KeycloakContext = React.createContext<KeycloakService | undefined>(undefined);"],"file":"KeycloakContext.js"}
|
||||
@@ -0,0 +1,77 @@
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*
|
||||
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export class KeycloakService {
|
||||
constructor(keycloak) {
|
||||
_defineProperty(this, "keycloakAuth", void 0);
|
||||
|
||||
this.keycloakAuth = keycloak;
|
||||
}
|
||||
|
||||
authenticated() {
|
||||
return this.keycloakAuth.authenticated ? this.keycloakAuth.authenticated : false;
|
||||
}
|
||||
|
||||
audiencePresent() {
|
||||
if (this.keycloakAuth.tokenParsed) {
|
||||
const audience = this.keycloakAuth.tokenParsed['aud'];
|
||||
return audience === 'account' || Array.isArray(audience) && audience.indexOf('account') >= 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
login(options) {
|
||||
this.keycloakAuth.login(options);
|
||||
}
|
||||
|
||||
logout(redirectUri = baseUrl) {
|
||||
this.keycloakAuth.logout({
|
||||
redirectUri: redirectUri
|
||||
});
|
||||
}
|
||||
|
||||
account() {
|
||||
this.keycloakAuth.accountManagement();
|
||||
}
|
||||
|
||||
authServerUrl() {
|
||||
const authServerUrl = this.keycloakAuth.authServerUrl;
|
||||
return authServerUrl.charAt(authServerUrl.length - 1) === '/' ? authServerUrl : authServerUrl + '/';
|
||||
}
|
||||
|
||||
realm() {
|
||||
return this.keycloakAuth.realm;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.keycloakAuth.token) {
|
||||
this.keycloakAuth.updateToken(5).success(() => {
|
||||
resolve(this.keycloakAuth.token);
|
||||
}).error(() => {
|
||||
reject('Failed to refresh token');
|
||||
});
|
||||
} else {
|
||||
reject('Not logged in');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=keycloak.service.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/keycloak-service/keycloak.service.ts"],"names":["KeycloakService","constructor","keycloak","keycloakAuth","authenticated","audiencePresent","tokenParsed","audience","Array","isArray","indexOf","login","options","logout","redirectUri","baseUrl","account","accountManagement","authServerUrl","charAt","length","realm","getToken","Promise","resolve","reject","token","updateToken","success","error"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA,OAAO,MAAMA,eAAN,CAAsB;AAGlBC,EAAAA,WAAW,CAACC,QAAD,EAA2B;AAAA;;AACzC,SAAKC,YAAL,GAAoBD,QAApB;AACH;;AAEME,EAAAA,aAAa,GAAY;AAC5B,WAAO,KAAKD,YAAL,CAAkBC,aAAlB,GAAkC,KAAKD,YAAL,CAAkBC,aAApD,GAAoE,KAA3E;AACH;;AAEMC,EAAAA,eAAe,GAAY;AAC9B,QAAI,KAAKF,YAAL,CAAkBG,WAAtB,EAAmC;AAC/B,YAAMC,QAAQ,GAAG,KAAKJ,YAAL,CAAkBG,WAAlB,CAA8B,KAA9B,CAAjB;AACA,aAAOC,QAAQ,KAAK,SAAb,IAA2BC,KAAK,CAACC,OAAN,CAAcF,QAAd,KAA2BA,QAAQ,CAACG,OAAT,CAAiB,SAAjB,KAA+B,CAA5F;AACH;;AACD,WAAO,KAAP;AACH;;AAEMC,EAAAA,KAAK,CAACC,OAAD,EAAuC;AAC/C,SAAKT,YAAL,CAAkBQ,KAAlB,CAAwBC,OAAxB;AACH;;AAEMC,EAAAA,MAAM,CAACC,WAAmB,GAAGC,OAAvB,EAAsC;AAC/C,SAAKZ,YAAL,CAAkBU,MAAlB,CAAyB;AAACC,MAAAA,WAAW,EAAEA;AAAd,KAAzB;AACH;;AAEME,EAAAA,OAAO,GAAS;AACnB,SAAKb,YAAL,CAAkBc,iBAAlB;AACH;;AAEMC,EAAAA,aAAa,GAAuB;AACvC,UAAMA,aAAa,GAAG,KAAKf,YAAL,CAAkBe,aAAxC;AACA,WAAOA,aAAa,CAAEC,MAAf,CAAsBD,aAAa,CAAEE,MAAf,GAAwB,CAA9C,MAAqD,GAArD,GAA2DF,aAA3D,GAA2EA,aAAa,GAAG,GAAlG;AACH;;AAEMG,EAAAA,KAAK,GAAuB;AAC/B,WAAO,KAAKlB,YAAL,CAAkBkB,KAAzB;AACH;;AAEMC,EAAAA,QAAQ,GAAoB;AAC/B,WAAO,IAAIC,OAAJ,CAAoB,CAACC,OAAD,EAAUC,MAAV,KAAqB;AAC5C,UAAI,KAAKtB,YAAL,CAAkBuB,KAAtB,EAA6B;AACzB,aAAKvB,YAAL,CACKwB,WADL,CACiB,CADjB,EAEKC,OAFL,CAEa,MAAM;AACXJ,UAAAA,OAAO,CAAC,KAAKrB,YAAL,CAAkBuB,KAAnB,CAAP;AACH,SAJL,EAKKG,KALL,CAKW,MAAM;AACTJ,UAAAA,MAAM,CAAC,yBAAD,CAAN;AACH,SAPL;AAQH,OATD,MASO;AACHA,QAAAA,MAAM,CAAC,eAAD,CAAN;AACH;AACJ,KAbM,CAAP;AAcH;;AAvDwB","sourcesContent":["/*\n * Copyright 2017 Red Hat, Inc. and/or its affiliates\n * and other contributors as indicated by the @author tags.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Keycloak, { KeycloakLoginOptions } from \"../../../../../../../../../../adapters/oidc/js\";\n\ndeclare const baseUrl: string;\nexport type KeycloakClient = Keycloak;\n\nexport class KeycloakService {\n private keycloakAuth: KeycloakClient;\n\n public constructor(keycloak: KeycloakClient) {\n this.keycloakAuth = keycloak;\n }\n\n public authenticated(): boolean {\n return this.keycloakAuth.authenticated ? this.keycloakAuth.authenticated : false;\n }\n\n public audiencePresent(): boolean {\n if (this.keycloakAuth.tokenParsed) {\n const audience = this.keycloakAuth.tokenParsed['aud'];\n return audience === 'account' || (Array.isArray(audience) && audience.indexOf('account') >= 0);\n }\n return false;\n }\n\n public login(options?: KeycloakLoginOptions): void {\n this.keycloakAuth.login(options);\n }\n\n public logout(redirectUri: string = baseUrl): void {\n this.keycloakAuth.logout({redirectUri: redirectUri});\n }\n\n public account(): void {\n this.keycloakAuth.accountManagement();\n }\n\n public authServerUrl(): string | undefined {\n const authServerUrl = this.keycloakAuth.authServerUrl;\n return authServerUrl!.charAt(authServerUrl!.length - 1) === '/' ? authServerUrl : authServerUrl + '/';\n }\n\n public realm(): string | undefined {\n return this.keycloakAuth.realm;\n }\n\n public getToken(): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n if (this.keycloakAuth.token) {\n this.keycloakAuth\n .updateToken(5)\n .success(() => {\n resolve(this.keycloakAuth.token as string);\n })\n .error(() => {\n reject('Failed to refresh token');\n });\n } else {\n reject('Not logged in');\n }\n });\n }\n}\n"],"file":"keycloak.service.js"}
|
||||
|
After Width: | Height: | Size: 627 B |
@@ -0,0 +1,126 @@
|
||||
/* Globals */
|
||||
.brand {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
width: 150px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
@media (max-width: 320px) {
|
||||
.delete-button {
|
||||
width: 120px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Linked Accounts screen */
|
||||
.idp-icon-social {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#github-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_github_transparent.svg);
|
||||
}
|
||||
|
||||
#linkedin-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_linkedin_transparent.svg);
|
||||
}
|
||||
|
||||
#facebook-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_facebook_transparent.svg);
|
||||
}
|
||||
|
||||
#google-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_google_transparent.svg);
|
||||
}
|
||||
|
||||
#microsoft-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_microsoft_transparent.svg);
|
||||
}
|
||||
|
||||
#instagram-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_instagram_transparent.svg);
|
||||
}
|
||||
|
||||
#stackoverflow-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_stack_transparent.svg);
|
||||
}
|
||||
|
||||
#twitter-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_twitter_transparent.svg);
|
||||
}
|
||||
|
||||
#openshift-idp-icon-social {
|
||||
background-image: url(../img/socialmedia/socialmedia_icons_openshift_transparent.svg);
|
||||
}
|
||||
|
||||
/* Account Page screen */
|
||||
.personal-info-form .pf-c-form__group-control {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
/* Device Activity screen */
|
||||
.signed-in-device-list .pf-c-data-list__item-row {
|
||||
--pf-c-data-list__item-row--PaddingRight: 0;
|
||||
--pf-c-data-list__item-row--PaddingLeft: 0;
|
||||
}
|
||||
|
||||
.signed-in-device-list .pf-c-data-list__expandable-content-body {
|
||||
--pf-c-data-list__expandable-content-body--PaddingRight: 0;
|
||||
}
|
||||
|
||||
.signed-in-device-grid {
|
||||
grid-template-columns: auto repeat(11, [col-start] 1fr);
|
||||
}
|
||||
|
||||
.signed-in-device-list.pf-c-data-list {
|
||||
--pf-c-data-list--sm--BorderTopWidth: 0;
|
||||
}
|
||||
|
||||
.pf-c-data-list__item {
|
||||
--pf-c-data-list__item--BorderBottomWidth: 1px;
|
||||
--pf-c-data-list__item--BorderBottomColor: var(--pf-global--BorderColor--100);
|
||||
}
|
||||
|
||||
.signed-in-device-list.pf-c-data-list {
|
||||
--pf-c-data-list--BorderTopWidth: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.pf-c-data-list__item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--pf-c-data-list__item--BackgroundColor);
|
||||
border-bottom: var(--pf-c-data-list__item--BorderBottomWidth) solid var(--pf-c-data-list__item--BorderBottomColor);
|
||||
}
|
||||
|
||||
.signed-in-device-list.pf-c-data-list {
|
||||
--pf-c-data-list--BorderTopWidth: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.signed-in-device-list .pf-c-description-list {
|
||||
--pf-c-description-list--GridTemplateColumns--count: 5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Signing in screen */
|
||||
.title-case:first-letter,
|
||||
.cred-title:first-letter,
|
||||
#otp-not-set-up .pf-c-empty-state__body:first-letter {
|
||||
text-transform: capitalize
|
||||
}
|
||||
|
||||
/* Applications screen */
|
||||
#applications-list-header .pf-c-data-list__item-content {
|
||||
--pf-c-data-list__item-content--md--PaddingBottom: 1rem;
|
||||
}
|
||||
|
||||
.pf-u-pl-35xl {
|
||||
padding-left: 4.5rem;
|
||||
}
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Stan Silvert
|
||||
*/
|
||||
export class AIACommand {
|
||||
constructor(keycloak, action) {
|
||||
this.keycloak = keycloak;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.keycloak.login({
|
||||
action: this.action
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=AIACommand.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/util/AIACommand.ts"],"names":["AIACommand","constructor","keycloak","action","execute","login"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA,OAAO,MAAMA,UAAN,CAAiB;AAEpBC,EAAAA,WAAW,CAASC,QAAT,EAA4CC,MAA5C,EAA4D;AAAA,SAAnDD,QAAmD,GAAnDA,QAAmD;AAAA,SAAhBC,MAAgB,GAAhBA,MAAgB;AAAE;;AAElEC,EAAAA,OAAO,GAAS;AACnB,SAAKF,QAAL,CAAcG,KAAd,CAAoB;AAChBF,MAAAA,MAAM,EAAE,KAAKA;AADG,KAApB;AAIH;;AATmB","sourcesContent":["/*\n * Copyright 2019 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {KeycloakService} from '../keycloak-service/keycloak.service';\n\n/**\n * @author Stan Silvert\n */\nexport class AIACommand {\n\n constructor(private keycloak: KeycloakService, private action: string) {}\n\n public execute(): void {\n this.keycloak.login({\n action: this.action,\n })\n\n }\n}"],"file":"AIACommand.js"}
|
||||
@@ -0,0 +1,19 @@
|
||||
function parse(linkHeader) {
|
||||
if (!linkHeader) return {};
|
||||
const links = linkHeader.split(/,\s*</);
|
||||
return links.reduce((acc, link) => {
|
||||
const matcher = link.match(/<?([^>]*)>(.*)/);
|
||||
if (!matcher) return {};
|
||||
const linkUrl = matcher[1];
|
||||
const rel = matcher[2].match(/\s*(.+)\s*=\s*"?([^"]+)"?/);
|
||||
|
||||
if (rel) {
|
||||
acc[rel[2]] = linkUrl;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export default parse;
|
||||
//# sourceMappingURL=ParseLink.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/util/ParseLink.ts"],"names":["parse","linkHeader","links","split","reduce","acc","link","matcher","match","linkUrl","rel"],"mappings":"AAMA,SAASA,KAAT,CAAeC,UAAf,EAAsD;AACpD,MAAI,CAACA,UAAL,EAAiB,OAAO,EAAP;AACjB,QAAMC,KAAK,GAAGD,UAAU,CAACE,KAAX,CAAiB,OAAjB,CAAd;AACA,SAAOD,KAAK,CAACE,MAAN,CAAoB,CAACC,GAAD,EAAaC,IAAb,KAAqC;AAC9D,UAAMC,OAAO,GAAGD,IAAI,CAACE,KAAL,CAAW,gBAAX,CAAhB;AACA,QAAI,CAACD,OAAL,EAAc,OAAO,EAAP;AACd,UAAME,OAAO,GAAGF,OAAO,CAAC,CAAD,CAAvB;AACA,UAAMG,GAAG,GAAGH,OAAO,CAAC,CAAD,CAAP,CAAWC,KAAX,CAAiB,2BAAjB,CAAZ;;AACA,QAAIE,GAAJ,EAAS;AACLL,MAAAA,GAAG,CAACK,GAAG,CAAC,CAAD,CAAJ,CAAH,GAAcD,OAAd;AACH;;AACD,WAAOJ,GAAP;AACD,GATM,EASJ,EATI,CAAP;AAUD;;AAED,eAAeL,KAAf","sourcesContent":["\nexport interface Links {\n prev?: string;\n next?: string;\n}\n\nfunction parse(linkHeader: string | undefined): Links {\n if (!linkHeader) return {};\n const links = linkHeader.split(/,\\s*</);\n return links.reduce<Links>((acc: Links, link: string): Links => {\n const matcher = link.match(/<?([^>]*)>(.*)/);\n if (!matcher) return {};\n const linkUrl = matcher[1];\n const rel = matcher[2].match(/\\s*(.+)\\s*=\\s*\"?([^\"]+)\"?/);\n if (rel) {\n acc[rel[2]] = linkUrl;\n }\n return acc;\n }, {});\n}\n\nexport default parse;"],"file":"ParseLink.js"}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2019 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a redirect uri that can return to this application with referrer and referrer_uri intact.
|
||||
*
|
||||
* @param currentLocation The ReactRouter location to return to.
|
||||
*
|
||||
* @author Stan Silvert
|
||||
*/
|
||||
export const createRedirect = currentLocation => {
|
||||
let redirectUri = baseUrl;
|
||||
|
||||
if (typeof referrer !== 'undefined') {
|
||||
// '_hash_' is a workaround for when uri encoding is not
|
||||
// sufficient to escape the # character properly.
|
||||
// The problem is that both the redirect and the application URL contain a hash.
|
||||
// The browser will consider anything after the first hash to be client-side. So
|
||||
// it sees the hash in the redirect param and stops.
|
||||
redirectUri += "?referrer=" + referrer + "&referrer_uri=" + referrerUri.replace('#', '_hash_');
|
||||
}
|
||||
|
||||
return encodeURIComponent(redirectUri) + encodeURIComponent("/#" + currentLocation);
|
||||
};
|
||||
//# sourceMappingURL=RedirectUri.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/app/util/RedirectUri.ts"],"names":["createRedirect","currentLocation","redirectUri","baseUrl","referrer","referrerUri","replace","encodeURIComponent"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,cAAc,GAAIC,eAAD,IAAqC;AAC/D,MAAIC,WAAmB,GAAGC,OAA1B;;AAEA,MAAI,OAAOC,QAAP,KAAoB,WAAxB,EAAqC;AACjC;AACA;AACA;AACA;AACA;AACAF,IAAAA,WAAW,IAAI,eAAeE,QAAf,GAA0B,gBAA1B,GAA6CC,WAAW,CAACC,OAAZ,CAAoB,GAApB,EAAyB,QAAzB,CAA5D;AACH;;AAED,SAAOC,kBAAkB,CAACL,WAAD,CAAlB,GAAkCK,kBAAkB,CAAC,OAAON,eAAR,CAA3D;AACH,CAbM","sourcesContent":["/*\n * Copyright 2019 Red Hat, Inc. and/or its affiliates\n * and other contributors as indicated by the @author tags.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ndeclare const baseUrl: string;\ndeclare const referrer: string;\ndeclare const referrerUri: string;\n\n/**\n * Create a redirect uri that can return to this application with referrer and referrer_uri intact.\n * \n * @param currentLocation The ReactRouter location to return to.\n * \n * @author Stan Silvert\n */\nexport const createRedirect = (currentLocation: string): string => {\n let redirectUri: string = baseUrl;\n \n if (typeof referrer !== 'undefined') {\n // '_hash_' is a workaround for when uri encoding is not\n // sufficient to escape the # character properly.\n // The problem is that both the redirect and the application URL contain a hash.\n // The browser will consider anything after the first hash to be client-side. So\n // it sees the hash in the redirect param and stops.\n redirectUri += \"?referrer=\" + referrer + \"&referrer_uri=\" + referrerUri.replace('#', '_hash_');\n }\n\n return encodeURIComponent(redirectUri) + encodeURIComponent(\"/#\" + currentLocation); \n}"],"file":"RedirectUri.js"}
|
||||