diff --git a/client/app/components/alerts/AlertSubscriptions.jsx b/client/app/components/alerts/AlertSubscriptions.jsx new file mode 100644 index 0000000000..f7e522a141 --- /dev/null +++ b/client/app/components/alerts/AlertSubscriptions.jsx @@ -0,0 +1,154 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { react2angular } from 'react2angular'; +import Select from 'antd/lib/select'; +import { includes, without, compact } from 'lodash'; + +import Destination from './Destination'; + +class AlertSubscriptions extends React.Component { + static propTypes = { + alertId: PropTypes.number.isRequired, + } + constructor(props) { + super(props); + this.props.$q + .all([ + this.props.Destination.query().$promise, + this.props.AlertSubscription.query({ alertId: this.props.alertId }).$promise, + ]) + .then((responses) => { + let destinations = responses[0]; + const subscribers = responses[1]; + + const mapF = s => s.destination && s.destination.id; + const subscribedDestinations = compact(subscribers.map(mapF)); + + const subscribedUsers = compact(subscribers.map(s => !s.destination && s.user.id)); + + destinations = destinations.filter(d => !includes(subscribedDestinations, d.id)); + + if (!includes(subscribedUsers, this.props.currentUser.id)) { + destinations.unshift({ + name: this.props.currentUser.name + ' (Email)', + id: null, + icon: 'fa-envelope', + }); + } + this.setState({ + subscribers, + destinations, + }); + }); + } + + state = { + selection: null, + subscribers: [], + destinations: [], + } + + saveSubscriber = () => { + const sub = new this.props.AlertSubscription({ alert_id: this.props.alertId }); + if (this.state.selection) { + sub.destination_id = this.state.selection; + } + + sub.$save( + () => { + this.props.toastr.success('Subscribed.'); + const destinations = this.state.destinations.filter(d => d.id !== this.state.selection); + this.setState({ + subscribers: this.state.subscribers.concat(sub), + destinations, + selection: destinations.length ? destinations[0].id : null, + }); + }, + () => { + this.props.toastr.error('Failed saving subscription.'); + }, + ); + } + + unsubscribe = (subscriber) => { + const destination = subscriber.destination; + const user = subscriber.user; + + subscriber.$delete( + () => { + this.props.toastr.success('Unsubscribed'); + let destinations; + const subscribers = without(this.state.subscribers, subscriber); + if (destination) { + destinations = this.state.destinations.concat(destination); + } else if (user.id === this.props.currentUser.id) { + destinations = this.state.destinations.concat({ + id: null, + name: this.props.currentUser.name + ' (Email)', + icon: 'fa-envelope', + }); + } + const newState = { subscribers, destinations }; + if (destinations.length === 1) { + newState.selection = destinations[0].id; + } + this.setState(newState); + }, + () => { + this.props.toastr.error('Failed unsubscribing.'); + }, + ); + } + + updateSelection = selection => this.setState({ selection }) + + render() { + return ( +
+

Notifications

+
+ +
+
+ + + {this.props.currentUser.isAdmin ? Create New Destination : ''} + +
+
+
+ {this.state.subscribers.map(s => ( +
+ + {this.props.currentUser.isAdmin || + this.props.currentUser.id === s.user.id ? + : '' + } +
+ ))} +
+
+ ); + } +} + +export default function init(ngModule) { + ngModule.component('alertSubscriptions', react2angular(AlertSubscriptions, null, ['currentUser', '$q', 'Destination', 'AlertSubscription', 'toastr'])); +} +init.init = true; diff --git a/client/app/components/alerts/Destination.jsx b/client/app/components/alerts/Destination.jsx new file mode 100644 index 0000000000..38412a1f8b --- /dev/null +++ b/client/app/components/alerts/Destination.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +export default function Destination(props) { + let icon; + let name; + if (props.destination.destination) { + icon = props.destination.destination.icon; + name = props.destination.destination.name; + } else if (props.destination.user) { + name = `${props.destination.user.name} (Email)`; + icon = 'fa-envelope'; + } else { + name = props.destination.name; + icon = props.destination.icon; + } + return ( + +  {name} + + ); +} + +Destination.propTypes = { + destination: PropTypes.shape({ + destination: PropTypes.shape({ + icon: PropTypes.string, + name: PropTypes.string, + }), + user: PropTypes.shape({ + name: PropTypes.string, + }), + }).isRequired, +}; diff --git a/client/app/components/alerts/alert-subscriptions/alert-subscriptions.html b/client/app/components/alerts/alert-subscriptions/alert-subscriptions.html deleted file mode 100644 index 4d3d0a246e..0000000000 --- a/client/app/components/alerts/alert-subscriptions/alert-subscriptions.html +++ /dev/null @@ -1,27 +0,0 @@ -
-

