Revision db8b1228
Added by Daniel Lobato Garcia over 7 years ago
app/models/notification_blueprint.rb | ||
---|---|---|
class NotificationBlueprint < ActiveRecord::Base
|
||
has_many :notifications
|
||
belongs_to :subject, :polymorphic => true
|
||
store :actions, :accessors => [:links], :coder => JSON
|
||
|
||
validates :message, :presence => true
|
||
validates :group, :presence => true
|
app/models/notification_recipient.rb | ||
---|---|---|
:subject => notification_blueprint.subject,
|
||
:created_at => notification.created_at,
|
||
:group => notification_blueprint.group,
|
||
:actions => notification_blueprint.actions
|
||
}
|
||
end
|
||
|
db/migrate/20170209084517_add_actions_to_notification_blueprint.rb | ||
---|---|---|
class AddActionsToNotificationBlueprint < ActiveRecord::Migration
|
||
def change
|
||
add_column :notification_blueprints, :actions, :text
|
||
end
|
||
end
|
webpack/assets/javascripts/react_app/components/notifications/Notification.js | ||
---|---|---|
import React from 'react';
|
||
import Icon from '../common/Icon';
|
||
import moment from 'moment';
|
||
import NotificationDropdown from './NotificationDropdown';
|
||
import NotificationActions from '../../actions/NotificationActions';
|
||
import '../../common/commonStyles.css';
|
||
|
||
/* eslint-disable camelcase */
|
||
const Notification = ({created_at, seen, text, level, id}) => {
|
||
const Notification = ({created_at, seen, text, level, id, actions}) => {
|
||
const created = moment(created_at);
|
||
const title = __('Click to mark as read').toString();
|
||
const tooltip = {
|
||
... | ... | |
return (
|
||
<div className="drawer-pf-notification">
|
||
<Icon type={level} css="pull-left"></Icon>
|
||
{actions.links && <NotificationDropdown links={actions.links} id={id} />}
|
||
{markup}
|
||
<div className="drawer-pf-notification-info">
|
||
<span className="date">{created.format('M/D/YY')}</span>
|
webpack/assets/javascripts/react_app/components/notifications/Notification.test.js | ||
---|---|---|
id: 1,
|
||
text: 'Job well done',
|
||
level: 'success',
|
||
created_at: '2016-12-13 16:52:47Z'
|
||
created_at: '2016-12-13 16:52:47Z',
|
||
actions: {
|
||
'links': [
|
||
{
|
||
'href': 'https://theforeman.org',
|
||
'title': 'Foreman blog'
|
||
}
|
||
]
|
||
}
|
||
};
|
||
/* eslint-enable camelcase */
|
||
|
||
... | ... | |
}
|
||
|
||
describe('Notification', () => {
|
||
let wrapper;
|
||
|
||
beforeEach(() => {
|
||
global.__ = (text) => text;
|
||
global.tfm = {
|
||
... | ... | |
activateTooltips: () => {}
|
||
}
|
||
};
|
||
wrapper = setup(notification);
|
||
});
|
||
|
||
it('displays text', () => {
|
||
const wrapper = setup(notification);
|
||
const messageElement = wrapper.find('.drawer-pf-notification-message');
|
||
|
||
expect(messageElement.text()).toBe('Job well done');
|
||
});
|
||
it('displays icon', () => {
|
||
const wrapper = setup(notification);
|
||
const iconElement = wrapper.find('.pficon.pficon-ok.pull-left');
|
||
|
||
expect(iconElement.length).toBe(1);
|
||
|
||
});
|
||
it('displays created date', () => {
|
||
const wrapper = setup(notification);
|
||
const dateElement = wrapper.find('.date');
|
||
|
||
expect(dateElement.text()).toBe('12/13/16');
|
||
});
|
||
it('display actions dropdown if links are provided', () => {
|
||
const dropdownMenu = wrapper.find('a');
|
||
|
||
expect(dropdownMenu.props().href).toBe('https://theforeman.org');
|
||
expect(dropdownMenu.text()).toBe('Foreman blog');
|
||
});
|
||
it('does not display actions dropdown if links are NOT provided', () => {
|
||
let notificationWithoutAction = notification;
|
||
|
||
delete notificationWithoutAction.actions.links;
|
||
const dropdownMenu = setup(notificationWithoutAction).find('a');
|
||
|
||
expect(dropdownMenu.node).not.toBeDefined();
|
||
});
|
||
xit('displays created time', () => {
|
||
const wrapper = setup(notification);
|
||
const timeElement = wrapper.find('.time');
|
||
|
||
expect(timeElement.text()).toBe('06:52:47 PM');
|
webpack/assets/javascripts/react_app/components/notifications/NotificationDropdown.js | ||
---|---|---|
import React from 'react';
|
||
import { Dropdown, Glyphicon, MenuItem } from 'react-bootstrap';
|
||
|
||
const NotificationDropdown = ({ links, id }) => {
|
||
const listLinks = links.map((link, i) => {
|
||
const liKey = `notification-link-${i}-${id}`;
|
||
|
||
return (
|
||
<MenuItem key={liKey} id={liKey} target="_blank" href={link.href}>
|
||
{link.title}
|
||
</MenuItem>
|
||
);
|
||
});
|
||
|
||
return (
|
||
<Dropdown className="pull-right dropdown-kebab-pf" pullRight key={id}
|
||
id={`notifications-dropdown-${id}`}>
|
||
<Dropdown.Toggle noCaret bsStyle="link">
|
||
<Glyphicon bsClass="fa" glyph="ellipsis-v" />
|
||
</Dropdown.Toggle>
|
||
<Dropdown.Menu>
|
||
{listLinks}
|
||
</Dropdown.Menu>
|
||
</Dropdown>
|
||
);
|
||
};
|
||
|
||
export default NotificationDropdown;
|
Also available in: Unified diff
Fixes #18426 - Add actions to notification entries
This adds support for the notifications to display actions. In case no
actions are provided, the dropdown kebab isn't shown. The actions
possible right now only include GET links.