Benachrichtigungssystem fertig, Quicklinks für Modulkram umgeschrieben, Modulsettings angefangen und für 0.8 erstmal fertig

This commit is contained in:
holger.trampe 2020-02-09 20:54:10 +01:00
parent 8fc7455cff
commit be8a215c51
21 changed files with 222 additions and 41 deletions

View File

@ -27,10 +27,13 @@ SECRET_KEY = '_qv2t2lmsctjxpbb4rrp=op%_20_hxzonv^mvty1o85c)l$s^q'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = ['digitale-agentur.com', 'www.digitale-agentur.com', 'localhost'] ALLOWED_HOSTS = ['digitale-agentur.com', 'www.digitale-agentur.com', 'localhost', "0.0.0.0"]
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'notificsys.apps.NotificsysConfig',
'users.apps.UsersConfig', 'users.apps.UsersConfig',
'dasettings.apps.DASettingsConfig', 'dasettings.apps.DASettingsConfig',
'areas.apps.AreasConfig', 'areas.apps.AreasConfig',
@ -86,6 +89,8 @@ TEMPLATES = [
WSGI_APPLICATION = 'digitaleagentur.wsgi.application' WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
ASGI_APPLICATION = 'digitaleagentur.routing.application'
# CKEDITOR # CKEDITOR
CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
@ -134,6 +139,7 @@ DATABASES = {
} }
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
@ -206,6 +212,8 @@ EMAIL_HOST_USER = "support@digitale-agentur.com"
EMAIL_HOST_PASSWORD = "aPx9m3!7x3m@8o!t" EMAIL_HOST_PASSWORD = "aPx9m3!7x3m@8o!t"
DEFAULT_FROM_EMAIL = "support@digitale-agentur.com" DEFAULT_FROM_EMAIL = "support@digitale-agentur.com"
# FOR DATEPICKER # FOR DATEPICKER
BOOTSTRAP4 = { BOOTSTRAP4 = {
'include_jquery': True, 'include_jquery': True,

View File

@ -7,7 +7,6 @@ from users.views import AgencyCreateView
from . import views from . import views
from ckeditor_uploader.views import upload from ckeditor_uploader.views import upload
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
''' '''
Main URLS Main URLS
@ -43,6 +42,7 @@ urlpatterns = [
path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'), path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'),
path('register/done', views.registerdone, name='register-done'), path('register/done', views.registerdone, name='register-done'),
path('summernote/', include('django_summernote.urls')), path('summernote/', include('django_summernote.urls')),
path('notifications/', include('notificsys.urls'), name="notifications")
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -78,7 +78,7 @@ function unflatten(arr) {
return tree; return tree;
} }
var html = ['<ul class="tree">']; var html = ['<ul class="tree" >'];
//Create UL-LI-List for tree //Create UL-LI-List for tree
function createList(arr) { function createList(arr) {

View File

@ -64,7 +64,7 @@ def singleorga(request, pk):
'user_id' : user_id, 'user_id' : user_id,
'prios' : prios, 'prios' : prios,
'mail' : user.email, 'mail' : user.email,
'userfunc' : user.profile.get_func_display, 'userfunc' : "CHANGE",
'imageurl' : user.profile.get_photo_url, 'imageurl' : user.profile.get_photo_url,
'compfunc' : user.profile.compfunc, 'compfunc' : user.profile.compfunc,
'phoneland' : user.profile.phoneland, 'phoneland' : user.profile.phoneland,

View File

@ -1,6 +1,7 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
{% if request.user.profile.agency.module_quicklinks %}
<div class="content-section col-6"> <div class="content-section col-6">
<h3>Quicklink anlegen</h3> <h3>Quicklink anlegen</h3>
<hr> <hr>
@ -13,4 +14,7 @@
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a> <a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
</form> </form>
</div> </div>
{% else %}
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -1,6 +1,7 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
{% if request.user.profile.agency.module_quicklinks %}
<div class="content-section"> <div class="content-section">
<div class="media"> <div class="media">
<div class="media-body"> <div class="media-body">
@ -17,4 +18,7 @@
</div> </div>
</form> </form>
</div> </div>
{% else %}
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -1,12 +1,14 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% load counter_tag %}
{% block content %} {% block content %}
{% if request.user.profile.agency.module_quicklinks %}
<div class="content-section col-12"> <div class="content-section col-12">
<h3>Quicklinks</h3> <h3>Quicklinks</h3>
<hr> <hr>
<p> <p>
Quicklinks helfen zur schnellen Verlinkung von oft genutzten Diensten. Quicklinks helfen zur schnellen Verlinkung von oft genutzten Diensten.
</p> </p>
{% if perms.users.ql_management %} {% if user|usergperm:"modulequicklinks" %}
<div class="row"> <div class="row">
<div class="content-section col-4"> <div class="content-section col-4">
<a class="btn btn-primary" href="{% url 'ql-addql' %}">Quicklink anlegen</a> <a class="btn btn-primary" href="{% url 'ql-addql' %}">Quicklink anlegen</a>
@ -86,4 +88,7 @@ function saveDefQL(){
}); });
} }
</script> </script>
{% else %}
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -1,6 +1,7 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
{% if request.user.profile.agency.module_quicklinks %}
<div class="content-section col-6"> <div class="content-section col-6">
<h3>Quicklink aktualisieren</h3> <h3>Quicklink aktualisieren</h3>
<hr> <hr>
@ -15,4 +16,7 @@
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a> <a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
</form> </form>
</div> </div>
{% else %}
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %} {% endblock content %}

