- 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:
parent
d1bebf51d4
commit
4b51d757e3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
|
@ -21,38 +21,57 @@
|
|||
<p>
|
||||
{{ mail }}
|
||||
</p>
|
||||
</div>
|
||||
</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> </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> </td>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<style>
|
||||
#orgasingle {
|
||||
border-collapse: separate;
|
||||
border-spacing: 25px 0px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -16,5 +16,5 @@ urlpatterns = [
|
|||
path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
|
||||
path('standard/<int:pk>/single', views.StandardSingle, name="standard-single"),
|
||||
path('standard/<int:pk>/area', views.StandardArea, name="standard-area"),
|
||||
path('standard/<int:pk>/task', views.StandardTask, name="standard-task")
|
||||
path('standard/<int:pk>/task', views.StandardTask, name="standard-task")
|
||||
]
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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,7 +221,9 @@
|
|||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- RESULTS -->
|
||||
<div id="searchresults_div"></div>
|
||||
|
||||
<!-- MESSAGES -->
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
|
@ -239,9 +243,11 @@
|
|||
</script>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
<div id="maincontent_for_search">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
</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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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']
|
||||
|
|
@ -259,4 +269,43 @@ def UsersPrioUpdate(request):
|
|||
return HttpResponse("udated...")
|
||||
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')
|
||||
|
||||
|
||||
Loading…
Reference in New Issue