Notifications

- -
- - - - - - -
-
- - - Create New Destination - -
- -
- -
-
- - -
-
-
diff --git a/client/app/components/alerts/alert-subscriptions/index.js b/client/app/components/alerts/alert-subscriptions/index.js deleted file mode 100644 index e0dc5793e4..0000000000 --- a/client/app/components/alerts/alert-subscriptions/index.js +++ /dev/null @@ -1,116 +0,0 @@ -import { includes, without, compact } from 'lodash'; -import template from './alert-subscriptions.html'; - -function controller($scope, $q, $sce, currentUser, AlertSubscription, Destination, toastr) { - 'ngInject'; - - $scope.newSubscription = {}; - $scope.subscribers = []; - $scope.destinations = []; - $scope.currentUser = currentUser; - - $q - .all([ - Destination.query().$promise, - AlertSubscription.query({ alertId: $scope.alertId }).$promise, - ]) - .then((responses) => { - const destinations = responses[0]; - const subscribers = responses[1]; - - const mapF = s => s.destination && s.destination.id; - const subscribedDestinations = compact(subscribers.map(mapF)); - - const subscribedUsers = compact(subscribers.map(s => !s.destination && s.user.id)); - - $scope.destinations = destinations.filter(d => !includes(subscribedDestinations, d.id)); - - if (!includes(subscribedUsers, currentUser.id)) { - $scope.destinations.unshift({ user: { name: currentUser.name } }); - } - - $scope.newSubscription.destination = $scope.destinations[0]; - $scope.subscribers = subscribers; - }); - - $scope.destinationsDisplay = (d) => { - if (!d) { - return ''; - } - - let destination = d; - if (d.destination) { - destination = destination.destination; - } else if (destination.user) { - destination = { - name: `${d.user.name} (Email)`, - icon: 'fa-envelope', - type: 'user', - }; - } - - return $sce.trustAsHtml(` ${destination.name}`); - }; - - $scope.saveSubscriber = () => { - const sub = new AlertSubscription({ alert_id: $scope.alertId }); - if ($scope.newSubscription.destination.id) { - sub.destination_id = $scope.newSubscription.destination.id; - } - - sub.$save( - () => { - toastr.success('Subscribed.'); - $scope.subscribers.push(sub); - $scope.destinations = without($scope.destinations, $scope.newSubscription.destination); - if ($scope.destinations.length > 0) { - $scope.newSubscription.destination = $scope.destinations[0]; - } else { - $scope.newSubscription.destination = undefined; - } - }, - () => { - toastr.error('Failed saving subscription.'); - }, - ); - }; - - $scope.unsubscribe = (subscriber) => { - const destination = subscriber.destination; - const user = subscriber.user; - - subscriber.$delete( - () => { - toastr.success('Unsubscribed'); - $scope.subscribers = without($scope.subscribers, subscriber); - if (destination) { - $scope.destinations.push(destination); - } else if (user.id === currentUser.id) { - $scope.destinations.push({ user: { name: currentUser.name } }); - } - - if ($scope.destinations.length === 1) { - $scope.newSubscription.destination = $scope.destinations[0]; - } - }, - () => { - toastr.error('Failed unsubscribing.'); - }, - ); - }; -} - -export default function init(ngModule) { - ngModule.directive('alertSubscriptions', () => ({ - restrict: 'E', - replace: true, - scope: { - alertId: '=', - }, - template, - controller, - })); -} - -init.init = true; -