Merge branch '17-Yuyu-Features/dashboard-notification' into 'main'
Dashboard Notification Center Closes #17 See merge request dev/yuyu_dashboard!9
This commit is contained in:
commit
e70423ce86
11 changed files with 303 additions and 1 deletions
|
@ -13,6 +13,7 @@ ln -sf $root/yuyu/local/enabled/_6103_admin_billing_price_configuration.py $hori
|
|||
ln -sf $root/yuyu/local/enabled/_6104_admin_billing_setting.py $horizon_path/openstack_dashboard/local/enabled/_6104_admin_billing_setting.py
|
||||
ln -sf $root/yuyu/local/enabled/_6104_admin_billing_setting.py $horizon_path/openstack_dashboard/local/enabled/_6104_admin_billing_setting.py
|
||||
ln -sf $root/yuyu/local/enabled/_6105_admin_billing_projects_invoice.py $horizon_path/openstack_dashboard/local/enabled/_6105_admin_billing_projects_invoice.py
|
||||
ln -sf $root/yuyu/local/enabled/_6106_admin_notification_center.py $horizon_path/openstack_dashboard/local/enabled/_6105_admin_notification_center.py
|
||||
|
||||
ln -sf $root/yuyu/local/enabled/_6111_project_billing_panel_group.py $horizon_path/openstack_dashboard/local/enabled/_6111_project_billing_panel_group.py
|
||||
ln -sf $root/yuyu/local/enabled/_6112_project_billing_overview.py $horizon_path/openstack_dashboard/local/enabled/_6112_project_billing_overview.py
|
||||
|
|
0
yuyu/admin/notification_center/__init__.py
Normal file
0
yuyu/admin/notification_center/__init__.py
Normal file
20
yuyu/admin/notification_center/panel.py
Normal file
20
yuyu/admin/notification_center/panel.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# 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.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
|
||||
class NotificationCenter(horizon.Panel):
|
||||
name = _("Notification Center")
|
||||
slug = "notification_center"
|
27
yuyu/admin/notification_center/tables.py
Normal file
27
yuyu/admin/notification_center/tables.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tables
|
||||
|
||||
|
||||
class NotificationFilterAction(tables.FilterAction):
|
||||
name = "notification_center_filter"
|
||||
|
||||
|
||||
class NotificationTable(tables.DataTable):
|
||||
title = tables.WrappingColumn("title", verbose_name=_("Title"),
|
||||
link="horizon:admin:notification_center:detail")
|
||||
short_description = tables.Column("short_description", verbose_name=_("Short Description"))
|
||||
recipient = tables.Column("recipient", verbose_name=_("Recipient"))
|
||||
sent_status = tables.Column("sent_status", verbose_name=_("Sent Status"))
|
||||
is_read = tables.Column("is_read", verbose_name=_("Is Read"))
|
||||
created_at = tables.Column("created_at", verbose_name=_("Created At"))
|
||||
|
||||
def get_object_id(self, obj):
|
||||
return obj["id"]
|
||||
|
||||
class Meta(object):
|
||||
name = "list_notification_center"
|
||||
verbose_name = _("Notification Center")
|
||||
multi_select = False
|
||||
table_actions = (NotificationFilterAction, )
|
|
@ -0,0 +1,60 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Notification Center" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Project: </dt>
|
||||
<dd>
|
||||
<select id="selection" onchange="onSelection(this.value)">
|
||||
<option value='{}'
|
||||
{% if not current_tenant_id %}selected {% endif %}
|
||||
>All</option>
|
||||
|
||||
<option
|
||||
value='{"tenant_id": "0"}'
|
||||
{% if "0" == current_tenant_id %}selected {% endif %}
|
||||
>General Notification
|
||||
</option>
|
||||
|
||||
{% for i in select_list %}
|
||||
<option
|
||||
value='{"tenant_id": "{{ i.id }}"}'
|
||||
{% if i.id == current_tenant_id %}selected {% endif %}
|
||||
>{{ i.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-sm-6 text-right">
|
||||
<a href="{% url 'horizon:admin:notification_center:read_all' current_tenant_id %}"
|
||||
class="btn btn-primary" style="margin-bottom: 8px">Mark to Read All</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{{ table.render }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript">
|
||||
function onSelection(val) {
|
||||
const data = JSON.parse(val);
|
||||
|
||||
if(data !== null){
|
||||
var search = "?tenant_id=" + data.tenant_id;
|
||||
window.location.href = window.location.protocol + "//" + window.location.host + window.location.pathname + search;
|
||||
}else {
|
||||
window.location.href = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,49 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Detail Notification" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="row">
|
||||
<div class="col-sm-12 text-right">
|
||||
{% if not notification.sent_status %}
|
||||
<a href="{% url 'horizon:admin:notification_center:resend' notification.id%}"
|
||||
class="btn btn-primary" style="margin-bottom: 8px">Resend Notification</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>{{ notification.title }}/{{ notification.id }}</strong></div>
|
||||
<div class="panel-body">
|
||||
<span><strong>Description:</strong></span>
|
||||
<p>{{ notification.short_description }}</p>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Recipient</th>
|
||||
<th scope="col">Sent Status</th>
|
||||
<th scope="col">Is Read</th>
|
||||
<th scope="col">Created At</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ notification.project.email_notification }}</td>
|
||||
<td>{{ notification.sent_status }}</td>
|
||||
<td>{{ notification.is_read }}</td>
|
||||
<td>{{ notification.created_at }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{% autoescape off %}{{ notification.content }}{% endautoescape %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
27
yuyu/admin/notification_center/urls.py
Normal file
27
yuyu/admin/notification_center/urls.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# 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.
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^(?P<notification_id>[^/]+)/$',
|
||||
views.DetailView.as_view(),
|
||||
name='detail'),
|
||||
url(r'^resend/(?P<notification_id>[^/]+)/$',
|
||||
views.ResendView.as_view(),
|
||||
name='resend'),
|
||||
url(r'^read_all/(?P<selection>[^/]+)$', views.ReadAllView.as_view(), name='read_all'),
|
||||
]
|
||||
|
90
yuyu/admin/notification_center/views.py
Normal file
90
yuyu/admin/notification_center/views.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
# 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.
|
||||
from django import shortcuts
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions, tables, views
|
||||
from openstack_dashboard import api
|
||||
from .tables import NotificationTable
|
||||
from ...cases.notification_use_case import NotificationCenterUseCase
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
page_title = _("Notification Center")
|
||||
template_name = "admin/notification_center/index.html"
|
||||
table_class = NotificationTable
|
||||
|
||||
notification_uc = NotificationCenterUseCase()
|
||||
|
||||
def get_data(self):
|
||||
filter_selection = self.request.GET.get('tenant_id', None)
|
||||
try:
|
||||
notification_uc = self.notification_uc.get_list(self.request, filter_selection)
|
||||
except Exception:
|
||||
notification_uc = []
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve data."))
|
||||
return notification_uc
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
if hasattr(self, "table"):
|
||||
context[self.context_object_name] = self.table
|
||||
|
||||
context['select_list'], _ = api.keystone.tenant_list(self.request, user=self.request.user.id)
|
||||
context['current_tenant_id'] = self.request.GET.get('tenant_id', None)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class DetailView(views.APIView):
|
||||
page_title = _("Notification Detail")
|
||||
template_name = "admin/notification_center/notification_detail.html"
|
||||
notification_uc = NotificationCenterUseCase()
|
||||
|
||||
def get_data(self, request, context, *args, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
notification_uc = self.notification_uc.get_detail(self.request,
|
||||
notification_id=self.kwargs['notification_id'])
|
||||
context['notification'] = notification_uc
|
||||
return context
|
||||
|
||||
|
||||
class ReadAllView(views.APIView):
|
||||
notification_uc = NotificationCenterUseCase()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
try:
|
||||
notifications = self.notification_uc.get_list(self.request,
|
||||
filter_selection=self.kwargs['selection'])
|
||||
for n in notifications:
|
||||
if not n["is_read"]:
|
||||
self.notification_uc.set_read(request, n['id'])
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to mark read All Notification, Please contact admin"))
|
||||
return shortcuts.redirect("horizon:admin:notification_center:index")
|
||||
|
||||
|
||||
class ResendView(views.APIView):
|
||||
notification_uc = NotificationCenterUseCase()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
try:
|
||||
notification_id = self.kwargs['notification_id']
|
||||
|
||||
self.notification_uc.set_resend(request, notification_id)
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to Resend Notification, Please contact admin"))
|
||||
return shortcuts.redirect("horizon:admin:notification_center:index")
|
|
@ -44,7 +44,6 @@ class IndexView(tables.DataTableView):
|
|||
context['project_list'], _ = api.keystone.tenant_list(self.request, user=self.request.user.id)
|
||||
context['current_project_id'] = self.request.GET.get('project_id', self.request.user.project_id)
|
||||
context['current_project_name'] = self.request.GET.get('project_name', self.request.user.project_id)
|
||||
print(context['project_list'])
|
||||
return context
|
||||
|
||||
def get_data(self):
|
||||
|
|
20
yuyu/cases/notification_use_case.py
Normal file
20
yuyu/cases/notification_use_case.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from openstack_dashboard.dashboards.yuyu.core import yuyu_client
|
||||
|
||||
|
||||
class NotificationCenterUseCase:
|
||||
def get_list(self, request, filter_selection=None):
|
||||
if filter_selection is None:
|
||||
return yuyu_client.get(request, f"notification/").json()
|
||||
|
||||
return yuyu_client.get(request, f"notification/?tenant_id={filter_selection}").json()
|
||||
|
||||
def get_detail(self, request, notification_id):
|
||||
response = yuyu_client.get(request, f"notification/{notification_id}").json()
|
||||
return response
|
||||
|
||||
def set_read(self, request, notification_id=None):
|
||||
return yuyu_client.get(request, f"notification/{notification_id}/set_read/").json()
|
||||
|
||||
def set_resend(self, request, notification_id):
|
||||
return yuyu_client.get(request, f"notification/{notification_id}/resend/").json()
|
||||
|
9
yuyu/local/enabled/_6106_admin_notification_center.py
Normal file
9
yuyu/local/enabled/_6106_admin_notification_center.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'notification_center'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'admin'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'billing'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'openstack_dashboard.dashboards.yuyu.admin.notification_center.panel.NotificationCenter'
|
Loading…
Add table
Reference in a new issue