View File

@ -6,11 +6,10 @@ from . import views
''' '''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben! Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
''' '''
urlpatterns = [ urlpatterns = [
path('', QlManagement.as_view(template_name="quicklinks/ql_management.html"), name='ql-management'), path('', QlManagement.as_view(template_name="quicklinks/ql_management.html"), name='ql-management'),
path('addql/', permission_required('users.ql_management')(QlAdd.as_view(template_name="quicklinks/ql_add.html")), name='ql-addql'), path('addql/', permission_required('users.modulequicklinks')(QlAdd.as_view(template_name="quicklinks/ql_add.html")), name='ql-addql'),
path('addql/<int:pk>/delete', permission_required('users.ql_management')(QlDeleteView.as_view()), name='ql-delete'), path('addql/<int:pk>/delete', permission_required('users.modulequicklinks')(QlDeleteView.as_view()), name='ql-delete'),
path('addql/<int:pk>/', permission_required('users.ql_management')(QlUpdateView.as_view()), name='ql-update'), path('addql/<int:pk>/', permission_required('users.modulequicklinks')(QlUpdateView.as_view()), name='ql-update'),
path('lerg/', views.loaddefaultql, name="ql-ajaxloaddef"), path('lerg/', views.loaddefaultql, name="ql-ajaxloaddef"),
] ]

View File

@ -5,12 +5,11 @@ from .models import QuickLinks
from .forms import QlAddQlForm from .forms import QlAddQlForm
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
from django.http import HttpResponse from django.http import HttpResponse, HttpResponseRedirect
# Create your views here. # Create your views here.
class QlManagement(LoginRequiredMixin, ListView): class QlManagement(LoginRequiredMixin, ListView):
model = QuickLinks model = QuickLinks
# Adding active_link # Adding active_link
# Loading only user same agency # Loading only user same agency
# Change context and return for template-data # Change context and return for template-data

View File

@ -48,6 +48,12 @@ class Agency(models.Model):
balance = models.FloatField(default=0.0, max_length=9, blank=True) balance = models.FloatField(default=0.0, max_length=9, blank=True)
nextdebiting = models.DateTimeField(default=timezone.now, blank=True) nextdebiting = models.DateTimeField(default=timezone.now, blank=True)
# MODULEEINSTELLUNGEN FÜR DIE AGENTUR
module_news = models.BooleanField(default=True)
module_quicklinks = models.BooleanField(default=True)
module_files = models.BooleanField(default=True)
module_organigramm = models.BooleanField(default=True)
def __str__(self): def __str__(self):
return f'{self.name}' return f'{self.name}'
@ -192,5 +198,5 @@ class AgencyGroup(models.Model):
('standardmanager', 'Standards bearbeiten und freischalten'), ('standardmanager', 'Standards bearbeiten und freischalten'),
('modulenews', 'News bearbeiten und veröffentlichen'), ('modulenews', 'News bearbeiten und veröffentlichen'),
('modulesconfig', 'Module verwalten'), ('modulesconfig', 'Module verwalten'),
('modulequicklinks', 'Quicklinks bearbeiten und erstellen') ('modulequicklinks', 'Quicklinks bearbeiten')
] ]

View File

