Basic fixes and cleanups

- Fix vue-notification-bell client dependency installation
- Fix linting issues
- Refactor rename some variables and types
This commit is contained in:
davelopez
2023-05-26 18:04:03 +02:00
parent 5650bd75fd
commit b670c3692d
14 changed files with 139 additions and 131 deletions
+1
View File
@@ -99,6 +99,7 @@
"vue": "^2.7.14",
"vue-infinite-scroll": "^2.0.2",
"vue-multiselect": "^2.1.7",
"vue-notification-bell": "^0.9.12",
"vue-observe-visibility": "^1.0.0",
"vue-prismjs": "^1.2.0",
"vue-router": "^3.6.5",
@@ -1,24 +1,20 @@
<template>
<div v-on:click="printNotifications()">
<div @click="printNotifications()">
<b-nav-item> <notification-bell icon-color="white" :count="count" :size="20"> </notification-bell> </b-nav-item>
</div>
</template>
<script>
import axios from "axios";
import { BNav, BNavItemDropdown, BNavItem } from "bootstrap-vue";
import { BNavItem } from "bootstrap-vue";
import { getGalaxyInstance } from "app";
import LoadingSpan from "components/LoadingSpan";
import NotificationBell from "vue-notification-bell";
import { errorMessageAsString } from "utils/simple-error";
export default {
components: {
LoadingSpan,
NotificationBell,
BNavItem,
BNavItemDropdown,
BNav,
},
data() {
const Galaxy = getGalaxyInstance();
@@ -29,9 +25,6 @@ export default {
showNotifications: false,
};
},
created() {
this.loadNotifications();
},
computed: {
loading() {
return this.notifications == null;
@@ -40,6 +33,9 @@ export default {
return this.notifications ? this.notifications.length : 0;
},
},
created() {
this.loadNotifications();
},
methods: {
loadNotifications() {
setInterval(() => {
@@ -3,15 +3,15 @@
<h3>Pending notifications</h3>
<!-- <notification-bell @click="loadNotifications()"> Notification Bell</notification-bell> -->
<!-- <button v-on:click="loadNotifications()"> Notification Bell</button> -->
<b-alert variant="error" v-if="errorMessage" show> </b-alert>
<b-alert v-if="errorMessage" variant="error" show> </b-alert>
<loading-span v-if="loading" message="Loading notifications" />
<ul v-else id="notifications">
<li v-for="notification in notifications" v-bind:key="notification.id">
<li v-for="notification in notifications" :key="notification.id">
<span>
<div class="ui success message">
<i class="close icon"></i>
<div class="header">
{{ notification.message_text }}
{{ notification.message }}
</div>
</div>
</span>
@@ -20,7 +20,7 @@
<h3>Create new notification</h3>
<p>Notification Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" @keyup.enter="putNotification($event)" />
<button v-on:click="putNotification(message)">Create Message</button>
<button @click="putNotification(message)">Create Message</button>
</div>
</template>
@@ -32,7 +32,7 @@ import { errorMessageAsString } from "utils/simple-error";
export default {
components: {
LoadingSpan
LoadingSpan,
},
data() {
const Galaxy = getGalaxyInstance();
@@ -43,14 +43,14 @@ export default {
message: "",
};
},
created() {
this.loadNotifications();
},
computed: {
loading() {
return this.notifications == null;
},
},
created() {
this.loadNotifications();
},
methods: {
loadNotifications() {
axios
@@ -61,7 +61,7 @@ export default {
.catch(this.handleError);
},
putNotification(message) {
const payload = { message_text: message };
const payload = { message };
axios
.post(this.notificationsUrl, payload)
.then((response) => {
@@ -1 +0,0 @@
// export { default as Notifications } from "./List.vue";
-1
View File
@@ -234,7 +234,6 @@ export function fetchMenu(options = {}) {
{
title: _l("Notifications"),
url: "/notifications",
target: "__use_router__",
},
],
};
+23 -2
View File
@@ -7876,9 +7876,9 @@ lodash.uniqby@4.5.0:
lodash._baseiteratee "~4.7.0"
lodash._baseuniq "~4.6.0"
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@latest:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lower-case@^2.0.2:
@@ -8488,6 +8488,11 @@ obuf@^1.0.0, obuf@^1.1.2:
resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
odometer@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/odometer/-/odometer-0.4.8.tgz#2f6703bf4c6b384c278236d04d4bc8171abe4374"
integrity sha512-bfKuAhWE/qMCiX9bwX90c5bTpt7MDVeq1e6YsOHQrYokNhv9jhS5JbR9kg6i+FeWmDgalf3VUtwNx1aVaZ8cgg==
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
@@ -11192,11 +11197,27 @@ vue-multiselect@^2.1.7:
resolved "https://registry.yarnpkg.com/vue-multiselect/-/vue-multiselect-2.1.7.tgz#f27afe3d46482b94810382af7a4826219255c47d"
integrity sha512-KIegcN+Ntwg3cbkY/jhw2s/+XJUM0Lpi/LcKFYCS8PrZHcWBl2iKCVze7ZCnRj3w8H7/lUJ9v7rj9KQiNxApBw==
vue-notification-bell@^0.9.12:
version "0.9.12"
resolved "https://registry.yarnpkg.com/vue-notification-bell/-/vue-notification-bell-0.9.12.tgz#f0098c16a8e4405dd506467da08c22079b3a836e"
integrity sha512-5HyYg0hpeJRRAax6vslfF/yA3qt5soUxnNozhbWIvwlSntv99HM7zSD5a9gWJ5wKYpgpXm/svf0GfxIBkw8jXw==
dependencies:
odometer "^0.4.8"
vue "^2.6.10"
vue-odometer "^1.0.2"
vue-observe-visibility@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/vue-observe-visibility/-/vue-observe-visibility-1.0.0.tgz"
integrity sha512-s5TFh3s3h3Mhd3jaz3zGzkVHKHnc/0C/gNr30olO99+yw2hl3WBhK3ng3/f9OF+qkW4+l7GkmwfAzDAcY3lCFg==
vue-odometer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/vue-odometer/-/vue-odometer-1.0.2.tgz#ccd43c4a6edae2c432959ea4bd63ece2cfe01a34"
integrity sha512-xQj1kdRrQDGhjZ9nb66I6wykR9lG5yvy74PLBpTHw7raGqahBgZOCvPWvC4nol8B8bJQeFWmpCBUidVjtouyng==
dependencies:
lodash latest
vue-prismjs@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/vue-prismjs/-/vue-prismjs-1.2.0.tgz"
+9 -10
View File
@@ -2,7 +2,6 @@ from typing import (
List,
Optional,
)
from xmlrpc.client import boolean
from sqlalchemy import false
@@ -18,7 +17,7 @@ class NotificationManager:
def __init__(self, sa_session: galaxy_scoped_session):
self.sa_session = sa_session
def index(self, limit: int = 10, offset: int = 0, user: Optional[model.User] = None):
def index(self, limit: Optional[int] = None, offset: Optional[int] = None, user: Optional[model.User] = None):
"""
Displays a collection (list) of notifications.
"""
@@ -32,11 +31,11 @@ class NotificationManager:
rval.append(notification)
return rval
def create(self, message_text: str):
def create(self, content: str):
"""
Creates a new notification.
"""
notification = model.Notification(message_text=message_text)
notification = model.Notification(content=content)
self.sa_session.add(notification)
self.sa_session.flush()
return notification
@@ -50,27 +49,27 @@ class NotificationManager:
raise ObjectNotFound(f"Notification with id {notification_id} was not found.")
return notification
def update(self, notification_id, updated_message: str):
def update(self, notification_id, updated_content: str):
"""
Modifies a notification.
"""
notification = self.sa_session.query(model.Notification).get(notification_id)
if notification is None:
raise ObjectNotFound(f"Notification with id {notification_id} was not found.")
notification.message_text = updated_message
notification.content = updated_content
self.sa_session.add(notification)
self.sa_session.flush()
return notification
def update_status(self, user_id, notification_id, status_seen: boolean):
def update_status(self, user_id, notification_id, seen: bool):
"""
Modifies a notification status.
"""
user = self.sa_session.query(model.User).get(user_id)
# user = self.sa_session.query(model.User).get(user_id)
notification = self.sa_session.query(model.Notification).get(notification_id)
if notification is None:
raise ObjectNotFound(f"Notification with id {notification_id} was not found.")
notification.status_seen = status_seen
notification.seen = seen
self.sa_session.add(notification)
self.sa_session.flush()
return notification
@@ -85,4 +84,4 @@ class NotificationManager:
assoc_ids.append(assoc.id)
self.sa_session.add(assoc)
self.sa_session.flush()
return assoc_ids
return assoc_ids
+6 -11
View File
@@ -2706,20 +2706,17 @@ class UserGroupAssociation(Base, RepresentById):
class Notification(Base, Dictifiable, RepresentById):
__tablename__ = "notification_push"
__tablename__ = "notification"
id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
message_text = Column(String, index=True)
content = Column(String(512), index=True)
deleted = Column(Boolean, index=True, default=False)
user_notification_associations = relationship("UserNotificationAssociation", back_populates="notification")
dict_collection_visible_keys = ["id", "message_text"]
dict_element_visible_keys = ["id", "message_text"]
def __init__(self, message_text=None):
self.message_text = message_text
def __init__(self, content):
self.content = content
self.deleted = False
@@ -2728,16 +2725,14 @@ class UserNotificationAssociation(Base, RepresentById):
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("galaxy_user.id"), index=True)
notification_id = Column(Integer, ForeignKey("notification_push.id"), index=True)
notification_id = Column(Integer, ForeignKey("notification.id"), index=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
seen = Column(Boolean, index=True, default=False)
user = relationship("User", back_populates="all_notifications")
notification = relationship("Notification", back_populates="user_notification_associations")
status_seen = Column(Boolean, index=True, default=False)
def __init__(self, user, notification):
self.user_id = user.id
self.notification_id = notification.id
self.user = user
self.notification = notification
@@ -897,7 +897,7 @@ def page_rating_association_factory():
@pytest.fixture
def notification() -> model.Notification:
new_notification = model.Notification(message_text="new_message")
new_notification = model.Notification(content="new_content")
return new_notification
@@ -936,7 +936,7 @@ def stored_workflow_tag_association_factory():
@pytest.fixture
def user_notification_association() -> model.UserNotificationAssociation:
user = model.User(email="test" + "@test.com", password="abcde", username="notification_user")
new_notification = model.Notification(message_text="new_message")
new_notification = model.Notification(content="new_content")
una = model.UserNotificationAssociation(user, new_notification)
return una
+3 -3
View File
@@ -3269,7 +3269,7 @@ class PageSummaryBase(Model):
class NotificationResponseModel(BaseModel):
id: EncodedDatabaseIdField
message_text: str
content: str
class Config:
orm_mode = True
@@ -3280,12 +3280,12 @@ class NotificationListResponseModel(BaseModel):
class NotificationCreateRequestModel(BaseModel):
message_text: str
content: str
user_ids: List[DecodedDatabaseIdField]
class NotificationUpdateRequestModel(BaseModel):
message_text: str
content: str
class MaterializeDatasetInstanceAPIRequest(Model):
+12 -14
View File
@@ -5,7 +5,7 @@ API operations on Notification objects.
import logging
from typing import Optional
from galaxy.managers.context import ProvidesAppContext
from galaxy.managers.context import ProvidesUserContext
from galaxy.managers.notification import NotificationManager
from galaxy.schema.fields import DecodedDatabaseIdField
from galaxy.schema.schema import (
@@ -33,8 +33,8 @@ class FastAPINotifications:
def index(
self,
limit: Optional[int] = 20,
offset: Optional[int] = 0,
trans: ProvidesAppContext = DependsOnTrans,
offset: Optional[int] = None,
trans: ProvidesUserContext = DependsOnTrans,
) -> NotificationListResponseModel:
return self.manager.index(limit=limit, offset=offset)
@@ -45,27 +45,25 @@ class FastAPINotifications:
def show(
self,
notification_id: DecodedDatabaseIdField,
trans: ProvidesAppContext = DependsOnTrans,
trans: ProvidesUserContext = DependsOnTrans,
) -> NotificationResponseModel:
return self.manager.show(notification_id)
@router.post("/api/notifications", summary="Create a notification message", require_admin=True)
@router.post("/api/notifications", summary="Create a notification", require_admin=True)
def create(
self,
payload: NotificationCreateRequestModel,
trans: ProvidesAppContext = DependsOnTrans,
trans: ProvidesUserContext = DependsOnTrans,
) -> NotificationResponseModel:
notification = self.manager.create(payload.message_text)
assoc_user_ids = self.manager.associate_user_notification(payload.user_ids, notification)
return notification, assoc_user_ids
notification = self.manager.create(payload.content)
self.manager.associate_user_notification(payload.user_ids, notification)
return notification
@router.put("/api/notifications/{notification_id}", summary="Updates a notificaton message")
@router.put("/api/notifications/{notification_id}", summary="Updates a notification")
def update(
self,
notification_id: DecodedDatabaseIdField,
payload: NotificationUpdateRequestModel,
trans: ProvidesAppContext = DependsOnTrans,
trans: ProvidesUserContext = DependsOnTrans,
) -> NotificationResponseModel:
return self.manager.update(notification_id, payload.message_text)
return self.manager.update(notification_id, payload.content)
+13 -13
View File
@@ -2,14 +2,14 @@ from galaxy_test.base.populators import DatasetPopulator
from ._framework import ApiTestCase
class NotificationsApiTestCase(ApiTestCase):
class TestNotificationsApi(ApiTestCase):
def setUp(self):
super().setUp()
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
def test_index(self):
encoded_user_id = self.dataset_populator.user_id()
create_notification_payload = {"message_text": "Test Message", "user_ids": [encoded_user_id]}
create_notification_payload = {"content": "Test Message", "user_ids": [encoded_user_id]}
notification_response = self._post("notifications", create_notification_payload, json=True, admin=True)
notification_response.raise_for_status()
notification_list_parameters = {"limit": 5, "offset": 0}
@@ -21,16 +21,16 @@ class NotificationsApiTestCase(ApiTestCase):
def test_create(self):
encoded_user_id = self.dataset_populator.user_id()
create_notification_payload = {"message_text": "Test Message", "user_ids": [encoded_user_id]}
create_notification_payload = {"content": "Test Message", "user_ids": [encoded_user_id]}
notification_response = self._post("notifications", create_notification_payload, json=True, admin=True)
notification_response.raise_for_status()
notification = notification_response.json()
assert notification["id"] is not None
assert notification["message_text"] == "Test Message"
assert notification["content"] == "Test Message"
def test_show(self):
encoded_user_id = self.dataset_populator.user_id()
create_notification_payload = {"message_text": "Test Message", "user_ids": [encoded_user_id]}
create_notification_payload = {"content": "Test Message", "user_ids": [encoded_user_id]}
notification_response = self._post("notifications", create_notification_payload, json=True, admin=True)
notification_response.raise_for_status()
notification = notification_response.json()
@@ -38,30 +38,30 @@ class NotificationsApiTestCase(ApiTestCase):
notification_response.raise_for_status()
notification = notification_response.json()
assert notification["id"] is not None
assert notification["message_text"] is not None
assert notification["content"] is not None
def test_update(self):
encoded_user_id = self.dataset_populator.user_id()
create_notification_payload = {"message_text": "Test Message", "user_ids": [encoded_user_id]}
create_notification_payload = {"content": "Test Message", "user_ids": [encoded_user_id]}
notification_response = self._post("notifications", create_notification_payload, json=True, admin=True)
notification_response.raise_for_status()
notification = notification_response.json()
create_update_payload = {"message_text": "New Message"}
create_update_payload = {"content": "New Message"}
notification_id = notification["id"]
notification_response = self._put(f"notifications/{notification_id}", create_update_payload, json=True)
notification_response.raise_for_status()
notification = notification_response.json()
assert notification["message_text"] == "New Message"
assert notification["content"] == "New Message"
# def test_update_status(self):
# encoded_user_id = self.dataset_populator.user_id()
# create_notification_payload = {"message_text": "Test Message", "user_ids": [encoded_user_id]}
# create_notification_payload = {"content": "Test Message", "user_ids": [encoded_user_id]}
# notification_response = self._post("notifications", create_notification_payload, json=True, admin=True)
# notification_response.raise_for_status()
# notification = notification_response.json()
# create_update_payload = {"status_seen": True}
# create_update_payload = {"seen": True}
# notification_id = notification["id"]
# notification_response = self._put(f"notifications/{notification_id}", create_update_payload, json=True)
# notification_response.raise_for_status()
# notification = notification_response.json()
# assert notification["message_text"] == "New Message"
# assert notification["content"] == "New Message"
@@ -0,0 +1,56 @@
import random
import pytest
from galaxy.managers.notification import NotificationManager
from galaxy.model import User
from galaxy.model.scoped_session import galaxy_scoped_session
from galaxy.model.unittest_utils import GalaxyDataTestApp
@pytest.fixture
def sa_session():
return GalaxyDataTestApp().model.session
@pytest.fixture
def notification_manager(sa_session: galaxy_scoped_session):
notification_manager = NotificationManager(sa_session)
return notification_manager
def test_update_notification(notification_manager: NotificationManager):
notification = notification_manager.create(content="New notification")
updated_content = "Updated notification"
notification_manager.update(notification.id, updated_content)
assert notification.content == updated_content
def create_user(sa_session: galaxy_scoped_session):
random_number = random.randint(0, 1000)
user = User(
email=f"test{random_number}@test.com",
password="abcde",
username=f"notification_user{random_number}",
)
sa_session.add(user)
sa_session.flush()
assert user.id is not None
return user
def test_create_notification(notification_manager: NotificationManager, sa_session: galaxy_scoped_session):
notification = notification_manager.create(content="New notification")
assert notification.id
assert notification.content == "New notification"
def test_associate_user_notification(notification_manager: NotificationManager, sa_session: galaxy_scoped_session):
user = create_user(sa_session)
notification = notification_manager.create(content="New notification")
notification_manager.associate_user_notification([user.id], notification)
assert len(user.all_notifications) == 1
assert len(notification.user_notification_associations) == 1
for association in notification.user_notification_associations:
assert association.user_id == user.id
assert association.notification_id == notification.id
-56
View File
@@ -1,56 +0,0 @@
import random
import pytest
from galaxy.managers.notification import NotificationManager
from galaxy.model import User
from galaxy.model.scoped_session import galaxy_scoped_session
from galaxy.model.unittest_utils import GalaxyDataTestApp
@pytest.fixture
def sa_session():
random.seed(43)
app = GalaxyDataTestApp()
return app.model.session
def create_notification_mananger(sa_session: galaxy_scoped_session):
notificationManager = NotificationManager(sa_session)
return notificationManager
def test_update_notification(sa_session: galaxy_scoped_session):
notificationManager = create_notification_mananger(sa_session)
notification = notificationManager.create(message_text="New notification")
updated_message = "Updated notification"
notificationManager.update(notification.id, updated_message)
assert notification.message_text == updated_message
def create_user(sa_session: galaxy_scoped_session):
random_number = random.randint(0, 1000)
user = User(
email="test" + str(random_number) + "@test.com",
password="abcde",
username="notification_user" + str(random_number),
)
sa_session.add(user)
sa_session.flush()
assert user.id is not None
return user
def create_user_notification_association(sa_session: galaxy_scoped_session, users, notification):
notificationManager = create_notification_mananger(sa_session)
notificationManager.associate_user_notification(users, notification)
def test_create_notification(sa_session: galaxy_scoped_session):
notificationManager = create_notification_mananger(sa_session)
notification = notificationManager.create(message_text="New notification")
user = create_user(sa_session)
create_user_notification_association(sa_session, [user], notification)
assert user.all_notifications is not None
# test backref from Notifcation to UserNotificationAssociation
assert notification.user_notification_associations is not None