Cropper bei Profilen hinzugefügt
This commit is contained in:
parent
6f4544af64
commit
f6f4b8f578
Binary file not shown.
|
|
@ -12,7 +12,6 @@ https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
@ -120,6 +119,7 @@ CKEDITOR_CONFIGS = {
|
||||||
}
|
}
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -5,16 +5,14 @@
|
||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
<h3>{{request.user.profile.agency.name}}</h3>
|
<h3>{{request.user.profile.agency.name}}</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<h4>Organigramm</h4>
|
<h4>Organigramm</h4>
|
||||||
|
{% if invisible_users > 0%}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
Achtung! {{invisible_users}} Mitarbeiter sind anderen Mitarbeitern untergeordnet, die nicht im Organigramm sichtbar sein sollen. Bitte prüfen sie die Zuordnung der übergeordneten Mitarbeiter!
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<div id="diagram"></div>
|
<div id="diagram"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="spinner" class="text-center" style="margin-top: 15%; width: 100%; height: 100%; display: none;margin-left:auto;
|
|
||||||
margin-right:auto;">
|
|
||||||
<div class="spinner-border text-danger" role="status">
|
|
||||||
<span class="sr-only">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -22,9 +20,6 @@ margin-right:auto;">
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var data = [
|
var data = [
|
||||||
{ 'id' : '{{request.user.profile.agency.pk}}', 'parent' : "", 'role': "", 'name': '{{request.user.profile.agency.name}}', 'color': '#71AF17', "imageUrl": "", 'children' : []},
|
{ 'id' : '{{request.user.profile.agency.pk}}', 'parent' : "", 'role': "", 'name': '{{request.user.profile.agency.name}}', 'color': '#71AF17', "imageUrl": "", 'children' : []},
|
||||||
{% for u in agencyuser %}
|
{% for u in agencyuser %}
|
||||||
|
|
@ -36,7 +31,6 @@ var data = [
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
//Check for Agency and User-IDs - dont touch the userid for URLs!
|
//Check for Agency and User-IDs - dont touch the userid for URLs!
|
||||||
for(i = 0; i < data.length; i++){
|
for(i = 0; i < data.length; i++){
|
||||||
for(k = 0; k < data.length; k++){
|
for(k = 0; k < data.length; k++){
|
||||||
|
|
@ -49,7 +43,6 @@ for(i = 0; i < data.length; i++){
|
||||||
data[m]['parent'] = data[m]['parent']*10;
|
data[m]['parent'] = data[m]['parent']*10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,13 +64,13 @@ function unflatten(arr) {
|
||||||
|
|
||||||
for (var id in mappedArr) {
|
for (var id in mappedArr) {
|
||||||
if (mappedArr.hasOwnProperty(id)) {
|
if (mappedArr.hasOwnProperty(id)) {
|
||||||
mappedElem = mappedArr[id];
|
mappedElem = mappedArr[id];
|
||||||
// If the element is not at the root level, add it to its parent array of children.
|
// If the element is not at the root level, add it to its parent array of children.
|
||||||
if (mappedElem.parent) {
|
if (mappedElem.parent) {
|
||||||
mappedArr[mappedElem['parent']]['children'].push(mappedElem);
|
mappedArr[mappedElem['parent']]['children'].push(mappedElem);
|
||||||
}
|
}
|
||||||
// If the element is at the root level, add it to first level elements array.
|
// If the element is at the root level, add it to first level elements array.
|
||||||
else {
|
else {
|
||||||
tree.push(mappedElem);
|
tree.push(mappedElem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +83,7 @@ var html = ['<ul class="tree">'];
|
||||||
//Create UL-LI-List for tree
|
//Create UL-LI-List for tree
|
||||||
function createList(arr) {
|
function createList(arr) {
|
||||||
html.push('<ul>');
|
html.push('<ul>');
|
||||||
$.each(arr, function(i, val) {
|
$.each(arr, function(i, val) {
|
||||||
if(val.parent == ""){
|
if(val.parent == ""){
|
||||||
html.push('<li><a href="#"><h4>' + val.name + "</h4></a>");
|
html.push('<li><a href="#"><h4>' + val.name + "</h4></a>");
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +93,7 @@ function createList(arr) {
|
||||||
if (val.children) {
|
if (val.children) {
|
||||||
createList(val.children)
|
createList(val.children)
|
||||||
}
|
}
|
||||||
html.push('</li>');
|
html.push('</li>');
|
||||||
});
|
});
|
||||||
html.push('</ul>');
|
html.push('</ul>');
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +108,6 @@ for(i = 0; i < html.length; i++){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToUser(id){
|
function goToUser(id){
|
||||||
window.location.href = "/orga/single/"+id;
|
window.location.href = "/orga/single/"+id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,23 @@ import webcolors
|
||||||
@login_required
|
@login_required
|
||||||
def mainorga(request):
|
def mainorga(request):
|
||||||
|
|
||||||
#leader = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='lead'))
|
|
||||||
#if len(leader) > 0:
|
|
||||||
# leader = leader[0]
|
|
||||||
#else:
|
|
||||||
# leader = None
|
|
||||||
|
|
||||||
agencyuser = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__visible=True).order_by('-id'))
|
agencyuser = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__visible=True).order_by('-id'))
|
||||||
|
nonvisibleuser = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__visible=False).order_by('-id'))
|
||||||
|
|
||||||
|
invisible_users = 0;
|
||||||
|
|
||||||
|
# Check, if parented users are invisible. Remove them and give user an info!
|
||||||
|
for ele in nonvisibleuser:
|
||||||
|
for vis in agencyuser:
|
||||||
|
if vis.profile.parent.profile.pk == ele.pk:
|
||||||
|
agencyuser.remove(vis)
|
||||||
|
invisible_users += 1
|
||||||
|
|
||||||
#indoor = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='indoor'))
|
|
||||||
#external = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='external'))
|
|
||||||
#trainee = list(User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).filter(profile__func='trainee'))
|
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'active_link' : 'orga',
|
'active_link' : 'orga',
|
||||||
'agencyuser' : agencyuser
|
'agencyuser' : agencyuser,
|
||||||
|
'invisible_users' : invisible_users
|
||||||
}
|
}
|
||||||
# 'leader' : leader,
|
|
||||||
# 'indoor' : indoor,
|
|
||||||
# 'external' : external,
|
|
||||||
# 'trainee' : trainee
|
|
||||||
|
|
||||||
|
|
||||||
return render(request, 'orga/orga_main.html', context)
|
return render(request, 'orga/orga_main.html', context)
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -66,6 +66,8 @@ Klasse für die Zusatzinfos eines Nutzers.
|
||||||
- Aufgaben
|
- Aufgaben
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Profile(models.Model):
|
class Profile(models.Model):
|
||||||
|
|
||||||
# AGENCY TASKS
|
# AGENCY TASKS
|
||||||
|
|
@ -88,7 +90,6 @@ class Profile(models.Model):
|
||||||
image = models.ImageField(default='userprofilepics/default.jpg', upload_to='userprofilepics', blank=True)
|
image = models.ImageField(default='userprofilepics/default.jpg', upload_to='userprofilepics', blank=True)
|
||||||
compfunc = models.CharField(max_length=60, blank=True)
|
compfunc = models.CharField(max_length=60, blank=True)
|
||||||
visible = models.BooleanField(default=True)
|
visible = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.user.last_name}'
|
return f'{self.user.last_name}'
|
||||||
|
|
@ -98,7 +99,7 @@ class Profile(models.Model):
|
||||||
return reverse('users-update', kwargs={'pk':self.pk})
|
return reverse('users-update', kwargs={'pk':self.pk})
|
||||||
|
|
||||||
# Erst Oberklasse speichern, dann Bild verkleinern
|
# Erst Oberklasse speichern, dann Bild verkleinern
|
||||||
|
'''
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
super().save()
|
super().save()
|
||||||
if self.image:
|
if self.image:
|
||||||
|
|
@ -114,7 +115,7 @@ class Profile(models.Model):
|
||||||
wsize = int((float(img.size[0]) * float(hpercent)))
|
wsize = int((float(img.size[0]) * float(hpercent)))
|
||||||
img = img.resize((wsize, baseheight), Image.ANTIALIAS)
|
img = img.resize((wsize, baseheight), Image.ANTIALIAS)
|
||||||
img.save(self.image.path)
|
img.save(self.image.path)
|
||||||
|
'''
|
||||||
@property
|
@property
|
||||||
def get_photo_url(self):
|
def get_photo_url(self):
|
||||||
if self.image and hasattr(self.image, 'url'):
|
if self.image and hasattr(self.image, 'url'):
|
||||||
|
|
@ -124,7 +125,8 @@ class Profile(models.Model):
|
||||||
|
|
||||||
# PERMISSIONS - Über alle Modelle hinweg, in der url.py wird dann die route verhindert!
|
# PERMISSIONS - Über alle Modelle hinweg, in der url.py wird dann die route verhindert!
|
||||||
# Im template: if perms.users.PERMISSION
|
# Im template: if perms.users.PERMISSION
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
permissions = [
|
permissions = [
|
||||||
('agency_change', 'Agenturinformationen verändern'),
|
('agency_change', 'Agenturinformationen verändern'),
|
||||||
('users_usermanagement', 'Benutzer bearbeiten'),
|
('users_usermanagement', 'Benutzer bearbeiten'),
|
||||||
|
|
@ -136,3 +138,4 @@ class Profile(models.Model):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*!
|
||||||
|
* Cropper.js v1.5.6
|
||||||
|
* https://fengyuanchen.github.io/cropperjs
|
||||||
|
*
|
||||||
|
* Copyright 2015-present Chen Fengyuan
|
||||||
|
* Released under the MIT license
|
||||||
|
*
|
||||||
|
* Date: 2019-10-04T04:33:44.164Z
|
||||||
|
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*!
|
||||||
|
* jQuery Cropper v1.0.1
|
||||||
|
* https://fengyuanchen.github.io/jquery-cropper
|
||||||
|
*
|
||||||
|
* Copyright 2018-present Chen Fengyuan
|
||||||
|
* Released under the MIT license
|
||||||
|
*
|
||||||
|
* Date: 2019-10-19T08:48:33.062Z
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('cropperjs')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['jquery', 'cropperjs'], factory) :
|
||||||
|
(global = global || self, factory(global.jQuery, global.Cropper));
|
||||||
|
}(this, function ($, Cropper) { 'use strict';
|
||||||
|
|
||||||
|
$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
|
||||||
|
Cropper = Cropper && Cropper.hasOwnProperty('default') ? Cropper['default'] : Cropper;
|
||||||
|
|
||||||
|
if ($ && $.fn && Cropper) {
|
||||||
|
var AnotherCropper = $.fn.cropper;
|
||||||
|
var NAMESPACE = 'cropper';
|
||||||
|
|
||||||
|
$.fn.cropper = function jQueryCropper(option) {
|
||||||
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||||
|
args[_key - 1] = arguments[_key];
|
||||||
|
}
|
||||||
|
|
||||||
|
var result;
|
||||||
|
this.each(function (i, element) {
|
||||||
|
var $element = $(element);
|
||||||
|
var isDestroy = option === 'destroy';
|
||||||
|
var cropper = $element.data(NAMESPACE);
|
||||||
|
|
||||||
|
if (!cropper) {
|
||||||
|
if (isDestroy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = $.extend({}, $element.data(), $.isPlainObject(option) && option);
|
||||||
|
cropper = new Cropper(element, options);
|
||||||
|
$element.data(NAMESPACE, cropper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof option === 'string') {
|
||||||
|
var fn = cropper[option];
|
||||||
|
|
||||||
|
if ($.isFunction(fn)) {
|
||||||
|
result = fn.apply(cropper, args);
|
||||||
|
|
||||||
|
if (result === cropper) {
|
||||||
|
result = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDestroy) {
|
||||||
|
$element.removeData(NAMESPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result !== undefined ? result : this;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.cropper.Constructor = Cropper;
|
||||||
|
$.fn.cropper.setDefaults = Cropper.setDefaults;
|
||||||
|
|
||||||
|
$.fn.cropper.noConflict = function noConflict() {
|
||||||
|
$.fn.cropper = AnotherCropper;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<!-- Custom fonts for this template-->
|
<!-- Custom fonts for this template-->
|
||||||
|
|
||||||
<link rel="canonical" href="https://www.digitale-agentur.com">
|
<link rel="canonical" href="https://www.digitale-agentur.com">
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||||
|
|
@ -32,6 +32,9 @@
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote.js"></script>
|
||||||
|
|
||||||
|
<!-- CROPPER -->
|
||||||
|
<link href="{% static 'users/css/cropper.min.css' %}" rel="stylesheet">
|
||||||
|
|
||||||
<!-- TABLE SORT -->
|
<!-- TABLE SORT -->
|
||||||
<!--<link rel="stylesheet" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">-->
|
<!--<link rel="stylesheet" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">-->
|
||||||
|
|
||||||
|
|
@ -331,6 +334,8 @@
|
||||||
<!-- CUSTOM FONT -->
|
<!-- CUSTOM FONT -->
|
||||||
<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">
|
<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- TABLE SORT -->
|
<!-- TABLE SORT -->
|
||||||
<!--<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
|
<!--<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
{% load static %}
|
||||||
{% block content %}
|
{% 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="content-section">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<img class="img-profile " width="17%" src="{{ prof_user.profile.get_photo_url }}">
|
<img class="img-profile " id="profpic" width="17%" src="{{ prof_user.profile.get_photo_url }}">
|
||||||
<div class="media-body col-5">
|
<div class="media-body col-5">
|
||||||
<h2 class="account-heading">Profil von {{ prof_user.first_name }} {{ prof_user.last_name }}</h2>
|
<h2 class="account-heading">Profil von {{ prof_user.first_name }} {{ prof_user.last_name }}</h2>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row mt-2">
|
<div class="row mt-2">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
@ -41,13 +44,13 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- Für das Speichern der Bilder enctype -->
|
<!-- Für das Speichern der Bilder enctype -->
|
||||||
<div class="col-7 mt-5">
|
<div class="col-7 mt-5">
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" id="newprofiledata" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<legend class="border-bottom mb-4">
|
<legend class="border-bottom mb-4">
|
||||||
Profil bearbeiten
|
Profil bearbeiten
|
||||||
</legend>
|
</legend>
|
||||||
<!-- FORMS LADEN -->
|
<!-- FORMS LADEN -->
|
||||||
{{ profileform_form|crispy }}
|
{{ 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>
|
<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>
|
</fieldset>
|
||||||
|
|
@ -63,7 +66,7 @@
|
||||||
<option id="{{us.pk}}" value="{{us.first_name}} {{us.last_name}}"></option>
|
<option id="{{us.pk}}" value="{{us.first_name}} {{us.last_name}}"></option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</datalist>
|
</datalist>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -73,6 +76,111 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- MODAL TO CROP THE IMAGE -->
|
||||||
|
<!-- MODAL TO CROP THE IMAGE -->
|
||||||
|
<div class="modal fade " id="modalCrop">
|
||||||
|
<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">
|
<script type="text/javascript">
|
||||||
var ua = window.navigator.userAgent;
|
var ua = window.navigator.userAgent;
|
||||||
var isIE = /MSIE|Trident/.test(ua);
|
var isIE = /MSIE|Trident/.test(ua);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ from .models import Profile, Agency
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from areas.models import Areas
|
from areas.models import Areas
|
||||||
from tasks.models import Tasks
|
from tasks.models import Tasks
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
# Standard-User-Formular - NUR Username und Password wird hier genutzt
|
# Standard-User-Formular - NUR Username und Password wird hier genutzt
|
||||||
class UsersAddNewUser(UserCreationForm):
|
class UsersAddNewUser(UserCreationForm):
|
||||||
|
|
@ -25,9 +27,13 @@ class UsersChangeProfil(forms.ModelForm):
|
||||||
|
|
||||||
# Formular zum hinzufügen neuer Agentur-Mitglieder
|
# Formular zum hinzufügen neuer Agentur-Mitglieder
|
||||||
class UsersAddProfileForm(forms.ModelForm):
|
class UsersAddProfileForm(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())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Profile
|
model = Profile
|
||||||
labels = {
|
labels = {
|
||||||
"phoneland" : "Telefon",
|
"phoneland" : "Telefon",
|
||||||
"phonemobile" : "Mobil",
|
"phonemobile" : "Mobil",
|
||||||
|
|
@ -36,7 +42,23 @@ class UsersAddProfileForm(forms.ModelForm):
|
||||||
"image" : "Profilbild",
|
"image" : "Profilbild",
|
||||||
"visible" : "Im Organigramm sichtbar"
|
"visible" : "Im Organigramm sichtbar"
|
||||||
}
|
}
|
||||||
fields = ['phoneland','phonemobile', 'visible', 'func', 'compfunc', 'image']
|
|
||||||
|
fields = ['phoneland','phonemobile', 'visible', 'func', 'compfunc', 'image', 'x', 'y', 'width', 'height']
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
photo = super(UsersAddProfileForm, 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')
|
||||||
|
image = Image.open(photo.image)
|
||||||
|
cropped_image = image.crop((x, y, w+x, h+y))
|
||||||
|
resized_image = cropped_image.resize((560, 560), Image.ANTIALIAS)
|
||||||
|
resized_image.save(photo.image.path)
|
||||||
|
return photo
|
||||||
|
except:
|
||||||
|
print("no photo")
|
||||||
|
|
||||||
# Formular zum hinzufügen neuer Agentur-Mitglieder
|
# Formular zum hinzufügen neuer Agentur-Mitglieder
|
||||||
class AgencyUpdateForm(forms.ModelForm):
|
class AgencyUpdateForm(forms.ModelForm):
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ from PIL import Image
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.contrib.auth.forms import PasswordResetForm
|
from django.contrib.auth.forms import PasswordResetForm
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
from io import StringIO
|
||||||
'''
|
'''
|
||||||
|
|
||||||
DASHBOARD-View
|
DASHBOARD-View
|
||||||
|
|
@ -201,9 +201,6 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
|
||||||
messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!')
|
messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!')
|
||||||
return HttpResponseRedirect('/dashboard/usersman/')
|
return HttpResponseRedirect('/dashboard/usersman/')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Benutzerprofil wird aktualisiert
|
# Benutzerprofil wird aktualisiert
|
||||||
@login_required
|
@login_required
|
||||||
def ProfileUpdateView(request, pk):
|
def ProfileUpdateView(request, pk):
|
||||||
|
|
@ -212,20 +209,20 @@ def ProfileUpdateView(request, pk):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
profileform_form = UsersAddProfileForm(request.POST, request.FILES, instance=prof_user.profile)
|
profileform_form = UsersAddProfileForm(request.POST, request.FILES, instance=prof_user.profile)
|
||||||
#profileform_parents = UsersAddProfileFormParents(request.POST, instance=request.user)
|
#profileform_parents = UsersAddProfileFormParents(request.POST, instance=request.user)
|
||||||
|
prename = prof_user.first_name
|
||||||
|
name = prof_user.last_name
|
||||||
|
|
||||||
if profileform_form.is_valid():
|
if profileform_form.is_valid():
|
||||||
profileform_form.save()
|
profileform_form.save()
|
||||||
prename = prof_user.first_name
|
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
|
||||||
name = prof_user.last_name
|
|
||||||
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
|
|
||||||
# Daten neu laden und nicht die "Mächten sie die Daten speichern...?"
|
|
||||||
return redirect('users-management')
|
return redirect('users-management')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Form in Klammern sind die aktuellen Daten :)
|
# Form in Klammern sind die aktuellen Daten :)
|
||||||
profileform_form = UsersAddProfileForm(instance=prof_user.profile)
|
profileform_form = UsersAddProfileForm(instance=prof_user.profile)
|
||||||
possible_users = User.objects.filter(profile__agency__pk=prof_user.profile.agency.pk)
|
|
||||||
|
# Nur User, die im Organigramm auch sichtbar sein, können ausgewählt werden
|
||||||
|
possible_users = User.objects.filter(profile__agency__pk=prof_user.profile.agency.pk).filter(profile__visible=True)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'prof_user' : prof_user,
|
'prof_user' : prof_user,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue