Subscription
This module allows a user to subscribe to a resource. This module does not include reading an events stream of changes to subscribed resources. Provided are the following: - A subscription directive that is configurable by resource and ID. It is sensitive to the logged-in state and the current ID, and will resolve its subscription state accordingly. - A service which allows a user to read and write their subscriptions. - Subscription UI added to various resource list items. Depends on https://review.openstack.org/108516 Change-Id: I2e9181e93209ce519f0a5eeb61630b1724a2527c
This commit is contained in:
parent
8667bada77
commit
3921f6bb80
|
@ -14,6 +14,9 @@
|
|||
<story-status-label story="story"/>
|
||||
</td>
|
||||
<td>
|
||||
<subscribe class="pull-right"
|
||||
resource="story"
|
||||
resource-id="story.id"></subscribe>
|
||||
<p>
|
||||
<a href="#!/story/{{story.id}}">
|
||||
{{story.title}}
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
</i>
|
||||
</a>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ng-if="searchResults.length != 0">
|
||||
|
|
|
@ -20,4 +20,9 @@
|
|||
class="text-muted">
|
||||
Not updated
|
||||
</em>
|
||||
</td>
|
||||
</td>
|
||||
<td>
|
||||
<subscribe class="pull-right"
|
||||
resource="project"
|
||||
resource-id="project.id"></subscribe>
|
||||
</td>
|
||||
|
|
|
@ -17,4 +17,9 @@
|
|||
</td>
|
||||
<td class="text-right col-xs-1">
|
||||
<story-status-label story="story"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<subscribe class="pull-right"
|
||||
resource="story"
|
||||
resource-id="story.id"></subscribe>
|
||||
</td>
|
|
@ -5,11 +5,6 @@
|
|||
/>
|
||||
</td>
|
||||
<td>
|
||||
<task-status-dropdown
|
||||
editable="false"
|
||||
status="{{task.status}}"
|
||||
class="pull-right"
|
||||
></task-status-dropdown>
|
||||
{{task.title}}
|
||||
<br/>
|
||||
<small class="text-muted"
|
||||
|
@ -17,4 +12,16 @@
|
|||
<a href="#!/story/{{story.id}}">
|
||||
{{story.id}}: {{story.title}}</a>
|
||||
</small>
|
||||
</td>
|
||||
</td>
|
||||
<td>
|
||||
<task-status-dropdown
|
||||
editable="false"
|
||||
status="{{task.status}}"
|
||||
></task-status-dropdown>
|
||||
</td>
|
||||
<td>
|
||||
<subscribe class="pull-right"
|
||||
resource="story"
|
||||
resource-id="story.id"></subscribe>
|
||||
</td>
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The angular resource for resource subscriptions.
|
||||
*
|
||||
* @see storyboardApiSignature
|
||||
*/
|
||||
angular.module('sb.services').factory('Subscription',
|
||||
function (ResourceFactory) {
|
||||
'use strict';
|
||||
|
||||
return ResourceFactory.build(
|
||||
'/subscriptions/:id',
|
||||
'/subscriptions/search',
|
||||
{id: '@id'}
|
||||
);
|
||||
});
|
|
@ -124,6 +124,7 @@
|
|||
</i>
|
||||
</a>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ng-if="searchResults.length != 0">
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<subscribe resource="story"
|
||||
resource-id="story.id"></subscribe>
|
||||
<strong>
|
||||
<a href="#!/story/{{story.id}}">
|
||||
{{story.title}}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
angular.module('storyboard',
|
||||
[ 'sb.services', 'sb.templates', 'sb.dashboard', 'sb.pages', 'sb.projects',
|
||||
'sb.auth', 'sb.story', 'sb.profile', 'sb.notification', 'sb.search',
|
||||
'sb.admin', 'ui.router', 'ui.bootstrap', 'monospaced.elastic',
|
||||
'angularMoment'])
|
||||
'sb.admin', 'sb.subscription', 'ui.router', 'ui.bootstrap',
|
||||
'monospaced.elastic', 'angularMoment'])
|
||||
.constant('angularMomentConfig', {
|
||||
preprocess: 'utc',
|
||||
timezone: 'UTC'
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A directive which checks, enables, and disables subscriptions by resource.
|
||||
*
|
||||
* @author Michael Krotscheck
|
||||
*/
|
||||
angular.module('sb.util').directive('subscribe',
|
||||
function (CurrentUser, Notification, Priority, SessionState, Session,
|
||||
Subscription) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
resource: '@',
|
||||
resourceId: '='
|
||||
},
|
||||
templateUrl: 'app/subscription/template/subscribe.html',
|
||||
link: function ($scope) {
|
||||
|
||||
/**
|
||||
* When we start, create a promise for the current user.
|
||||
*/
|
||||
var cuPromise = CurrentUser.resolve();
|
||||
|
||||
/**
|
||||
* Is this control currently enabled?
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
$scope.enabled = Session.isLoggedIn();
|
||||
|
||||
/**
|
||||
* Is this user subscribed to this resource?
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
$scope.subscribed = false;
|
||||
|
||||
/**
|
||||
* Is the control currently trying to resolve the user's
|
||||
* subscription?
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
$scope.resolving = false;
|
||||
|
||||
/**
|
||||
* The loaded subscription resource
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
$scope.subscription = null;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @param currentUser
|
||||
*/
|
||||
$scope.currentUser = null;
|
||||
cuPromise.then(function (user) {
|
||||
$scope.currentUser = user;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set or clear the subscription.
|
||||
*/
|
||||
function setSubscription(subscription) {
|
||||
$scope.subscription = subscription || null;
|
||||
$scope.subscribed = !!$scope.subscription;
|
||||
}
|
||||
|
||||
// Subscribe to login/logout events for enable/disable/resolve.
|
||||
var removeNotifier = Notification.intercept(function (message) {
|
||||
switch (message.type) {
|
||||
case SessionState.LOGGED_IN:
|
||||
$scope.enabled = true;
|
||||
resolveSubscription();
|
||||
break;
|
||||
case SessionState.LOGGED_OUT:
|
||||
$scope.enabled = false;
|
||||
$scope.subscribed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}, Priority.LAST);
|
||||
|
||||
// Remove the notifier when this scope is destroyed.
|
||||
$scope.$on('$destroy', removeNotifier);
|
||||
|
||||
/**
|
||||
* Resolve whether the current user already has a subscription
|
||||
* to this resource.
|
||||
*/
|
||||
function resolveSubscription() {
|
||||
|
||||
if (!Session.isLoggedIn()) {
|
||||
setSubscription();
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.resolving = true;
|
||||
|
||||
cuPromise.then(
|
||||
function (user) {
|
||||
Subscription.query({
|
||||
user_id: user.id,
|
||||
target_type: $scope.resource,
|
||||
target_id: $scope.resourceId
|
||||
},
|
||||
function (results) {
|
||||
setSubscription(results[0]);
|
||||
$scope.resolving = false;
|
||||
},
|
||||
function () {
|
||||
setSubscription();
|
||||
$scope.resolving = false;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the user clicks on this control, activate/deactivate the
|
||||
* subscription.
|
||||
*/
|
||||
$scope.toggleSubscribe = function () {
|
||||
if ($scope.resolving) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.resolving = true;
|
||||
|
||||
if (!!$scope.subscription) {
|
||||
$scope.subscription.$delete(function () {
|
||||
setSubscription();
|
||||
$scope.resolving = false;
|
||||
}, function () {
|
||||
$scope.resolving = false;
|
||||
});
|
||||
} else {
|
||||
|
||||
cuPromise.then(
|
||||
function (user) {
|
||||
var sub = new Subscription({
|
||||
user_id: user.id,
|
||||
target_type: $scope.resource,
|
||||
target_id: $scope.resourceId
|
||||
});
|
||||
sub.$create(function (result) {
|
||||
setSubscription(result);
|
||||
$scope.resolving = false;
|
||||
}, function () {
|
||||
$scope.resolving = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// On initialization, resolve.
|
||||
resolveSubscription();
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The StoryBoard subscription module. Adds directives and services necessary
|
||||
* for a user to subscribe to resource changes in storyboard.
|
||||
*
|
||||
* @author Michael Krotscheck
|
||||
*/
|
||||
angular.module('sb.subscription', ['sb.notification']);
|
|
@ -0,0 +1,20 @@
|
|||
<span ng-if="!enabled && !resolving"
|
||||
class="text-muted">
|
||||
<i ng-if="subscribed"
|
||||
class="fa fa-star"></i>
|
||||
<i ng-if="!subscribed"
|
||||
class="fa fa-star-o"></i>
|
||||
</span>
|
||||
<span ng-if="resolving"
|
||||
class="text-muted">
|
||||
<i class="fa fa-spin fa-refresh"></i>
|
||||
</span>
|
||||
<a ng-if="enabled && !resolving"
|
||||
href=""
|
||||
title="Subscribe"
|
||||
ng-click="toggleSubscribe()">
|
||||
<i ng-if="subscribed"
|
||||
class="fa fa-star"></i>
|
||||
<i ng-if="!subscribed"
|
||||
class="fa fa-star-o"></i>
|
||||
</a>
|
Loading…
Reference in New Issue