- Sicherheitslücke beim ändern von Priorisierungen geschlossen, die angeforderte ID wird nun mit der Agency des eingeloggten USers verglichen

- Suche implementiert: Jetzt kann aus jeder Ansicht heraus sofort gesucht werden, man kann von den Ergebnissen des Standards direkt zum Standard gehen; Es wurd gesucht im Namen, COntext und Hersteller. Sollte die Suiche gelöscht werden sieht man die aktuelle Ansicht wieder
This commit is contained in:
holger.trampe 2019-12-06 18:04:58 +01:00
parent d1bebf51d4
commit 4b51d757e3
69 changed files with 211 additions and 57 deletions

View File

@ -7,6 +7,7 @@ from users.views import AgencyCreateView
from . import views
from ckeditor_uploader.views import upload
from django.contrib.auth.decorators import login_required
'''
ADMINPAGE - Verwaltung der Super-User
- LOGIN-Page

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Binary file not shown.

View File

@ -8,7 +8,10 @@
<tbody>
<tr>
<td colspan="3" class="text-center">
{% if leader != None %}
<a href="{% url 'orga-single' leader.pk %}">
{% endif %}
<div>
<img class="img-profile mb-2 " width="12%" src="{{ leader.profile.image.url }}">
</div>

View File

@ -4,11 +4,11 @@
<h3>Bereiche und Aufgaben von {{user_first_name}} {{user_last_name}}</h3>
<hr>
<div class="media">
<img class="img-profile" width="12%" src="{{ imageurl }}">
<div class="media-body col-7">
<img class="img-profile" width="12%" src="{{ imageurl }}" >
<div class="media-body">
<div class="col-8">
<div class="row ml-2">
<div class="col-3">
<h6><b>Name</b></h6>
<p>
{{ user_first_name }} {{ user_last_name }}
@ -22,37 +22,56 @@
{{ mail }}
</p>
</div>
<div class="col-md-3">
<h6><b>Tätigkeit</b></h6>
<p>
{{ compfunc }}
</p>
<h6><b>Festznetz</b></h6>
<p>
{{ phoneland }}
</p>
<h6><b>Mobil</b></h6>
<p>
{{ phonemobile }}
</p>
</div>
</div>
</div>
</div>
<table class="table borderless mt-3">
<tbody>
<hr>
<table class="table" id="orgasingle">
<thead>
<tr >
{% for area in areas %}
<td class="text-center" style="background-color: rgba({{area.color.0}},{{area.color.1}},{{area.color.2}}, 0.3); color: #ffffff"><h4 style="color: rgba(0,0,0, 1);"><b>{{area.name}}</b></h4></td>
<td>&nbsp;</td>
{% endfor %}
</tr>
<tr style="background-color: {{area.hex}}">
</thead>
<tbody>
<tr>
{% for area in areas %}
<td class="text-center">
{%for prio in prios %}
{% if prio.task.area.pk == area.pk %}
<div style="background-color: rgba({{area.color.0}},{{area.color.1}},{{area.color.2}}, 1)" class="mb-2 p-2">
<span style=" color: #FFFFFF;"><h5>{{prio.task.name}}</h5></span>
<td class="text-center" style="background-color: rgba({{area.color.0}},{{area.color.1}},{{area.color.2}}, 0.3)">
{%for prio in prios %}
{% if prio.task.area.pk == area.pk and prio.task.visible %}
<div style="background-color: rgba({{area.color.0}},{{area.color.1}},{{area.color.2}}, 1)" class="mb-2 pt-3 pb-1">
<span style=" color: #FFFFFF;"><h6>{{prio.task.name}}</h6></span>
</div>
{% endif %}
{% endfor %}
</td><td>&nbsp;</td>
</td>
{% endfor %}
</tr>
</tbody>
</table>
<style>
#orgasingle {
border-collapse: separate;
border-spacing: 25px 0px;
}
</style>
</div>
{% endblock content %}

View File

@ -9,7 +9,11 @@ import webcolors
@login_required
def mainorga(request):
leader = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='lead'))[0]
leader = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='lead'))
if len(leader) > 0:
leader = leader[0]
else:
leader = None
indoor = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='indoor'))
external = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='external'))
trainee = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='trainee'))
@ -31,7 +35,11 @@ def mainorga(request):
@login_required
def singleorga(request, pk):
user = User.objects.get(pk=pk)
'''
VON GROß NACH KLEIN - SINNLOS
prios = Prio.objects.filter(user__pk=pk).order_by('-prio')[::-1]
'''
prios = Prio.objects.filter(user__pk=pk).order_by('-prio')
areas = list(Areas.objects.filter(agency__pk=request.user.profile.agency.pk))
i = 0
for area in areas:
@ -52,7 +60,10 @@ def singleorga(request, pk):
'prios' : prios,
'mail' : user.email,
'userfunc' : user.profile.get_func_display,
'imageurl' : user.profile.image.url
'imageurl' : user.profile.image.url,
'compfunc' : user.profile.compfunc,
'phoneland' : user.profile.phoneland,
'phonemobile' : user.profile.phonemobile
}
return render(request, 'orga/orga_single.html', context)

View File

@ -8,10 +8,10 @@ from django.contrib import messages
from django.http import HttpResponse, JsonResponse
from users.priomodel import Prio
# Create your views here.
class TasksManagement(LoginRequiredMixin, ListView):
model = Tasks
# Adding active_link
# Loading only user same agency
# Change context and return for template-data

View File

@ -101,7 +101,7 @@
<hr class="sidebar-divider">
<!-- Heading -->
<div class="sidebar-heading">
Agenturverwaltung
Agenturorga
</div>
{%endif%}
@ -173,12 +173,14 @@
<!-- 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 type="text" class="form-control bg-light border-0 small" placeholder="Suche..." aria-label="Suche" aria-describedby="basic-addon2">
<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">
<i class="fas fa-search fa-sm"></i>
<button class="btn btn-primary" type="button" onclick="javascript:clearSF()">
<i class="fas fa-times fa-sm"></i>
</button>
</div>
</div>
</form>
@ -219,6 +221,8 @@
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- RESULTS -->
<div id="searchresults_div"></div>
<!-- MESSAGES -->
{% if messages %}
@ -239,9 +243,11 @@
</script>
{% endfor %}
{% endif %}
<div id="maincontent_for_search">
{% block content %}
{% endblock %}
</div>
{% block content %}
{% endblock %}
</div>
<!-- End of Main Content -->
@ -288,3 +294,67 @@
</body>
</html>
<script type="text/javascript">
function clearSF(){
$("#searchfield").val("");
$("#searchresults_div").empty();
$("#searchresults_div").hide();
$("#maincontent_for_search").show();
}
function startSearch(searchstring){
if(searchstring.length > 2){
$("#maincontent_for_search").hide();
$("#searchresults_div").show();
$.ajax(
{
type: "GET",
url: "/dashboard/globalsearch",
data:{
searchstring: searchstring
},
success: function( data )
{
$("#searchresults_div").empty();
if(data['res'].length > 1){
$("#searchresults_div").append('<h4>' + data['res'].length + ' Sucherergebnisse</h4><hr>');
}
else if(data['res'].length == 1){
$("#searchresults_div").append('<h4>' + data['res'].length + ' Sucherergebnis</h4><hr>');
}
else {
$("#searchresults_div").append('<h4>Keine Sucherergebnis</h4><hr>');
}
for (var i = 0; i < data['res'].length; i++)
{
$("#searchresults_div").append('<div class="mb-4"><div class="card"><div class="card-header py-3 d-flex flex-row align-items-center justify-content-between"><a href="/standards/standard/'+data['res'][i]['id']+'/single"><h5><u>'+data['res'][i]['name']+'</u></h5></a><div class="dropdown no-arrow"></div></div><div class="card-body"><h6 class="card-title">Von '+data['res'][i]['first_name']+' '+data['res'][i]['last_name']+' | <small>Zuletzt bearbeitet von '+data['res'][i]['first_name_mod']+' '+data['res'][i]['last_name_mod']+' am '+data['res'][i]['last_modified_on']+'</small></h6><p class="card-text">'+data['res'][i]['content']+'</p></div></div></div>');
}
}
});
}
else {
$("#searchresults_div").empty();
$("#searchresults_div").hide();
$("#maincontent_for_search").show();
}
}
function goToStandard(id){
$.ajax(
{
type: "GET",
url: "/dashboard/standardrout",
data:{
's_id': id
},
success (data){
console.log(data);
}
});
}
</script>

View File

@ -28,12 +28,11 @@
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
<div class="dropdown-header">Benutzerdaten</div>
<a class="dropdown-item" href="{% url 'users-update' item.profile.pk %}">Bearbeiten</a>
<a class="dropdown-item" href="{% url 'users-perm-update' item.profile.pk %}">Rechte</a>
<a class="dropdown-item" href="{% url 'users-prio' item.pk %}">Priorisierung</a>
<hr class="sidebar-divider">
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'users-perm-update' item.profile.pk %}">Rechte</a>
<!--<div class="dropdown-header"></div>-->
<a class="dropdown-item" href="#">Bereiche</a>
<a class="dropdown-item" href="#">Aufgaben</a>
<a class="dropdown-item" href="#">Zuständigkeitenn</a>
{% if item != request.user %}
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'users-delete' item.pk %}" >Löschen</a>

View File

@ -3,7 +3,7 @@
{% block content %}
<div class="content-section">
<h3>Priorisierung von {{ user_first_name }} {{ user_last_name }} verändern</h3>
<small>Elemente mit einer kleineren Zahl werden im Organigramm weiter oben angezeigt. Die Änderungen werden sofort gespeichert.</small>
<small>Elemente mit einer größeren Zahl werden im Organigramm weiter oben angezeigt. Die Änderungen werden sofort gespeichert.</small>
<hr>
<div class="col-12">
{% for area in areas %}

View File

@ -24,7 +24,9 @@ urlpatterns = [
path('agencyinfo/', views.agency, name='agencyinfo'),
path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'),
path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'),
path('prioupdate/', views.UsersPrioUpdate, name="users-prioupdate")
path('prioupdate/', views.UsersPrioUpdate, name="users-prioupdate"),
path('globalsearch/', views.GlobalSearch, name="globalsearch"),
path('standardrout/', views.searchStandardRouter, name="standardrouter")
]

View File

@ -1,4 +1,4 @@
from django.shortcuts import render, redirect
from django.shortcuts import render, redirect, reverse
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.decorators import login_required
from django.conf import settings
@ -10,10 +10,13 @@ from django.db import models
from .models import Profile, Agency
from django.core.mail import send_mail
from django.contrib.auth.models import Permission
from django.http import HttpResponseRedirect,HttpResponse
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from areas.models import Areas
from tasks.models import Tasks
from .priomodel import Prio
from standards.models import Standards
from datetime import datetime
from django.utils import formats
'''
DASHBOARD-View
@ -234,24 +237,31 @@ class AgencyUpdateView(LoginRequiredMixin, UpdateView):
'''
def UsersPrio(request, pk):
user = User.objects.get(pk=pk)
prios = Prio.objects.filter(user__pk=pk)
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
user_first_name = user.first_name
user_last_name = user.last_name
user_id = user.pk
context = {
'active_link' : '',
'areas' : areas,
'user_first_name' : user_first_name,
'user_last_name' : user_last_name,
'user_id' : user_id,
'prios' : prios
}
return render(request, 'users/users_prio.html', context)
if(user.profile.agency.pk != request.user.profile.agency.pk):
return HttpResponseRedirect('users-dashboard')
else:
prios = Prio.objects.filter(user__pk=pk)
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
user_first_name = user.first_name
user_last_name = user.last_name
user_id = user.pk
context = {
'active_link' : '',
'areas' : areas,
'user_first_name' : user_first_name,
'user_last_name' : user_last_name,
'user_id' : user_id,
'prios' : prios
}
return render(request, 'users/users_prio.html', context)
def UsersPrioUpdate(request):
if request.method == 'GET':
tempuser = User.objects.get(pk=request.GET['userid'])
if request.method == 'GET' and tempuser.profile.agency.pk == request.user.profile.agency.pk:
prio = Prio.objects.filter(user__pk=request.GET['userid']).filter(task__pk=request.GET['taskid'])
prio = list(prio)[0]
prio.prio = request.GET['value']
@ -260,3 +270,42 @@ def UsersPrioUpdate(request):
else:
return HttpResponse("Request method is not a GET")
# Searxh for Standards by name, content, creator - standards needs to be public!
def GlobalSearch(request):
if request.method == 'GET':
searchfor = request.GET['searchstring']
results = {}
ag = request.user.profile.agency.pk
results = Standards.objects.filter(agency__pk=ag, public=True).filter(name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(content__contains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(area__name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(task__name__icontains=searchfor) | Standards.objects.filter(agency__pk=ag, public=True).filter(created_standard_by__last_name__icontains=searchfor)|Standards.objects.filter(agency__pk=ag, public=True).filter(created_standard_by__first_name__icontains=searchfor)
results = list(results)
final_results = []
i = 0
for ele in results:
tempele = {}
tempele['id'] = ele.pk
tempele['name'] = ele.name
# First 100 chars of the Content
tempele['content'] = ele.content[:100]
tempele['first_name'] = ele.created_standard_by.first_name
tempele['last_name'] = ele.created_standard_by.last_name
tempele['first_name_mod'] = ele.last_modified_by.first_name
tempele['last_name_mod'] = ele.last_modified_by.last_name
tempele['created'] = formats.date_format(ele.created_standard_date, "d.m.Y")
tempele['last_modified_on'] = formats.date_format(ele.last_modified_on, "d.m.Y")
final_results.append(tempele)
i += 1
return JsonResponse({'res' : final_results})
else:
return HttpResponse("Request method is not a GET")
def searchStandardRouter(request):
if request.method == 'GET':
return redirect('/standards/standard/'+request.GET['s_id']+'/single')
else:
return redirect('dashboard')