Skip to content

Commit

Permalink
EPMRPP-97554 || Notifications (#4141)
Browse files Browse the repository at this point in the history
* EPMRPP-97554 || Notifications

* EPMRPP-97554 || code review fix

* EPMRPP-97554 || lib upgrade

* EPMRPP-97554 || lib upgrade

* EPMRPP-97554 || crf - 2
  • Loading branch information
maria-hambardzumian authored Dec 23, 2024
1 parent dead1d4 commit c1437ab
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 271 deletions.
8 changes: 4 additions & 4 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@formatjs/intl-pluralrules": "1.3.9",
"@formatjs/intl-relativetimeformat": "4.5.1",
"@formatjs/intl-utils": "1.6.0",
"@reportportal/ui-kit": "^0.0.1-alpha.26",
"@reportportal/ui-kit": "^0.0.1-alpha.38",
"axios": "1.6.4",
"c3": "0.7.20",
"chart.js": "2.9.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,132 @@ import { CSSTransition, TransitionGroup } from 'react-transition-group';
import classNames from 'classnames/bind';
import { connect } from 'react-redux';
import { hideNotification } from 'controllers/notification';
import { NotificationItem } from './notificationListItem';
import { SystemAlert } from '@reportportal/ui-kit';
import Parser from 'html-react-parser';
import DOMPurify from 'dompurify';
import { defineMessages, injectIntl } from 'react-intl';
import styles from './notificationList.scss';

const cx = classNames.bind(styles);

const messages = defineMessages({
successLogin: { id: 'NotificationItem.successLogin', defaultMessage: 'Signed in successfully' },
failureDefault: {
id: 'NotificationItem.failureDefault',
defaultMessage: 'An error occurred while connecting to server: {error}',
},
infoLogout: { id: 'NotificationItem.infoLogout', defaultMessage: 'You have been logged out' },
assignSuccess: {
id: 'ProjectsPage.assignSuccess',
defaultMessage: 'You have been assigned to the project',
},
assignError: {
id: 'ProjectsPage.assignError',
defaultMessage: 'An error occurred during assigning to the project',
},
unassignSuccess: {
id: 'ProjectsPage.unassignSuccess',
defaultMessage: 'You have been unassigned from the project',
},
unassignError: {
id: 'ProjectsPage.unassignError',
defaultMessage: 'An error occurred during unassigning from the project',
},
deleteError: {
id: 'ProjectsPage.deleteError',
defaultMessage: 'An error occurred during deleting the project',
},
addDefectTypeSuccess: {
id: 'Project.addDefectTypeSuccess',
defaultMessage: 'Defect Type has been successfully created',
},
updateDefectTypeSuccess: {
id: 'Project.updateDefectTypeSuccess',
defaultMessage: 'Defect Type has been successfully updated',
},
deleteDefectTypeSuccess: {
id: 'Project.deleteDefectTypeSuccess',
defaultMessage: 'Defect Type has been deleted successfully',
},
updateProjectNotificationsConfigurationSuccess: {
id: 'NotificationsTab.updateProjectNotificationsConfigurationSuccess',
defaultMessage: 'Notification settings were successfully updated!',
},
addProjectSuccess: {
id: 'ProjectsPage.addProjectSuccess',
defaultMessage: "The project ''{name}'' was successfully created",
},
projectExists: {
id: 'ProjectsPage.projectExists',
defaultMessage: "The project ''{name}'' is already exists",
},
resetToGlobalSuccess: {
id: 'InstancesSection.resetToGlobalSuccess',
defaultMessage: 'Global integrations successfully applied',
},
addIntegrationSuccess: {
id: 'InstancesSection.addIntegrationSuccess',
defaultMessage: 'Integration successfully added',
},
removePluginSuccess: {
id: 'InstancesSection.removePluginSuccess',
defaultMessage: 'Plugin has been uninstalled successfully',
},
updateIntegrationSuccess: {
id: 'IntegrationSettingsContainer.updateIntegrationSuccess',
defaultMessage: 'Integration successfully updated',
},
removeIntegrationSuccess: {
id: 'ConnectionSection.removeIntegrationSuccess',
defaultMessage: 'Integration successfully deleted',
},
addDashboardSuccess: {
id: 'DashboardPage.addDashboardSuccess',
defaultMessage: 'Dashboard has been added',
},
deleteDashboardSuccess: {
id: 'DashboardPage.deleteDashboardSuccess',
defaultMessage: 'Dashboard has been deleted',
},
addPatternSuccess: {
id: 'PatternAnalysis.addPatternSuccess',
defaultMessage: 'Pattern rule has been created',
},
updatePatternSuccess: {
id: 'PatternAnalysis.updatePatternSuccess',
defaultMessage: 'Pattern rule updated successfully',
},
deletePatternSuccess: {
id: 'PatternAnalysis.deletePatternSuccess',
defaultMessage: 'Pattern rule deleted successfully',
},
updatePAStateSuccess: {
id: 'PatternAnalysis.updatePAStateSuccess',
defaultMessage: 'Pattern analysis settings were successfully updated',
},
saveFilterSuccess: {
id: 'LaunchFiltersToolbar.saveFilterSuccess',
defaultMessage: 'Filter has been saved',
},
updateFilterSuccess: {
id: 'LaunchFiltersToolbar.updateFilterSuccess',
defaultMessage: 'Filter has been updated',
},
deleteTestItemSuccess: {
id: 'TestItemsPage.success',
defaultMessage: 'Item was deleted',
},
deleteTestItemMultipleSuccess: {
id: 'TestItemsPage.successMultiple',
defaultMessage: 'Items were deleted',
},
fetchApiKeysError: {
id: 'ProfilePage.apiKeys.fetchApiKeysError',
defaultMessage: 'An error occurred during fetch API keys',
},
});

@injectIntl
@connect(
(state) => ({
notifications: state.notifications,
Expand All @@ -37,15 +158,28 @@ export class NotificationList extends PureComponent {
static propTypes = {
notifications: PropTypes.arrayOf(PropTypes.object).isRequired,
hideNotification: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};

render() {
const { formatMessage } = this.props.intl;
return (
<div className={cx('notification-list')} data-automation-id="notificationsContainer">
<TransitionGroup>
{this.props.notifications.map((m) => (
<CSSTransition key={m.uid} timeout={500} classNames="notification-transition">
<NotificationItem {...m} onMessageClick={this.props.hideNotification} />
{this.props.notifications.map(({ uid, type, messageId, values, message }) => (
<CSSTransition key={uid} timeout={1000} classNames="notification-transition">
<div className={cx('notification-item-wrapper')}>
<SystemAlert
type={type}
title={Parser(
DOMPurify.sanitize(
messageId ? formatMessage(messages[messageId], values) : message,
),
)}
onClose={() => this.props.hideNotification(uid)}
className={cx('notification-item')}
/>
</div>
</CSSTransition>
))}
</TransitionGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,53 @@

.notification-list {
position: fixed;
bottom: 0;
left: 0;
right: 0;
bottom: 48px;
left: 50%;
opacity: 0.8;
max-width: 600px;
transform: translateX(-50%);
}

.notification-item-wrapper {
margin-top: 16px;
overflow: hidden;
opacity: 0;
max-height: 0;
min-height: 0;
}

:global {
.notification-transition-enter {
opacity: 0.01;
height: 0;
max-height: 0;
min-height: 0;
}

.notification-transition-enter-done {
opacity: 1;
transform: translateY(0);
max-height: 80px;
min-height: 56px;
}

.notification-transition-enter-active {
opacity: 1;
height: 36px;
max-height: 80px;
min-height: 56px;
transition: all 200ms ease-in;
}

.notification-transition-exit {
opacity: 1;
height: 36px;
max-height: 80px;
min-height: 56px;
}

.notification-transition-exit-active {
opacity: 0.01;
height: 0;
transform: translateY(20px);
transition: all 700ms ease-in;
max-height: 0;
min-height: 0;
}
}

This file was deleted.

Loading

0 comments on commit c1437ab

Please sign in to comment.