KEYCLOAK-10205: Alerts and Notifications
This commit is contained in:
parent
a050e70389
commit
38933fdfed
6 changed files with 115 additions and 10 deletions
|
@ -18,6 +18,7 @@
|
||||||
//import {KeycloakNotificationService} from '../notification/keycloak-notification.service';
|
//import {KeycloakNotificationService} from '../notification/keycloak-notification.service';
|
||||||
import {KeycloakService} from '../keycloak-service/keycloak.service';
|
import {KeycloakService} from '../keycloak-service/keycloak.service';
|
||||||
import Axios, {AxiosRequestConfig, AxiosResponse} from 'axios';
|
import Axios, {AxiosRequestConfig, AxiosResponse} from 'axios';
|
||||||
|
import {ContentAlert} from '../content/ContentAlert';
|
||||||
|
|
||||||
//import {NotificationType} from 'patternfly-ng/notification';*/
|
//import {NotificationType} from 'patternfly-ng/notification';*/
|
||||||
|
|
||||||
|
@ -86,6 +87,7 @@ export class AccountServiceClient {
|
||||||
|
|
||||||
private handleError(error: Error): void {
|
private handleError(error: Error): void {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
ContentAlert.danger(error.name + ': ' + error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeConfig(endpoint: string, config: AxiosRequestConfig = {}): Promise<AxiosRequestConfig> {
|
private makeConfig(endpoint: string, config: AxiosRequestConfig = {}): Promise<AxiosRequestConfig> {
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* 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 'react';
|
||||||
|
import {Alert, AlertActionCloseButton} from '@patternfly/react-core';
|
||||||
|
import {Msg} from '../widgets/Msg';
|
||||||
|
|
||||||
|
interface ContentAlertProps {}
|
||||||
|
|
||||||
|
type AlertVariant = 'success' | 'danger' | 'warning' | 'info';
|
||||||
|
interface ContentAlertState {
|
||||||
|
isVisible: boolean;
|
||||||
|
message: string;
|
||||||
|
variant: AlertVariant;
|
||||||
|
}
|
||||||
|
export class ContentAlert extends React.Component<ContentAlertProps, ContentAlertState> {
|
||||||
|
private static instance: ContentAlert;
|
||||||
|
|
||||||
|
private constructor(props: ContentAlertProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {isVisible: false, message: '', variant: 'success'};
|
||||||
|
ContentAlert.instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message A literal text message or localization key.
|
||||||
|
*/
|
||||||
|
public static success(message: string) {
|
||||||
|
ContentAlert.instance.postAlert(message, 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message A literal text message or localization key.
|
||||||
|
*/
|
||||||
|
public static danger(message: string) {
|
||||||
|
ContentAlert.instance.postAlert(message, 'danger');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message A literal text message or localization key.
|
||||||
|
*/
|
||||||
|
public static warning(message: string) {
|
||||||
|
ContentAlert.instance.postAlert(message, 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message A literal text message or localization key.
|
||||||
|
*/
|
||||||
|
public static info(message: string) {
|
||||||
|
ContentAlert.instance.postAlert(message, 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
private hideAlert = () => {
|
||||||
|
this.setState({isVisible: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
private postAlert = (message: string, variant: AlertVariant) => {
|
||||||
|
this.setState({isVisible: true,
|
||||||
|
message: Msg.localize(message),
|
||||||
|
variant});
|
||||||
|
|
||||||
|
if (variant !== 'danger') {
|
||||||
|
setTimeout(() => this.setState({isVisible: false}), 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactNode {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{ this.state.isVisible &&
|
||||||
|
<section className="pf-c-page__main-section pf-m-light">
|
||||||
|
<Alert
|
||||||
|
title=''
|
||||||
|
variant={this.state.variant}
|
||||||
|
variantLabel=''
|
||||||
|
aria-label=''
|
||||||
|
action={<AlertActionCloseButton onClose={this.hideAlert} />}
|
||||||
|
>
|
||||||
|
{this.state.message}
|
||||||
|
</Alert>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Msg} from '../widgets/Msg';
|
import {Msg} from '../widgets/Msg';
|
||||||
|
import {ContentAlert} from './ContentAlert';
|
||||||
|
|
||||||
interface ContentPageProps {
|
interface ContentPageProps {
|
||||||
title: string; // Literal title or key into message bundle
|
title: string; // Literal title or key into message bundle
|
||||||
|
@ -35,6 +36,7 @@ export class ContentPage extends React.Component<ContentPageProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
<ContentAlert/>
|
||||||
<section className="pf-c-page__main-section pf-m-light">
|
<section className="pf-c-page__main-section pf-m-light">
|
||||||
<div className="pf-c-content">
|
<div className="pf-c-content">
|
||||||
<h1><Msg msgKey={this.props.title}/></h1>
|
<h1><Msg msgKey={this.props.title}/></h1>
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {AccountServiceClient} from '../../account-service/account.service';
|
||||||
import {Features} from '../../widgets/features';
|
import {Features} from '../../widgets/features';
|
||||||
import {Msg} from '../../widgets/Msg';
|
import {Msg} from '../../widgets/Msg';
|
||||||
import {ContentPage} from '../ContentPage';
|
import {ContentPage} from '../ContentPage';
|
||||||
|
import {ContentAlert} from '../ContentAlert';
|
||||||
|
|
||||||
declare const features: Features;
|
declare const features: Features;
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ export class AccountPage extends React.Component<AccountPageProps, AccountPageSt
|
||||||
AccountServiceClient.Instance.doPost("/", {data: reqData})
|
AccountServiceClient.Instance.doPost("/", {data: reqData})
|
||||||
.then((response: AxiosResponse<FormFields>) => {
|
.then((response: AxiosResponse<FormFields>) => {
|
||||||
this.setState({canSubmit: false});
|
this.setState({canSubmit: false});
|
||||||
alert('Data posted:' + response.statusText);
|
ContentAlert.success('accountUpdatedMessage');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
map: {
|
map: {
|
||||||
'./Accordion': '@empty', //'./Accordion/index.js,
|
'./Accordion': '@empty', //'./Accordion/index.js,
|
||||||
'./ActionGroup': './ActionGroup/index.js',
|
'./ActionGroup': './ActionGroup/index.js',
|
||||||
'./Alert': '@empty', //'./Alert/index.js',
|
'./Alert': './Alert/index.js',
|
||||||
'./AboutModal': '@empty', //'./AboutModal/index.js',
|
'./AboutModal': '@empty', //'./AboutModal/index.js',
|
||||||
'./ApplicationLauncher': '@empty', //'./ApplicationLauncher/index.js',
|
'./ApplicationLauncher': '@empty', //'./ApplicationLauncher/index.js',
|
||||||
'./Avatar': './Avatar/index.js',
|
'./Avatar': './Avatar/index.js',
|
||||||
|
@ -154,7 +154,7 @@
|
||||||
'./Gallery': '@empty', //'./Gallery/index.js',
|
'./Gallery': '@empty', //'./Gallery/index.js',
|
||||||
'./Level': '@empty', //'./Level/index.js',
|
'./Level': '@empty', //'./Level/index.js',
|
||||||
'./Grid': '@empty', //'./Grid/index.js',
|
'./Grid': '@empty', //'./Grid/index.js',
|
||||||
'./Stack': '@empty', //'./Stack/index.js',
|
'./Stack': './Stack/index.js',
|
||||||
'./Split': '@empty', //'./Split/index.js',
|
'./Split': '@empty', //'./Split/index.js',
|
||||||
'./Toolbar': './Toolbar/index.js',
|
'./Toolbar': './Toolbar/index.js',
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@
|
||||||
'./icons/chart-line-icon.js': '@empty',
|
'./icons/chart-line-icon.js': '@empty',
|
||||||
'./icons/chart-pie-icon.js': '@empty',
|
'./icons/chart-pie-icon.js': '@empty',
|
||||||
'./icons/check-icon.js': '@empty',
|
'./icons/check-icon.js': '@empty',
|
||||||
'./icons/check-circle-icon.js': '@empty',
|
//'./icons/check-circle-icon.js': '@empty',
|
||||||
'./icons/check-double-icon.js': '@empty',
|
'./icons/check-double-icon.js': '@empty',
|
||||||
'./icons/check-square-icon.js': '@empty',
|
'./icons/check-square-icon.js': '@empty',
|
||||||
'./icons/cheese-icon.js': '@empty',
|
'./icons/cheese-icon.js': '@empty',
|
||||||
|
@ -466,8 +466,8 @@
|
||||||
'./icons/euro-sign-icon.js': '@empty',
|
'./icons/euro-sign-icon.js': '@empty',
|
||||||
'./icons/exchange-alt-icon.js': '@empty',
|
'./icons/exchange-alt-icon.js': '@empty',
|
||||||
'./icons/exclamation-icon.js': '@empty',
|
'./icons/exclamation-icon.js': '@empty',
|
||||||
'./icons/exclamation-circle-icon.js': '@empty',
|
//'./icons/exclamation-circle-icon.js': '@empty',
|
||||||
'./icons/exclamation-triangle-icon.js': '@empty',
|
//'./icons/exclamation-triangle-icon.js': '@empty',
|
||||||
'./icons/expand-icon.js': '@empty',
|
'./icons/expand-icon.js': '@empty',
|
||||||
'./icons/expand-arrows-alt-icon.js': '@empty',
|
'./icons/expand-arrows-alt-icon.js': '@empty',
|
||||||
'./icons/external-link-alt-icon.js': '@empty',
|
'./icons/external-link-alt-icon.js': '@empty',
|
||||||
|
@ -647,7 +647,7 @@
|
||||||
'./icons/industry-icon.js': '@empty',
|
'./icons/industry-icon.js': '@empty',
|
||||||
'./icons/infinity-icon.js': '@empty',
|
'./icons/infinity-icon.js': '@empty',
|
||||||
'./icons/info-icon.js': '@empty',
|
'./icons/info-icon.js': '@empty',
|
||||||
'./icons/info-circle-icon.js': '@empty',
|
//'./icons/info-circle-icon.js': '@empty',
|
||||||
'./icons/italic-icon.js': '@empty',
|
'./icons/italic-icon.js': '@empty',
|
||||||
'./icons/jedi-icon.js': '@empty',
|
'./icons/jedi-icon.js': '@empty',
|
||||||
'./icons/joint-icon.js': '@empty',
|
'./icons/joint-icon.js': '@empty',
|
||||||
|
@ -1004,7 +1004,7 @@
|
||||||
'./icons/thumbs-up-icon.js': '@empty',
|
'./icons/thumbs-up-icon.js': '@empty',
|
||||||
'./icons/thumbtack-icon.js': '@empty',
|
'./icons/thumbtack-icon.js': '@empty',
|
||||||
'./icons/ticket-alt-icon.js': '@empty',
|
'./icons/ticket-alt-icon.js': '@empty',
|
||||||
'./icons/times-icon.js': '@empty',
|
//'./icons/times-icon.js': '@empty',
|
||||||
'./icons/times-circle-icon.js': '@empty',
|
'./icons/times-circle-icon.js': '@empty',
|
||||||
'./icons/tint-icon.js': '@empty',
|
'./icons/tint-icon.js': '@empty',
|
||||||
'./icons/tint-slash-icon.js': '@empty',
|
'./icons/tint-slash-icon.js': '@empty',
|
||||||
|
|
Loading…
Reference in a new issue