@ -3,6 +3,9 @@ from django.contrib.auth.models import User, Group
from django.dispatch import receiver from django.dispatch import receiver
from .models import Profile, Agency, AgencyGroup from .models import Profile, Agency, AgencyGroup
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from notificsys.models import UserNotification
from django.core.mail import send_mail
from django.template.loader import render_to_string
# SIGNALS FOR USER # SIGNALS FOR USER
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs): def create_profile(sender, instance, created, **kwargs):
@ -28,17 +31,59 @@ def save_profile(sender, instance, **kwargs):
# SIGNALS FOR GROUPS # SIGNALS FOR GROUPS
@receiver(signal=m2m_changed, sender=User.groups.through) @receiver(signal=m2m_changed, sender=User.groups.through)
def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs): def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs):
# USERGROUP IS CHANGED
# IF FALSE NO MAILS WILL BE SEND - IN PRODUCTIVITY CHANGE TO TRUE #
GLOBALSENDMAILS = True
# GROUPSETTINGS FOR SOME USER WAS CHANGED
if isinstance(instance, Group): if isinstance(instance, Group):
group_touched = AgencyGroup.objects.get(group=instance) group_touched = AgencyGroup.objects.get(group=instance)
user_touched = User.objects.get(pk=list(pk_set)[0]) user_touched = User.objects.get(pk=list(pk_set)[0])
# A USER WAS REMOVED FROM A GROUP
if(action == 'post_remove'): # PUSH NOTIFICATION FOR GROUOPCHANGES
print("USER REMOVED " + user_touched.first_name + " FROM GROUP " + group_touched.agencygroupname) if(user_touched.profile.add_new_group_push):
# A USER WAS ADDED TO A GROUP if(action == 'post_remove'):
elif(action == 'post_add'): newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt.", notificationtype="groupchanges")
print("USER ADDED " + user_touched.first_name + " TO GROUP " + group_touched.agencygroupname) newnotification.save()
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt.", notificationtype="groupchanges")
newnotification.save()
# E-MAILNOTIFICATIONS FOR GROUPCHANGES
if(user_touched.profile.add_new_group_mail):
notificationtext = ""
if(action == 'post_remove'):
notificationtext = "Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt."
username = user_touched.first_name + " " + user_touched.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext})
if(GLOBALSENDMAILS):
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
'support@digitale-agentur.com',
[user_touched.email],
html_message=msg_html,
fail_silently=False
)
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
notificationtext = "Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt."
username = user_touched.first_name + " " + user_touched.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext})
if(GLOBALSENDMAILS):
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
'support@digitale-agentur.com',
[user_touched.email],
html_message=msg_html,
fail_silently=False
)

View File

