Erste Adminoberfläche implementiert
This commit is contained in:
parent
847f01fb1f
commit
9ff6268b8a
|
|
@ -22,6 +22,11 @@ areas/migrations/*
|
|||
!areas/migrations/__init__.py
|
||||
areas/__pycache__/*
|
||||
|
||||
|
||||
adm/migrations/*
|
||||
!adm/migrations/__init__.py
|
||||
adm/__pycache__/*
|
||||
|
||||
standards/migrations/*
|
||||
!standards/migrations/__init__.py
|
||||
standards/__pycache__/*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AdmConfig(AppConfig):
|
||||
name = 'adm'
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
# Create your models here.
|
||||
# MAIN RECOVERDIR PASSWORD AND CONFIG
|
||||
class MainStatistic(models.Model):
|
||||
staticdate = models.DateField(default=timezone.now)
|
||||
agencys = models.IntegerField(default=0)
|
||||
users = models.IntegerField(default=0)
|
||||
standards = models.IntegerField(default=0)
|
||||
chatmessages = models.IntegerField(default=0)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{% extends "adm/adm_base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h4>Agenturübersicht</h4>
|
||||
<hr>
|
||||
<table class="table table-hover" id="agdata" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Agenturname</th>
|
||||
<th scope="col">Mitarbeiter</th>
|
||||
<th scope="col">Standards</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody >
|
||||
{% for ele in agencys %}
|
||||
<tr>
|
||||
<td>{{ele.name}}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#agdata').DataTable({
|
||||
"language": {
|
||||
"search" : "Suche",
|
||||
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
|
||||
"lengthMenu": "Zeige _MENU_ Einträge",
|
||||
"zeroRecords": "Nichts gefunden",
|
||||
"infoEmpty": "Keine Einträge",
|
||||
"paginate": {
|
||||
"first": "Erste",
|
||||
"last": "Letzte",
|
||||
"next": "Nächste",
|
||||
"previous": "Zurück"
|
||||
},
|
||||
},
|
||||
"pageLength": 50,
|
||||
"buttons" : {
|
||||
"className" : "btn-danger"
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,694 @@
|
|||
{% load static %}
|
||||
{% load counter_tag %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="{% static 'users/img/favicon.ico' %}">
|
||||
<title>Digitale Agentur - Administrativer Bereich</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
|
||||
<link rel="canonical" href="https://www.digitale-agentur.com">
|
||||
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js" type="text/javascript"></script>-->
|
||||
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
|
||||
|
||||
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
|
||||
<!--<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">-->
|
||||
<link href="{%static 'users/css/google_font.css' %}" rel="stylesheet" type="text/css">
|
||||
|
||||
|
||||
<!--<link href="{%static 'users/css/bootstrap.min.css' %}" rel="stylesheet">-->
|
||||
<!--<link href='https://fonts.googleapis.com/css?family=Roboto&display=swap' rel='stylesheet' type='text/css'>-->
|
||||
<link href="{%static 'users/css/google_swap.css' %}" rel="stylesheet" type="text/css">
|
||||
<!-- include summernote css/js -->
|
||||
<!--<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.js"></script>-->
|
||||
|
||||
<!--<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>-->
|
||||
<script src="{%static 'users/js/jquery_ui_min.js' %}" type="text/javascript"></script>
|
||||
<!-- <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>-->
|
||||
<!-- CROPPER -->
|
||||
<link href="{% static 'users/css/cropper.min.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- DATATABLES -->
|
||||
<!--<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" type="text/css" rel="stylesheet">-->
|
||||
<link href="{% static 'users/css/jquery_datatables.css' %}" type="text/css" rel="stylesheet">
|
||||
<!--<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" type="text/css" rel="stylesheet">-->
|
||||
<link href="{% static 'users/css/datatables_bs4.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'users/css/sb-admin-2.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
<link href="{% static 'users/css/theme.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
<script src="{%static 'users/js/bs4_summernote.js' %}" type="text/javascript"></script>
|
||||
<!--<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote-bs4.js"></script>-->
|
||||
<link href="{% static 'users/css/bs4_summernote.css' %}" type="text/css" rel="stylesheet">
|
||||
<!--<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote.css" rel="stylesheet" type="text/css">-->
|
||||
<script type="text/javascript" src="{% static 'summernote/lang/summernote-de-DE.min.js' %}"></script>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper" >
|
||||
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class=" bg-gray-900 sidebar sidebar-dark accordion fixed-top " style="overflow: all; height: 100vh;"id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}">
|
||||
<i class="fas fa-laptop"></i>
|
||||
<div class="sidebar-brand-text mx-2" style="">Digitale Agentur</div>
|
||||
</a>
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider my-0">
|
||||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
{% if active_link == 'adm-statistic' %}
|
||||
<li class="nav-item active">
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
{%endif%}
|
||||
<a class="nav-link" href="{% url 'adm-main' %}">
|
||||
<i class="fas fa-chart-bar"></i>
|
||||
<span>Statistik</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
{% if active_link == 'adm-agencys' %}
|
||||
<li class="nav-item active">
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
{%endif%}
|
||||
<a class="nav-link" href="{% url 'adm-agencys' %}">
|
||||
<i class="fas fa-user-friends"></i>
|
||||
<span>Agenturen</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<!--
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</ul>
|
||||
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<style scoped>
|
||||
.sidebar{
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height : 100%; or
|
||||
height : 100vh; or
|
||||
height : 450px;
|
||||
}
|
||||
#content-wrapper {
|
||||
margin-left: 212px;
|
||||
margin-top: -72px;
|
||||
}
|
||||
/* MARGIN TOP FOR FIREFOX */
|
||||
@-moz-document url-prefix() {
|
||||
#content-wrapper {
|
||||
margin-left: 212px;
|
||||
margin-top: -158px;
|
||||
}
|
||||
}
|
||||
|
||||
/* MARGIN FOR IOS/SAFARI 10+ and 6+ */
|
||||
@media not all and (min-resolution:.001dpcm) {
|
||||
@media {
|
||||
#content-wrapper {
|
||||
margin-left: 212px;
|
||||
margin-top: -158px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) {
|
||||
@media {
|
||||
#content-wrapper {
|
||||
margin-left: 212px;
|
||||
margin-top: -158px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@media screen and (max-width: 768px) {
|
||||
#content-wrapper {
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
}*/
|
||||
</style>
|
||||
<div id="content-wrapper">
|
||||
<!-- Main Content -->
|
||||
<!-- Topbar -->
|
||||
<nav id="topnavbarmain" class="navbar navbar-expand navbar-light bg-white topbar fixed-top mb-4 static-top shadow" style="margin-left: 224px;">
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3" onclick="javascript:toggleSidebar()">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<!-- Topbar Search -->
|
||||
<!-- <form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<div class="input-group">
|
||||
<input list="searchres" placeholder="Agenturweite Suche..." id="search_string" onkeyup="javascript:startSearch(this.value)" class="form-control bg-light border-0 small" >
|
||||
-->
|
||||
<!--
|
||||
<input type="text" onkeyup="javascript:startSearch(this.value)" class="form-control bg-light border-0 small" placeholder="Suche..." aria-label="Suche" aria-describedby="basic-addon2" id="searchfield">
|
||||
-->
|
||||
<!--
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button" onclick="javascript:clearSF()">
|
||||
<i class="fas fa-times fa-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form> -->
|
||||
<style type="text/css">
|
||||
.dropdown-header {
|
||||
background-color: #5a5c69 !important;
|
||||
border-color: #5a5c69 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto ">
|
||||
|
||||
|
||||
<!-- ALERT_AREA -->
|
||||
<!-- Nav Item - Alerts -->
|
||||
|
||||
<style type="text/css">
|
||||
{% getonlinestatuscolor request.user as onlinecolor %}
|
||||
.roundimg_base {
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
-moz-box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
}
|
||||
</style>
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="mr-2 d-none d-lg-inline text-gray-600 small">{{request.user.first_name}} {{request.user.last_name}}
|
||||
</span>
|
||||
<img id="userbaseprofilepicture" class="img-profile roundimg_base ml-2" src="{{ user.profile.get_photo_url }}">
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(0)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: green"></i>
|
||||
Online
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(1)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: red"></i>
|
||||
Beschäftigt
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(2)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: yellow"></i>
|
||||
Abwesend
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(3)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: grey"></i>
|
||||
Offline anzeigen
|
||||
</a>
|
||||
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<!--<a class="dropdown-item" onclick="userGoToSettings({{user.pk}})" href="{% url 'orga-single' user.pk %}">-->
|
||||
<a class="dropdown-item" onclick="userGoToSettings()" href="#/">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Einstellungen
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="userGoToNotification()" href="#/">
|
||||
<i class="fas fa-bell fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Benachrichtigungen
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{% url 'users-logout' %}">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Abmelden
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- End of Topbar -->
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid" >
|
||||
|
||||
|
||||
<div id="maincontent" style="min-height: 100%; margin-top: 85px;" >
|
||||
<!-- MESSAGES -->
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show col-6" role="alert" id="message_{{forloop.counter}}">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div style="height: 300px"> </div>
|
||||
</div> <!-- End of Main Content CONTAINER FLUID-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- CHAT BUTTON -->
|
||||
|
||||
|
||||
<!-- End of Page Wrapper -->
|
||||
<!--
|
||||
<footer class="sticky-footer bg-white" style="width: 86.2%;position: absolute;
|
||||
bottom: 0; margin-top: 80px; padding-top: 20px; padding-bottom: 20px;
|
||||
">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © digitale-agentur.com für <b>{{ user.profile.agency.name }}</b></span><br /><small>Version 0.0.5</small>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
-->
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<!--<script src="{%static 'users/vendor/jquery/jquery.min.js' %}"></script>-->
|
||||
<script type="text/javascript" src="{%static 'users/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script type="text/javascript" src="{%static 'users/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
|
||||
<!-- DATABLES JS -->
|
||||
<!--<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
|
||||
<script type="text/javascript" src="{%static 'users/js/jquery_dataTables.min.js' %}"></script>
|
||||
<!--<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>-->
|
||||
<script type="text/javascript" src="{%static 'users/js/bs4_dt.js' %}"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script type="text/javascript" src="{%static 'users/js/sb-admin-2.js' %}"></script>
|
||||
<!-- CUSTOM FONT -->
|
||||
<!--<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">-->
|
||||
|
||||
|
||||
<!-- TABLE SORT -->
|
||||
<!--<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<!--<script src="vendor/chart.js/Chart.min.js"></script>-->
|
||||
|
||||
<!-- Page level custom scripts -->
|
||||
<!--<script src="js/demo/chart-area-demo.js"></script>-->
|
||||
<!--<script src="js/demo/chart-pie-demo.js"></script>-->
|
||||
|
||||
|
||||
<link href="{% static 'users/css/custom.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{% if request.user.profile.showtooltips %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function userGoToSettings(){
|
||||
localStorage.setItem('activeTabSettings', "profil");
|
||||
location.href = "{% url 'dasettings' %}"
|
||||
}
|
||||
|
||||
function userGoToNotification(){
|
||||
localStorage.setItem('activeTabSettings', "notifications");
|
||||
location.href = "{% url 'dasettings' %}"
|
||||
}
|
||||
|
||||
function clearSF(){
|
||||
$("#searchcontent").empty();
|
||||
$("#searchcontent").hide();
|
||||
$("#maincontent").show();
|
||||
$("#search_string").val("");
|
||||
}
|
||||
|
||||
function startSearch(searchstring){
|
||||
if(searchstring.length > 2){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dashboard/globalsearch",
|
||||
data:{
|
||||
searchstring: searchstring
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#maincontent").hide();
|
||||
$("#searchcontent").show();
|
||||
$("#searchcontent").html(data);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#searchcontent").empty();
|
||||
$("#searchcontent").hide();
|
||||
$("#maincontent").show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
if($( window ).width() < 768)
|
||||
{
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle the side navigation
|
||||
function toggleSidebar(){
|
||||
|
||||
if(sidebar_hidden == false){
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "105px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "105px");
|
||||
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
else{
|
||||
$("#accordionSidebar").removeClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
$( window ).resize(function() {
|
||||
if($( window ).width() < 750)
|
||||
{
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
else{
|
||||
$("#accordionSidebar").removeClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "212px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "224px");
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
});
|
||||
/*
|
||||
AJAX CALL FOR NOTIFICATIONS
|
||||
|
||||
*/
|
||||
newunknownotificationscounter = 0;
|
||||
function loadUnsendNotifications(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/notifications/checknotifications",
|
||||
data : {
|
||||
action : "checknotifications"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#notification_items").html("");
|
||||
notifications = data['unknownnotification'];
|
||||
var i = 0;
|
||||
for (var key in notifications) {
|
||||
|
||||
$("#notification_items").append('<span><a href="/'+notifications[i]['elelink']+'" id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center"><div><div class="small text-gray-500">'+notifications[i]['date']+'</div>'+notifications[i]['text']+'</div></a></span>')
|
||||
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;
|
||||
$("#notification_items").html("");
|
||||
for (var key in notifications) {
|
||||
if(newunknownotificationscounter <= 5){
|
||||
$("#notification_items").append('<a href="/'+notifications[i]['elelink']+'" id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center"><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).on('click', function (e) {
|
||||
|
||||
if(e.target["id"] != 'chatButton'){
|
||||
if ($(e.target).closest("#chat_alluserscontent").length === 0) {
|
||||
$("#chat_alluserscontent").fadeOut();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<!-- WEBSOCKETS -->
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
$("#chat_alluserscontent").hide();
|
||||
|
||||
ws_string = 'wss://'
|
||||
if (location.protocol !== 'https:') {
|
||||
ws_string = 'ws://'
|
||||
}
|
||||
|
||||
const mainwebsocket = new WebSocket(ws_string+window.location.host+"/ws/")
|
||||
|
||||
mainwebsocket.onmessage = function(e) {
|
||||
|
||||
console.log(e);
|
||||
|
||||
|
||||
if(e["data"] != "presence_update")
|
||||
{
|
||||
//HANDLER FOR ALL PUSHNOTIFICATIONS
|
||||
if(e["data"].split("__")[0] == "pushnotification"){
|
||||
|
||||
/*
|
||||
Check for Chat-Message in CHatview or invisible-Browser
|
||||
*/
|
||||
tempsplit = e["data"].split("__");
|
||||
finalsplit = tempsplit[1].split(" ");
|
||||
|
||||
if(finalsplit[0] != "Chat"){
|
||||
var notify = new Notification('Digitale Agentur', {
|
||||
body: e["data"].split("__")[1]
|
||||
});
|
||||
}
|
||||
else{
|
||||
{% if active_link == "chat" %}
|
||||
chatopen= true;
|
||||
{% else %}
|
||||
chatopen= false;
|
||||
{% endif %}
|
||||
|
||||
windowvisible = false;
|
||||
//Get Minimized-Window-Status to show up chat message, when window is in chat, but not focused by user
|
||||
|
||||
if(!document.hasFocus()){
|
||||
var notify = new Notification('Digitale Agentur', {
|
||||
body: e["data"].split("__")[1]
|
||||
});
|
||||
}
|
||||
else if(chatopen == false){
|
||||
if($("#dynamicchatwindow").is(":visible")){
|
||||
console.log("user in chat...")
|
||||
}
|
||||
else{
|
||||
var notify = new Notification('Digitale Agentur', {
|
||||
body: e["data"].split("__")[1]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
loadUnsendNotifications();
|
||||
loadUnviewnNotifications();
|
||||
}
|
||||
else{
|
||||
|
||||
{% if active_link == "chat" %}
|
||||
if(preventUpdatePresLive == false){
|
||||
updatePresenceLive();
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
};
|
||||
|
||||
mainwebsocket.onclose = function(e) {
|
||||
console.error('Chat socket closed unexpectedly');
|
||||
};
|
||||
|
||||
|
||||
//HEARTBEAT every minute
|
||||
setInterval(function()
|
||||
{
|
||||
mainwebsocket.send(JSON.stringify("heartbeat"));
|
||||
console.log("heartbeat is alive...");
|
||||
},60000);
|
||||
|
||||
|
||||
});
|
||||
|
||||
function changeOnlineStatus(newstat){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "{% url 'users-updateonlinestat' %}",
|
||||
data : {
|
||||
newstat : newstat
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data["newstat"] == "0"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px green',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px green',
|
||||
'box-shadow': '0px 0px 4px 5px green'
|
||||
})
|
||||
}
|
||||
else if(data["newstat"] == "1"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px red',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px red',
|
||||
'box-shadow': '0px 0px 4px 5px red'
|
||||
})
|
||||
}
|
||||
else if(data["newstat"] == "2"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px orange',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px orange',
|
||||
'box-shadow': '0px 0px 4px 5px orange'
|
||||
})
|
||||
}
|
||||
else if(data["newstat"] == "3"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px grey',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px grey',
|
||||
'box-shadow': '0px 0px 4px 5px grey'
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.onerror = function (msg, url, line) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!window.Notification) {
|
||||
console.log('Browser does not support notifications.');
|
||||
} else {
|
||||
// check if permission is already granted
|
||||
if (Notification.permission === 'granted') {
|
||||
// show notification here
|
||||
} else {
|
||||
// request permission from user
|
||||
Notification.requestPermission().then(function(p) {
|
||||
if(p === 'granted') {
|
||||
// show notification here
|
||||
console.log("User receive notifications.")
|
||||
} else {
|
||||
console.log('User blocked notifications.');
|
||||
}
|
||||
}).catch(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$("#chatButton").click(function(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "{% url 'chat:chtaajax-getloggedusers' %}",
|
||||
data : {
|
||||
action : "getloggedusers"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#chat_alluserscontent").fadeToggle();
|
||||
$("#chat_alluserscontent").html(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "adm/adm_base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h4>Statistikdaten über alle</h4>
|
||||
<hr>
|
||||
<table class="table table-hover" id="statistics" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Datum</th>
|
||||
<th scope="col">Agenturen</th>
|
||||
<th scope="col">Benutzer</th>
|
||||
<th scope="col">Standards</th>
|
||||
<th scope="col">Chatnachrichten</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody >
|
||||
{% for ele in statistik %}
|
||||
<tr>
|
||||
<td>{{ele.staticdate|date:"d.m.Y"}}</td>
|
||||
<td>{{ele.agencys}}</td>
|
||||
<td>{{ele.users}}</td>
|
||||
<td>{{ele.standards}}</td>
|
||||
<td>{{ele.chatmessages}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#statistics').DataTable({
|
||||
"language": {
|
||||
"search" : "Suche",
|
||||
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
|
||||
"lengthMenu": "Zeige _MENU_ Einträge",
|
||||
"zeroRecords": "Nichts gefunden",
|
||||
"infoEmpty": "Keine Einträge",
|
||||
"paginate": {
|
||||
"first": "Erste",
|
||||
"last": "Letzte",
|
||||
"next": "Nächste",
|
||||
"previous": "Zurück"
|
||||
},
|
||||
},
|
||||
"pageLength": 50,
|
||||
"buttons" : {
|
||||
"className" : "btn-danger"
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
from django.urls import path
|
||||
from .views import *
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
|
||||
'''
|
||||
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
||||
'''
|
||||
|
||||
urlpatterns = [
|
||||
path('', AdmMain.as_view(), name='adm-main'),
|
||||
path('ag/', AdmAgencys.as_view(), name="adm-agencys"),
|
||||
path('cron/<slug:code>', statisticCronJob, name="adm-cron")
|
||||
]
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, FormView, TemplateView
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import render, redirect, reverse
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
|
||||
from .models import MainStatistic
|
||||
from django.contrib.auth.models import User
|
||||
from chat.models import ChatMessage
|
||||
from users.models import Agency
|
||||
from standards.models import Standards
|
||||
|
||||
def checkForStuffUser(request):
|
||||
if request.user.is_staff:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class AdmMain(TemplateView):
|
||||
template_name = "adm/adm_main.html"
|
||||
|
||||
def dispatch(self, *args, **kwargs):
|
||||
if(checkForStuffUser(self.request)):
|
||||
return super().dispatch(*args, **kwargs)
|
||||
else:
|
||||
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
||||
return redirect("login")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context.update({'active_link' : "adm-statistic"})
|
||||
|
||||
context.update({'statistik' : MainStatistic.objects.all().order_by('-staticdate')})
|
||||
|
||||
return context
|
||||
|
||||
class AdmAgencys(TemplateView):
|
||||
template_name = "adm/adm_agencys.html"
|
||||
|
||||
def dispatch(self, *args, **kwargs):
|
||||
if(checkForStuffUser(self.request)):
|
||||
return super().dispatch(*args, **kwargs)
|
||||
else:
|
||||
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
||||
return redirect("login")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context.update({'active_link' : "adm-agencys"})
|
||||
|
||||
context.update({'agencys' : Agency.objects.all()})
|
||||
|
||||
return context
|
||||
|
||||
# CRONJOB, um die Statistik zu füllen!
|
||||
def statisticCronJob(request, code):
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY_STATSTIC):
|
||||
print("STATISTIC is running...")
|
||||
newMainS = MainStatistic(agencys=len(Agency.objects.all()),users=len(User.objects.all().exclude(is_staff=True, is_superuser=True)),standards=len(Standards.objects.all()),chatmessages=len(ChatMessage.objects.all()))
|
||||
newMainS.save()
|
||||
data.update({"status" : "success"})
|
||||
else:
|
||||
print("API STATISTIC CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -38,6 +38,7 @@ X_FRAME_OPTIONS = 'SAMEORIGIN'
|
|||
SECRET_KEY = '_qv2t2lmsctjxpbb4rrp=op%_20_hxzonv^mvty1o85c)l$s^q'
|
||||
|
||||
CRONAPIKEY = "gCddsaz6NOnE9QbXZM5LasdEk122D"
|
||||
CRONAPIKEY_STATSTIC = "aiszdausd876asdtuzagshjdajgAHGJHSDSD67daiuhdj"
|
||||
MAILINFOKEY = "jka7sd8iukashdna78skduJAHDsu6dilaksdjba65a68iadbhjak"
|
||||
# API KEY LEXOFFICE
|
||||
LEX_API = "8f9ba01f-9e84-42c7-9548-48c254f14c19"
|
||||
|
|
@ -68,6 +69,7 @@ INSTALLED_APPS = [
|
|||
'timemanagement.apps.TimemanagementConfig',
|
||||
'recoverdir.apps.RecoverdirConfig',
|
||||
'news.apps.NewsConfig',
|
||||
'adm.apps.AdmConfig',
|
||||
'crispy_forms',
|
||||
'colorful',
|
||||
'django_summernote',
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ urlpatterns = [
|
|||
path('areas/', include('areas.urls'), name="areas-management"),
|
||||
path('tasks/', include('tasks.urls'), name="tasks-management"),
|
||||
path('organizer/', include('organizer.urls'), name="ql-management"),
|
||||
path('adm/', include('adm.urls'), name="adm"),
|
||||
path('cloud/', include('cloud.urls'), name="cloud-main"),
|
||||
path('standards/', include('standards.urls'), name="standards"),
|
||||
path('rd/', include('recoverdir.urls'), name="recoverdir"),
|
||||
|
|
|
|||
|
|
@ -232,6 +232,17 @@
|
|||
</style>
|
||||
<div id="bottom_info" style="z-index: -200">
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
{% if request.user.is_staff %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="{% url 'adm-main' %}" aria-expanded="true" style="margin-top: -15px">
|
||||
<i class="fas fa-user-shield"></i>
|
||||
<span>Adminoberfläche</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
{% if active_link == 'dasettings' %}
|
||||
<li class="nav-item active">
|
||||
{% else%}
|
||||
|
|
@ -242,6 +253,7 @@
|
|||
<span>Einstellungen</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if active_link == 'support' %}
|
||||
<li class="nav-item active">
|
||||
{% else%}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,16 @@
|
|||
<i class="fas fa-laptop"></i>
|
||||
<h3>Digitale Agentur Login</h3>
|
||||
</legend>
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert" id="message_{{forloop.counter}}">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ form|crispy }}
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
Loading…
Reference in New Issue