Notificsys fehlte
This commit is contained in:
parent
57ae275c9c
commit
361dfc4158
|
|
@ -0,0 +1,22 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section">
|
||||
<div class="media">
|
||||
<div class="media-body">
|
||||
<h2 class="account-heading">Bereich {{ object.name }} löschen?</h2>
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<p>Alle unter diesem Bereich erstellten Aufgaben und Standards werden gelöscht!</p>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-danger">Bereich löschen</button>
|
||||
<a href="{% url 'areas-management' %}" class="btn btn-success">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section col-6">
|
||||
<h3>Neuen Bereich anlegen</h3>
|
||||
<hr>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<div class="form-group mb-2 mb-3">
|
||||
<span>Farbe</span><input type="color" id="color-picker" name="areacolor " />
|
||||
</div>
|
||||
<p>Nachdem Erstellen eines Bereichs können Mitarbeiter zugewiesen werden.</p>
|
||||
<hr>
|
||||
<button type="submit" class="btn btn-success" href="{% url 'areas-addarea' %} ">Bereich anlegen</button>
|
||||
<a class="btn" href="{% url 'areas-management' %} ">Abbrechen</a>
|
||||
</form>
|
||||
</div>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/> <!-- 'classic' theme -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.es5.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#div_id_color").hide();
|
||||
})
|
||||
|
||||
const pickr1 = new Pickr({
|
||||
el: '#color-picker',
|
||||
default: "#000000",
|
||||
components: {
|
||||
preview: false,
|
||||
hue: true
|
||||
}
|
||||
});
|
||||
|
||||
pickr1.on('changestop', function(){
|
||||
var col = pickr1.getColor().toHEXA().toString();
|
||||
pickr1.setColor(col);
|
||||
$("#id_color").val(col);
|
||||
});
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||
<div class="content-section col-12">
|
||||
<h3>Bereichsverwaltung</h3>
|
||||
<hr>
|
||||
<p>
|
||||
Bereiche unterteilen die Agentur in verschiedene Verantwortungsbereiche.
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="content-section col-4">
|
||||
<a class="btn btn-primary" href="{% url 'areas-addarea' %} ">Bereich anlegen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="form-group mb-2">
|
||||
<input class="form-control" id="tableSearch" size="50" type="text" placeholder="Suche in Tabelle...">
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="areas_maintable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Erstellt von</th>
|
||||
<th scope="col">Erstellt am</th>
|
||||
<th scope="col">Farbe</th>
|
||||
<th scope="col"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tableresults">
|
||||
{% for item in areas_of_agency %}
|
||||
<tr id="{{ item.pk }}">
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.created_area_by.first_name }} {{ item.created_area_by.last_name }}</td>
|
||||
<td>{{ item.created_area_date }}</td>
|
||||
<td><div style="width: 60px; height: 20px; background-color: {{ item.color }}"></div></td>
|
||||
<td>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
|
||||
<div class="dropdown-header">Bereichsinfo</div>
|
||||
<a class="dropdown-item" href="{% url 'areas-manage' item.pk %}">Bearbeiten</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger" href="{% url 'areas-delete' item.pk %}" >Löschen</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
/*$('#areas_maintable').DataTable();*/
|
||||
$("#tableSearch").on("keyup", function() {
|
||||
var value = $(this).val().toLowerCase();
|
||||
$("#tableresults tr").filter(function() {
|
||||
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Update the sort-list by drag'n'drop
|
||||
*/
|
||||
$( "tbody" ).sortable({
|
||||
update: function( event, ui ) {
|
||||
datatoserver = [];
|
||||
var rows = $( "tbody" ).sortable( "widget" )[0]['rows'];
|
||||
for(i = 0; i < rows.length; i++){
|
||||
datatoserver.push({"id" : rows[i]['id'], "neworder" : i});
|
||||
}
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/areas/updateorder",
|
||||
data:{
|
||||
action: "newareaorder",
|
||||
finalod : JSON.stringify(datatoserver)
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
console.log(data);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load static %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section col-6" onmouseup="javascript:checkValue()">
|
||||
<h3>Bereich aktualisieren</h3>
|
||||
<hr>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<div class="form-group mb-2 mb-3">
|
||||
<span>Farbe</span><input type="color" id="color-picker" name="areacolor " />
|
||||
</div>
|
||||
<h6>Mitarbeiter hinzufügen</h6>
|
||||
<div class="input-group mb-3">
|
||||
<input class="form-control" list="usersfree" name="searchusers" id="searchusers" type="text" onkeyup="javascript:checkValue()" onchange="javascript:checkValue()" >
|
||||
<div class="input-group-append">
|
||||
<button type="button" id="addusertoareabtn" onclick="javascript:addUserToArea()" class="btn btn-success" disabled>Mitarbeiter hinzufügen</button>
|
||||
<button type="button" onclick="javascript:clearSearchfield()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<datalist id="usersfree">
|
||||
{% for us in possible_users %}
|
||||
<option id="{{us.pk}}" value="{{us.first_name}} {{us.last_name}}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
</datalist>
|
||||
</div>
|
||||
<hr>
|
||||
<h6>Zugewiesene Mitarbeiter</h6>
|
||||
<div id="added_users_button">
|
||||
{% if added_users|length > 0 %}
|
||||
<p id="no_user_in_area" style="display: none">Noch kein Mitarbeiter zugewiesen.</p>
|
||||
{% for us in added_users %}
|
||||
<span id="span_btn_{{us.pk}}" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromArea('{{ us.pk }}')">{{ us.first_name }} {{ us.last_name }} <i class="fas fa-times"></i></a >
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p id="no_user_in_area">Diesem Bereich ist noch kein Mitarbeiter zugewiesen.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<button type="submit" class="btn btn-success">Bereich aktualisieren</button>
|
||||
<a class="btn" href="{% url 'areas-management' %} ">Abbrechen</a>
|
||||
</form>
|
||||
</div>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/> <!-- 'classic' theme -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.es5.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#div_id_color").hide();
|
||||
})
|
||||
|
||||
const pickr1 = new Pickr({
|
||||
el: '#color-picker',
|
||||
default: "{{object.color}}",
|
||||
components: {
|
||||
preview: false,
|
||||
hue: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
pickr1.on('changestop', function(){
|
||||
var col = pickr1.getColor().toHEXA().toString();
|
||||
pickr1.setColor(col);
|
||||
$("#id_color").val(col);
|
||||
});
|
||||
|
||||
var ua = window.navigator.userAgent;
|
||||
var isIE = /MSIE|Trident/.test(ua);
|
||||
if ( isIE ) {
|
||||
//IE specific code goes here
|
||||
setInterval(function()
|
||||
{
|
||||
checkValue();
|
||||
},250);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var tempid = null;
|
||||
var tempcounter = 0;
|
||||
function addUserToArea(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/areas/areaajax",
|
||||
data:{
|
||||
userid: tempid,
|
||||
action : 'adduser',
|
||||
objectid : {{objectid}}
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
clearSearchfield();
|
||||
//Add User-Button
|
||||
$("#added_users_button").append('<span id="span_btn_'+data['userid']+'" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromArea('+data['userid']+')">'+data['username_clean']+' <i class="fas fa-times"></i></a ></span>');
|
||||
|
||||
$("#usersfree").empty();
|
||||
for (var i in data['remaining_users']) {
|
||||
id = data['remaining_users'][i]['id'];
|
||||
name = data['remaining_users'][i]['first_name'] + " " + data['remaining_users'][i]['last_name'];
|
||||
$("#usersfree").append('<option id="'+id+'" value="'+name+'"></option>');
|
||||
}
|
||||
if(data['remaining_users_counter'] == 0){
|
||||
$("#no_user_in_area").show();
|
||||
}
|
||||
else {
|
||||
$("#no_user_in_area").hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Remove individual User from area, appened to the datalist!
|
||||
function removeUserFromArea(user_id){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/areas/areaajax",
|
||||
data:{
|
||||
userid: user_id,
|
||||
action : 'remuser',
|
||||
objectid : {{objectid}}
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
//Remove User-Button
|
||||
$("#span_btn_"+data['userid']).remove();
|
||||
//Rebuilding the Datalist
|
||||
$("#usersfree").empty();
|
||||
for (var i in data['remaining_users']) {
|
||||
id = data['remaining_users'][i]['id'];
|
||||
name = data['remaining_users'][i]['first_name'] + " " + data['remaining_users'][i]['last_name'];
|
||||
$("#usersfree").append('<option id="'+id+'" value="'+name+'"></option>');
|
||||
}
|
||||
if(data['remaining_users_counter'] == 0){
|
||||
$("#no_user_in_area").show();
|
||||
}
|
||||
else {
|
||||
$("#no_user_in_area").hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Clearing searchfield and set AddUser to false
|
||||
function clearSearchfield(){
|
||||
$("#searchusers").val("");
|
||||
$("#addusertoareabtn").prop('disabled', true);
|
||||
}
|
||||
|
||||
|
||||
//Check for valid input on inputfield
|
||||
function checkValue(){
|
||||
var g = $('#searchusers').val();
|
||||
var id = $('#usersfree').find('option[value="' + g + '"]').attr('id');
|
||||
if(id != undefined && id.length > 0){
|
||||
tempid = id;
|
||||
$("#addusertoareabtn").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
tempid = null;
|
||||
$("#addusertoareabtn").prop("disabled", true);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock content %}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,32 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:34
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0004_data_subdir'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DataDir',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, default='', max_length=2000, null=True)),
|
||||
('is_root', models.BooleanField(default=True)),
|
||||
('date_created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('date_last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('agency', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='users.Agency')),
|
||||
('dirs', models.ManyToManyField(blank=True, related_name='dirs_in_dirs', to='cloud.DataDir')),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
||||
('visibleby', models.ManyToManyField(blank=True, related_name='visible_by_user', to='users.AgencyGroup')),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:34
|
||||
|
||||
import cloud.models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0005_datadir'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DataFiles',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, default='', max_length=2000, null=True)),
|
||||
('file', models.FileField(max_length=255, null=True, upload_to=cloud.models.user_directory_path)),
|
||||
('date_created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('date_last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('agency', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='users.Agency')),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
||||
('parent', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cloud.DataDir')),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloud', '0006_datafiles'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='datadir',
|
||||
name='datafiles',
|
||||
field=models.ManyToManyField(blank=True, related_name='files_in_dir', to='cloud.DataFiles'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datafiles',
|
||||
name='parent',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='thisfileindir', to='cloud.DataDir'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloud', '0007_auto_20200214_2236'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='is_root',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:38
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0008_auto_20200214_2237'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='DataFiles',
|
||||
new_name='DataFile',
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:41
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('cloud', '0009_auto_20200214_2238'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='owner',
|
||||
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 22:41
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('cloud', '0010_auto_20200214_2241'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='owner',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-14 23:13
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0011_auto_20200214_2241'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='datadir',
|
||||
name='parent',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dir_in_dir', to='cloud.DataDir'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='agency',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 13:47
|
||||
|
||||
import cloud.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloud', '0012_auto_20200214_2313'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='file',
|
||||
field=models.FileField(blank=True, max_length=255, null=True, upload_to=cloud.models.user_directory_path),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 14:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloud', '0013_auto_20200215_1347'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='parent',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='thisfileindir', to='cloud.DataDir'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 14:27
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0014_auto_20200215_1411'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='agency',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.Agency'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='owner',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 15:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloud', '0015_auto_20200215_1427'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='datadir',
|
||||
name='datafiles',
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 19:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0016_remove_datadir_datafiles'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='agency',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='users.Agency'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='parent',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='dir_in_dir', to='cloud.DataDir'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='agency',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='users.Agency'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-15 19:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0062_auto_20200213_2207'),
|
||||
('cloud', '0017_auto_20200215_1910'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='agency',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datadir',
|
||||
name='parent',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dir_in_dir', to='cloud.DataDir'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='datafile',
|
||||
name='agency',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.Agency'),
|
||||
),
|
||||
]
|
||||
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.
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h3>Auf diesen Dateibereich haben Sie keinen Zugriff!</h3>
|
||||
<hr>
|
||||
</div>
|
||||
{% endblock %}
|
||||
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.
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class DASettingsConfig(AppConfig):
|
||||
name = 'dasettings'
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
from django import forms
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from users.models import AgencyGroup, Agency, Profile, AgencyJob
|
||||
from PIL import Image
|
||||
|
||||
# Change logged Users Data (Usernamen an Email) NUR HIER MÖGLICH!
|
||||
class UsersSelfChangeForm(forms.ModelForm):
|
||||
email = forms.EmailField()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['email']
|
||||
|
||||
# Form für die Benachrichtigungseinstellungen
|
||||
class UsersNotificationForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Profile
|
||||
labels = {
|
||||
"news_mail" : "Agentur-News",
|
||||
"user_standard_public_mail" : "Veröffentlichung meiner Standards",
|
||||
"agency_new_standard_mail" : "Neue Agentur-Standards",
|
||||
'add_new_group_mail' : "Gruppenmitgliedschaften",
|
||||
'add_task_mail' : "Tätigkeitsbereich"
|
||||
}
|
||||
fields = ['news_mail', 'news_push', 'user_standard_public_mail', 'user_standard_public_push', 'agency_new_standard_mail', 'agency_new_standard_push', 'add_new_group_mail', 'add_new_group_push', 'add_task_mail', 'add_task_push']
|
||||
|
||||
# PERMISSION GROUPS FORM
|
||||
class AgencyGroupPerms(forms.Form):
|
||||
'''
|
||||
Permission-System
|
||||
|
||||
Persmissions werden im Model gesetzt, hier automatisch als Form ausgegeben.
|
||||
Hat der Nutzer eine der genannten Rechte, wird die Checkbox automatisch TRUE gesetzt.
|
||||
Die erstellen Felder werden entsprechend den Feldern hinzugefügt und ausgegeben.
|
||||
|
||||
@param: user
|
||||
- User ist der aufgerufene User!
|
||||
'''
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
temprof = AgencyGroup
|
||||
for ele in temprof._meta.permissions:
|
||||
self.fields[ele[0]] = forms.BooleanField(required=False, initial=False, help_text=(ele[1]))
|
||||
|
||||
# LOADING ALL MODUL-OPTIONS
|
||||
class AgencyModulsForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Agency
|
||||
labels = {
|
||||
'module_news' : "Agentur-News",
|
||||
'module_quicklinks' : "Quicklinks",
|
||||
'module_files' : "Dateien",
|
||||
'module_organigramm' : "Organigramm",
|
||||
}
|
||||
fields = ['module_news','module_quicklinks','module_files','module_organigramm']
|
||||
|
||||
# NEW USER FORM
|
||||
class UserNewUserForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ["first_name", "last_name", "email"]
|
||||
|
||||
# NEW USER PROFILE FORM
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
|
||||
x = forms.FloatField(widget=forms.HiddenInput())
|
||||
y = forms.FloatField(widget=forms.HiddenInput())
|
||||
width = forms.FloatField(widget=forms.HiddenInput())
|
||||
height = forms.FloatField(widget=forms.HiddenInput())
|
||||
rotation = forms.FloatField(widget=forms.HiddenInput())
|
||||
|
||||
class Meta:
|
||||
model = Profile
|
||||
labels = {
|
||||
"persnumber" : "Personalnummer",
|
||||
"visible" : "Im Organigramm sichtbar",
|
||||
"phonemobile" : "Mobilnummer",
|
||||
"phoneland" : "Festnetznummer",
|
||||
"image": "Profilbild",
|
||||
"func" : "Agenturfunktion",
|
||||
"compfunc" : "Tätigkeit"
|
||||
}
|
||||
widgets = {"parent" : forms.HiddenInput()}
|
||||
fields = ["parent", "func", "compfunc", "visible", "phoneland", "phonemobile", "persnumber", "image" ]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['func'].queryset = AgencyJob.objects.filter(agency__pk=self.instance.agency.pk)
|
||||
|
||||
def save(self):
|
||||
photo = super(UserProfileForm, self).save()
|
||||
try:
|
||||
x = self.cleaned_data.get('x')
|
||||
y = self.cleaned_data.get('y')
|
||||
w = self.cleaned_data.get('width')
|
||||
h = self.cleaned_data.get('height')
|
||||
rotation = self.cleaned_data.get('rotation')
|
||||
image = Image.open(photo.image)
|
||||
rotatet_image = image.rotate(rotation, expand=True)
|
||||
cropped_image = rotatet_image.crop((x, y, w+x, h+y))
|
||||
resized_image = cropped_image.resize((300, 300), Image.ANTIALIAS)
|
||||
resized_image.save(photo.image.path)
|
||||
return photo
|
||||
except:
|
||||
print("no photo")
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
{% load crispy_forms_tags %}
|
||||
{% load static %}
|
||||
{% load mathfilters %}
|
||||
{% load humanize %}
|
||||
<button type="button" class="btn btn-primary" onclick="javascript:showAgencyJob()" data-toggle="tooltip" data-placement="top" title="Fügen Sie hier weitere Standard-Agenturfunktionen zu oder bearbeiten bestehende.">Agenturfunktionen verwalten</button>
|
||||
<hr>
|
||||
<script src="{% static 'users/js/cropper.min.js' %}"></script>
|
||||
<script src="{% static 'users/js/jquery-cropper.js' %}"></script>
|
||||
<div class="col-12">
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="form_type" value="agencyform">
|
||||
<input type="hidden" name="settings_area" value="agency">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group">
|
||||
<!-- FORMS LADEN -->
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
{% for formfield in agencyform %}
|
||||
{% if forloop.counter|divisibleby:5 %}
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{formfield|as_crispy_field}}
|
||||
{% else %}
|
||||
{{formfield|as_crispy_field}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h5 class="mt-3">Abrechnung</h5>
|
||||
<p>Kontostand: <b>{{request.user.profile.agency.balance|floatformat:0}} €</b></p>
|
||||
<p>Nächste Abbuchung am <b>{{request.user.profile.agency.nextdebiting|date:"d.m.Y"}}</b></p>
|
||||
<p>Max. Nutzungszeit: <b>{{request.user.profile.agency.balance|div:30|floatformat:0}} Monate</b></p>
|
||||
<p>IBAN: DE4412345678912345</p>
|
||||
<p><small>Laden Sie das Konto mit einem beliebigen Geldbetrag auf. Die Kosten belaufen sich auf 40 € pro Monat.</small></p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Agenturdaten Aktualisieren</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- MODAL TO CROP THE IMAGE -->
|
||||
<div class="modal fade " id="modalCrop" data-backdrop="static" data-keyboard="false">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Bereich bestimmen</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="clearImgField()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="imgmodbody">
|
||||
<img src="" id="imagemod" style="max-width: 100%; max-height: 100%;">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group pull-left" role="group">
|
||||
<button type="button" class="btn btn-default js-zoom-in">
|
||||
<i class="fas fa-search-plus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-zoom-out">
|
||||
<i class="fas fa-search-minus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-rot-left">
|
||||
<i class="fas fa-undo-alt"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-rot-right">
|
||||
<i class="fas fa-redo-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="clearImgField()">Abbrechen</button>
|
||||
<button type="button" class="btn btn-primary js-crop-and-upload">Ausschneiden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
/* TEST FÜR RECHTE - GEHT, SO DANN DIE TEXTFELDER UND DEN BUTTON ENTFERNEN! */
|
||||
/*
|
||||
$(document).ready(function(){
|
||||
$(".textinput").attr("disabled", true);
|
||||
$(".emailinput").attr("disabled", true);
|
||||
$(".clearablefileinput").attr("disabled", true);
|
||||
})*/
|
||||
|
||||
/* CROPPER */
|
||||
$("#id_x").val(0);
|
||||
$("#id_y").val(0);
|
||||
$("#id_width").val(1500);
|
||||
$("#id_height").val(750);
|
||||
$("#id_rotation").val(0);
|
||||
|
||||
function clearImgField(){
|
||||
$("#id_agencypic").val("");
|
||||
}
|
||||
|
||||
|
||||
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
|
||||
$("#id_agencypic").change(function () {
|
||||
if (this.files && this.files[0]) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
$("#imagemod").attr("src", e.target.result);
|
||||
$("#modalCrop").modal("show");
|
||||
}
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
var cropBoxData;
|
||||
var canvasData;
|
||||
var $image = $("#imagemod");
|
||||
$("#modalCrop").on("shown.bs.modal", function () {
|
||||
$image.cropper({
|
||||
viewMode: 3,
|
||||
aspectRatio: 2/1,
|
||||
strict: false,
|
||||
cropBoxMovable: true,
|
||||
cropBoxResizable: true,
|
||||
minCropBoxWidth: 750,
|
||||
minCropBoxHeight: 350,
|
||||
ready: function () {
|
||||
$image.cropper("setCanvasData", canvasData);
|
||||
$image.cropper("setCropBoxData", cropBoxData);
|
||||
}
|
||||
});
|
||||
$("#imgmodbody").css({
|
||||
"maxWidth": 465
|
||||
});
|
||||
|
||||
}).on("hidden.bs.modal", function () {
|
||||
cropBoxData = $image.cropper("getCropBoxData");
|
||||
canvasData = $image.cropper("getCanvasData");
|
||||
$image.cropper("destroy");
|
||||
});
|
||||
|
||||
$(".js-zoom-in").click(function () {
|
||||
$image.cropper("zoom", 0.1);
|
||||
});
|
||||
|
||||
$(".js-zoom-out").click(function () {
|
||||
$image.cropper("zoom", -0.1);
|
||||
});
|
||||
|
||||
$(".js-rot-right").click(function () {
|
||||
$image.cropper("rotate", 90);
|
||||
});
|
||||
|
||||
$(".js-rot-left").click(function () {
|
||||
$image.cropper("rotate", -90);
|
||||
});
|
||||
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
|
||||
$(".js-crop-and-upload").click(function () {
|
||||
var cropData = $image.cropper("getData");
|
||||
$("#id_x").val(cropData["x"]);
|
||||
$("#id_y").val(cropData["y"]);
|
||||
$("#id_height").val(cropData["height"]);
|
||||
$("#id_width").val(cropData["width"]);
|
||||
$("#id_rotation").val(cropData["rotate"]);
|
||||
$("#id_agencypic").attr("src", $image);
|
||||
$("#modalCrop").modal('toggle');
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
AGENCY JOB FUNCTIONS
|
||||
|
||||
*/
|
||||
function showAgencyJob(){
|
||||
$("#agencyJobs").modal("toggle");
|
||||
}
|
||||
|
||||
function addAgencyJob(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_agencyfunc"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
new_id = data["data"]["new_id"];
|
||||
$('#allagencyjobs > tbody:last-child').append('<tr id="agencyjob_'+new_id+'"><td><input class="form-control" type="text" value="" placeholder="Neue Funktion" onkeyup="javascript:updateFunc('+new_id+', this.value)"></td><td><button type="button" class="btn btn-danger" onclick="javascript:funcDel('+new_id+')" data-toggle="tooltip" data-placement="top" title="Agenturfunktion löschen"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var todelid = 0;
|
||||
|
||||
function funcDel(id){
|
||||
todelid = id;
|
||||
$("#agencyJobs").modal("toggle");
|
||||
$("#delAgencyJob").modal("toggle");
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_agencyfunc",
|
||||
id : id
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#delFuncBody").html("Achtung! Die Funktion <b>" + data['data']['funcname'] + "</b> wird gelöscht. Alle Mitarbeiter mit dieser Funktion erhalten eine leere Funktionsbeschreibung. Fortfahren?");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function doDelAgencyJob(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "delete_agencyfunc",
|
||||
id : todelid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#agencyJobs").modal("toggle");
|
||||
$("#delAgencyJob").modal("toggle");
|
||||
$('#agencyjob_' + todelid).remove();
|
||||
todelid = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
timeout = null;
|
||||
function updateFunc(id, funcname){
|
||||
var letters = /^[A-Za-zßäöüÄÖÜ_0-9 ]+$/;
|
||||
if(funcname.match(letters))
|
||||
{
|
||||
//SAVE ONLY EVERY SECOND
|
||||
$("#erroninput").hide();
|
||||
$("#savebreak").show();
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(function () {
|
||||
if(funcname.match(letters))
|
||||
{
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "update_agencyfunc",
|
||||
id : id,
|
||||
newvalue : funcname
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data["success"]){
|
||||
$("#savebreak").hide();
|
||||
$("#funcupdate").fadeTo(2000, 500).slideUp(500, function(){
|
||||
$("#funcupdate").fadeOut(500);
|
||||
});
|
||||
}
|
||||
else{
|
||||
$("#erroninput").show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
$("#erroninput").show();
|
||||
$("#savebreak").hide();
|
||||
$("#funcupdate").hide();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
else{
|
||||
$("#erroninput").show();
|
||||
$("#savebreak").hide();
|
||||
$("#funcupdate").hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- MODAL FOR AGENCYJOBS -->
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="agencyJobs" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Agenturfunktionen bearbeiten</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-hover" id="allagencyjobs">
|
||||
<tbody>
|
||||
{% for ele in agencyjobs %}
|
||||
<tr id="agencyjob_{{ele.pk}}">
|
||||
<td>
|
||||
<input class="form-control" type="text" value="{{ele.name}}" onkeyup="javascript:updateFunc({{ele.pk}}, this.value)">
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger" onclick="javascript:funcDel({{ele.pk}})" data-toggle="tooltip" data-placement="top" title="Agenturfunktion löschen"><i class="fas fa-trash-alt"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="erroninput" class="alert alert-danger" style="display: none">Falsche Eingabe! Es wird nichts gespeichert.</div>
|
||||
<div id="savebreak" class="alert alert-success" style="display: none">Speichern pausiert...</div>
|
||||
<div id="funcupdate" class="alert alert-success" style="display: none">Agenturfunktionen aktualisiert.</div>
|
||||
<button type="button" class="btn btn-primary" title="Neue Funktion hinzufügen" onclick="javascript:addAgencyJob()" data-toggle="tooltip" data-placement="top" title="Dialog für eine neue Agenturfunktion öffnen"><i class="fas fa-plus"></i> Funktion</button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CONFIRMA DELETE DIALOG -->
|
||||
<div class="modal fade" id="delAgencyJob" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Agenturfunktion löschen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="delFuncBody">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelAgencyJob()">Agenturfunktion löschen</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:$('#agencyJobs').modal('toggle')">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,476 @@
|
|||
{% load counter_tag %}
|
||||
<div class="col-9">
|
||||
<button type="button" class="btn btn-primary" onclick="javascript:addGroup()" data-toggle="tooltip" data-placement="top" title="Neue Gruppe erstellen, Namen und Rechte vergeben und anschließend Mitglieder hinzufügen."><i class="fas fa-plus"></i> Gruppe</button>
|
||||
|
||||
<!-- GROUPS -->
|
||||
|
||||
|
||||
<!-- COUNTER USER IN GROUPS -->
|
||||
<div id="allGroups">
|
||||
<div id="groupAccordion" class="mt-3">
|
||||
{% for aggroup in agencygroups %}
|
||||
{% setvar 0 %}
|
||||
{% for user in usersofagency %}
|
||||
{% for group in user.groups.all %}
|
||||
{% if group.name == aggroup.group.name %}
|
||||
{% incvar %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% getvar as varcounter %}
|
||||
<div class="card mb-2">
|
||||
<div class="card-header" id="agroup_{{aggroup.pk}}" style="float: left">
|
||||
<h5 class="mb-0">
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#agroup_{{aggroup.pk}}_card" aria-expanded="false" aria-controls="agroup_{{aggroup.pk}}_card"><small><i class="fas fa-chevron-down"></i></small></button>
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#agroup_{{aggroup.pk}}_card" aria-expanded="false" aria-controls="agroup_{{aggroup.pk}}_card">
|
||||
<span id="groupname_{{aggroup.pk}}" >Gruppe <b>{{aggroup.agencygroupname}} </b></span><small>(<span id="groupcounter_{{aggroup.pk}}">{{varcounter}}</span>)</small>
|
||||
</button>
|
||||
<button type="button" style="float: right" class="btn btn-primary btn-sm" onclick="javascript:changeGroupName({{aggroup.pk}})" data-toggle="tooltip" data-placement="top" title="Gruppennamen andern"><small><i class="fas fa-pen"></i></small></button>
|
||||
{% if not aggroup.savefordel %}
|
||||
<button style="float: right" type="button" class="btn btn-danger btn-sm mr-1" onclick="javascript:delGroup({{aggroup.pk}})" data-toggle="tooltip" data-placement="top" title="Gruppe löschen. Nur möglich, bei selbst erstellten Gruppen."><i class="fas fa-trash-alt"></i></button>
|
||||
{% endif %}
|
||||
{% if aggroup.savefordel %}
|
||||
<button style="float: right" type="button" class="btn btn-danger btn-sm mr-1" onclick="javascript:delGroup({{aggroup.pk}})" data-toggle="tooltip" data-placement="top" title="Gruppe löschen. Nur möglich, bei selbst erstellten Gruppen." disabled><i class="fas fa-trash-alt" ></i></button>
|
||||
{% endif %}
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<div id="agroup_{{aggroup.pk}}_card" class="collapse" aria-labelledby="agroup_{{aggroup.pk}}" data-parent="#groupAccordion">
|
||||
<div class="card-body">
|
||||
<h5>Gruppenrechte <small><i data-toggle="tooltip" data-placement="top" title="Gruppenrechte beeinflussen die Möglichkeiten der Mitarbeiter in einer Gruppe, z.B. dürfen nur Mitarbeiter in einer Gruppe mit dem Recht News entsprechend News erstellen, veröffentlichen und bearbeiten." class="far fa-question-circle"></i></small></h5>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
{% for perm in perms %}
|
||||
{% if forloop.counter|divisibleby:7 %}
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="custom-control custom-checkbox mb-2 {{perm.name}}">
|
||||
<input type="checkbox" class="custom-control-input" name="{{aggroup.pk}}_{{perm.name}}" id="{{aggroup.pk}}_{{perm.name}}" onchange="javascript:changePerm(this.id)" {% if aggroup.is_admin %} disabled="true" {% endif %}>
|
||||
<label class="custom-control-label" for="{{aggroup.pk}}_{{perm.name}}" >{{perm.help_text}}</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="custom-control custom-checkbox mb-2 {{perm.name}}" >
|
||||
<input type="checkbox" class="custom-control-input" name="{{aggroup.pk}}_{{perm.name}}" id="{{aggroup.pk}}_{{perm.name}}" onchange="javascript:changePerm(this.id)" {% if aggroup.is_admin %} disabled="true" {% endif %}>
|
||||
<label class="custom-control-label" for="{{aggroup.pk}}_{{perm.name}}" >{{perm.help_text}}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div><!-- END ROW RIGHT -->
|
||||
<hr>
|
||||
<div col="10">
|
||||
<h6>Mitarbeiter zur Gruppe <b>{{aggroup.agencygroupname}}</b> hinzufügen</h6>
|
||||
<div class="input-group mb-3 col-5">
|
||||
<input class="form-control searchuserfields" list="usersfree_{{aggroup.pk}}" id="searchusers_{{aggroup.pk}}" type="text" onkeyup="javascript:checkSearchUser({{aggroup.pk}})">
|
||||
<div class="input-group-append">
|
||||
<button type="button" onclick="javascript:clearSearchfield({{aggroup.pk}})" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<datalist id="usersfree_{{aggroup.pk}}">
|
||||
{% for user in usersofagency %}
|
||||
{% if not user|has_group:aggroup.group.name %}
|
||||
<option id="{{user.pk}}_{{aggroup.pk}}" value="{{user.first_name}} {{user.last_name}}">
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
</datalist>
|
||||
</div>
|
||||
<hr>
|
||||
<h6>Gruppenmitglieder in <b>{{aggroup.agencygroupname}}</b></h6>
|
||||
{% if varcounter > 0 %}
|
||||
<span id="nogroupmember_{{aggroup.pk}}" style="display: none">Diese Gruppe hat noch keine Mitglieder.</span>
|
||||
{% else %}
|
||||
<span id="nogroupmember_{{aggroup.pk}}">Diese Gruppe hat noch keine Mitglieder.</span>
|
||||
{% endif %}
|
||||
<div id="added_users_button_{{aggroup.pk}}">
|
||||
{% for user in usersofagency %}
|
||||
{% for group in user.groups.all %}
|
||||
{% if group.name == aggroup.group.name %}
|
||||
{% if request.user == user and aggroup.is_admin %}
|
||||
<span class="badge badge-pill badge-primary mr-2 mt-2"><button class="btn btn-primary" disabled="true">{{ user.first_name }} {{ user.last_name }}</button></span>
|
||||
{% else %}
|
||||
<span id="span_btn_{{user.pk}}_{{aggroup.pk}}" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromGroup({{ user.pk }}, {{aggroup.pk}})">{{ user.first_name }} {{ user.last_name }} <i class="fas fa-times"></i></a >
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ADDING GROUP PERMS -->
|
||||
{% for aggroup in agencygroups %}
|
||||
{% for p in aggroup.group.permissions.all %}
|
||||
{% for perm in perms %}
|
||||
{% if p.codename == perm.name %}
|
||||
<script>$("#{{aggroup.pk}}_{{perm.name}}").prop('checked', true);</script>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
<script>
|
||||
|
||||
/* CHECK FOR ACTIVATED MODULS */
|
||||
module_news = '{{request.user.profile.agency.module_news}}'
|
||||
module_quicklinks = '{{request.user.profile.agency.module_quicklinks}}'
|
||||
//module_files = '{{request.user.profile.agency.module_files}}'
|
||||
//module_organigramm = '{{request.user.profile.agency.module_organigramm}}'
|
||||
|
||||
if(module_quicklinks == "False"){
|
||||
$(".modulequicklinks").remove();
|
||||
}
|
||||
|
||||
if(module_news == "False"){
|
||||
$(".modulenews").remove();
|
||||
}
|
||||
|
||||
|
||||
var ua = window.navigator.userAgent;
|
||||
var isIE = /MSIE|Trident/.test(ua);
|
||||
if ( isIE ) {
|
||||
//IE specific code goes here
|
||||
setInterval(function()
|
||||
{
|
||||
alluserfields = $(".searchuserfields").each(function(key, value){
|
||||
specific_userfield_id = value['id'].split("_")[1];
|
||||
checkSearchUser(specific_userfield_id);
|
||||
});
|
||||
},400);
|
||||
}
|
||||
|
||||
//returns the params of url GET
|
||||
function getUrlVars() {
|
||||
var vars = {};
|
||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
|
||||
vars[key] = value;
|
||||
});
|
||||
return vars;
|
||||
}
|
||||
//Show Save-Toast while reload side by new group
|
||||
$(document).ready(function(){
|
||||
if( getUrlVars()["showtoast"]){
|
||||
$('#notchange_done').toast('show');
|
||||
}
|
||||
if(getUrlVars()["groupdel"]){
|
||||
$("#toast_savecontent").html("Gruppe erfolgreich gelöscht!");
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
MANAGE GROUP FUNCTIONS
|
||||
*/
|
||||
groupaction = 0;
|
||||
groupupdate_id = false;
|
||||
tempid_useraddgroup = 0;
|
||||
function clearSearchfield(groupid){
|
||||
$("#searchusers_" + groupid).val("");
|
||||
}
|
||||
|
||||
function checkSearchUser(groupid){
|
||||
var g = $('#searchusers_' + groupid).val();
|
||||
var id = $('#usersfree_' + groupid).find('option[value="' + g + '"]').attr('id');
|
||||
if(id != undefined && id.length > 0){
|
||||
tempid_useraddgroup = id.split("_")[0];
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_user_to_group",
|
||||
groupid : groupid,
|
||||
userid: tempid_useraddgroup,
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
groupid = data['data']['groupid'];
|
||||
userid = data['data']['userid'];
|
||||
user_fname = data['data']['user_fname'];
|
||||
user_lname = data['data']['user_lname'];
|
||||
$('#notchange_done').toast('show');
|
||||
$("#" + userid + "_" + groupid).remove();
|
||||
$("#toast_savecontent").html("Mitarbeiter erfolgreich hinzugefügt!");
|
||||
$("#added_users_button_" + groupid).append('<span id="span_btn_'+userid+'_'+groupid+'" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromGroup('+userid+', '+groupid+')">'+user_fname+' '+user_lname+' <i class="fas fa-times"></i></a >');
|
||||
clearSearchfield(groupid);
|
||||
newgroupcounter = parseInt($("#groupcounter_" + groupid).html())+1;
|
||||
$("#groupcounter_" + groupid).html(newgroupcounter);
|
||||
if(newgroupcounter > 0){
|
||||
$("#nogroupmember_" + groupid).hide();
|
||||
}
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Mitarbeiter konnte nicht hinzugefügt werden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function removeUserFromGroup(userid, groupid){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "remove_user_from_group",
|
||||
groupid : groupid,
|
||||
userid: userid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
groupid = data['data']['groupid'];
|
||||
userid = data['data']['userid'];
|
||||
user_fname = data['data']['user_fname'];
|
||||
user_lname = data['data']['user_lname'];
|
||||
$('#notchange_done').toast('show');
|
||||
$("#toast_savecontent").html("Mitarbeiter erfolgreich entfernt!");
|
||||
$("#span_btn_" + userid + "_" + groupid).remove();
|
||||
newgroupcounter = parseInt($("#groupcounter_" + groupid).html())-1;
|
||||
$("#groupcounter_" + groupid).html(newgroupcounter);
|
||||
if(newgroupcounter == 0){
|
||||
$("#nogroupmember_" + groupid).show();
|
||||
}
|
||||
$("#usersfree_" + groupid).append('<option id="'+userid+'_'+groupid+'" value="'+ user_fname +' '+ user_lname +'">');
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Mitarbeiter konnte nicht entfernt werden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changePerm(tosplitid){
|
||||
var splitted = tosplitid.split("_");
|
||||
perm_groupid = splitted[0];
|
||||
perm_name = splitted[1];
|
||||
perm_value = $("#"+tosplitid).is(":checked");
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "change_perm_group",
|
||||
id : perm_groupid,
|
||||
perm: perm_name,
|
||||
val : perm_value
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
|
||||
if(data['success']){
|
||||
$('#notchange_done').toast('show');
|
||||
$("#toast_savecontent").html("Gruppenrechte gespeichert!");
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Gruppenrechte nicht gespeichert!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delGroup(groupid){
|
||||
groupupdate_id = groupid;
|
||||
$("#delAgencyGroup").modal("toggle");
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_groupname",
|
||||
id : groupid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#delGroupBody").html("Soll Gruppe <b>" + data["data"]["groupname"] + "</b> glöscht werden? Mitarbeiter in dieser Gruppe <u>werden nicht gelöscht</u>.")
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doDelGroup(){
|
||||
$("#delAgencyGroup").modal("toggle");
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "delete_group",
|
||||
id : groupupdate_id
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
|
||||
if(data['success']){
|
||||
window.location.href = window.location.href + "?showtoast=true&groupdel=true";
|
||||
}
|
||||
else{
|
||||
$("#newGroup").modal("toggle");
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Gruppe konnte nicht gelöscht werden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changeGroupName(groupid){
|
||||
addGroup();
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_groupname",
|
||||
id : groupid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#newgroupname").val(data['data']['groupname']);
|
||||
$("#modTitle").html("Gruppenname ändern");
|
||||
$("#saveNewGroup").prop("disabled", false);
|
||||
groupupdate_id = groupid;
|
||||
groupaction = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//SHOW ADD GROUP MODAL
|
||||
function addGroup(){
|
||||
groupaction = 0;
|
||||
$("#newGroup").modal("toggle");
|
||||
$("#newgroupname").val("");
|
||||
$("#groupnameerr").hide();
|
||||
$("#saveNewGroup").prop("disabled", true);
|
||||
$("#modTitle").html("Gruppe erstellen");
|
||||
}
|
||||
|
||||
//CREATE NEW GROUP
|
||||
function updateGroupName(){
|
||||
namevalue = $("#newgroupname").val();
|
||||
//ADD GROUP
|
||||
if(groupaction == 0){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_group",
|
||||
newvalue : namevalue
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
|
||||
if(data['success']){
|
||||
window.location.href = window.location.href + "?showtoast=true";
|
||||
}
|
||||
else{
|
||||
$("#newGroup").modal("toggle");
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//CHANGE GROUP
|
||||
else if(groupaction == 1){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "update_groupname",
|
||||
id : groupupdate_id,
|
||||
newvalue : namevalue
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$("#newGroup").modal("toggle");
|
||||
$('#notchange_done').toast('show');
|
||||
$("#groupname_" + groupupdate_id).html("Gruppe <b>"+data['data']['newvalue']+" </b>");
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//VALIDATE FOR CORRECT INPUT IN GROUP
|
||||
function validateGroupName(groupname){
|
||||
var letters = /^[A-Za-zßäöüÄÖÜ_\-0-9 ]+$/;
|
||||
if(groupname.length > 0){
|
||||
if(!groupname.match(letters))
|
||||
{
|
||||
$("#groupnameerr").show();
|
||||
$("#saveNewGroup").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#groupnameerr").hide();
|
||||
$("#saveNewGroup").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$("#groupnameerr").hide();
|
||||
$("#saveNewGroup").prop("disabled", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- MODEAL NEW GROUP -->
|
||||
<div class="modal fade" id="newGroup" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modTitle"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input class="form-control" id="newgroupname" type="text" value="" placeholder="Gruppenname" onkeyup="javascript:validateGroupName(this.value)">
|
||||
<div id="groupnameerr" class="alert alert-danger mt-3" style="display: none">Falsche Eingabe! Keine Sonderzeichen!</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Abrechen</button>
|
||||
<button id="saveNewGroup" type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:updateGroupName()" disabled="true">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CONFIRMA DELETE GROUP -->
|
||||
<div class="modal fade" id="delAgencyGroup" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="groupDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Gruppe löschen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="delGroupBody">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelGroup()">Gruppe löschen</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{% load crispy_forms_tags %}
|
||||
<div class="col-6 mt-3">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Modul</th>
|
||||
<th scope="col">Aktiviert</th>
|
||||
<th scope="col">Einstellungen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="module_checkboxes">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="form_type" value="agencymodform">
|
||||
<input type="hidden" name="settings_area" value="moduls">
|
||||
{% for formfield in modulform %}
|
||||
<tr>
|
||||
<td>{{formfield.label_tag}}</td>
|
||||
<td>{{formfield}}</td>
|
||||
<td><button type="button" class="btn btn-sm btn-primary" disabled="true"><i class="fas fa-cog"></i></button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit" class="btn btn-success" data-toggle="tooltip" data-placement="top" title="Mit dem Speichern wird die Seite neu geladen, damit alle Einstellungen aktualisiert werden. Werden Module deaktiviert, gehen die Einstellungen und zugewiesenen Rechte nicht verloren.">Moduleinstellungen aktualisieren</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{% load crispy_forms_tags %}
|
||||
<div class="col-6 mt-3">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Benachrichtigung</th>
|
||||
<th scope="col">E-Mail</th>
|
||||
<th scope="col">Push</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="checkboxes">
|
||||
{% for formfield in notificationform %}
|
||||
{% if forloop.counter|divisibleby:2 %}
|
||||
<td>{{formfield}}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>{{formfield.label_tag}}</td>
|
||||
<td>{{formfield}}</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- Flexbox container for aligning the toasts -->
|
||||
</div>
|
||||
<script>
|
||||
$('input:checkbox').change(
|
||||
function(){
|
||||
ele = $(this).prop("name");
|
||||
if(!ele.includes("module")){
|
||||
new_stat = 0;
|
||||
if($(this).prop("checked")){
|
||||
new_stat = 1;
|
||||
}
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "update_notifications",
|
||||
fieldname : ele,
|
||||
new_stat : new_stat
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$('#notchange_done').toast('show');
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$(".toast").toast({
|
||||
autohide: true,
|
||||
delay : 3000
|
||||
});
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
{% load crispy_forms_tags %}
|
||||
<div class="media">
|
||||
<img class="img-profile " width="17%" src="{{ user.profile.get_photo_url }}">
|
||||
<div class="media-body col-5">
|
||||
<h2 class="account-heading">Profil von {{ user.first_name }} {{ user.last_name }}</h2>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h6><b>Name</b></h6>
|
||||
<p>
|
||||
{{ user.first_name }} {{ user.last_name }}
|
||||
</p>
|
||||
<h6><b>E-Mail</b></h6>
|
||||
<p>
|
||||
{{ user.email }}
|
||||
</p>
|
||||
<h6><b>Agenturfunktion</b></h6>
|
||||
<p>
|
||||
{{ user.profile.func }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h6><b>Tätigkeit</b></h6>
|
||||
<p>
|
||||
{{ user.profile.compfunc }}
|
||||
</p>
|
||||
<h6><b>Festnetz</b></h6>
|
||||
<p>
|
||||
{{ user.profile.phoneland }}
|
||||
</p>
|
||||
<h6><b>Mobil</b></h6>
|
||||
<p>
|
||||
{{ user.profile.phonemobile }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<div class="col-8">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="form_type" value="userform">
|
||||
<input type="hidden" name="settings_area" value="profil">
|
||||
<fieldset class="form-group mb-2">
|
||||
<legend class="border-bottom mb-4">
|
||||
Profil bearbeiten
|
||||
</legend>
|
||||
{% if request.user.profile.showtooltips %}
|
||||
<div class="custom-control custom-checkbox mb-2" >
|
||||
<input type="checkbox" class="custom-control-input" name="showtooltips" id="showtooltips" checked>
|
||||
<label class="custom-control-label" for="showtooltips" >Tooltips anzeigen</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="custom-control custom-checkbox mb-2">
|
||||
<input type="checkbox" class="custom-control-input" name="showtooltips" id="showtooltips">
|
||||
<label class="custom-control-label" for="showtooltips">Tooltips anzeigen</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- FORMS LADEN -->
|
||||
{{ userform|crispy }}
|
||||
</fieldset>
|
||||
|
||||
<small>Agenturrelevante Daten (Bild, Telefonnummer etc.) werden in der Benutzerverwaltung verändert.</small>
|
||||
<div class="form-group mt-3">
|
||||
<button type="submit" class="btn btn-success">E-Mailadresse aktualisieren</button>
|
||||
</div>
|
||||
</form>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="form_type" value="passwordform">
|
||||
<input type="hidden" name="settings_area" value="profil">
|
||||
<fieldset class="form-group mb-2">
|
||||
<!-- FORMS LADEN -->
|
||||
{{ passwordform|crispy}}
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group mt-3">
|
||||
<button type="submit" class="btn btn-success">Passwort ändern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
$("#showtooltips").change(function(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "change_showtooltips"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success'])
|
||||
{
|
||||
$('#notchange_done').toast('show');
|
||||
$("#toast_savecontent").html("Tooltipseinstellung erfolgreich gespeichert!");
|
||||
|
||||
if(data['data']['newttvalue']){
|
||||
$('*').tooltip("enable");
|
||||
}
|
||||
else{
|
||||
$('*').tooltip("disable");
|
||||
}
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Tooltips konnten nicht gespeichert werden!");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load counter_tag %}
|
||||
{% block content %}
|
||||
|
||||
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center" style="min-height: 200px; max-width: 250px; position: fixed; margin-top: -3%; margin-left: 70.5%; z-index: 10">
|
||||
<!-- Then put toasts within -->
|
||||
<div id="notchange_done" class="toast alert-success" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<strong class="mr-auto">Gespeichert</strong>
|
||||
<!--<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>-->
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
<div id="toast_savecontent">Änderungen wurden gespeichert.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center" style="min-height: 200px; max-width: 250px; position: fixed; margin-top: -3%; margin-left: 70.5%; z-index: 10">
|
||||
<!-- Then put toasts within -->
|
||||
<div id="notchange_err" class="toast alert-danger" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<strong class="mr-auto">Fehler aufgetreten</strong>
|
||||
<!--
|
||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
-->
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
<div id="toast_errcontent">Bitte kontaktieren Sie den Support.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-section col-12">
|
||||
|
||||
<h3>Einstellungen</i></b> <small><i data-toggle="tooltip" data-placement="top" title="Hier können Agenturweite Einstellungen (Mitarbeiter, Gruppen, Agenturinfos, Bereiche und Tätigkeiten, Abrechnung, Module usw.) verwaltet werden." class="far fa-question-circle"></i></small></h3>
|
||||
<hr>
|
||||
<ul class="nav nav-tabs" id="settingsTabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="profil-tab" data-toggle="tab" href="#profil" role="tab" aria-controls="profil" aria-selected="false" >Profil</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="notifications-tab" data-toggle="tab" href="#notifications" role="tab" aria-controls="notifications-tab" aria-selected="false">Benachrichtigungen</a>
|
||||
</li>
|
||||
{% if user|usergperm:"agencyinfo" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="agency-tab" data-toggle="tab" href="#agency" role="tab" aria-controls="agency" aria-selected="false">Agentur</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"structuremanager" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="structure-tab" data-toggle="tab" href="#structure" role="tab" aria-controls="structure" aria-selected="false">Struktur</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"usermanager" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="user-tab" data-toggle="tab" href="#user" role="tab" aria-controls="user" aria-selected="false">Mitarbeiter</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"groupmanager" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="groups-tab" data-toggle="tab" href="#groups" role="tab" aria-controls="groups" aria-selected="false">Gruppen</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"modulesconfig" %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="moduls-tab" data-toggle="tab" href="#moduls" role="tab" aria-controls="moduls" aria-selected="false">Module</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="tab-content" id="settingsTabsContent">
|
||||
<div class="tab-pane fade show" id="profil" role="tabpanel" aria-labelledby="profil-tab">
|
||||
<h5 class="mt-3">Profileinstellungen <small><i data-toggle="tooltip" data-placement="top" title="Hier können Sie Einstellungen an ihrem Profil vornehmen (E-Mail, Passwort und, ob die Tooltips angezeigt werden sollen). Alle anderen Einstellungen werden von Mitarbeitern mit entsprechenden Gruppenrechten verwaltet." class="far fa-question-circle"></i></small></h5>
|
||||
<hr>
|
||||
{% block profil_content %}
|
||||
{% include "dasettings/profil_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="notifications" role="tabpanel" aria-labelledby="notifications-tab">
|
||||
<h5 class="mt-3">Benachrichtigungen <small><i data-toggle="tooltip" data-placement="top" title="Stellen Sie hier ein, welche Art der Benachrichtigung (E-Mail oder Push) Sie für welches Ereignis (Gruppenzuweisungen, Veröffentlichung eines Standards, neue Agenturnews usw.) erhalten möchten." class="far fa-question-circle"></i></small></h5>
|
||||
|
||||
{% block notifications_content %}
|
||||
{% include "dasettings/notifications_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% if user|usergperm:"agencyinfo" %}
|
||||
<div class="tab-pane fade" id="agency" role="tabpanel" aria-labelledby="agency-tab">
|
||||
<h5 class="mt-3">Agenturinformationen <small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier die Informationen Ihrer Agentur, z.B. Adresse, E-Mailadresse und Telefon." class="far fa-question-circle"></i></small></h5>
|
||||
<hr>
|
||||
{% block agency_content %}
|
||||
{% include "dasettings/agency_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"structuremanager" %}
|
||||
<div class="tab-pane fade" id="structure" role="tabpanel" aria-labelledby="structure-tab">
|
||||
<h5 class="mt-3">Struktur <small><i data-toggle="tooltip" data-placement="top" title="Richten Sie hier Bereiche und Tätigkeiten ein, um diese in Standards und Organigramm als Agenturstruktur zu nutzen." class="far fa-question-circle"></i></small></h5>
|
||||
<hr>
|
||||
{% block structure_content %}
|
||||
{% include "dasettings/structure_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"usermanager" %}
|
||||
<div class="tab-pane fade" id="user" role="tabpanel" aria-labelledby="user-tab">
|
||||
<h5 class="mt-3">Mtarbeiter <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie hier neue Mtarbeiter an, weisen ihnen Gruppen zu und ändern Sie Stammdaten wie Foto, Namen und Agenturfunktion." class="far fa-question-circle"></i></small></h5>
|
||||
<hr>
|
||||
{% block user_content %}
|
||||
{% include "dasettings/user_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"groupmanager" %}
|
||||
<div class="tab-pane fade" id="groups" role="tabpanel" aria-labelledby="groups-tab">
|
||||
<h5 class="mt-3">Gruppen <small><i data-toggle="tooltip" data-placement="top" title="Hier werden Gruppen erstellt und bearbeitet sowie Mitglieder der Gruppen hinzugefügt und entfernt. Zudem können Rechte der Gruppen vergeben werden." class="far fa-question-circle"></i></small></h5>
|
||||
<hr>
|
||||
{% block groups_content %}
|
||||
{% include "dasettings/groups_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user|usergperm:"modulesconfig" %}
|
||||
<div class="tab-pane fade" id="moduls" role="tabpanel" aria-labelledby="moduls-tab">
|
||||
<h5 class="mt-3">Module <small><i data-toggle="tooltip" data-placement="top" title="Hier werden Module aktiviert oder deaktiviert sowie individuelle Einstellungen der Module gemacht. Wird ein Modul deaktiviert, gehen Einstellungen und Dateien nicht verloren." class="far fa-question-circle"></i></small></h5>
|
||||
{% block moduls_content %}
|
||||
{% include "dasettings/moduls_content.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var defaultsettingsview = "profil";
|
||||
/* COOKIE FOR SAVING OPEN TAB */
|
||||
$(document).ready(function(){
|
||||
|
||||
$(".toast").toast({
|
||||
autohide: true,
|
||||
delay : 3000
|
||||
});
|
||||
//Check prev Side
|
||||
var check_for_settings = document.referrer;
|
||||
//If prev side was not settings, reload cookie
|
||||
if(check_for_settings.indexOf("settings") == -1){
|
||||
$('#' + defaultsettingsview).tab('show');
|
||||
document.cookie = "lastview=" + defaultsettingsview;
|
||||
}
|
||||
|
||||
// Load active Tab with CSS class, if last Side was part of Settings
|
||||
if(getCookie('lastview').length > 0){
|
||||
$('#' + getCookie('lastview')).tab('show');
|
||||
$(".nav-link").removeClass("active");
|
||||
$("#" + getCookie('lastview') + "-tab").addClass("active");
|
||||
}
|
||||
});
|
||||
|
||||
//Change Cookie-Settings when changing Tab
|
||||
$('#settingsTabs a').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
lastview_name = $(this)[0]['hash'].substring(1);
|
||||
document.cookie = "lastview="+lastview_name;
|
||||
});
|
||||
|
||||
//Get Cookie by Name from document.cookie. Returns a String!
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var decodedCookie = decodeURIComponent(document.cookie);
|
||||
var ca = decodedCookie.split(';');
|
||||
for(var i = 0; i <ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,747 @@
|
|||
{% load static %}
|
||||
{% load counter_tag %}
|
||||
|
||||
<script src="{% static 'users/js/jquery-cropper.js' %}"></script>
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||
|
||||
<script src="{% static 'users/js/colorPick.js' %}"></script>
|
||||
<link rel="stylesheet" href="{% static 'users/css/colorPick.css' %}">
|
||||
<style>
|
||||
.colorPickSelector {
|
||||
border-radius: 5px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: all linear .2s;
|
||||
-moz-transition: all linear .2s;
|
||||
-ms-transition: all linear .2s;
|
||||
-o-transition: all linear .2s;
|
||||
transition: all linear .2s;
|
||||
}
|
||||
|
||||
.colorPickSelector:hover { transform: scale(1.1); }
|
||||
</style>
|
||||
<div class="col-6">
|
||||
<button type="button" class="btn btn-primary" onclick="javascript:addArea(false)" data-toggle="tooltip" data-placement="top" title="Neuen Bereich erstellen."><i class="fas fa-plus"></i> Bereich</button>
|
||||
</div>
|
||||
|
||||
<div id="allAreas" class="mt-3 col-8">
|
||||
<div class="areaCollapseContent" id="sortableAreas" class="mt-3">
|
||||
{%for area in agencyareas%}
|
||||
<div class="card mb-2" id="maincard_{{area.pk}}">
|
||||
<div class="card-header" id="area_{{area.pk}}" style="background-color: {{area.color}};opacity:0.8;">
|
||||
<h5 class="mb-0" style="opacity:1.0;">
|
||||
|
||||
<small><i class="fas fa-sort"></i> </small>
|
||||
<button class="btn btn-link " data-toggle="collapse" data-target="#area_content_{{area.pk}}" aria-expanded="false" aria-controls="area_content_{{area.pk}}"><small><i class="fas fa-chevron-down"></i></small></button>
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#area_content_{{area.pk}}" aria-expanded="false" aria-controls="area_content_{{area.pk}}">
|
||||
<span id="areaname_{{area.pk}}" style="color: #ffffff">Bereich <b>{{area.name}} </b></span>
|
||||
</button>
|
||||
<button type="button" style="float: right" class="btn btn-primary btn-sm" onclick="javascript:addArea({{area.pk}})" data-toggle="tooltip" data-placement="top" title="Bereichsnamen und -farbe ändern"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button style="float: right" type="button" class="btn btn-danger btn-sm mr-1" onclick="javascript:delArea({{area.pk}})" data-toggle="tooltip" data-placement="top" title="Bereich löschen"><i class="fas fa-trash-alt"></i></button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="area_content_{{area.pk}}" class="collapse" data-labelledby="area_{{area.pk}}" data-parent="#sortableAreas">
|
||||
<div class="card-body">
|
||||
<button class="btn btn-primary" onclick="javascript:addTask({{area.pk}})" data-toggle="tooltip" data-placement="top" title="Neue Tätigkeit hinzufügen."><i class="fas fa-plus"></i> Tätigkeit</button>
|
||||
<table class="table table-hover mt-2" id="areatask_{{area.pk}}_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Bereich</th>
|
||||
<th scope="col">Erstellt von</th>
|
||||
<th scope="col">Erstellt am</th>
|
||||
<th scope="col"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="areatask_{{area.pk}}">
|
||||
{% for task in alltasks %}
|
||||
{% if task.area.pk == area.pk %}
|
||||
<tr id="task_{{task.id}}" name="{{task.name}}">
|
||||
<td><a href="{% url 'standard-task' task.pk %}" id="taskname_td_area_{{task.pk}}">{{task.name }}</a></td>
|
||||
<td>{{ task.area.name }}</td>
|
||||
<td>{{ task.created_area_by.first_name }} {{ task.created_area_by.last_name }}</td>
|
||||
<td>{{ task.created_area_date }}</td>
|
||||
<td>
|
||||
<button style="float: right" class="btn btn-primary btn-sm" onclick="javascript:updateTaskComplete({{task.pk}})" data-toggle="tooltip" data-placement="top" title="Tätigkeit bearbeiten"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button style="float: right" type="button" class="btn btn-danger btn-sm mr-1" onclick="javascript:delTask({{task.pk}})" data-toggle="tooltip" data-placement="top" title="Tätigkeit löschen"><i class="fas fa-trash-alt"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODEAL NEW CHANGE AREA -->
|
||||
<div class="modal fade" id="mainmodalArea" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="mainmodalArea_title"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Bereichsname:</label>
|
||||
<input class="form-control" id="newareaname" type="text" value="" placeholder="Bereichsname" onkeyup="javascript:validateAreaName(this.value)">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Bereichsfarbe:</label>
|
||||
<div id="areacolor" class="colorPickSelector"></div>
|
||||
</div>
|
||||
<div id="newareaname_err" class="alert alert-danger mt-3" style="display: none">Falsche Eingabe! Keine Sonderzeichen!</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Abrechen</button>
|
||||
<button id="doActionAreaModal" type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:mainmodalAreaSave()" disabled="true">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- CONFIRMA DELETE Area -->
|
||||
<div class="modal fade" id="delArea" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Bereich löschen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Möchten Sie den Bereich <b><span id="areaName"></span></b> wirklich löschen? Alle darin enthaltenen Tätigkeiten <u>und Standards</u> werden ebenfalls entfernt!
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelArea()">Bereich löschen</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:$('#delArea').modal('toggle')">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- MODEAL ADD TASK -->
|
||||
<div class="modal fade" id="mainmodalTasks" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="mainmodalArea_title">Neue Tätigkeit</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Tätigkeitsname:</label>
|
||||
<input class="form-control" id="newtaskname" type="text" value="" placeholder="Bereichsname" onkeyup="javascript:validateTaskName(this.value, 0)">
|
||||
</div>
|
||||
Nach dem Erstellen der Tätigkeit können Mitarbeiter zugewiesen werden.
|
||||
<div id="newtaskname_err" class="alert alert-danger mt-3" style="display: none">Falsche Eingabe! Keine Sonderzeichen!</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Abrechen</button>
|
||||
<button id="doActionTaskModal" type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:mainmodalTaskSave()" disabled="true">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- UPDATE TASK MODAL -->
|
||||
<div class="modal fade" id="updateTask" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Tätigkeit <b><span id="tasknametoupdate"></span></b> bearbeiten</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Tätigkeitsname:</label>
|
||||
<input class="form-control" id="updateTaskName" type="text" value="" placeholder="Bereichsname" onkeyup="javascript:validateTaskName(this.value, 1)">
|
||||
</div>
|
||||
|
||||
<h6>Bereich: <small><i data-toggle="tooltip" data-placement="top" title="Wird der Bereich verändert, werden auch alle Standards in den neuen Bereich verschoben." class="far fa-question-circle"></i></small></h6>
|
||||
<div class="input-group mb-3">
|
||||
<select class="custom-select" id="taskAreaSelected">
|
||||
{%for area in agencyareas%}
|
||||
<option value="{{area.pk}}">{{area.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="updateTaskName_err" class="alert alert-danger mt-3" style="display: none">Falsche Eingabe! Keine Sonderzeichen!</div>
|
||||
<div class="custom-control custom-checkbox mb-2 mt-2">
|
||||
<input type="checkbox" class="custom-control-input" id="visibleTask" onchange="javascript:changeVisibleTask()">
|
||||
<label class="custom-control-label" for="visibleTask" >Im Organigramm sichtbar</label>
|
||||
</div>
|
||||
<h6>Mitarbeiter hinzufügen:</h6>
|
||||
<div class="input-group mb-3">
|
||||
<input class="form-control searchuserfieldstask" list="possusers" id="searchusertotask" type="text" onkeyup="javascript:checkUserToTask()" >
|
||||
<div class="input-group-append">
|
||||
<button type="button" onclick="javascript:clearSearchfieldAddToTask()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<datalist id="possusers"></datalist>
|
||||
</div>
|
||||
|
||||
<h6>Zugewiesene Mitarbeiter:</h6>
|
||||
<div id="added_users_button"></div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:updateTask()" id="doActionUpdateTask">Tätigkeit aktualisieren</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:$('#updateTask').modal('toggle')">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CONFIRMA STRUCTURE CHANGE RELOAD -->
|
||||
<div class="modal fade" id="structureChangeReload" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Struktur verändert</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Achtung! Die grundlegende Struktur der Tätigkeiten wurde verändert. Die Seite wird einmal neu geladen, sobald Sie dieses Fenster schließen.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:window.location=window.location">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CONFIRMA DELETE Task -->
|
||||
<div class="modal fade" id="delTask" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Tätigkeit löschen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Möchten Sie den Bereich <b><span id="taskName"></span></b> wirklich löschen? Alle darin enthaltenen <u>Standards</u> werden ebenfalls entfernt!
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelTask()">Tätigkeit löschen</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:$('#delTask').modal('toggle')">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var ua = window.navigator.userAgent;
|
||||
var isIE = /MSIE|Trident/.test(ua);
|
||||
if ( isIE ) {
|
||||
//IE specific code goes here
|
||||
setInterval(function()
|
||||
{
|
||||
alluserfields = $(".searchuserfieldstask").each(function(key, value){
|
||||
specific_userfield_id = value['id'].split("_")[1];
|
||||
checkUserToTask();
|
||||
});
|
||||
},400);
|
||||
}
|
||||
|
||||
function checkUserToTask(){
|
||||
var g = $('#searchusertotask').val();
|
||||
var id = $('#possusers').find('option[value="' + g + '"]').attr('id');
|
||||
if(id != undefined && id.length > 0){
|
||||
tempid_useraddtask = id.split("_")[0];
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/tasks/areaajax",
|
||||
data:{
|
||||
userid: tempid_useraddtask,
|
||||
action : 'adduser',
|
||||
objectid : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
clearSearchfieldAddToTask();
|
||||
//Add User-Button
|
||||
$("#added_users_button").append('<span id="span_btn_'+data['userid']+'" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromTask('+data['userid']+')">'+data['username_clean']+' <i class="fas fa-times"></i></a ></span>');
|
||||
|
||||
$("#possusers").empty();
|
||||
for (var i in data['remaining_users']) {
|
||||
id = data['remaining_users'][i]['id'];
|
||||
name = data['remaining_users'][i]['first_name'] + " " + data['remaining_users'][i]['last_name'];
|
||||
$("#possusers").append('<option id="'+id+'" value="'+name+'"></option>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Initial function for draggable areas
|
||||
$( function() {
|
||||
$( "#sortableAreas" ).sortable
|
||||
({
|
||||
axis:"y",
|
||||
update: function( event, ui )
|
||||
{
|
||||
datatoserver = [];
|
||||
var rows = $( "#sortableAreas" ).sortable( "widget" )[0]['children'];
|
||||
for(i = 0; i < rows.length; i++){
|
||||
tempid = rows[i]['id'].split("_")[1];
|
||||
datatoserver.push({"id" : tempid, "neworder" : i});
|
||||
}
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/areas/updateorder",
|
||||
data:{
|
||||
action: "newareaorder",
|
||||
finalod : JSON.stringify(datatoserver)
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$('#notchange_done').toast('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( "#sortableAreas" ).disableSelection();
|
||||
|
||||
taskaddtoarea = false;
|
||||
|
||||
|
||||
function clearSearchfieldAddToTask(){
|
||||
$("#searchusertotask").val("");
|
||||
}
|
||||
|
||||
function addTask(areaid){
|
||||
taskaddtoarea = areaid;
|
||||
$("#mainmodalTasks").modal("toggle");
|
||||
$("#newtaskname").val("");
|
||||
$("#doActionTaskModal").prop("disabled", true);
|
||||
$("#newtaskname_err").hide();
|
||||
}
|
||||
|
||||
|
||||
function mainmodalTaskSave(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_task",
|
||||
newvalue : $("#newtaskname").val(),
|
||||
areaid : taskaddtoarea
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
newtaskid = data['data']['newtaskid'];
|
||||
newtaskname = data['data']['name'];
|
||||
newtaskareaname = data['data']['areaname'];
|
||||
taskcreatedby = data['data']['taskcreator_fullname'];
|
||||
taskcreateddate = data['data']['createdate'];
|
||||
$("#areatask_" + taskaddtoarea).prepend('<tr id="task_'+newtaskid+'"><td><a href="/standards/standard/'+newtaskid+'/task" id="taskname_td_area_'+newtaskid+'">'+newtaskname+'</a></td><td>'+newtaskareaname+'</td><td>'+taskcreatedby+'</td><td>'+taskcreateddate+'</td><td><button style="float: right" class="btn btn-primary btn-sm" onclick="javascript:updateTaskComplete('+newtaskid+')" data-toggle="tooltip" data-placement="top" title="Tätigkeit bearbeiten"><small><i class="fas fa-pen"></i></small></button><button style="float: right" type="button" class="btn btn-danger btn-sm mr-1" onclick="javascript:delTask('+newtaskid+')" data-toggle="tooltip" data-placement="top" title="Tätigkeit löschen"><i class="fas fa-trash-alt"></i></button></td> ></tr>');
|
||||
}
|
||||
|
||||
else{
|
||||
$("#mainmodalArea").modal('toggle');
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Fehler beim Erstellen des Bereichs!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateTask(){
|
||||
namevalue = $("#updateTaskName").val();
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "change_taskname",
|
||||
newvalue : namevalue,
|
||||
newareaid : $("#taskAreaSelected").val(),
|
||||
id : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("a#taskname_td_area_" + workingTaskId).text(data["data"]["newvalue"]);
|
||||
$("#updateTask").modal("toggle");
|
||||
$('#updateTask').on('hidden.bs.modal', function (e) {
|
||||
console.log(data)
|
||||
if(data["data"]["smoved"]){
|
||||
$("#structureChangeReload").modal("toggle");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeUserFromTask(userid){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/tasks/areaajax",
|
||||
data:{
|
||||
userid: userid,
|
||||
action : 'remuser',
|
||||
objectid : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
//Remove User-Button
|
||||
$("#span_btn_"+data['userid']).remove();
|
||||
$("#possusers").empty();
|
||||
for (var i in data['remaining_users']) {
|
||||
id = data['remaining_users'][i]['id'];
|
||||
name = data['remaining_users'][i]['first_name'] + " " + data['remaining_users'][i]['last_name'];
|
||||
$("#possusers").append('<option id="'+id+'" value="'+name+'" class="addusertotask_remclass"></option>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateTaskComplete(id){
|
||||
workingTaskId = id;
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_taskname",
|
||||
id : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#added_users_button").html("");
|
||||
$("#possusers").empty();
|
||||
$("#taskAreaSelected").val(data["data"]["taskarea"]);
|
||||
$("#updateTask").modal("toggle");
|
||||
$("#updateTaskName").val(data['data']['taskname']);
|
||||
$("#tasknametoupdate").html(data['data']['taskname']);
|
||||
if(data['data']['visible'] == true){
|
||||
$("#visibleTask").prop("checked", true);
|
||||
}
|
||||
else{
|
||||
$("#visibleTask").prop("checked", false);
|
||||
}
|
||||
//ADDED USERS
|
||||
for(i = 0; i < data["data"]["addedl"]; i++){
|
||||
$("#added_users_button").append('<span id="span_btn_'+data["data"]["added_users"][i]['userid']+'" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromTask('+data["data"]["added_users"][i]['userid']+')">'+data["data"]["added_users"][i]['fullname']+' <i class="fas fa-times"></i></a ></span>')
|
||||
}
|
||||
//POSSIBLE USERS
|
||||
for(i = 0; i < data["data"]["possl"]; i++){
|
||||
$("#possusers").append('<option id="'+data["data"]["possible_users"][i]['userid']+'" value="'+ data["data"]["possible_users"][i]['fullname']+'" class="addusertotask_remclass">');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changeVisibleTask(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "update_visible_taskname",
|
||||
id : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{}
|
||||
});
|
||||
}
|
||||
|
||||
//Validate new Area-Name
|
||||
function validateTaskName(newtaskname, updateornew){
|
||||
// NEW TASK
|
||||
var letters = /^[A-Za-zßäöüÄÖÜ_\-0-9 ]+$/;
|
||||
if(updateornew == 0)
|
||||
{
|
||||
|
||||
if(newtaskname.length > 0){
|
||||
if(!newtaskname.match(letters))
|
||||
{
|
||||
$("#newtaskname_err").show();
|
||||
$("#doActionTaskModal").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#newtaskname_err").hide();
|
||||
$("#doActionTaskModal").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$("#newtaskname_err").hide();
|
||||
$("#doActionTaskModal").prop("disabled", true);
|
||||
}
|
||||
|
||||
}
|
||||
//UPDATE TASK
|
||||
else{
|
||||
if(newtaskname.length > 0){
|
||||
if(!newtaskname.match(letters))
|
||||
{
|
||||
$("#updateTaskName_err").show();
|
||||
$("#doActionUpdateTask").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#updateTaskName_err").hide();
|
||||
$("#doActionUpdateTask").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$("#updateTaskName_err").hide();
|
||||
$("#doActionUpdateTask").prop("disabled", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
workingTaskId = false;
|
||||
|
||||
function delTask(taskid){
|
||||
workingTaskId = taskid;
|
||||
$("#delTask").modal("toggle");
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_taskname",
|
||||
id : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#taskName").html(data['data']['taskname']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doDelTask(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "remove_task",
|
||||
id : workingTaskId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$('#notchange_done').toast('show');
|
||||
$("#task_"+workingTaskId).remove();
|
||||
}
|
||||
else{
|
||||
$("#delArea").modal('toggle');
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Fehler beim Erstellen des Bereichs!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function doDelArea(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "remove_area",
|
||||
id : workingAreaId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
window.location.href = window.location.href + "?showtoast=true";
|
||||
}
|
||||
else{
|
||||
$("#delArea").modal('toggle');
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Fehler beim Erstellen des Bereichs!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function delArea(areaid){
|
||||
workingAreaId = areaid;
|
||||
$("#delArea").modal("toggle");
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_areaname",
|
||||
id : areaid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#areaName").html(data['data']['areaname']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
0 = DEFAULT
|
||||
1 = NEW AREA
|
||||
2 = CHANGE AREA
|
||||
*/
|
||||
modalarea_action = 0;
|
||||
areaupdateid = false;
|
||||
default_colorpickerinit = "#3498db";
|
||||
newareacolor= "#ffffff";
|
||||
//Prepare addArea-Modal and show
|
||||
function addArea(workingAreaId)
|
||||
{
|
||||
if(workingAreaId == false)
|
||||
{
|
||||
$("#mainmodalArea_title").html("Neuen Bereich anlegen");
|
||||
$("#mainmodalArea").modal('toggle');
|
||||
$("#newareaname").val("");
|
||||
default_colorpickerinit = "#3498db";
|
||||
modalarea_action = 1;
|
||||
}
|
||||
else {
|
||||
areaupdateid = workingAreaId;
|
||||
modalarea_action = 2;
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "get_areaname",
|
||||
id : workingAreaId
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#mainmodalArea_title").html("Bereich bearbeiten");
|
||||
$("#mainmodalArea").modal('toggle');
|
||||
$("#newareaname").val(data['data']['areaname']);
|
||||
$("#doActionAreaModal").prop("disabled", false);
|
||||
default_colorpickerinit = data['data']['areacolor'];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$('#mainmodalArea').on('shown.bs.modal', function() {
|
||||
$(".colorPickSelector").colorPick(
|
||||
{
|
||||
'initialColor': default_colorpickerinit,
|
||||
'allowRecent': true,
|
||||
'recentMax': 5,
|
||||
'allowCustomColor': false,
|
||||
'palette': ["#1abc9c", "#16a085", "#2ecc71", "#27ae60", "#3498db", "#2980b9", "#9b59b6", "#8e44ad", "#34495e", "#2c3e50", "#f1c40f", "#f39c12", "#e67e22", "#d35400", "#e74c3c", "#c0392b", "#ecf0f1", "#bdc3c7", "#95a5a6", "#7f8c8d"],
|
||||
'onColorSelected': function() {
|
||||
this.element.css({'backgroundColor': this.color, 'color': this.color});
|
||||
newareacolor = this.color;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Validate new Area-Name
|
||||
function validateAreaName(newareaname){
|
||||
var letters = /^[A-Za-zßäöüÄÖÜ_\-0-9 ]+$/;
|
||||
if(newareaname.length > 0){
|
||||
if(!newareaname.match(letters))
|
||||
{
|
||||
$("#newareaname_err").show();
|
||||
$("#doActionAreaModal").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#newareaname_err").hide();
|
||||
$("#doActionAreaModal").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$("#newareaname_err").hide();
|
||||
$("#doActionAreaModal").prop("disabled", true);
|
||||
}
|
||||
}
|
||||
|
||||
//Final save-Area
|
||||
function mainmodalAreaSave(){
|
||||
namevalue = $("#newareaname").val();
|
||||
//ADD AREA
|
||||
if(modalarea_action == 1){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_area",
|
||||
newvalue : namevalue,
|
||||
color : newareacolor
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
window.location.href = window.location.href + "?showtoast=true";
|
||||
}
|
||||
else{
|
||||
$("#mainmodalArea").modal('toggle');
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Fehler beim Erstellen des Bereichs!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//CHANGE AREA
|
||||
else if(modalarea_action == 2){
|
||||
console.log(newareacolor);
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "update_areaname",
|
||||
id : areaupdateid,
|
||||
newvalue : namevalue,
|
||||
color : newareacolor
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$("#mainmodalArea").modal('toggle');
|
||||
$('#notchange_done').toast('show');
|
||||
$("#areaname_" + areaupdateid).html("Bereich <b>"+data['data']['newvalue']+" </b>");
|
||||
$("#area_" + areaupdateid).css("background-color", data['data']['color']);
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Fehler beim Erstellen des Bereichs!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section col-5">
|
||||
<h3>Stammdaten von {{user_fullname}} ändern</h3>
|
||||
<hr>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{{ userform|crispy }}
|
||||
<hr>
|
||||
<a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a>
|
||||
<button type="submit" class="btn btn-primary" style="float: right">Stammdaten speichern</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{% load counter_tag %}
|
||||
<a href="{% url 'newuserfirst' %}"class="btn btn-primary active" data-toggle="tooltip" data-placement="top" title="Fügen Sie hier einen weiteren Mitarbeiter Ihrer Agentur hinzu.">+ Mitarbeiter</a>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="form-group mb-2">
|
||||
<input class="form-control" id="tableSearch" size="50" type="text" placeholder="Suche in Tabelle...">
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">E-Mail</th>
|
||||
<th scope="col">Agenturfunktion</th>
|
||||
<th scope="col">Tätigkeit</th>
|
||||
<th scope="col">Telefon</th>
|
||||
<th scope="col">Mobil</th>
|
||||
<th scope="col"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tableresults">
|
||||
{% for item in usersofagency %}
|
||||
<tr>
|
||||
<td><a href="{% url 'user_updateprofile' item.pk 0 %}">{{item.first_name }} {{ item.last_name }}</a></td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{% if item.profile.func == None %}-{%else%}{{ item.profile.func }}{%endif%}</td>
|
||||
<td>{{ item.profile.compfunc }}</td>
|
||||
<td>{{ item.profile.phoneland }}</td>
|
||||
<td>{{ item.profile.phonemobile }}</td>
|
||||
<td>
|
||||
{% if item != request.user %}
|
||||
<a class="dropdown-item text-danger" href="{% url 'users-delete' item.pk %}" ><i class="fas fa-trash-alt"></i></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$("#tableSearch").on("keyup", function() {
|
||||
var value = $(this).val().toLowerCase();
|
||||
$("#tableresults tr").filter(function() {
|
||||
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section col-5">
|
||||
<h3>Neuer Benutzer <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie zuerst die Stammdaten fest. Anschließend können Agenturfunktion, Gruppen und Profilbild eingetragen werden." class="far fa-question-circle"></i></small></h3>
|
||||
<hr>
|
||||
<div class="progress mb-3" style="max-height: 15px;">
|
||||
<div class="progress-bar" role="progressbar" style="width: 30%; " aria-valuenow="30" aria-valuemin="0" aria-valuemax="100">Schritt 1: Stammdaten</div>
|
||||
</div>
|
||||
<small>Legen Sie hier die Stammdaten des neuen Mitarbeiters fest.</small>
|
||||
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{{ newuserform|crispy }}
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="true" id="sendmailnewuser" name="sendmailnewuser">
|
||||
<label class="form-check-label" for="sendmailnewuser" name="sendmailnewuser">
|
||||
E-Mailbenachrichtigung schicken
|
||||
</label>
|
||||
</div>
|
||||
<small>*: Der Benutzer erhält direkt eine E-Mail mit einem Link zur Passworterstellung, wenn der Haken bei <i>E-Mailbenachrichtung schicken</i> gesetzt ist. Dies kann später auch wiederholt werden.</small>
|
||||
|
||||
<hr>
|
||||
<a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a>
|
||||
<button type="submit" class="btn btn-primary" style="float: right">Weiter zu Schritt 2</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load counter_tag %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<script src="{% static 'users/js/cropper.min.js' %}"></script>
|
||||
<script src="{% static 'users/js/jquery-cropper.js' %}"></script>
|
||||
|
||||
|
||||
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center" style="min-height: 200px; max-width: 250px; position: fixed; margin-top: -3%; margin-left: 70.5%; z-index: 10">
|
||||
<!-- Then put toasts within -->
|
||||
<div id="notchange_done" class="toast alert-success" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<strong class="mr-auto">Gespeichert</strong>
|
||||
<!--<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>-->
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
<div id="toast_savecontent">Änderungen wurden gespeichert.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center" style="min-height: 200px; max-width: 250px; position: fixed; margin-top: -3%; margin-left: 70.5%; z-index: 10">
|
||||
<!-- Then put toasts within -->
|
||||
<div id="notchange_err" class="toast alert-danger" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<strong class="mr-auto">Fehler aufgetreten</strong>
|
||||
<!--
|
||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
-->
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
<div id="toast_errcontent">Bitte kontaktieren Sie den Support.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-section col-10">
|
||||
<h3>Profil von {{user_fullname}} bearbeiten <small><i data-toggle="tooltip" data-placement="top" title="Geben Sie hier die Profildaten für den Mitarbeiter ein." class="far fa-question-circle"></i></small></h3>
|
||||
<hr>
|
||||
{% if newuser == 1 %}
|
||||
<div class="progress mb-3" style="max-height: 15px;">
|
||||
<div class="progress-bar" role="progressbar" style="width: 80%; " aria-valuenow="80" aria-valuemin="0" aria-valuemax="100">Schritt 2: Profildaten festlegen</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="media mb-4">
|
||||
<img class="img-profile" style="width: 15%;" src="{{ imagelink }}">
|
||||
<div class="media-body col-6">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h6><b>Name</b></h6>
|
||||
<p>
|
||||
{{ user_fullname }}
|
||||
</p>
|
||||
<h6><b>E-Mail</b></h6>
|
||||
<p>
|
||||
{{ mail }}
|
||||
</p>
|
||||
<a type="button" class="btn-primary btn-sm active" href="{% url 'changeusermaindata' vieweduser %}">Stammdaten ändern</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="userprof_formtype" value="profileform">
|
||||
<div class="mt-2">
|
||||
<p>Gruppen <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie fest, in welchen Gruppen der neue Mitarbeiter sein soll. Standardmäßig sind alle Mitarbeiter in der Gruppe Mitarbeiter (wenn diese nicht umbenannt worden ist)." class="far fa-question-circle"></i></small></p>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
{% for g in agencygroups %}
|
||||
{% if forloop.counter|divisibleby:6 %}
|
||||
</div><div class="col-4">
|
||||
<div class="custom-control custom-checkbox mb-2">
|
||||
{% if vieweduser|useringroupbyid:g.group.name %}
|
||||
<input type="checkbox" class="custom-control-input" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:updateUser({{vieweduser}}, {{g.pk}}, this.checked)" checked="true">
|
||||
{% else %}
|
||||
<input type="checkbox" class="custom-control-input" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:updateUser({{vieweduser}}, {{g.pk}}, this.checked)">
|
||||
{% endif %}
|
||||
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="custom-control custom-checkbox mb-2">
|
||||
{% if vieweduser|useringroupbyid:g.group.name %}
|
||||
<input type="checkbox" class="custom-control-input" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:updateUser({{vieweduser}}, {{g.pk}}, this.checked)" checked="true">
|
||||
{% else %}
|
||||
<input type="checkbox" class="custom-control-input" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:updateUser({{vieweduser}}, {{g.pk}}, this.checked)">
|
||||
{% endif %}
|
||||
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="mt-2">
|
||||
<p>Übergeordneter Mitarbeiter <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie fest, welche Mitarbeiter über diesen im Organigramm steht. Ist die Einstellung leer, wir" class="far fa-question-circle"></i></small></p>
|
||||
<select name="usertoparent" id="usertoparent" class="select form-control col-4">
|
||||
<option value="">---------</option>
|
||||
{% for singleparent in usertoparent %}
|
||||
{% if parentuser == singleparent.pk %}
|
||||
<option value="{{singleparent.pk}}" selected>{{singleparent.first_name}} {{singleparent.last_name}} </option>
|
||||
{% else %}
|
||||
<option value="{{singleparent.pk}}">{{singleparent.first_name}} {{singleparent.last_name}} </option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<hr>
|
||||
<p>Persönliches Profil</p>
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
{% for field in profileform %}
|
||||
{% if forloop.counter|divisibleby:6 %}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{{field|as_crispy_field}}
|
||||
{% else %}
|
||||
{{field|as_crispy_field}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% if newuser == 1 %}
|
||||
<button type="submit" class="btn btn-primary" style="float: right">Profilerstellung abschließen</button>
|
||||
{% else %}
|
||||
<button type="submit" name="submitprof" class="btn btn-primary" style="float: right">Profil Aktualisieren</button>
|
||||
{% endif %}
|
||||
<a class="btn" href="{% url 'dasettings' %} ">Profilbearbeitung abbrechen</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODAL TO CROP THE IMAGE --><div class="modal fade " id="modalCrop" data-backdrop="static" data-keyboard="false">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Bereich bestimmen</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="clearImgField()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" id="imgmodbody">
|
||||
<img src="" id="imagemod" style="max-width: 100%; max-height: 100%;">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group pull-left" role="group">
|
||||
<button type="button" class="btn btn-default js-zoom-in">
|
||||
<i class="fas fa-search-plus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-zoom-out">
|
||||
<i class="fas fa-search-minus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-rot-left">
|
||||
<i class="fas fa-undo-alt"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-rot-right">
|
||||
<i class="fas fa-redo-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="clearImgField()">Abbrechen</button>
|
||||
<button type="button" class="btn btn-primary js-crop-and-upload">Ausschneiden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
function showMainUserForm(){
|
||||
$("#changeMainUserData").modal("toggle");
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
$(".toast").toast({
|
||||
autohide: true,
|
||||
delay : 3000
|
||||
});
|
||||
});
|
||||
|
||||
function updateUser(userid, groupid, newvalue){
|
||||
if(newvalue){
|
||||
addUserToGroup(userid, groupid);
|
||||
}
|
||||
else{
|
||||
removeUserFromGroup(userid, groupid);
|
||||
}
|
||||
}
|
||||
|
||||
function removeUserFromGroup(userid, groupid){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "remove_user_from_group",
|
||||
groupid : groupid,
|
||||
userid: userid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$('#notchange_done').toast('show');
|
||||
$("#toast_savecontent").html("Mitarbeiter erfolgreich aus der Gruppe entfernt!");
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Mitarbeiter konnte nicht entfernt werden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function addUserToGroup(userid, groupid){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dasettings/ajax",
|
||||
data:{
|
||||
action : "add_user_to_group",
|
||||
groupid : groupid,
|
||||
userid: userid,
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data['success']){
|
||||
$('#notchange_done').toast('show');
|
||||
$("#toast_savecontent").html("Mitarbeiter erfolgreich der Gruppe hinzugefügt!");
|
||||
}
|
||||
else{
|
||||
$('#notchange_err').toast('show');
|
||||
$("#toast_errcontent").html("Mitarbeiter konnte nicht hinzugefügt werden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* CROPPER */
|
||||
$("#id_x").val(0);
|
||||
$("#id_y").val(0);
|
||||
$("#id_width").val(300);
|
||||
$("#id_height").val(300);
|
||||
$("#id_rotation").val(0);
|
||||
|
||||
function clearImgField(){
|
||||
$("#id_image").val("");
|
||||
}
|
||||
|
||||
|
||||
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
|
||||
$("#id_image").change(function () {
|
||||
if (this.files && this.files[0]) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
$("#imagemod").attr("src", e.target.result);
|
||||
$("#modalCrop").modal("show");
|
||||
}
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
var cropBoxData;
|
||||
var canvasData;
|
||||
var $image = $("#imagemod");
|
||||
$("#modalCrop").on("shown.bs.modal", function () {
|
||||
$image.cropper({
|
||||
viewMode: 3,
|
||||
aspectRatio: 1/1,
|
||||
strict: false,
|
||||
cropBoxMovable: true,
|
||||
cropBoxResizable: true,
|
||||
minCropBoxWidth: 200,
|
||||
minCropBoxHeight: 200,
|
||||
ready: function () {
|
||||
$image.cropper("setCanvasData", canvasData);
|
||||
$image.cropper("setCropBoxData", cropBoxData);
|
||||
}
|
||||
});
|
||||
$("#imgmodbody").css({
|
||||
"maxWidth": 465
|
||||
});
|
||||
|
||||
}).on("hidden.bs.modal", function () {
|
||||
cropBoxData = $image.cropper("getCropBoxData");
|
||||
canvasData = $image.cropper("getCanvasData");
|
||||
$image.cropper("destroy");
|
||||
});
|
||||
|
||||
$(".js-zoom-in").click(function () {
|
||||
$image.cropper("zoom", 0.1);
|
||||
});
|
||||
|
||||
$(".js-zoom-out").click(function () {
|
||||
$image.cropper("zoom", -0.1);
|
||||
});
|
||||
|
||||
$(".js-rot-right").click(function () {
|
||||
$image.cropper("rotate", 90);
|
||||
});
|
||||
|
||||
$(".js-rot-left").click(function () {
|
||||
$image.cropper("rotate", -90);
|
||||
});
|
||||
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
|
||||
$(".js-crop-and-upload").click(function () {
|
||||
var cropData = $image.cropper("getData");
|
||||
$("#id_x").val(cropData["x"]);
|
||||
$("#id_y").val(cropData["y"]);
|
||||
$("#id_height").val(cropData["height"]);
|
||||
$("#id_width").val(cropData["width"]);
|
||||
$("#id_rotation").val(cropData["rotate"]);
|
||||
$("#id_image").attr("src", $image);
|
||||
$("#modalCrop").modal('toggle');
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
from django.urls import path
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from . import views
|
||||
from .views import NewUserFirstStep, UserProfileUpdate, UserChangeMain
|
||||
'''
|
||||
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
||||
'''
|
||||
|
||||
urlpatterns = [
|
||||
path('main/', views.DASettings, name='dasettings'),
|
||||
path('newuser/s1', permission_required('users.usermanager')(views.NewUserFirstStep), name='newuserfirst'),
|
||||
path('changeus/<int:pk>/', permission_required('users.usermanager')(views.UserChangeMain), name='changeusermaindata'),
|
||||
path('ajax/', views.SettingsAjaxRouter, name="dasettings-ajax"),
|
||||
path('usprof/<int:pk>/<int:newuser>', permission_required('users.usermanager')(views.UserProfileUpdate), name="user_updateprofile")
|
||||
]
|
||||
|
|
@ -0,0 +1,557 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
|
||||
from .forms import UsersSelfChangeForm, UsersNotificationForm, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import update_session_auth_hash
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
from users.usersforms import AgencyUpdateForm
|
||||
from users.models import AgencyJob, AgencyGroup
|
||||
from django.contrib.auth.models import User, Group, Permission
|
||||
import random
|
||||
import string
|
||||
from users.usersforms import UsersPermForm
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic import CreateView
|
||||
from users.models import Profile
|
||||
from areas.models import Areas
|
||||
from tasks.models import Tasks
|
||||
import webcolors
|
||||
from datetime import datetime
|
||||
from standards.models import Standards
|
||||
|
||||
def randomString(stringLength=10):
|
||||
"""Generate a random string of fixed length """
|
||||
letters = string.ascii_lowercase
|
||||
return ''.join(random.choice(letters) for i in range(stringLength))
|
||||
|
||||
@login_required
|
||||
def checkForGroupName(request, newgroupname):
|
||||
stat = True
|
||||
groupsagency = AgencyGroup.objects.filter(agency__pk=request.user.profile.agency.pk)
|
||||
for group in groupsagency:
|
||||
if group.agencygroupname.upper() == newgroupname.upper():
|
||||
stat = False
|
||||
return stat
|
||||
|
||||
@login_required
|
||||
def getAllForms(request, context):
|
||||
# USERFORMS
|
||||
userform = UsersSelfChangeForm(instance=request.user)
|
||||
passwordform = PasswordChangeForm(request.user)
|
||||
context.update({'userform' : userform})
|
||||
context.update({'passwordform' : passwordform})
|
||||
|
||||
# NOTIFICTAION FORMS
|
||||
notificationform = UsersNotificationForm(instance=request.user.profile)
|
||||
context.update({'notificationform' : notificationform})
|
||||
|
||||
# AGENCY UPDATE FORMS
|
||||
agencyform = AgencyUpdateForm(instance=request.user.profile.agency)
|
||||
context.update({'agencyform' : agencyform})
|
||||
|
||||
#PERMS
|
||||
perms = AgencyGroupPerms()
|
||||
context.update({'perms' : perms})
|
||||
|
||||
#MODULFORMS
|
||||
modulform = AgencyModulsForm(instance=request.user.profile.agency)
|
||||
context.update({'modulform' : modulform})
|
||||
|
||||
# USER FOR USERTABLE
|
||||
users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
|
||||
return context
|
||||
|
||||
|
||||
'''
|
||||
Lädt die Formulare für die einzelnen Einstellungen vollständig
|
||||
'''
|
||||
@login_required
|
||||
def DASettings(request):
|
||||
context = {
|
||||
'active_link' : 'dasettings'
|
||||
}
|
||||
context = getAllForms(request, context)
|
||||
|
||||
# USERS FOR MEMBERS AND GROUPCOUNTERS
|
||||
usersofagency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).order_by("last_name")
|
||||
context.update({"usersofagency" : usersofagency})
|
||||
|
||||
# LOAD AGENCYJOBS
|
||||
context.update({"agencyjobs" : AgencyJob.objects.filter(agency__pk=request.user.profile.agency.pk).order_by("name")})
|
||||
|
||||
# LOAD GROUPS
|
||||
agencygroups = AgencyGroup.objects.filter(agency__pk=request.user.profile.agency.pk).order_by("agencygroupname")
|
||||
context.update({"agencygroups" : agencygroups})
|
||||
|
||||
# LOAD AREAS
|
||||
agencyareas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk).order_by('areaorder')
|
||||
context.update({"agencyareas" : agencyareas})
|
||||
|
||||
# LOAD TASKS
|
||||
alltasks = Tasks.objects.filter(agency__pk=request.user.profile.agency.pk).order_by('name')
|
||||
context.update({"alltasks" : alltasks})
|
||||
|
||||
if request.method == 'POST' and request.POST.get("settings_area") == "profil":
|
||||
return SettingsProfilManagement(request, context)
|
||||
elif request.method == 'POST' and request.POST.get("settings_area") == "agency":
|
||||
return SettingsAgency(request, context)
|
||||
elif request.method == 'POST' and request.POST.get("settings_area") == "moduls":
|
||||
return SettingsAgencyModuls(request, context)
|
||||
|
||||
|
||||
|
||||
# Returning the data from database for normal-loading Settings
|
||||
else:
|
||||
# DEFAULT DATA FORM-INFOS
|
||||
# Hier müssen alle Standard-Formulare rein, damit die Seite Settings
|
||||
# generell geladen werden kann.
|
||||
# PROFILE FORMS
|
||||
userform = UsersSelfChangeForm(instance=request.user)
|
||||
passwordform = PasswordChangeForm(request.user)
|
||||
context.update({'userform' : userform})
|
||||
context.update({'passwordform' : passwordform})
|
||||
|
||||
# NOTIFICTAION FORMS
|
||||
notificationform = UsersNotificationForm(instance=request.user.profile)
|
||||
context.update({'notificationform' : notificationform})
|
||||
|
||||
# AGENCY UPDATE FORMS
|
||||
agencyform = AgencyUpdateForm(instance=request.user.profile.agency)
|
||||
context.update({'agencyform' : agencyform})
|
||||
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
|
||||
'''
|
||||
|
||||
AGENCY
|
||||
|
||||
Hier werden die Agenturinfos ink. Agenturcropper für das Agenturbild angepasst.
|
||||
|
||||
'''
|
||||
@login_required
|
||||
def SettingsAgency(request, context):
|
||||
if request.POST.get("form_type") == "agencyform":
|
||||
agencyform = AgencyUpdateForm(request.POST, instance=request.user.profile.agency)
|
||||
if agencyform.is_valid():
|
||||
if 'agencypic' in request.FILES:
|
||||
request.user.profile.agency.agencypic = request.FILES['agencypic']
|
||||
agencyform.save()
|
||||
context['agencyform'] = AgencyUpdateForm(instance=request.user.profile.agency)
|
||||
messages.success(request, f'Agenturdaten aktualisiert!')
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
else:
|
||||
messages.success(request, f'Daten falsch eingegeben!')
|
||||
context['agencyform'] = AgencyUpdateForm(instance=request.user.profile.agency)
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
|
||||
@login_required
|
||||
def SettingsAgencyModuls(request, context):
|
||||
if request.POST.get("form_type") == "agencymodform":
|
||||
agencymoduleform = AgencyModulsForm(request.POST, instance=request.user.profile.agency)
|
||||
if agencymoduleform.is_valid():
|
||||
agencymoduleform.save()
|
||||
context['modulform'] = AgencyModulsForm(instance=request.user.profile.agency)
|
||||
messages.success(request, f'Moduleinstellungen aktualisiert!')
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
else:
|
||||
context['modulform'] = AgencyModulsForm(instance=request.user.profile.agency)
|
||||
messages.success(request, f'Fehler beim aktualisieren! Bitte wenden Sie sich an den Support.')
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
|
||||
'''
|
||||
|
||||
Hier werden die Profilinfos des User zurückgesetzt; Parameter kommen von Settings()
|
||||
|
||||
- Email
|
||||
- Passwort aktualisieren
|
||||
|
||||
'''
|
||||
@login_required
|
||||
def SettingsProfilManagement(request, context):
|
||||
# Check, which form
|
||||
# USERFORM
|
||||
if request.POST.get("form_type") == "userform":
|
||||
userform = UsersSelfChangeForm(request.POST, instance=request.user)
|
||||
if userform.is_valid():
|
||||
userform.save()
|
||||
messages.success(request, f'E-Mailadresse aktualisiert!')
|
||||
passwordform = PasswordChangeForm(request.user)
|
||||
context['userform'] = userform
|
||||
context['passwordform'] = passwordform
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
else:
|
||||
messages.success(request, f'Keine E-Mailadresse eingegeben oder E-Mail bereits vorhanden!')
|
||||
passwordform = PasswordChangeForm(request.user)
|
||||
userform = UsersSelfChangeForm(instance=request.user)
|
||||
context['userform'] = userform
|
||||
context['passwordform'] = passwordform
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
# PASSWORDFORM
|
||||
elif request.POST.get("form_type") == "passwordform":
|
||||
passwordform = PasswordChangeForm(request.user, request.POST)
|
||||
if passwordform.is_valid():
|
||||
passwordform.save()
|
||||
update_session_auth_hash(request, request.user)
|
||||
userform = UsersSelfChangeForm(instance=request.user)
|
||||
context['userform'] = userform
|
||||
context['passwordform'] = passwordform
|
||||
messages.success(request, f'Passwort aktualisiert!')
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
else:
|
||||
messages.success(request, f'Passwort falsch eingegeben!')
|
||||
passwordform = PasswordChangeForm(request.user)
|
||||
userform = UsersSelfChangeForm(instance=request.user)
|
||||
context['userform'] = userform
|
||||
context['passwordform'] = passwordform
|
||||
return render(request, 'dasettings/settings.html', context)
|
||||
|
||||
@login_required
|
||||
def SettingsAjaxRouter(request):
|
||||
success = False
|
||||
data = {}
|
||||
# UPDATE NOTIFICATIONS BY FIELDNAME AND NEW VALUE
|
||||
if request.method == 'GET' and request.GET['action'] == "update_notifications" :
|
||||
success = False
|
||||
new_stat = request.GET['new_stat']
|
||||
field_to_change = getattr(request.user.profile, request.GET['fieldname'])
|
||||
if(field_to_change or not field_to_change):
|
||||
if(new_stat == "1"):
|
||||
setattr(request.user.profile, request.GET['fieldname'], True)
|
||||
else:
|
||||
setattr(request.user.profile, request.GET['fieldname'], False)
|
||||
request.user.profile.save()
|
||||
success = True
|
||||
# UPDATE TOOLTUP
|
||||
elif request.method == 'GET' and request.GET['action'] == "change_showtooltips" :
|
||||
newtooltipvalue = False
|
||||
user = User.objects.get(pk=request.user.pk, profile__agency=request.user.profile.agency)
|
||||
if user.profile.showtooltips:
|
||||
user.profile.showtooltips = False
|
||||
else:
|
||||
user.profile.showtooltips = True
|
||||
newtooltipvalue = True
|
||||
user.save()
|
||||
success = True
|
||||
data = {'newttvalue' : newtooltipvalue}
|
||||
# UPDATE AGENCYJOB
|
||||
elif request.method == 'GET' and request.GET['action'] == "update_agencyfunc" :
|
||||
job_id = request.GET['id']
|
||||
job_value = request.GET['newvalue']
|
||||
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
|
||||
tempjob.name = job_value
|
||||
tempjob.save()
|
||||
success = True
|
||||
# DELETE AGENVY JOB FUNC - RETURN ONLY NAME FOR CONFIRM
|
||||
elif request.method == 'GET' and request.GET['action'] == "get_agencyfunc" :
|
||||
job_id = request.GET['id']
|
||||
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
|
||||
data = {"funcname" : tempjob.name}
|
||||
success = True
|
||||
# DELETE FINAL AGECY JOB
|
||||
elif request.method == 'GET' and request.GET['action'] == "delete_agencyfunc" :
|
||||
job_id = request.GET['id']
|
||||
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
|
||||
tempjob.delete()
|
||||
success = True
|
||||
elif request.method == 'GET' and request.GET['action'] == "add_agencyfunc" :
|
||||
tempjob = AgencyJob(name="", agency=request.user.profile.agency)
|
||||
tempjob.save()
|
||||
data = {"new_id" : tempjob.pk}
|
||||
success = True
|
||||
# GRUPPENAMEN AKTUALISIEREN
|
||||
elif request.method == 'GET' and request.GET['action'] == "update_groupname" :
|
||||
group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
if(checkForGroupName(request, request.GET['newvalue'])):
|
||||
group.agencygroupname = request.GET['newvalue']
|
||||
group.save()
|
||||
data = {"newvalue" : group.agencygroupname}
|
||||
success = True
|
||||
else:
|
||||
success = False
|
||||
# GRUPPENNAMEN HOLEN
|
||||
elif request.method == 'GET' and request.GET['action'] == "get_groupname" :
|
||||
group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
data = {"groupname" : group.agencygroupname}
|
||||
success = True
|
||||
elif request.method == 'GET' and request.GET['action'] == "add_group" :
|
||||
if(checkForGroupName(request, request.GET['newvalue'])):
|
||||
tempgroup = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
|
||||
tempgroup.save()
|
||||
tempgroup_ag = AgencyGroup(savefordel=False, group=tempgroup, agency=request.user.profile.agency, agencygroupname=request.GET['newvalue'])
|
||||
tempgroup_ag.save()
|
||||
success = True
|
||||
data = {"group_id" : tempgroup_ag.pk, "group_name" : tempgroup_ag.agencygroupname}
|
||||
else:
|
||||
success = False
|
||||
elif request.method == 'GET' and request.GET['action'] == "delete_group" :
|
||||
groupag = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
group_to_del = groupag.group
|
||||
group_to_del.delete()
|
||||
success = True
|
||||
# PERMISSIONS ON GROUP!
|
||||
elif request.method == 'GET' and request.GET['action'] == "change_perm_group" :
|
||||
success = True
|
||||
group_id = request.GET['id']
|
||||
perm_name = request.GET['perm']
|
||||
val = request.GET['val']
|
||||
aggroup = AgencyGroup.objects.get(pk=group_id, agency=request.user.profile.agency)
|
||||
# CHECK IF REQUESTED USER IS IN THIS AGENCY
|
||||
if(request.user.profile.agency.pk == aggroup.agency.pk):
|
||||
if(val == "true"):
|
||||
tempperm = Permission.objects.get(codename=perm_name)
|
||||
aggroup.group.permissions.add(tempperm)
|
||||
else:
|
||||
tempperm = Permission.objects.get(codename=perm_name)
|
||||
aggroup.group.permissions.remove(tempperm)
|
||||
else:
|
||||
success = False
|
||||
# REMOVE USER FROM GROUP
|
||||
elif request.method == 'GET' and request.GET['action'] == "remove_user_from_group" :
|
||||
success = True
|
||||
groupid = request.GET['groupid']
|
||||
userid = request.GET['userid']
|
||||
aggroup = AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency)
|
||||
usertoremove = User.objects.get(pk=userid, profile__agency=request.user.profile.agency)
|
||||
# CHECK IF REQUESTED USER IS IN THIS AGENCY
|
||||
if(request.user.profile.agency.pk == aggroup.agency.pk):
|
||||
if aggroup.group in usertoremove.groups.all():
|
||||
aggroup.group.user_set.remove(usertoremove)
|
||||
|
||||
data = {"userid" : usertoremove.pk, "groupid" : aggroup.pk, "user_fname" : usertoremove.first_name, "user_lname" : usertoremove.last_name}
|
||||
else:
|
||||
success = False
|
||||
# ADD USER TO GROUP
|
||||
elif request.method == 'GET' and request.GET['action'] == "add_user_to_group" :
|
||||
success = True
|
||||
groupid = request.GET['groupid']
|
||||
userid = request.GET['userid']
|
||||
aggroup = AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency)
|
||||
usertoadd = User.objects.get(pk=userid, profile__agency=request.user.profile.agency)
|
||||
# CHECK IF REQUESTED USER IS IN THIS AGENCY
|
||||
if(request.user.profile.agency.pk == aggroup.agency.pk):
|
||||
aggroup.group.user_set.add(usertoadd)
|
||||
data = {"userid" : usertoadd.pk, "groupid" : aggroup.pk, "user_fname" : usertoadd.first_name, "user_lname" : usertoadd.last_name}
|
||||
else:
|
||||
success = False
|
||||
# AREA
|
||||
# AREANAMEN HOLEN
|
||||
elif request.method == 'GET' and request.GET['action'] == "get_areaname" :
|
||||
area = Areas.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
data = {"areaname" : area.name, "areacolor" : area.color}
|
||||
success = True
|
||||
# ARENAMEN UPDATE
|
||||
elif request.method == 'GET' and request.GET['action'] == "update_areaname" :
|
||||
area = Areas.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
area.name = request.GET['newvalue']
|
||||
area.color = request.GET['color']
|
||||
area.save()
|
||||
data = {"newvalue" : area.name, "color" : area.color}
|
||||
success = True
|
||||
# ADD AREA
|
||||
elif request.method == 'GET' and request.GET['action'] == "add_area" :
|
||||
area = Areas(created_area_by=request.user, agency=request.user.profile.agency, name=request.GET["newvalue"], color=request.GET['color'])
|
||||
area.save()
|
||||
success = True
|
||||
# REMOVE AREA
|
||||
elif request.method == 'GET' and request.GET['action'] == "remove_area" :
|
||||
Areas(pk=request.GET['id']).delete()
|
||||
success = True
|
||||
# ADD TASK
|
||||
elif request.method == 'GET' and request.GET['action'] == "add_task" :
|
||||
task = Tasks(created_area_by=request.user, area=Areas.objects.get(pk=request.GET['areaid']), agency=request.user.profile.agency, name=request.GET["newvalue"])
|
||||
task.save()
|
||||
taskcreator_fullname = task.created_area_by.first_name + " " + task.created_area_by.last_name
|
||||
data = {"name" : task.name, "newtaskid" : task.pk, "areaname" : task.area.name, "taskcreator_fullname" : taskcreator_fullname, "createdate" : task.created_area_date.strftime("%d. %B %Y")}
|
||||
success = True
|
||||
# TASKNAME VISIBLE UND USERS HOLEN
|
||||
elif request.method == 'GET' and request.GET['action'] == "get_taskname" :
|
||||
task = Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
# User still in Area
|
||||
# Get all Users from same Agency which are NOT in context_added_users
|
||||
added_users = task.usersfield.all()
|
||||
addus = {}
|
||||
posus = {}
|
||||
i = 0
|
||||
# GET ADDED USERS
|
||||
for us in added_users:
|
||||
addus.update({ i : {"fullname" : us.first_name + " " + us.last_name, "userid" : us.pk}})
|
||||
i += 1
|
||||
|
||||
# GET POSSIBLE TO ADD USERS
|
||||
k = 0
|
||||
possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).exclude(pk__in=added_users)
|
||||
print(possible_users)
|
||||
for us in possible_users:
|
||||
posus.update({ k : {"fullname" : us.first_name + " " + us.last_name, "userid" : us.pk}})
|
||||
k += 1
|
||||
print(posus)
|
||||
data = {"taskname" : task.name, "visible" : task.visible, "added_users" : addus, "addedl" : i, "possl" : k, "possible_users" : posus, "taskarea" : task.area.pk}
|
||||
success = True
|
||||
# REMOVE Task
|
||||
elif request.method == 'GET' and request.GET['action'] == "remove_task" :
|
||||
Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency).delete()
|
||||
success = True
|
||||
# UPDATE TASK VISIBLE
|
||||
elif request.method == 'GET' and request.GET['action'] == "update_visible_taskname" :
|
||||
task = Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
|
||||
if(task.visible):
|
||||
task.visible = False;
|
||||
else:
|
||||
task.visible = True;
|
||||
task.save()
|
||||
success = True
|
||||
# UPDATE TASKNAME
|
||||
elif request.method == 'GET' and request.GET['action'] == "change_taskname" :
|
||||
task = Tasks.objects.get(pk=request.GET['id'])
|
||||
task.name = request.GET["newvalue"]
|
||||
data = {"newvalue" : task.name}
|
||||
newareaid = request.GET["newareaid"]
|
||||
standardsmoved = False
|
||||
if int(task.area.pk) != int(newareaid):
|
||||
standardsmoved = True
|
||||
newareaobj = Areas.objects.get(pk=newareaid, agency=request.user.profile.agency)
|
||||
Standards.objects.filter(agency=request.user.profile.agency, area=task.area).update(area=newareaobj)
|
||||
task.area = newareaobj
|
||||
task.save()
|
||||
data = {"newvalue" : task.name, "smoved" : standardsmoved}
|
||||
success = True
|
||||
else:
|
||||
success = False
|
||||
return JsonResponse({"success" : success, "data" : data})
|
||||
|
||||
|
||||
'''
|
||||
UserProfileUpdate
|
||||
|
||||
unterscheidet zwischen newuser=0 --> PROFIL AKTUALISIEREN
|
||||
und newuser=1 --> PROFIL Neu speichern
|
||||
|
||||
'''
|
||||
@login_required
|
||||
def UserProfileUpdate(request, pk, newuser=0):
|
||||
usertochange = User.objects.get(pk=pk)
|
||||
user_fullname = usertochange.first_name + " " + usertochange.last_name
|
||||
parentuser = ""
|
||||
if(usertochange.profile.parent != None):
|
||||
parentuser = usertochange.profile.parent.pk
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'image' in request.FILES:
|
||||
usertochange.profile.image = request.FILES['image']
|
||||
formtosave = False
|
||||
|
||||
formtosave = UserProfileForm(request.POST, instance=usertochange.profile)
|
||||
|
||||
if formtosave.is_valid():
|
||||
try:
|
||||
usertochange.profile.parent = User.objects.get(pk=request.POST['usertoparent'], profile__agency=request.user.profile.agency)
|
||||
usertochange.save()
|
||||
except Exception as e:
|
||||
usertochange.profile.parent = None
|
||||
usertochange.save()
|
||||
|
||||
formtosave.save()
|
||||
messages.success(request, f'Profil gespeichert!')
|
||||
return redirect('dasettings')
|
||||
else:
|
||||
messages.success(request, f'Fehlerhafte Eingabe!')
|
||||
context = {
|
||||
'active_link' : 'dasettings',
|
||||
'user_fullname' : user_fullname,
|
||||
'newuser' : newuser,
|
||||
'vieweduser' : usertochange.pk,
|
||||
'parentuser' : parentuser,
|
||||
'mail' : usertochange.email,
|
||||
'imagelink' : usertochange.profile.get_photo_url,
|
||||
'profileform' : UserProfileForm(instance=usertochange.profile),
|
||||
'usertoparent' : User.objects.filter(profile__agency__pk=usertochange.profile.agency.pk, profile__visible=True)
|
||||
}
|
||||
return render(request, 'dasettings/user_usprof.html', context)
|
||||
else:
|
||||
|
||||
context = {
|
||||
'active_link' : 'dasettings',
|
||||
'user_fullname' : user_fullname,
|
||||
'newuser' : newuser,
|
||||
'mail' : usertochange.email,
|
||||
'vieweduser' : usertochange.pk,
|
||||
'imagelink' : usertochange.profile.get_photo_url,
|
||||
'profileform' : UserProfileForm(instance=usertochange.profile),
|
||||
'parentuser' : parentuser,
|
||||
'usertoparent' : User.objects.filter(profile__agency__pk=usertochange.profile.agency.pk, profile__visible=True),
|
||||
'agencygroups' : AgencyGroup.objects.filter(agency__pk=usertochange.profile.agency.pk).order_by("agencygroupname")
|
||||
}
|
||||
return render(request, 'dasettings/user_usprof.html', context)
|
||||
|
||||
# View zur Veränderung der Stammdaten des Benutzers
|
||||
@login_required
|
||||
def UserChangeMain(request, pk):
|
||||
usertochange = User.objects.get(pk=pk, profile__agency=request.user.profile.agency)
|
||||
user_fullname = usertochange.first_name + " " + usertochange.last_name
|
||||
if request.method == 'POST':
|
||||
formtosave = UserNewUserForm(request.POST, instance=usertochange)
|
||||
if formtosave.is_valid():
|
||||
formtosave.save()
|
||||
formtosave.save()
|
||||
messages.success(request, f'Stammdaten aktualisiert!')
|
||||
return redirect('dasettings')
|
||||
else:
|
||||
messages.success(request, f'Fehlerhafte Eingabe! Mailadresse bereits vorhanden!')
|
||||
context = {
|
||||
'active_link' : 'dasettings',
|
||||
'user_fullname' : user_fullname,
|
||||
'userform' : UserNewUserForm(request.POST, instance=usertochange),
|
||||
}
|
||||
return render(request, 'dasettings/user_changemaindata.html', context)
|
||||
else:
|
||||
context = {
|
||||
'active_link' : 'dasettings',
|
||||
'user_fullname' : user_fullname,
|
||||
'userform' : UserNewUserForm(instance=usertochange),
|
||||
}
|
||||
return render(request, 'dasettings/user_changemaindata.html', context)
|
||||
|
||||
# Method for first User-Creation-Step
|
||||
@login_required
|
||||
def NewUserFirstStep(request):
|
||||
|
||||
context = {
|
||||
'active_link' : 'dasettings'
|
||||
}
|
||||
|
||||
if request.method == 'POST':
|
||||
newuserform = UserNewUserForm(request.POST)
|
||||
if newuserform.is_valid():
|
||||
if(request.POST.get("sendmailnewuser")):
|
||||
send_mail(
|
||||
request.user.profile.agency.name + ' Account',
|
||||
'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort.',
|
||||
'support@digitale-agentur.com',
|
||||
[newuserform.cleaned_data.get('email')],
|
||||
html_message=msg_html,
|
||||
fail_silently=False,
|
||||
)
|
||||
newuser = newuserform.save(commit=False)
|
||||
newuser.username = newuser.email
|
||||
newprofile = Profile(agency=request.user.profile.agency, parent=None)
|
||||
newprofile.save()
|
||||
newuser.profile = newprofile
|
||||
newuser.save()
|
||||
newuser_id = newuser.id
|
||||
messages.success(request, f'Benutzer angelegt!')
|
||||
getadmingroup = AgencyGroup.objects.filter(savefordel=True, is_admin=False, agency=request.user.profile.agency)
|
||||
for g in getadmingroup:
|
||||
g.group.user_set.add(newuser)
|
||||
return redirect('/dasettings/usprof/'+str(newuser_id)+'/1')
|
||||
else:
|
||||
messages.success(request, f'Daten falsch eingegeben!')
|
||||
context['newuserform'] = UserNewUserForm(request.POST)
|
||||
return render(request, 'dasettings/user_newuser_step1.html', context)
|
||||
|
||||
# Returning the data from database for normal-loading Settings
|
||||
else:
|
||||
newuserform = UserNewUserForm()
|
||||
context.update({'newuserform' : newuserform})
|
||||
|
||||
return render(request, 'dasettings/user_newuser_step1.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.
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class NotificsysConfig(AppConfig):
|
||||
name = 'notificsys'
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-09 15:35
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserNotification',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('notificationtype', models.CharField(blank=True, max_length=60)),
|
||||
('wassend', models.BooleanField(default=False)),
|
||||
('wasviewed', models.BooleanField(default=False)),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('notificationtext', models.CharField(blank=True, max_length=200)),
|
||||
('fromuser', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='fromuser', to=settings.AUTH_USER_MODEL)),
|
||||
('touser', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='touser', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-09 16:06
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('notificsys', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='usernotification',
|
||||
name='fromuser',
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-09 16:20
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('notificsys', '0002_remove_usernotification_fromuser'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='usernotification',
|
||||
name='touser',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.2 on 2020-02-09 21:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('notificsys', '0003_auto_20200209_1620'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='usernotification',
|
||||
name='elementid',
|
||||
field=models.IntegerField(blank=True, default=None, null=True),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,27 @@
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from datetime import datetime, timedelta
|
||||
from django.contrib.auth.models import User
|
||||
# Create your models here.
|
||||
'''
|
||||
|
||||
class UserNotification
|
||||
|
||||
Model für Benachrichtigungen
|
||||
|
||||
'''
|
||||
class UserNotification(models.Model):
|
||||
|
||||
# Wenn der User gelöscht wird, wird auch die Notification entfernt
|
||||
touser = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
notificationtype = models.CharField(max_length=60, blank=True)
|
||||
# Notifcaton was send or not (for sound-update at the client)
|
||||
wassend = models.BooleanField(default=False)
|
||||
# Wurde gesehen
|
||||
wasviewed = models.BooleanField(default=False)
|
||||
created = models.DateTimeField(default=timezone.now)
|
||||
elementid = models.IntegerField(default=None, null=True, blank=True)
|
||||
# Eventuell automatisches Lösch-Datum
|
||||
#willdeleted = models.DateTimeField(default=timezone.now()+timedelta(days=30))
|
||||
# Textcontent
|
||||
notificationtext = models.CharField(max_length=200, blank=True)
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-5">
|
||||
<h3>Alle Benachrichtigungen</h3>
|
||||
<hr>
|
||||
<button href="#" class="btn btn-danger mb-2" data-toggle="tooltip" data-placement="top" title="Alle Benachrichtigung löschen" onclick="javascript:delNotify(false)">Alle Benachrichtigungen löschen</button>
|
||||
{% for notification in usernotifications %}
|
||||
|
||||
<div class="card mb-2 notifydelclass" id="notify_{{notification.pk}}">
|
||||
<div class="card-body">
|
||||
<button href="#" class="btn btn-danger" style="float: right;" onclick="javascript:delNotify({{notification.pk}})"><i class="fas fa-trash-alt"></i></button>
|
||||
<p class="card-text">
|
||||
{% if notification.notificationtype == "agencynews" %}
|
||||
<a href="/news/news/{{notification.elementid}}/single" class="" style="text-decoration: none; color: #000000">
|
||||
{{notification.notificationtext}}
|
||||
</a><br />
|
||||
{% else %}
|
||||
{{notification.notificationtext}}<br />
|
||||
{% endif %}
|
||||
<small>Am {{notification.created}}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- CONFIRMA DELETE ALL NOTIFICATIONS -->
|
||||
<div class="modal fade" id="delAllNotifictaions" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="agencyDelFunction" aria-hidden="true">
|
||||
<div class="modal-dialog " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Alle Benachrichtigungen löschen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Möchten Sie alle Benachrichtigungen löschen?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelAllNotifications()">Alle Benachrichtigungen löschen</button>
|
||||
<button type="button" class="btn btn-success" data-dismiss="modal">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var todelnotifyid = false;
|
||||
function delNotify(notifydelid){
|
||||
todelnotifyid = notifydelid;
|
||||
if(!notifydelid){
|
||||
$("#delAllNotifictaions").modal("toggle");
|
||||
}
|
||||
else{
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/notifications/delsingle",
|
||||
data : {
|
||||
action : "delsingle",
|
||||
todelid : notifydelid
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$("#notify_" + todelnotifyid).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function doDelAllNotifications(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/notifications/delall",
|
||||
data : {
|
||||
action : "delall"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$(".notifydelclass").remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
<!doctype html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
|
||||
<head>
|
||||
<title> </title>
|
||||
<!--[if !mso]><!-- -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<!--<![endif]-->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
table,
|
||||
td {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
p {
|
||||
display: block;
|
||||
margin: 13px 0;
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG/>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
<!--[if lte mso 11]>
|
||||
<style type="text/css">
|
||||
.mj-outlook-group-fix { width:100% !important; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
@import url(https://fonts.googleapis.com/css?family=Roboto:300,400,500,700);
|
||||
</style>
|
||||
<!--<![endif]-->
|
||||
<style type="text/css">
|
||||
@media only screen and (min-width:480px) {
|
||||
.mj-column-per-100 {
|
||||
width: 100% !important;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="">
|
||||
<!--[if mso | IE]>
|
||||
<table
|
||||
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
|
||||
>
|
||||
<tr>
|
||||
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
|
||||
<![endif]-->
|
||||
<div style="margin:0px auto;max-width:600px;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;">
|
||||
<!--[if mso | IE]>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||
|
||||
<tr>
|
||||
|
||||
<td
|
||||
class="" style="vertical-align:top;width:600px;"
|
||||
>
|
||||
<![endif]-->
|
||||
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
||||
<tr>
|
||||
<td style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<p style="border-top:solid 4px #5a5c69;font-size:1;margin:0px auto;width:100%;"> </p>
|
||||
<!--[if mso | IE]>
|
||||
<table
|
||||
align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 4px #5a5c69;font-size:1;margin:0px auto;width:550px;" role="presentation" width="550px"
|
||||
>
|
||||
<tr>
|
||||
<td style="height:0;line-height:0;">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-family:Roboto;font-size:20px;line-height:1;text-align:left;color:#000000;">
|
||||
<h2>Digitale Agentur | Benachrichtigung</h2>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-family:Roboto;font-size:18px;line-height:1;text-align:left;color:#000000;">
|
||||
<p>Hallo {{username}},</p>
|
||||
<p>{{notificationtext}}</p>
|
||||
<p>Weitere Informationen erhalten Sie von Ihrem Agenturleiter. Vielen Dank, dass Sie die Plattform <b>Digitale Agentur</b> nutzen!</p>
|
||||
<p>Mit freundlichen Grüßen</p>
|
||||
<p>Ihr Team von Digitale Agentur</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<p style="border-top:solid 4px #5a5c69;font-size:1;margin:0px auto;width:100%;"> </p>
|
||||
<!--[if mso | IE]>
|
||||
<table
|
||||
align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 4px #5a5c69;font-size:1;margin:0px auto;width:550px;" role="presentation" width="550px"
|
||||
>
|
||||
<tr>
|
||||
<td style="height:0;line-height:0;">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--[if mso | IE]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
from django.urls import path
|
||||
from .views import CheckNotifications, GetBasicNotifications, ShowAllNotifications, ChangeNotificationsToViewed, delAllNotification, delSingleNotification
|
||||
|
||||
urlpatterns = [
|
||||
path('checknotifications/', CheckNotifications, name='checknotifications'),
|
||||
path('getnotifications/', GetBasicNotifications, name='getnotifications'),
|
||||
path('showallnotificaions/', ShowAllNotifications, name='showallnotificaions'),
|
||||
path('newnotificationsviewed/', ChangeNotificationsToViewed, name='newnotificationsviewed'),
|
||||
path('delsingle/', delSingleNotification, name='delsinglenotification'),
|
||||
path('delall/', delAllNotification, name='delall'),
|
||||
]
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
from django.shortcuts import render
|
||||
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
|
||||
from .models import UserNotification
|
||||
from django.views import generic
|
||||
from django.contrib.auth.decorators import login_required
|
||||
# Create your views here.
|
||||
|
||||
@login_required
|
||||
def CheckNotifications(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'checknotifications':
|
||||
#print("HERE WE ARE")
|
||||
unknownnotification = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=False).order_by('-created')[:5]
|
||||
|
||||
data = {};
|
||||
i = 0
|
||||
for notify in unknownnotification:
|
||||
|
||||
elelink = "notifications/showallnotificaions/"
|
||||
if notify.notificationtype == "agencynews":
|
||||
elelink = "news/news/" + str(notify.elementid) + "/single"
|
||||
|
||||
formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M")
|
||||
|
||||
data.update({ i : {
|
||||
"not_id" : notify.pk,
|
||||
"type": notify.notificationtype,
|
||||
"date" : formatedDate,
|
||||
"text" : notify.notificationtext,
|
||||
"elelink" : elelink
|
||||
}})
|
||||
i += 1
|
||||
notify.save()
|
||||
|
||||
return JsonResponse({"unknownnotification" : data})
|
||||
|
||||
# Create your views here.
|
||||
@login_required
|
||||
def GetBasicNotifications(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'oldnotifications':
|
||||
#print("HERE WE ARE")
|
||||
oldnotifications = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=True, wasviewed=False).order_by('-created')[:5]
|
||||
|
||||
data = {};
|
||||
i = 0
|
||||
for notify in oldnotifications:
|
||||
|
||||
elelink = "notifications/showallnotificaions/"
|
||||
if notify.notificationtype == "agencynews":
|
||||
elelink = "news/news/" + str(notify.elementid) + "/single"
|
||||
|
||||
formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M")
|
||||
|
||||
data.update({ i : {
|
||||
"not_id" : notify.pk,
|
||||
"type": notify.notificationtype,
|
||||
"date" : formatedDate,
|
||||
"text" : notify.notificationtext,
|
||||
"elelink" : elelink
|
||||
}})
|
||||
i += 1
|
||||
notify.save()
|
||||
|
||||
return JsonResponse({"oldnotifications" : data})
|
||||
|
||||
@login_required
|
||||
def ShowAllNotifications(request):
|
||||
context ={}
|
||||
context["usernotifications"] = UserNotification.objects.filter(touser__pk=request.user.pk).order_by('-created')
|
||||
return render(request, "notificsys/allnotifications.html", context)
|
||||
|
||||
@login_required
|
||||
def ChangeNotificationsToViewed(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'newnotificationsviewed':
|
||||
oldnotifications = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=False, wasviewed=False).order_by('-created')[:5]
|
||||
data = {};
|
||||
i = 0
|
||||
for notify in oldnotifications:
|
||||
formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M")
|
||||
data.update({ i : {
|
||||
"not_id" : notify.pk,
|
||||
"type": notify.notificationtype,
|
||||
"date" : formatedDate,
|
||||
"text" : notify.notificationtext
|
||||
}})
|
||||
i += 1
|
||||
notify.wassend = True
|
||||
notify.save()
|
||||
return JsonResponse({})
|
||||
|
||||
@login_required
|
||||
def delSingleNotification(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'delsingle':
|
||||
todelnotification = UserNotification.objects.get(pk=request.GET['todelid'])
|
||||
todelnotification.delete()
|
||||
|
||||
return JsonResponse({})
|
||||
|
||||
@login_required
|
||||
def delAllNotification(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'delall':
|
||||
todelnotification = UserNotification.objects.filter(touser__pk=request.user.pk).delete()
|
||||
|
||||
return JsonResponse({})
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Django==3.0.2
|
||||
django-appconf==1.0.3
|
||||
django-bootstrap-datepicker-plus==3.0.5
|
||||
django-cleanup==4.0.0
|
||||
django-colorful==1.3
|
||||
django-crispy-forms==1.8.1
|
||||
django-image-cropping==1.3.0
|
||||
django-js-asset==1.2.2
|
||||
django-jsonfield==1.3.1
|
||||
django-mathfilters==0.4.0
|
||||
django-mptt==0.11.0
|
||||
django-polymorphic==2.0.3
|
||||
django-redis==4.11.0
|
||||
django-staticfiles==1.2.1
|
||||
django-summernote==0.8.11.6
|
||||
django-templatetags==1.1
|
||||
django-user-agents==0.4.0
|
||||
djangorestframework==3.11.0
|
||||
easy-thumbnails==2.7
|
||||
mysqlclient==1.4.6
|
||||
Pillow==6.2.1
|
||||
requests==2.22.0
|
||||
requests-oauthlib==1.3.0
|
||||
user-agents==2.1
|
||||
webcolors==1.10
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h3>Auf diesen Standard haben Sie keinen Zugriff!</h3>
|
||||
<hr>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*!
|
||||
*
|
||||
* ColorPick jQuery plugin
|
||||
* https://github.com/philzet/ColorPick.js
|
||||
*
|
||||
* Copyright (c) 2017-2019 Phil Zet (a.k.a. Phil Zakharchenko)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
*/
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Open Sans"), local("OpenSans"),
|
||||
url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff)
|
||||
format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Open Sans Bold"), local("OpenSans-Bold"),
|
||||
url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzKRDOzjiPcYnFooOUGCOsRk.woff)
|
||||
format("woff");
|
||||
}
|
||||
|
||||
#colorPick * {
|
||||
-webkit-transition: all linear 0.2s;
|
||||
-moz-transition: all linear 0.2s;
|
||||
-ms-transition: all linear 0.2s;
|
||||
-o-transition: all linear 0.2s;
|
||||
transition: all linear 0.2s;
|
||||
}
|
||||
|
||||
#colorPick {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
position: absolute;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.2);
|
||||
padding: 15px;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
#colorPick span {
|
||||
font-size: 9pt;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
color: #bbb;
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.customColorHash {
|
||||
border-radius: 5px;
|
||||
height: 23px;
|
||||
width: 122px;
|
||||
margin: 1px 4px;
|
||||
padding: 0 4px;
|
||||
border: 1px solid #babbba;
|
||||
outline: none;
|
||||
}
|
||||
.customColorHash.error {
|
||||
border-color: #ff424c;
|
||||
color: #ff424c;
|
||||
}
|
||||
|
||||
.colorPickButton {
|
||||
border-radius: 5px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0px 3px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
border: thin solid #eee;
|
||||
}
|
||||
|
||||
.colorPickButton:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.colorPickDummy {
|
||||
background: #fff;
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
*, *:before, *:after {box-sizing: border-box;}
|
||||
ul, ol {margin: 0; padding: 0;}
|
||||
li {list-style: none; line-height: 1.6rem;}
|
||||
|
||||
/* List styling */
|
||||
.jslists{
|
||||
font-size: 1.3rem;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.jslist-ul, .jslist-ol, .jslist-li {margin-left: 12px;} /* Unordered lists */
|
||||
.jsl-collapsed {display: none;}
|
||||
.jsl-list-closed {
|
||||
float: left;
|
||||
clear: both;
|
||||
margin: 2px 4px 2px 0px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg aria-hidden="true" data-prefix="far" data-icon="plus-square" class="svg-inline--fa fa-plus-square fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"></path></svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
.jsl-open {display: block;}
|
||||
.jsl-list-open {background-image: url('data:image/svg+xml;utf8,<svg aria-hidden="true" data-prefix="far" data-icon="minus-square" class="svg-inline--fa fa-minus-square fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"></path></svg>');}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*!
|
||||
*
|
||||
* ColorPick jQuery plugin
|
||||
* https://github.com/philzet/ColorPick.js
|
||||
*
|
||||
* Copyright (c) 2017-2019 Phil Zet (a.k.a. Phil Zakharchenko)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
*/
|
||||
(function( $ ) {
|
||||
|
||||
$.fn.colorPick = function(config) {
|
||||
|
||||
return this.each(function() {
|
||||
new $.colorPick(this, config || {});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$.colorPick = function (element, options) {
|
||||
options = options || {};
|
||||
this.options = $.extend({}, $.fn.colorPick.defaults, options);
|
||||
if(options.str) {
|
||||
this.options.str = $.extend({}, $.fn.colorPick.defaults.str, options.str);
|
||||
}
|
||||
$.fn.colorPick.defaults = this.options;
|
||||
this.color = this.options.initialColor.toUpperCase();
|
||||
this.element = $(element);
|
||||
|
||||
var dataInitialColor = this.element.data('initialcolor');
|
||||
if (dataInitialColor) {
|
||||
this.color = dataInitialColor;
|
||||
this.appendToStorage(this.color);
|
||||
}
|
||||
|
||||
var uniquePalette = [];
|
||||
$.each($.fn.colorPick.defaults.palette.map(function(x){ return x.toUpperCase() }), function(i, el){
|
||||
if($.inArray(el, uniquePalette) === -1) uniquePalette.push(el);
|
||||
});
|
||||
|
||||
this.palette = uniquePalette;
|
||||
|
||||
return this.element.hasClass(this.options.pickrclass) ? this : this.init();
|
||||
};
|
||||
|
||||
$.fn.colorPick.defaults = {
|
||||
'initialColor': '#3498db',
|
||||
'paletteLabel': 'Farbauswahl',
|
||||
'allowRecent': true,
|
||||
'recentMax': 5,
|
||||
'allowCustomColor': false,
|
||||
'palette': ["#1abc9c", "#16a085", "#2ecc71", "#27ae60", "#3498db", "#2980b9", "#9b59b6", "#8e44ad", "#34495e", "#2c3e50", "#f1c40f", "#f39c12", "#e67e22", "#d35400", "#e74c3c", "#c0392b", "#ecf0f1", "#bdc3c7", "#95a5a6", "#7f8c8d"],
|
||||
'onColorSelected': function() {
|
||||
this.element.css({'backgroundColor': this.color, 'color': this.color});
|
||||
}
|
||||
};
|
||||
|
||||
$.colorPick.prototype = {
|
||||
|
||||
init : function(){
|
||||
|
||||
var self = this;
|
||||
var o = this.options;
|
||||
|
||||
$.proxy($.fn.colorPick.defaults.onColorSelected, this)();
|
||||
|
||||
this.element.click(function(event) {
|
||||
event.preventDefault();
|
||||
self.show(event.pageX, event.pageY);
|
||||
|
||||
$('.customColorHash').val(self.color);
|
||||
|
||||
$('.colorPickButton').click(function(event) {
|
||||
self.color = $(event.target).attr('hexValue');
|
||||
self.appendToStorage($(event.target).attr('hexValue'));
|
||||
self.hide();
|
||||
$.proxy(self.options.onColorSelected, self)();
|
||||
return false;
|
||||
});
|
||||
$('.customColorHash').click(function(event) {
|
||||
return false;
|
||||
}).keyup(function (event) {
|
||||
var hash = $(this).val();
|
||||
if (hash.indexOf('#') !== 0) {
|
||||
hash = "#"+hash;
|
||||
}
|
||||
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hash)) {
|
||||
self.color = hash;
|
||||
self.appendToStorage(hash);
|
||||
$.proxy(self.options.onColorSelected, self)();
|
||||
$(this).removeClass('error');
|
||||
} else {
|
||||
$(this).addClass('error');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}).blur(function() {
|
||||
self.element.val(self.color);
|
||||
$.proxy(self.options.onColorSelected, self)();
|
||||
self.hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('click', function(event) {
|
||||
self.hide();
|
||||
return true;
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
appendToStorage: function(color) {
|
||||
if ($.fn.colorPick.defaults.allowRecent === true) {
|
||||
var storedColors = JSON.parse(localStorage.getItem("colorPickRecentItems"));
|
||||
if (storedColors == null) {
|
||||
storedColors = [];
|
||||
}
|
||||
if ($.inArray(color, storedColors) == -1) {
|
||||
storedColors.unshift(color);
|
||||
storedColors = storedColors.slice(0, $.fn.colorPick.defaults.recentMax)
|
||||
localStorage.setItem("colorPickRecentItems", JSON.stringify(storedColors));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show: function(left, top) {
|
||||
|
||||
$("#colorPick").remove();
|
||||
|
||||
$("#mainmodalArea").append('<div id="colorPick" style="display:none;top:' + top + 'px;left:' + left + 'px"><span>'+$.fn.colorPick.defaults.paletteLabel+'</span></div>');
|
||||
jQuery.each(this.palette, function (index, item) {
|
||||
$("#colorPick").append('<div class="colorPickButton" hexValue="' + item + '" style="background:' + item + '"></div>');
|
||||
});
|
||||
if ($.fn.colorPick.defaults.allowCustomColor === true) {
|
||||
$("#colorPick").append('<input type="text" style="margin-top:5px" class="customColorHash" />');
|
||||
}
|
||||
if ($.fn.colorPick.defaults.allowRecent === true) {
|
||||
$("#colorPick").append('<span style="margin-top:5px">Kürzlich</span>');
|
||||
if (JSON.parse(localStorage.getItem("colorPickRecentItems")) == null || JSON.parse(localStorage.getItem("colorPickRecentItems")) == []) {
|
||||
$("#colorPick").append('<div class="colorPickButton colorPickDummy"></div>');
|
||||
} else {
|
||||
jQuery.each(JSON.parse(localStorage.getItem("colorPickRecentItems")), function (index, item) {
|
||||
$("#colorPick").append('<div class="colorPickButton" hexValue="' + item + '" style="background:' + item + '"></div>');
|
||||
if (index == $.fn.colorPick.defaults.recentMax-1) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
$("#colorPick").fadeIn(200);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
$( "#colorPick" ).fadeOut(200, function() {
|
||||
$("#colorPick").remove();
|
||||
return this;
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
}( jQuery ));
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* JSLists v0.4.5
|
||||
* © 2016 George Duff
|
||||
*
|
||||
* Release date: 01/06/2016
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2016 George Duff
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// TO DO LIST - Will get round to most of them at some point!
|
||||
// Add folder & file icons dynamically from param
|
||||
// Collapse All & Open All are ropey at best!
|
||||
// Add a search function
|
||||
// Make the margins user definable
|
||||
// Add support for UL & OL
|
||||
|
||||
var blackCircle = '● ';
|
||||
var openCircle = '◎ ';
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
function define_JSLists() {
|
||||
var JSLists = {};
|
||||
|
||||
var JSLists_Error = function(error, alertType) {
|
||||
console.log(error);
|
||||
}
|
||||
var getUl = function(){
|
||||
return document.getElementsByTagName("UL");
|
||||
};
|
||||
|
||||
var getOl = function(){
|
||||
return document.getElementsByTagName("OL");
|
||||
};
|
||||
|
||||
var getAllLists = function(){
|
||||
var olLists = Array.prototype.slice.call(document.getElementsByTagName("UL")),
|
||||
ulLists = Array.prototype.slice.call(document.getElementsByTagName("OL"))
|
||||
var gLists = olLists.concat(ulLists);
|
||||
return gLists;
|
||||
}
|
||||
|
||||
JSLists.searchList = function(listId, searchTerm) {
|
||||
var i, j, lilNodes, liItems = document.getElementsByTagName("LI");
|
||||
for(i=0; i<liItems.length; i++) {
|
||||
if(liItems[i].hasChildNodes()) {
|
||||
for(j=0; j<liItems[i].childNodes.length; j++) {
|
||||
if(liItems[i].childNodes[j].innerHTML == searchTerm) {
|
||||
//?????
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSLists.collapseAll = function(listId) {
|
||||
var i, ulLists = document.getElementsByTagName("UL");
|
||||
for(i=0; i<ulLists.length; i++) {
|
||||
if(ulLists[i].className == "jsl-collapsed") {
|
||||
console.log(ulLists[i].className + '\n' + '@');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
JSLists.openAll = function(listId){
|
||||
var i, olLists = Array.prototype.slice.call(document.getElementsByTagName("UL")),
|
||||
ulLists = Array.prototype.slice.call(document.getElementsByTagName("OL"))
|
||||
var gLists = olLists.concat(ulLists);
|
||||
|
||||
for(i=1; i<gLists.length; i++) {
|
||||
gLists[i].setAttribute('class', 'jsl-open');
|
||||
};
|
||||
};
|
||||
|
||||
JSLists.padUnorderedLists = function(listId) {
|
||||
var i, listItems = document.getElementById(listId).getElementsByTagName("UL");
|
||||
for(i=0; i<listItems.length; i++) {
|
||||
listItems[i].classList.add('jslist-ul');
|
||||
}
|
||||
};
|
||||
|
||||
JSLists.padOrderedLists = function(listId) {
|
||||
var i, listItems = document.getElementById(listId).getElementsByTagName("UL");
|
||||
for(i=0; i<listItems.length; i++) {
|
||||
listItems[i].classList.add('jslist-ol');
|
||||
}
|
||||
};
|
||||
|
||||
JSLists.padLists = function(listId) {
|
||||
var i, listItems = document.getElementById(listId).getElementsByTagName("LI");
|
||||
for(i=0; i<listItems.length; i++) {
|
||||
if(listItems[i].childNodes[0].className != "jsl-collapsed-arrow") {
|
||||
listItems[i].classList.add('jslist-li');
|
||||
}
|
||||
}
|
||||
for(i=1; i<listItems.length; i++) {
|
||||
// console.log(listItems[i].childNodes.length);
|
||||
if(listItems[i].classList = "jslist-li" && listItems[i].childNodes.length < 2) {
|
||||
listItems[i].innerHTML = blackCircle + listItems[i].innerHTML
|
||||
}
|
||||
}
|
||||
this.padUnorderedLists(listId);
|
||||
this.padOrderedLists(listId);
|
||||
};
|
||||
|
||||
JSLists.createTree = function(listId, bulletPoint) {
|
||||
document.getElementById(listId).style.display = "none;"
|
||||
var i, j, curElem, ulCount, olCount, listItems = document.getElementById(listId).getElementsByTagName('LI'); //this should be the main parent
|
||||
for(i=0; i<listItems.length; i++) {
|
||||
if(listItems[i].id.length > 0) {
|
||||
curElem = document.getElementById(listItems[i].id);
|
||||
ulCount = document.getElementById(listItems[i].id).getElementsByTagName("UL");
|
||||
if(ulCount.length > 0){
|
||||
for(j=0; j<ulCount.length; j++) {
|
||||
if(ulCount[j].nodeName == "UL") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ulCount[j].setAttribute('class', 'jsl-collapsed');
|
||||
var tglDiv = document.createElement("div");
|
||||
tglDiv.setAttribute('class', 'jsl-list-closed');
|
||||
tglDiv.setAttribute("id", listItems[i].id + i +'_tgl');
|
||||
curElem.insertBefore(tglDiv, curElem.childNodes[0]);
|
||||
|
||||
document.getElementById(listItems[i].id + i +'_tgl').addEventListener('click', function(e) {
|
||||
document.getElementById(e.target.id).classList.toggle('jsl-list-open');
|
||||
document.getElementById(e.target.id).parentElement.lastElementChild.classList.toggle('jsl-open');
|
||||
e.stopPropagation();
|
||||
},true);
|
||||
}
|
||||
} else {
|
||||
listItems[i].setAttribute("id", listId+"tmp"+i);
|
||||
curElem = document.getElementById(listId+"tmp"+i);
|
||||
ulCount = document.getElementById(listItems[i].id).getElementsByTagName("UL");
|
||||
|
||||
if(ulCount.length > 0) { //There is a nested UL in this LI element, now find the position of the UL
|
||||
for(j=0; j<ulCount.length; j++) {
|
||||
if(ulCount[j].nodeName == "UL") {
|
||||
break; //Multiple UL's? //Set class collapseAll here
|
||||
}
|
||||
}
|
||||
ulCount[j].setAttribute('class', 'jsl-collapsed');
|
||||
var tglDiv = document.createElement("div");
|
||||
tglDiv.setAttribute('class', 'jsl-list-closed');
|
||||
tglDiv.setAttribute("id", listItems[i].id + i +'_tgl');
|
||||
curElem.insertBefore(tglDiv, curElem.childNodes[0]);
|
||||
|
||||
document.getElementById(listItems[i].id + i +'_tgl').addEventListener('click', function(e){
|
||||
document.getElementById(e.target.id).classList.toggle('jsl-list-open');
|
||||
document.getElementById(e.target.id).parentElement.lastElementChild.classList.toggle('jsl-open');
|
||||
e.stopPropagation();
|
||||
},true);
|
||||
}
|
||||
listItems[i].removeAttribute("id");
|
||||
}
|
||||
}
|
||||
setTimeout(function() {
|
||||
document.getElementById(listId).style.display = "block;"
|
||||
}, 50); // stops FOUC!
|
||||
this.padLists(listId);
|
||||
};
|
||||
|
||||
// JSLists.applyToList = function(listId, listType, applyIcons, applyTheme, themeNumber){
|
||||
//Check the params here
|
||||
// does the id exist?
|
||||
JSLists.applyToList = function(listId, bulletPoint) {
|
||||
this.createTree(listId, "UL");
|
||||
};
|
||||
return JSLists;
|
||||
}
|
||||
|
||||
//define the JSLists library in the global namespace if it doesn't already exist
|
||||
if(typeof(JSLists) === 'undefined') {
|
||||
window.JSLists = define_JSLists();
|
||||
}else{
|
||||
console.log("JSLists already defined.");
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h3>Agentur <b>{{ request.user.profile.agency.name }}</b></h3>
|
||||
<hr>
|
||||
<div class="col-md-6">
|
||||
<h6><b>Inhaber</b></h6>
|
||||
<p>
|
||||
{{ request.user.profile.agency.inhaber }}
|
||||
</p>
|
||||
<h6><b>Adresse</b></h6>
|
||||
<p>
|
||||
{{ request.user.profile.agency.street }}
|
||||
</p>
|
||||
<p>
|
||||
{{ request.user.profile.agency.plz }} {{ request.user.profile.agency.city }}
|
||||
</p>
|
||||
<h6><b>Kontaktdaten</b></h6>
|
||||
<p>
|
||||
{{ request.user.profile.agency.agency_email }}
|
||||
</p>
|
||||
<p>
|
||||
{{ request.user.profile.agency.phone }}
|
||||
</p>
|
||||
<h6><b>Agenturbild</b></h6>
|
||||
<p>
|
||||
<img class="img-profile" width="75%" src="{{ request.user.profile.agency.get_photo_url }}">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section">
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<div class="col-7">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group">
|
||||
<legend class="border-bottom mb-4">
|
||||
Agenturinformationen bearbeiten
|
||||
</legend>
|
||||
<!-- FORMS LADEN -->
|
||||
{{ form|crispy }}
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
<a href="{% url 'agencyinfo' %}" class="btn">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section">
|
||||
<div class="media">
|
||||
<img class="img-profile " width="17%" src="{{ user.profile.get_photo_url }}">
|
||||
<div class="media-body col-5">
|
||||
<h2 class="account-heading">Profil von {{ user.first_name }} {{ user.last_name }}</h2>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h6><b>Name</b></h6>
|
||||
<p>
|
||||
{{ user.first_name }} {{ user.last_name }}
|
||||
</p>
|
||||
<h6><b>E-Mail</b></h6>
|
||||
<p>
|
||||
{{ user.email }}
|
||||
</p>
|
||||
<h6><b>Agenturfunktion</b></h6>
|
||||
<p>
|
||||
{{ user.profile.get_func_display }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h6><b>Tätigkeit</b></h6>
|
||||
<p>
|
||||
{{ user.profile.compfunc }}
|
||||
</p>
|
||||
<h6><b>Festnetz</b></h6>
|
||||
<p>
|
||||
{{ user.profile.phoneland }}
|
||||
</p>
|
||||
<h6><b>Mobil</b></h6>
|
||||
<p>
|
||||
{{ user.profile.phonemobile }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<div class="col-7 mt-5">
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group mb-2">
|
||||
<legend class="border-bottom mb-4">
|
||||
Profil bearbeiten
|
||||
</legend>
|
||||
<!-- FORMS LADEN -->
|
||||
{{ u_form|crispy }}
|
||||
</fieldset>
|
||||
|
||||
<small>Agenturrelevante Daten werden in der Benutzerverwaltung verändert.</small>
|
||||
<div class="form-group mt-3">
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
<a href="{% url 'users-management' %}" class="btn">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<script src="{% static 'users/js/cropper.min.js' %}"></script>
|
||||
<script src="{% static 'users/js/jquery-cropper.js' %}"></script>
|
||||
<div class="content-section">
|
||||
<div class="media">
|
||||
<img class="img-profile " id="profpic" width="17%" src="{{ prof_user.profile.get_photo_url }}">
|
||||
<div class="media-body col-5">
|
||||
<h2 class="account-heading">Profil von {{ prof_user.first_name }} {{ prof_user.last_name }}</h2>
|
||||
<hr>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-6">
|
||||
<h6><b>Name</b></h6>
|
||||
<p>
|
||||
{{ prof_user.first_name}} {{ prof_user.last_name }}
|
||||
</p>
|
||||
<h6><b>E-Mail</b></h6>
|
||||
<p>
|
||||
{{ prof_user.email }}
|
||||
</p>
|
||||
<h6><b>Agenturfunktion</b></h6>
|
||||
<p>
|
||||
{{ prof_user.profile.get_func_display }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6><b>Tätigkeit</b></h6>
|
||||
<p>
|
||||
{{ prof_user.profile.compfunc }}
|
||||
</p>
|
||||
<h6><b>Festnetz</b></h6>
|
||||
<p>
|
||||
{{ prof_user.profile.phoneland }}
|
||||
</p>
|
||||
<h6><b>Mobil</b></h6>
|
||||
<p>
|
||||
{{ prof_user.profile.phonemobile }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Für das Speichern der Bilder enctype -->
|
||||
<div class="col-7 mt-5">
|
||||
<form method="POST" id="newprofiledata" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group">
|
||||
<legend class="border-bottom mb-4">
|
||||
Profil bearbeiten
|
||||
</legend>
|
||||
<!-- FORMS LADEN -->
|
||||
{{ profileform_form|crispy }}
|
||||
<button type="button" id="" onclick="javascript:sendPassMail({{prof_user.pk}})" class="btn btn-success">E-Mail mit Link zur Passworterstellung senden</button> <span class="alert alert-success" id="mailsend" role="alert" style="display: none;"> E-Mail gesendet!</span>
|
||||
</fieldset>
|
||||
Übergeordneter Mitarbeiter: <span id="ps_act">{{prof_user.profile.parent.first_name}} {{prof_user.profile.parent.last_name}}</span>
|
||||
<div class="input-group mb-3">
|
||||
<input class="form-control" name="puser" id="puser" list="parentuser" type="text" onkeyup="javascript:checkValueAddParent()">
|
||||
<div class="input-group-append">
|
||||
<button type="button" id="addusertouserp" onclick="javascript:addUserParentUser()" class="btn btn-success" disabled>Festlegen</button>
|
||||
<button type="button" onclick="javascript:clearSearchfield()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<datalist id="parentuser" nmae="parentuser">
|
||||
{% for us in possible_users %}
|
||||
<option id="{{us.pk}}" value="{{us.first_name}} {{us.last_name}}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Speichern</button>
|
||||
<a href="{% url 'users-management' %}" class="btn">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MODAL TO CROP THE IMAGE -->
|
||||
<!-- MODAL TO CROP THE IMAGE -->
|
||||
<div class="modal fade " id="modalCrop" data-backdrop="static" data-keyboard="false">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Bereich bestimmen</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="clearImgField()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div class="modal-body" id="imgmodbody">
|
||||
<img src="" id="imagemod" style="max-width: 100%; max-height: 100%;">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group pull-left" role="group">
|
||||
<button type="button" class="btn btn-default js-zoom-in">
|
||||
<span class="glyphicon glyphicon-zoom-in"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default js-zoom-out">
|
||||
<span class="glyphicon glyphicon-zoom-out"></span>
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="clearImgField()">Abbrechen</button>
|
||||
<button type="button" class="btn btn-primary js-crop-and-upload">Ausschneiden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block javascript %}
|
||||
<script>
|
||||
|
||||
$("#id_x").val(0);
|
||||
$("#id_y").val(0);
|
||||
$("#id_width").val($("#profpic")[0]['naturalWidth']);
|
||||
$("#id_height").val($("#profpic")[0]['naturalHeight']);
|
||||
|
||||
function clearImgField(){
|
||||
$("#id_image").val("");
|
||||
}
|
||||
|
||||
|
||||
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
|
||||
$("#id_image").change(function () {
|
||||
if (this.files && this.files[0]) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
$("#imagemod").attr("src", e.target.result);
|
||||
$("#modalCrop").modal("show");
|
||||
}
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
var cropBoxData;
|
||||
var canvasData;
|
||||
var $image = $("#imagemod");
|
||||
$("#modalCrop").on("shown.bs.modal", function () {
|
||||
$image.cropper({
|
||||
viewMode: 3,
|
||||
aspectRatio: 1/1,
|
||||
strict: false,
|
||||
cropBoxMovable: true,
|
||||
cropBoxResizable: true,
|
||||
minCropBoxWidth: 200,
|
||||
minCropBoxHeight: 200,
|
||||
ready: function () {
|
||||
$image.cropper("setCanvasData", canvasData);
|
||||
$image.cropper("setCropBoxData", cropBoxData);
|
||||
}
|
||||
});
|
||||
$("#imgmodbody").css({
|
||||
"maxWidth": 465
|
||||
});
|
||||
|
||||
}).on("hidden.bs.modal", function () {
|
||||
cropBoxData = $image.cropper("getCropBoxData");
|
||||
canvasData = $image.cropper("getCanvasData");
|
||||
$image.cropper("destroy");
|
||||
});
|
||||
|
||||
$(".js-zoom-in").click(function () {
|
||||
$image.cropper("zoom", 0.1);
|
||||
});
|
||||
|
||||
$(".js-zoom-out").click(function () {
|
||||
$image.cropper("zoom", -0.1);
|
||||
});
|
||||
|
||||
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
|
||||
$(".js-crop-and-upload").click(function () {
|
||||
var cropData = $image.cropper("getData");
|
||||
$("#id_x").val(cropData["x"]);
|
||||
$("#id_y").val(cropData["y"]);
|
||||
$("#id_height").val(cropData["height"]);
|
||||
$("#id_width").val(cropData["width"]);
|
||||
$("#id_image").attr("src", $image);
|
||||
$("#modalCrop").modal('toggle');
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
<script type="text/javascript">
|
||||
var ua = window.navigator.userAgent;
|
||||
var isIE = /MSIE|Trident/.test(ua);
|
||||
if ( isIE ) {
|
||||
//IE specific code goes here
|
||||
setInterval(function()
|
||||
{
|
||||
checkValueAddParent();
|
||||
},250);
|
||||
}
|
||||
|
||||
|
||||
//Call Function in view to send e-mail with pass-reset-data
|
||||
function sendPassMail(id){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dashboard/sendpassmail",
|
||||
data:{
|
||||
userid : {{prof_user.pk}}
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
if(data["message"] == 0){
|
||||
$("#mailsend").fadeIn().delay(4000).fadeOut();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
tempid = null;
|
||||
function clearSearchfield(){
|
||||
$("#puser").val("");
|
||||
$("#addusertouserp").prop('disabled', true);
|
||||
}
|
||||
|
||||
function addUserParentUser(){
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dashboard/setuserparent",
|
||||
data:{
|
||||
userid: tempid,
|
||||
action : 'adduserp',
|
||||
objectid : {{prof_user.pk}}
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
console.log(data);
|
||||
clearSearchfield();
|
||||
//Add User-Button
|
||||
$("#ps_act").html(data['username_clean']);
|
||||
$("#parentuser").empty();
|
||||
for (var i in data['remaining_users']) {
|
||||
id = data['remaining_users'][i]['id'];
|
||||
name = data['remaining_users'][i]['first_name'] + " " + data['remaining_users'][i]['last_name'];
|
||||
$("#parentuser").append('<option id="'+id+'" value="'+name+'"></option>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkValueAddParent()
|
||||
{
|
||||
|
||||
var g = $('#puser').val();
|
||||
var id = $('#parentuser').find('option[value="' + g + '"]').attr('id');
|
||||
if(id != undefined && id.length > 0){
|
||||
tempid = id;
|
||||
$("#addusertouserp").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
tempid = null;
|
||||
$("#addusertouserp").prop('disabled', true);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section col-6">
|
||||
<h3>Neuer Benutzer</h3>
|
||||
<hr>
|
||||
<!-- FORMS LADEN users/userforms.py und users/views.py -->
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="true" id="sendmailnewuser" name="sendmailnewuser">
|
||||
<label class="form-check-label" for="sendmailnewuser" name="sendmailnewuser">
|
||||
E-Mailbenachrichtigung schicken
|
||||
</label>
|
||||
</div>
|
||||
<small>*: Der Benutzer erhält direkt eine E-Mail mit einem Link zur Passworterstellung, wenn der Haken bei <i>E-Mailbenachrichtung schicken</i> gesetzt ist. Dies kann später auch wiederholt werden.</small>
|
||||
<hr>
|
||||
<button type="submit" class="btn btn-success" href="{% url 'users-adduser' %} ">Benutzer anlegen</button>
|
||||
<a class="btn" href="{% url 'users-management' %} ">Abbrechen</a>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
|
||||
|
||||
|
||||
{% extends "users/base.html" %}
|
||||
{% block content %}
|
||||
<div class="content-section col-12">
|
||||
<h3>Benutzerverwaltung</h3>
|
||||
<hr>
|
||||
<p>
|
||||
Erstellen Sie weitere Mitarbeiter ihrer Agentur. Die neuen Benutzer erhalten eine E-Mail mit einem entsprechenden Link, um ihr Passwort zu generieren.
|
||||
</p>
|
||||
<div class="row mb-3">
|
||||
<div class="content-section col-4">
|
||||
<a class="btn btn-primary" href="{% url 'users-adduser' %} ">Benutzer anlegen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group mb-2">
|
||||
<input class="form-control" id="tableSearch" size="50" type="text" placeholder="Suche in Tabelle...">
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Benutzername</th>
|
||||
<th scope="col">E-Mail</th>
|
||||
<th scope="col">Agenturfunktion</th>
|
||||
<th scope="col">Tätigkeit</th>
|
||||
<th scope="col">Telefon</th>
|
||||
<th scope="col">Mobil</th>
|
||||
<th scope="col"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tableresults">
|
||||
{% for item in users_of_agency %}
|
||||
<tr>
|
||||
<td><a href="{% url 'orga-single' item.pk %}">{{item.first_name }} {{ item.last_name }}</a></td>
|
||||
<td>{{ item.username }}</td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{{ item.profile.get_func_display }}</td>
|
||||
<td>{{ item.profile.compfunc }}</td>
|
||||
<td>{{ item.profile.phoneland }}</td>
|
||||
<td>{{ item.profile.phonemobile }}</td>
|
||||
<td>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
|
||||
<div class="dropdown-header">Benutzerdaten</div>
|
||||
<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="{% url 'users-areataskupdate' item.pk %}">Zuständigkeiten</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>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$("#tableSearch").on("keyup", function() {
|
||||
var value = $(this).val().toLowerCase();
|
||||
$("#tableresults tr").filter(function() {
|
||||
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{% extends "users/base.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block content %}
|
||||
<div class="content-section">
|
||||
<h3>Reihenfolge im Organigramm von {{ user_first_name }} {{ user_last_name }}</h3>
|
||||
<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 %}
|
||||
<h4>Bereich {{ area.name }}</h4>
|
||||
{% for prio in prios %}
|
||||
{% if prio.task.area == area %}
|
||||
<div class="form-group row">
|
||||
<label for="{{forloop.counter}}" class="col-sm-2 col-form-label"><h5>{{ prio.task.name }}</h5></label>
|
||||
<div class="col-sm-1" style="float:right" >
|
||||
<input type="number" min="0" class="form-control" id="{{forloop.counter}}" value="{{ prio.prio}}" onkeyup="javascript:updatePrio({{prio.pk}}, {{prio.task.pk}}, this.value)" onchange="javascript:updatePrio({{prio.pk}}, {{prio.task.pk}}, this.value)"></div><span class="badge badge-success mt-1 mb-3" id="save_{{prio.pk}}" style="display: none; font-size: 0.8em;">Gespeichert</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor%}
|
||||
<hr>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<a href="{% url 'users-dashboard' %}" class="btn btn-success">Zum Dashboard</a>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function updatePrio(prio, task, value)
|
||||
{
|
||||
console.log({{userprio.pk}} + " " + prio + " " + task + " VAL: " + value);
|
||||
$.ajax(
|
||||
{
|
||||
type: "GET",
|
||||
url: "/dashboard/prioupdate",
|
||||
data:{
|
||||
userid: {{user_id}},
|
||||
prioid : 'adduser',
|
||||
taskid : task,
|
||||
value : value
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
$('#save_'+prio).show();
|
||||
setTimeout(function() {
|
||||
$('#save_'+prio).fadeOut();
|
||||
}, 1000 );
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
||||
Loading…
Reference in New Issue