@ -46,9 +46,6 @@
</head> </head>
<body> <body>
{% if perms.users.agencyinfo %}
<script type="text/javascript">alert(0);</script>
{% endif %}
<!-- Page Wrapper --> <!-- Page Wrapper -->
<div id="wrapper"> <div id="wrapper">
<!-- Sidebar --> <!-- Sidebar -->
@ -116,16 +113,18 @@
</a> </a>
</li> </li>
--> -->
{% if active_link == 'quicklinks' %} {% if request.user.profile.agency.module_quicklinks %}
<li class="nav-item active"> {% if active_link == 'quicklinks' %}
{% else%} <li class="nav-item active">
<li class="nav-item"> {% else%}
{%endif%} <li class="nav-item">
<a class="nav-link " href="{% url 'ql-management' %}" aria-expanded="true"> {%endif%}
<i class="fas fa-external-link-alt"></i> <a class="nav-link " href="{% url 'ql-management' %}" aria-expanded="true">
<span>Quicklinks</span> <i class="fas fa-external-link-alt"></i>
</a> <span>Quicklinks</span>
</li> </a>
</li>
{% endif %}
{% if active_link == 'cloud' %} {% if active_link == 'cloud' %}
@ -288,6 +287,28 @@
<!-- Topbar Navbar --> <!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto "> <ul class="navbar-nav ml-auto ">
<!-- ALERT_AREA -->
<!-- Nav Item - Alerts -->
<li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" onclick="changeNewNotToViewed()" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-bell fa-fw"></i>
<!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter" id="notificationcounter"></span>
</a>
<!-- Dropdown - Alerts -->
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown" id="allnotificationsarea">
<h6 class="dropdown-header bg-success text-white">
Benachrichtigungen
</h6>
<!-- ITEMS -->
<span id="notification_items"></span>
<!-- ITEMS END -->
<a class="dropdown-item text-center small text-gray-500" href="{% url 'showallnotificaions' %}">Alle Benachrichtigungen ansehen</a>
</div>
</li>
<div class="topbar-divider d-none d-sm-block"></div> <div class="topbar-divider d-none d-sm-block"></div>
<!-- Nav Item - User Information --> <!-- Nav Item - User Information -->
<li class="nav-item dropdown no-arrow"> <li class="nav-item dropdown no-arrow">
@ -326,11 +347,11 @@
{% endif %} {% endif %}
<div id="searchcontent"> <div id="searchcontent">
</div> </div>
<div id="maincontent"> <div id="maincontent" styl="min-height: 100%">
{% block content %} {% block content %}
{% endblock %} {% endblock %}
</div> </div>
<div style="height: 300px">&nbsp;</div>
</div> <!-- End of Main Content CONTAINER FLUID--> </div> <!-- End of Main Content CONTAINER FLUID-->
<!-- End of Content Wrapper --> <!-- End of Content Wrapper -->
</div> </div>
@ -374,6 +395,7 @@
<!-- Page level custom scripts --> <!-- Page level custom scripts -->
<!--<script src="js/demo/chart-area-demo.js"></script>--> <!--<script src="js/demo/chart-area-demo.js"></script>-->
<!--<script src="js/demo/chart-pie-demo.js"></script>--> <!--<script src="js/demo/chart-pie-demo.js"></script>-->
</body> </body>
</html> </html>
@ -453,9 +475,7 @@ function getDimensions() {
window.addEventListener('resize', function() { window.addEventListener('resize', function() {
if (!throttled) { // nur wenn throttled nicht gesetzt ist if (!throttled) { // nur wenn throttled nicht gesetzt ist
getDimensions(); // Callback-Aktion getDimensions(); // Callback-Aktion
throttled = true; // Jetzt wird wieder ausgebremst throttled = true; // Jetzt wird wieder ausgebremst
setTimeout(function() { // Timeout setTimeout(function() { // Timeout
throttled = false; throttled = false;
}, delay); }, delay);
@ -463,4 +483,91 @@ window.addEventListener('resize', function() {
}); });
getDimensions(); getDimensions();
/*
AJAX CALL FOR NOTIFICATIONS
*/
newunknownotificationscounter = 0;
function loadUnsendNotifications(){
$.ajax(
{
type: "GET",
url: "/notifications/checknotifications",
data : {
action : "checknotifications"
},
success: function( data )
{
notifications = data['unknownnotification'];
var i = 0;
for (var key in notifications) {
$("#notification_items").append('<a id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center" onclick="removeNotification('+notifications[i]['not_id']+')"><div><div class="small text-gray-500">'+notifications[i]['date']+'</div>'+notifications[i]['text']+'</div></a>')
i = i + 1;
newunknownotificationscounter = newunknownotificationscounter + 1;
}
$("#notificationcounter").html("");
if(i > 0){$("#notificationcounter").html(i);}
}
});
}
function loadUnviewnNotifications(){
$.ajax(
{
type: "GET",
url: "/notifications/getnotifications",
data : {
action : "oldnotifications"
},
success: function( data )
{
notifications = data['oldnotifications'];
i = 0;
for (var key in notifications) {
if(newunknownotificationscounter <= 5){
$("#notification_items").append('<a id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center" onclick="removeNotification('+notifications[i]['not_id']+')"><div><div class="small text-gray-500">'+notifications[i]['date']+'</div>'+notifications[i]['text']+'</div></a>')
i = i + 1;
}
}
}
});
}
function changeNewNotToViewed(){
$.ajax(
{
type: "GET",
url: "/notifications/newnotificationsviewed",
data : {
action : "newnotificationsviewed"
},
success: function( data )
{
$("#notificationcounter").html("");
}
});
}
function removeNotification(notifyid){
//$("#notifyid_" + notifyid).remove()
//$("#allnotificationsarea").show();
}
$(document).ready(function(){
$("#notification_items").html("");
loadUnsendNotifications();
loadUnviewnNotifications();
});
$(window).click(function() {
$("#notification_items").html("");
loadUnsendNotifications();
loadUnviewnNotifications();
});
</script> </script>