Add support for targeting notifications to organizations and remove the password_required notification for new orbs
This commit is contained in:
parent
578add3b9e
commit
525ef8d14f
8 changed files with 61 additions and 16 deletions
|
@ -278,7 +278,7 @@ class NotificationKind(BaseModel):
|
||||||
class Notification(BaseModel):
|
class Notification(BaseModel):
|
||||||
uuid = CharField(default=uuid_generator, index=True)
|
uuid = CharField(default=uuid_generator, index=True)
|
||||||
kind = ForeignKeyField(NotificationKind, index=True)
|
kind = ForeignKeyField(NotificationKind, index=True)
|
||||||
notification_user = ForeignKeyField(User, index=True)
|
target = ForeignKeyField(User, index=True)
|
||||||
metadata_json = TextField(default='{}')
|
metadata_json = TextField(default='{}')
|
||||||
created = DateTimeField(default=datetime.now, index=True)
|
created = DateTimeField(default=datetime.now, index=True)
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ class InvalidBuildTriggerException(DataModelException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_user(username, password, email):
|
def create_user(username, password, email, is_organization=False):
|
||||||
if not validate_email(email):
|
if not validate_email(email):
|
||||||
raise InvalidEmailAddressException('Invalid email address: %s' % email)
|
raise InvalidEmailAddressException('Invalid email address: %s' % email)
|
||||||
if not validate_username(username):
|
if not validate_username(username):
|
||||||
|
@ -96,7 +96,7 @@ def create_user(username, password, email):
|
||||||
|
|
||||||
# If the password is None, then add a notification for the user to change
|
# If the password is None, then add a notification for the user to change
|
||||||
# their password ASAP.
|
# their password ASAP.
|
||||||
if not pw_hash:
|
if not pw_hash and not is_organization:
|
||||||
create_notification('password_required', new_user)
|
create_notification('password_required', new_user)
|
||||||
|
|
||||||
return new_user
|
return new_user
|
||||||
|
@ -107,7 +107,7 @@ def create_user(username, password, email):
|
||||||
def create_organization(name, email, creating_user):
|
def create_organization(name, email, creating_user):
|
||||||
try:
|
try:
|
||||||
# Create the org
|
# Create the org
|
||||||
new_org = create_user(name, None, email)
|
new_org = create_user(name, None, email, is_organization=True)
|
||||||
new_org.organization = True
|
new_org.organization = True
|
||||||
new_org.save()
|
new_org.save()
|
||||||
|
|
||||||
|
@ -1546,24 +1546,44 @@ def list_trigger_builds(namespace_name, repository_name, trigger_uuid,
|
||||||
.where(RepositoryBuildTrigger.uuid == trigger_uuid))
|
.where(RepositoryBuildTrigger.uuid == trigger_uuid))
|
||||||
|
|
||||||
|
|
||||||
def create_notification(kind, user, metadata={}):
|
def create_notification(kind, target, metadata={}):
|
||||||
kind_ref = NotificationKind.get(name=kind)
|
kind_ref = NotificationKind.get(name=kind)
|
||||||
notification = Notification.create(kind=kind_ref, notification_user=user,
|
notification = Notification.create(kind=kind_ref, target=target,
|
||||||
metadata_json=json.dumps(metadata))
|
metadata_json=json.dumps(metadata))
|
||||||
return notification
|
return notification
|
||||||
|
|
||||||
|
|
||||||
def list_notifications(user, kind=None):
|
def list_notifications(user, kind=None):
|
||||||
|
Org = User.alias()
|
||||||
|
AdminTeam = Team.alias()
|
||||||
|
AdminTeamMember = TeamMember.alias()
|
||||||
|
AdminUser = User.alias()
|
||||||
|
|
||||||
query = (Notification.select()
|
query = (Notification.select()
|
||||||
.join(User)
|
.join(User)
|
||||||
.where(Notification.notification_user == user))
|
|
||||||
|
.switch(Notification)
|
||||||
|
.join(Org, JOIN_LEFT_OUTER, on=(Org.id == Notification.target))
|
||||||
|
.join(AdminTeam, JOIN_LEFT_OUTER, on=(Org.id ==
|
||||||
|
AdminTeam.organization))
|
||||||
|
.join(TeamRole, JOIN_LEFT_OUTER, on=(AdminTeam.role == TeamRole.id))
|
||||||
|
.switch(AdminTeam)
|
||||||
|
.join(AdminTeamMember, JOIN_LEFT_OUTER, on=(AdminTeam.id ==
|
||||||
|
AdminTeamMember.team))
|
||||||
|
.join(AdminUser, JOIN_LEFT_OUTER, on=(AdminTeamMember.user ==
|
||||||
|
AdminUser.id)))
|
||||||
|
|
||||||
|
where_clause = ((Notification.target == user) |
|
||||||
|
((AdminUser.id == user) &
|
||||||
|
(TeamRole.name == 'admin')))
|
||||||
|
|
||||||
if kind:
|
if kind:
|
||||||
query = query.join(NotificationKind).where(NotificationKind.name == kind)
|
where_clause = where_clause & (NotificationKind.name == kind)
|
||||||
|
|
||||||
return query.order_by(Notification.created).desc()
|
return query.where(where_clause).order_by(Notification.created).desc()
|
||||||
|
|
||||||
|
|
||||||
def delete_notifications_by_kind(user, kind):
|
def delete_notifications_by_kind(target, kind):
|
||||||
kind_ref = NotificationKind.get(name=kind)
|
kind_ref = NotificationKind.get(name=kind)
|
||||||
Notification.delete().where(Notification.notification_user == user, Notification.kind == kind_ref).execute()
|
Notification.delete().where(Notification.target == target,
|
||||||
|
Notification.kind == kind_ref).execute()
|
||||||
|
|
|
@ -2521,6 +2521,7 @@ def get_logs(namespace, start_time, end_time, performer_name=None,
|
||||||
|
|
||||||
def notification_view(notification):
|
def notification_view(notification):
|
||||||
return {
|
return {
|
||||||
|
'organization': notification.target.username if notification.target.organization else None,
|
||||||
'kind': notification.kind.name,
|
'kind': notification.kind.name,
|
||||||
'created': notification.created,
|
'created': notification.created,
|
||||||
'metadata': json.loads(notification.metadata_json),
|
'metadata': json.loads(notification.metadata_json),
|
||||||
|
|
|
@ -18,6 +18,16 @@
|
||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-view-element .orginfo {
|
||||||
|
margin-top: 8px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-view-element .orginfo .orgname {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
.notification-view-element .circle {
|
.notification-view-element .circle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 14px;
|
top: 14px;
|
||||||
|
@ -30,12 +40,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification-view-element .datetime {
|
.notification-view-element .datetime {
|
||||||
margin-top: 10px;
|
margin-top: 16px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-view-element .message {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.notification-view-element .container {
|
.notification-view-element .container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
ng-class="notificationService.notificationClasses"
|
ng-class="notificationService.notificationClasses"
|
||||||
bs-tooltip=""
|
bs-tooltip=""
|
||||||
title="{{ notificationService.notificationSummaries }}"
|
title="{{ notificationService.notificationSummaries }}"
|
||||||
|
data-html="true"
|
||||||
data-placement="left"
|
data-placement="left"
|
||||||
data-container="body">
|
data-container="body">
|
||||||
{{ notificationService.notifications.length }}
|
{{ notificationService.notifications.length }}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<div class="notification-view-element">
|
<div class="notification-view-element">
|
||||||
<div class="container" ng-click="showNotification();">
|
<div class="container" ng-click="showNotification();">
|
||||||
<div class="message">{{ getMessage(notification) }}</div>
|
|
||||||
<div class="datetime">{{ parseDate(notification.created) | date:'medium'}}</div>
|
|
||||||
<div class="circle" ng-class="getClass(notification)"></div>
|
<div class="circle" ng-class="getClass(notification)"></div>
|
||||||
|
<div class="message">{{ getMessage(notification) }}</div>
|
||||||
|
<div class="orginfo" ng-if="notification.organization">
|
||||||
|
<img src="//www.gravatar.com/avatar/{{ getGravatar(notification.organization) }}?s=24&d=identicon" />
|
||||||
|
<span class="orgname">{{ notification.organization }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="datetime">{{ parseDate(notification.created) | date:'medium'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3356,11 +3356,16 @@ quayApp.directive('notificationView', function () {
|
||||||
'notification': '=notification',
|
'notification': '=notification',
|
||||||
'parent': '=parent'
|
'parent': '=parent'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $location, NotificationService) {
|
controller: function($scope, $element, $location, UserService, NotificationService) {
|
||||||
$scope.getMessage = function(notification) {
|
$scope.getMessage = function(notification) {
|
||||||
return NotificationService.getMessage(notification);
|
return NotificationService.getMessage(notification);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.getGravatar = function(orgname) {
|
||||||
|
var organization = UserService.getOrganization(orgname);
|
||||||
|
return organization['gravatar'] || '';
|
||||||
|
};
|
||||||
|
|
||||||
$scope.parseDate = function(dateString) {
|
$scope.parseDate = function(dateString) {
|
||||||
return Date.parse(dateString);
|
return Date.parse(dateString);
|
||||||
};
|
};
|
||||||
|
|
Binary file not shown.
Reference in a new issue