Fixed Keycloak v19 themes incompatibility issues with Keycloak v16 themes

This commit is contained in:
Vincenzo Cestone 2022-09-28 18:56:07 +02:00
parent e17cf835ba
commit 905bec8ead
11 changed files with 120 additions and 108 deletions

View File

@ -3,7 +3,7 @@
"id": "personal-info",
"path": "personal-info",
"icon": "pf-icon-user",
"label": "personalInfoHtmlTitle",
"label": "personalInfoSidebarTitle",
"descriptionLabel": "personalInfoIntroMessage",
"content" : [
{
@ -25,27 +25,27 @@
{
"id": "security",
"icon": "pf-icon-security",
"label": "Account Security",
"label": "accountSecuritySidebarTitle",
"descriptionLabel": "accountSecurityIntroMessage",
"content": [
{
"id": "signingin",
"path": "security/signingin",
"label": "signingIn",
"label": "signingInSidebarTitle",
"modulePath": "/content/signingin-page/SigningInPage.js",
"componentName": "SigningInPage"
},
{
"id": "device-activity",
"path": "security/device-activity",
"label": "device-activity",
"label": "deviceActivitySidebarTitle",
"modulePath": "/content/device-activity-page/DeviceActivityPage.js",
"componentName": "DeviceActivityPage"
},
{
"id": "linked-accounts",
"path": "security/linked-accounts",
"label": "linkedAccountsHtmlTitle",
"label": "linkedAccountsSidebarTitle",
"modulePath": "/content/linked-accounts-page/LinkedAccountsPage.js",
"componentName": "LinkedAccountsPage",
"hidden": "!features.isLinkedAccountsEnabled"
@ -61,6 +61,16 @@
"modulePath": "/content/applications-page/ApplicationsPage.js",
"componentName": "ApplicationsPage"
},
{
"id": "groups",
"path": "groups",
"icon": "pf-icon-server-group",
"label": "groupLabel",
"descriptionLabel": "groupDescriptionLabel",
"modulePath": "/content/group-page/GroupsPage.js",
"componentName": "GroupsPage",
"hidden": "!features.isViewGroupsEnabled"
},
{
"id": "resources",
"icon": "pf-icon-repository",

View File

@ -1,7 +1,7 @@
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 { Button, Grid, GridItem, Expandable, Modal } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
import { PageSection, PageSectionVariants, Button, Grid, GridItem, ExpandableSection, Modal } 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";
@ -38,62 +38,66 @@ export class AccountExtraPage extends React.Component {
render() {
const accountUrl = this.context["accountUrl"];
return React.createElement(ContentPage, {
return /*#__PURE__*/React.createElement(ContentPage, {
title: "accountExtraInfoHtmlTitle",
introMessage: "accountExtraSubMessage"
}, React.createElement(AvatarForm, {
}, /*#__PURE__*/React.createElement(PageSection, {
isFilled: true,
variant: PageSectionVariants.light
}, /*#__PURE__*/React.createElement(AvatarForm, {
accountUrl: accountUrl
}), React.createElement("div", {
}), /*#__PURE__*/React.createElement("div", {
id: "delete-account",
style: {
marginTop: "30px"
}
}, React.createElement(Expandable, {
toggleText: Msg.localize('deleteAccount')
}, React.createElement(Grid, {
gutter: "sm"
}, React.createElement(GridItem, {
}, /*#__PURE__*/React.createElement(ExpandableSection, {
toggleText: Msg.localize('deleteAccount'),
displaySize: "large"
}, /*#__PURE__*/React.createElement(Grid, {
hasGutter: true
}, /*#__PURE__*/React.createElement(GridItem, {
span: 8
}, React.createElement("p", {
}, /*#__PURE__*/React.createElement("p", {
dangerouslySetInnerHTML: {
__html: Msg.localize('deleteAccountInfoMessage')
}
})), React.createElement(GridItem, {
})), /*#__PURE__*/React.createElement(GridItem, {
span: 4
}, React.createElement(Button, {
}, /*#__PURE__*/React.createElement(Button, {
id: "delete-account-btn",
variant: "danger",
onClick: e => this.handleModalToggle(true),
className: "delete-button"
}, React.createElement(Msg, {
}, /*#__PURE__*/React.createElement(Msg, {
msgKey: "doDelete"
}))))), React.createElement(Modal, {
}))))), /*#__PURE__*/React.createElement(Modal, {
width: '50%',
title: Msg.localize('deleteAccountDialogHeader'),
isOpen: this.state.isModalOpen,
onClose: () => this.handleModalToggle(false),
actions: [React.createElement(Button, {
actions: [/*#__PURE__*/React.createElement(Button, {
key: "confirm",
variant: "danger",
onClick: this.modalConfirmDelete
}, React.createElement(Msg, {
}, /*#__PURE__*/React.createElement(Msg, {
msgKey: "doDeleteConfirm"
})), React.createElement(Button, {
})), /*#__PURE__*/React.createElement(Button, {
key: "cancel",
variant: "secondary",
onClick: e => this.handleModalToggle(false)
}, React.createElement(Msg, {
}, /*#__PURE__*/React.createElement(Msg, {
msgKey: "doCancel"
}))]
}, React.createElement("div", {
}, /*#__PURE__*/React.createElement("div", {
dangerouslySetInnerHTML: {
__html: Msg.localize('deleteAccountWarningMessage')
}
}), React.createElement("div", {
}), /*#__PURE__*/React.createElement("div", {
dangerouslySetInnerHTML: {
__html: Msg.localize('deleteAccountConfirmMessage')
}
}))));
})))));
}
}

View File

@ -141,49 +141,48 @@ export class AvatarForm extends React.Component {
border: '1px solid lightgray',
boxShadow: 'lightgray 6px 3px 10px 2px'
};
return React.createElement(Form, {
return /*#__PURE__*/React.createElement(Form, {
id: "avatarForm",
method: "post",
isHorizontal: true,
action: avatarUrl,
encType: "multipart/form-data",
onSubmit: event => this.handleSubmit(event)
}, React.createElement(FormGroup, {
}, /*#__PURE__*/React.createElement(FormGroup, {
label: Msg.localize('avatarLabel'),
fieldId: "avatar-current-or-preview",
helperTextInvalid: this.state.errors.avatar,
isValid: this.state.errors.avatar === ''
}, avatarSrc !== "" ? React.createElement(Avatar, {
validated: this.state.errors.avatar === '' ? 'success' : 'error'
}, avatarSrc !== "" ? /*#__PURE__*/React.createElement(Avatar, {
src: avatarSrc,
style: avatarStyle,
alt: "Avatar image preview",
onError: this.handleError
}) : React.createElement(Avatar, {
}) : /*#__PURE__*/React.createElement(Avatar, {
src: noAvatarSrc,
style: avatarStyle,
alt: "No avatar found"
})), React.createElement(FormGroup, {
})), /*#__PURE__*/React.createElement(FormGroup, {
fieldId: "avatar-upload",
label: React.createElement("span", null, React.createElement(Msg, {
label: /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Msg, {
msgKey: "uploadLabel"
}), ' ', React.createElement(Tooltip, {
content: React.createElement(Msg, {
}), ' ', /*#__PURE__*/React.createElement(Tooltip, {
content: /*#__PURE__*/React.createElement(Msg, {
msgKey: "avatarInfo"
})
}, React.createElement(OutlinedQuestionCircleIcon, null)))
}, React.createElement(FileUpload, {
}, /*#__PURE__*/React.createElement(OutlinedQuestionCircleIcon, null)))
}, /*#__PURE__*/React.createElement(FileUpload, {
id: "simple-file",
filename: filename,
filenamePlaceholder: Msg.localize('dragdropInfo'),
browseButtonText: Msg.localize('browseButton'),
clearButtonText: Msg.localize('clearButton'),
onChange: this.handleFileInputChange
})), React.createElement(ActionGroup, null, React.createElement(Button, {
})), /*#__PURE__*/React.createElement(ActionGroup, null, /*#__PURE__*/React.createElement(Button, {
id: "save-btn",
type: "submit",
variant: "primary",
isDisabled: filename === ""
}, React.createElement(Msg, {
}, /*#__PURE__*/React.createElement(Msg, {
msgKey: "doSave"
}))));
}

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { Button, Grid, GridItem, Expandable, Modal, Form } from '@patternfly/react-core';
import { PageSection, PageSectionVariants,Button, Grid, GridItem, ExpandableSection, Modal } from '@patternfly/react-core';
import { AccountServiceContext } from '../../account-service/AccountServiceContext';
import { Msg } from '../../widgets/Msg';
import { ContentPage } from '../ContentPage';
@ -45,42 +45,44 @@ export class AccountExtraPage extends React.Component<AccountExtraPageProps, Acc
<ContentPage title="accountExtraInfoHtmlTitle"
introMessage="accountExtraSubMessage"
>
<AvatarForm accountUrl={accountUrl} />
<PageSection isFilled variant={PageSectionVariants.light}>
<AvatarForm accountUrl={accountUrl} />
<div id="delete-account" style={{marginTop:"30px"}}>
<Expandable toggleText={Msg.localize('deleteAccount')}>
<Grid gutter={"sm"}>
<GridItem span={8}>
<p dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountInfoMessage')}} />
</GridItem>
<GridItem span={4}>
<Button id="delete-account-btn" variant="danger"
onClick={(e) => this.handleModalToggle(true)} className="delete-button"
>
<Msg msgKey="doDelete" />
<div id="delete-account" style={{marginTop:"30px"}}>
<ExpandableSection toggleText={Msg.localize('deleteAccount')} displaySize="large">
<Grid hasGutter>
<GridItem span={8}>
<p dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountInfoMessage')}} />
</GridItem>
<GridItem span={4}>
<Button id="delete-account-btn" variant="danger"
onClick={(e) => this.handleModalToggle(true)} className="delete-button"
>
<Msg msgKey="doDelete" />
</Button>
</GridItem>
</Grid>
</ExpandableSection>
<Modal
width={'50%'}
title={Msg.localize('deleteAccountDialogHeader')}
isOpen={this.state.isModalOpen}
onClose={() => this.handleModalToggle(false)}
actions={[
<Button key="confirm" variant="danger" onClick={this.modalConfirmDelete}>
<Msg msgKey="doDeleteConfirm" />
</Button>,
<Button key="cancel" variant="secondary" onClick={(e) => this.handleModalToggle(false)}>
<Msg msgKey="doCancel" />
</Button>
</GridItem>
</Grid>
</Expandable>
<Modal
width={'50%'}
title={Msg.localize('deleteAccountDialogHeader')}
isOpen={this.state.isModalOpen}
onClose={() => this.handleModalToggle(false)}
actions={[
<Button key="confirm" variant="danger" onClick={this.modalConfirmDelete}>
<Msg msgKey="doDeleteConfirm" />
</Button>,
<Button key="cancel" variant="secondary" onClick={(e) => this.handleModalToggle(false)}>
<Msg msgKey="doCancel" />
</Button>
]}
>
<div dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountWarningMessage')}} />
<div dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountConfirmMessage')}} />
</Modal>
</div>
]}
>
<div dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountWarningMessage')}} />
<div dangerouslySetInnerHTML={{ __html: Msg.localize('deleteAccountConfirmMessage')}} />
</Modal>
</div>
</PageSection>
</ContentPage>
)

View File

@ -139,14 +139,14 @@ export class AvatarForm extends React.Component<AvatarFormProps, AvatarFormState
boxShadow: 'lightgray 6px 3px 10px 2px'
}
return (
<Form id="avatarForm" method="post" isHorizontal
<Form id="avatarForm" method="post"
action={avatarUrl} encType="multipart/form-data"
onSubmit={event => this.handleSubmit(event)}
>
<FormGroup label={Msg.localize('avatarLabel')}
fieldId="avatar-current-or-preview"
helperTextInvalid={this.state.errors.avatar}
isValid={this.state.errors.avatar === ''}
validated={this.state.errors.avatar === '' ? 'success' : 'error'}
>
{ avatarSrc !== ""
? <Avatar src={avatarSrc} style={avatarStyle} alt="Avatar image preview" onError={this.handleError}/>

View File

@ -1,19 +1,13 @@
# This theme will inherit everything from its parent unless
# it is overridden in the current theme.
parent=keycloak.v2
# Look at the styles.css file to see examples of using PatternFly's CSS variables
# for modifying look and feel.
styles=css/styles.css
# This is the logo in upper lefthand corner.
# It must be a relative path.
logo=/public/d4science-logo.png
# This is the link followed when clicking on the logo.
# It can be any valid URL, including an external site.
logoUrl=./
logoUrl=https://www.d4science.org/
# This is the icon for the account console.
# It must be a relative path.
favIcon=/public/favicon.ico
favIcon=/public/favicon.ico

View File

@ -26,23 +26,25 @@
</div>
</div>
</#if>
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="email" name="email" value="${(user.email!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
/>
<#if user.editEmailAllowed>
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="email" name="email" value="${(user.email!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
/>
<#if messagesPerField.existsError('email')>
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('email'))?no_esc}
</span>
</#if>
<#if messagesPerField.existsError('email')>
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('email'))?no_esc}
</span>
</#if>
</div>
</div>
</div>
</#if>
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">

View File

@ -1,6 +1,6 @@
<#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false displayWide=false>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" class="${properties.kcHtmlClass!}">
<!DOCTYPE html>
<html class="${properties.kcHtmlClass!}">
<head>
<meta charset="utf-8">
@ -47,6 +47,7 @@
class="${properties.kcHeaderWrapperClass!}">${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}</div>
</div>
-->
<div style="${properties.headerReplacementStyle!}"></div>
<div class="${properties.kcFormCardClass!} <#if displayWide>${properties.kcFormCardWideClass!}</#if>">
<!-- D4Science logos header inside formCard -->
@ -114,7 +115,7 @@
<#nested "show-username">
<div id="kc-username" class="${properties.kcFormGroupClass!}">
<label id="kc-attempted-username">${auth.attemptedUsername}</label>
<a id="reset-login" href="${url.loginRestartFlowUrl}">
<a id="reset-login" href="${url.loginRestartFlowUrl}" aria-label="${msg("restartLoginTooltip")}">
<div class="kc-login-tooltip">
<i class="${properties.kcResetFlowIcon!}"></i>
<span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>
@ -127,7 +128,7 @@
<#nested "show-username">
<div id="kc-username" class="${properties.kcFormGroupClass!}">
<label id="kc-attempted-username">${auth.attemptedUsername}</label>
<a id="reset-login" href="${url.loginRestartFlowUrl}">
<a id="reset-login" href="${url.loginRestartFlowUrl}" aria-label="${msg("restartLoginTooltip")}">
<div class="kc-login-tooltip">
<i class="${properties.kcResetFlowIcon!}"></i>
<span class="kc-tooltip-text">${msg("restartLoginTooltip")}</span>

View File

@ -1,14 +1,14 @@
parent=keycloak
import=common/keycloak
#styles=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css lib/zocial/zocial.css css/d4science.css
styles=css/login.css css/tile.css css/d4science.css
styles=css/login.css css/d4science.css
#stylesCommon=web_modules/@patternfly/react-core/dist/styles/base.css web_modules/@patternfly/react-core/dist/styles/app.css node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css lib/pficon/pficon.css
#titleTag=
#favicon=https://services.d4science.org/favicon.ico
contentBgImg=img/color-triangles.png
#contentStyle=background: url("https://url-of-background-img");
headerReplacementStyle=height: 0;
logoHeaderStyle=display: flex; justify-content: space-between; width: 100%;