Kategorien fertig Bug bei Upload für QS Ersetzlogik fertig Kleinigkeiten

This commit is contained in:
holger.trampe 2020-04-18 12:41:31 +02:00
parent 5284ef72fb
commit 3783e5de44
29 changed files with 966 additions and 196 deletions

View File

@ -159,6 +159,8 @@ a.disabled {
gespeichert.
</small></p>
</div>
<hr>
<small>Erlaubte Dateitypen: Office- und OpenOffice-Formate, PNG, JPG/JPEG, SVG, FLV, Videoformate, EPS. Maximale Uploadgröße: 2 GB</small>
</div>
{% endif %}
<!-- MODAL CHANGE DIRNAME -->
@ -198,7 +200,7 @@ a.disabled {
</button>
</div>
<div class="modal-body">
Mit löschen fortfahren? Alle Dateien in diesem Verzeichnis werden ebenfalls gelöscht!
Mit dem Löschen fortfahren? Alle Dateien in diesem Verzeichnis werden ebenfalls gelöscht!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelDataDir()">Löschen</button>&nbsp;&nbsp;
@ -213,13 +215,13 @@ a.disabled {
<div class="modal-dialog " role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Datei nicht erlaubt</h5>
<h5 class="modal-title" id="exampleModalLongTitle">Fehler beim Upload</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Diesen Dateitypen dürfen Sie nicht hochladen.
<div class="modal-body">
Die Datei konnte nicht hochgeladen werden. Bitte prüfen Sie die erlaubten Dateitypen und den verfügbaren Speicherplatz. Andernfalls melden Sie sich bei unserem Support support@digitale-agentur.com!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
@ -433,11 +435,37 @@ a.disabled {
</div>
<div class="modal-body">
<i class="fas fa-spinner fa-spin"></i> Datei wird hochgeladen...
<div class="progress">
<div class="progress-bar" id="uploadprocessbar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
<!-- CONFIRMA DOUBLE FILE -->
<div class="modal fade" id="doubleFileChoiceModal" 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">Datei bereits vorhanden</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Die Datei <b><span id="doublefile_name"></span></b> ist bereits vorhanden. Soll die Datei ersetzt oder beide behalten werden?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 1)">Alte Datei ersetzen</button>&nbsp;&nbsp;
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 0)">Beide behalten</button>
</div>
</div>
</div>
</div>
<style>
/* DATATABLES */
.paginate_button {
@ -457,7 +485,6 @@ if ( isIE ) {
{
if($('#replaceFileModal').is(':visible')){
console.log("HI!");
updateLinkedFiles();
}
@ -474,6 +501,8 @@ if ( isIE ) {
delay : 5000
});
$('#dirfilestable').DataTable({
responsive : true,
"language": {
@ -759,21 +788,76 @@ $('.droppable_div').on('dragleave', function (e) {
currentid = e["currentTarget"]['id'];
$("#{{parentid}}_div").removeClass('bg-secondary');
});
allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*, image/x-png, image/gif, image/jpg, image/jpeg, image/JPEG, image/JPG, docx, JPEG, JPG, doc, odt, ODT, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
//allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*, image/x-png, image/gif, image/jpg, image/jpeg, image/JPEG, image/JPG, docx, JPEG, JPG, doc, odt, ODT, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
allowedtypes = ['doc','docx','odt','ods','xls','xlsx','xlsm','ppt','pptx','mov','avi','svg','png','jpg','jpeg','mp3', 'wav', 'zip', 'rar', 'mp4', 'mwv', 'flv', 'eps', 'txt', 'pdf']
function getFileExtension1(filename) {
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}
var filetodo_ex = "";
var parid_ex = "";
function replaceFileDirectChoice(filetodo, choice){
$("#doubleFileChoiceModal").modal("toggle");
doUploadAction(filetodo_ex, parid_ex, choice);
}
function uploadAction(filetodo, parid){
filetodo_ex = filetodo;
parid_ex = parid;
$.ajax(
{
type: "GET",
url: "{% url 'cloud-adddir' parentid %}",
data:{
action : "check_doublefile",
name : filetodo.name
},
success: function( data )
{
if(data["data"]["found"]){
$("#doubleFileChoiceModal").modal("toggle");
$("#doublefile_name").html(filetodo.name);
}
else{
doUploadAction(filetodo, parid, 0);
}
}
});
}
function doUploadAction(filetodo, parid, replacestat){
//Check for double File on Server
var formData = new FormData($("#uploadFileForm")[0]);
formData.append("uploadedfile", filetodo);
formData.append("uploadsource", "cloud");
formData.append("replace", replacestat);
var bar = $('.bar');
var percent = $('.percent');
console.log(filetodo.type);
if(allowedtypes.indexOf(filetodo.type) != -1 && filetodo.type.length > 0){
var c = false;
for (i = 0; i < allowedtypes.length; i++) {
if (allowedtypes[i].localeCompare(getFileExtension1(filetodo.name)) == 0)
{
c = true;
}
}
if(c && filetodo.type.length > 0){
//CHECK QUOTA
calculate_quota = filetodo.size / (1024* 1024*1024) + actquotasize
console.log(calculate_quota);
if(calculate_quota > 2){
setTimeout(function(){$("#uploadModalProgress").modal("toggle");}, 1000);
$('#uploadModalProgress').on('hidden.bs.modal', function (e) {
@ -784,8 +868,8 @@ function uploadAction(filetodo, parid){
$.ajax({
url: "{% url 'cloud-adddir' %}" + parid,
headers: {
"X-CSRFTOKEN": "{{ csrf_token }}"
},
"X-CSRFTOKEN": "{{ csrf_token }}"
},
data: formData,
type: 'POST',
cache: false,
@ -794,7 +878,17 @@ function uploadAction(filetodo, parid){
beforeSend: function(){
$("#uploadModalProgress").modal("toggle");
},
success: function(data) {
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
$("#uploadprocessbar").css("width", percentComplete + "%");
}
}, false);
return xhr;
},
success: function(data) {
if(data["success"] == true){
setTimeout(function(){window.location = window.location;}, 1000);
}
@ -809,8 +903,10 @@ function uploadAction(filetodo, parid){
}
}
else{
$("#forbiddenFileType").modal("toggle")
}
$("#forbiddenFileType").modal("toggle");
}
}
</script>
{% endif %}

View File

@ -10,7 +10,7 @@ from .forms import CloudAddFileForm
from django.conf import settings
from django.core.files.storage import default_storage
from digitaleagentur.settings import BASE_DIR
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponse, Http404
from .models import DataDir, DataFile
from datetime import datetime
from users.models import AgencyGroup
@ -19,6 +19,9 @@ from django.http import FileResponse
from standards.models import Standards
from django.contrib import messages
import os
import sys
from django.conf import settings
'''
Prüft, ob ein Nutzer in diesen Ordner Zugriffsrechte hat. Läuft den gesamten Strang bis nach oben,
@ -38,7 +41,6 @@ def checkUserDirRights(request, startdir, userid):
# Get dirs to check
while( singleObj.is_root != True and canview == True):
for g in singleObj.visibleby.all():
grouptomach.append(g.group)
@ -158,7 +160,13 @@ def adddirbyajax(request, parent):
if(fileobj in ls.addedfiles.all()):
linked_standards_final.append({ "id" : ls.pk, "name" : ls.name });
data = {'filename' : fileobj.name, 'linked_standards' : linked_standards_final}
# CHECK DOUBLE FILENAME
elif(request.GET.get("action") == "check_doublefile"):
fileobj = list(DataFile.objects.filter(name__icontains=request.GET.get('name'), agency=request.user.profile.agency))
if len(fileobj) > 0:
data = {"found" : True}
else:
data = {"found" : False}
# DELETE FILE
elif(request.GET.get("action") == "del_file"):
DataFile.objects.filter(pk=request.GET.get('id'), agency=request.user.profile.agency).delete()
@ -233,10 +241,18 @@ def adddirbyajax(request, parent):
tempdir = False
tempdir = DataDir.objects.get(pk=parent)
uploadsource = request.POST["uploadsource"]
replace = request.POST["replace"]
print(replace)
# DECODE
request.decoding = 'utf-8'
# VALIDATE FILE-TYPE
file_ext = request.FILES['uploadedfile'].name.split(".")[1]
allowed_types = ["txt", "TXT", "png", "PNG", "jpeg", "JPEG", "jpg", "JPG", "PDF", "pdf", "csv", "CSV", "DOC", "doc", "DOCX", "docx", "ODT", "odt", "PPT", "ppt", "PPTX", "pptx", "XLS", "xls", "XLSX", "xlsx"]
allowed_types = ["txt", "TXT", "png", "PNG", "jpeg", "JPEG", "jpg", "JPG", "PDF", "pdf", "csv", "CSV", "DOC", "doc", "DOCX", "docx", "ODT", "odt", "PPT", "ppt", "PPTX", "pptx", "XLS", "xls", "XLSX", "xlsx", "mov", "MOV", "SVG", "svg", "ZIP", "zip", "RAR", "rar", "EPS", "eps", "MP3", "mp3", "WAV", "wav", "avi", "AVI", "FLV", "flv", "MP4", "mp4"]
file_ok = False
for t in allowed_types:
if t == file_ext:
file_ok = True
@ -246,10 +262,19 @@ def adddirbyajax(request, parent):
if(uploadsource == "standards"):
datadir_parentid = list(DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk))[0]
else:
datadir_parentid = tempdir
tempdatafile = DataFile(file=request.FILES['uploadedfile'], name=str(request.FILES['uploadedfile'].name), owner=request.user, parent=datadir_parentid, agency=request.user.profile.agency)
tempdatafile.save()
datadir_parentid = tempdir
if(replace == "0"):
tempdatafile = DataFile(file=request.FILES['uploadedfile'], name=str(request.FILES['uploadedfile'].name).encode().decode(encoding='UTF-8',errors='strict'), owner=request.user, parent=datadir_parentid, agency=request.user.profile.agency)
else:
tempdatafile = list(DataFile.objects.filter(name__icontains=request.FILES['uploadedfile'].name, agency=request.user.profile.agency))[0]
tempdatafile.file = request.FILES['uploadedfile']
try:
tempdatafile.save()
except:
success = False
print("Fehler beim Speichern der Datei")
data = {'savedobj_id' : tempdatafile.pk, 'savedobj_name' : tempdatafile.name}
else:
success = False
@ -295,17 +320,22 @@ def getsubdirs(request, dirid):
@login_required
def trydownloadfile(request, pk):
file = DataFile.objects.get(pk=pk)
filetodownload = file.file.open()
checkuserrights = checkUserDirRights(request, file.parent, request.user.id)
if(checkuserrights):
response = FileResponse(filetodownload)
if(checkuserrights):
file_path = os.path.join(settings.MEDIA_ROOT, file.file.name)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
file_ext = file.name.split(".")[1]
response = HttpResponse(fh.read(), content_type="application/file")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
return response
else:
context = {
'active_link' : 'cloud',
}
return render(request, 'cloud/noentrie.html', context)

View File

@ -34,7 +34,7 @@
{% endif %}
</td>
<td>{{agn.creator_agency.name }}
&nbsp;<button style="float: right" class="btn btn-secondary btn-sm" onclick="javascript:$('#showAgencyInfo_{{agn.creator_agency.pk}}').modal('toggle');"><i class="fas fa-info-circle"></i></button>
&nbsp;<i style="float: right" onclick="javascript:$('#showAgencyInfo_{{agn.creator_agency.pk}}').modal('toggle');" class="fas fa-info-circle"></i>
</td>
<td>{{agn.creator.first_name }} {{agn.creator.last_name }}</td>
<td>{{agn.created_on }}</td>

View File

@ -96,7 +96,8 @@
</div>
{% if user|usergperm:"agencyinfo" %}
<div class="tab-pane fade" id="agency" role="tabpanel" aria-labelledby="agency-tab">
<h5 class="mt-3">Agenturinformationen{% if request.user.profile.showtooltips %}&nbsp;<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>{% endif %}</h5>
<h5 class="mt-3">Agenturinformationen{% if request.user.profile.showtooltips %}&nbsp;<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>{% endif %}
</h5>
<hr>
{% block agency_content %}
{% include "dasettings/agency_content.html" %}
@ -115,10 +116,10 @@
{% if user|usergperm:"agencynetwork" %}
<div class="tab-pane fade" id="agencynetwork" role="tabpanel" aria-labelledby="agencynetwork-tab">
<h5 class="mt-3">Agenturverbünde{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Ihre eigenen Agenturverbünde und in welchen Sie Mitglied sind." class="far fa-question-circle"></i></small>{% endif %}</h5>
<hr>
<hr>
{% block agencynetwork_content %}
{% include "dasettings/agencynetwork_content.html" %}
{% endblock %}
{% endblock %}
</div>
{% endif %}
{% if user|usergperm:"structuremanager" %}
@ -164,50 +165,46 @@ 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;
}
$(".toast").toast({
autohide: true,
delay : 3000
});
//Check prev Side
var activeTab = localStorage.getItem('activeTabSettings');
if(activeTab){
if($('#' + activeTab).find().prevObject.length != 0){
$('#' + activeTab).tab('show');
$(".nav-link").removeClass("active");
$("#" + activeTab + "-tab").addClass("active");
}
else{
$("#profil-tab").addClass("active");
$('#profil').tab('show');
}
}
else{
$("#profil-tab").addClass("active");
$('#profil').tab('show');
}
// 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;
console.log(document.cookie)
localStorage.setItem('activeTabSettings', 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 %}

View File

@ -26,7 +26,7 @@ noclickeffect:active { border-style: outset !important;}
<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>&nbsp;Bereich</button>
</div>
<hr>
<div id="allAreas" class="mt-3 col-9">
<div class="areaCollapseContent" id="sortableAreas" class="mt-3">
{%for area in agencyareas%}

View File

@ -15,11 +15,36 @@ import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
################################################### PROD DEV LOCAL CONFIGURATION ###############################
BASE_URL = "https://dev01.digitale-agentur.com/"
#BASE_URL = "https://digitale-agentur.com/"
#BASE_URL = "http://localhost:8000/"
CRONAPIKEY = "gCddsaz6NOnE9QbXZM5LasdEk122D"
############################################## DEV #####################################
# MAIL DEV
EMAIL_HOST = 'smtp.strato.de'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = "support@dev01.digitale-agentur.com"
EMAIL_HOST_PASSWORD = "support@dev01.digitale-agentur.com"
DEFAULT_FROM_EMAIL = "support@dev01.digitale-agentur.com"
# DEV
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME' : 'digitaleagentur_dev01',
'USER' : 'digitaleagentur_dev01',
'PASSWORD' : 't3TvtGAOkFHYXdJlUMIu9u3U',
'PORT' : 3306
}
}
############################################## DEV #####################################
# Nach zehn Stunden läuft der Cookie ab!
SESSION_COOKIE_AGE = 8*60*60
@ -99,18 +124,7 @@ TEMPLATES = [
WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
# DEV
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME' : 'digitaleagentur_dev01',
'USER' : 'digitaleagentur_dev01',
'PASSWORD' : 't3TvtGAOkFHYXdJlUMIu9u3U',
'PORT' : 3306
}
}
@ -181,13 +195,6 @@ GRAPPELLI_CLEAN_INPUT_TYPES = False
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# MAIL DEV
EMAIL_HOST = 'smtp.strato.de'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = "support@dev01.digitale-agentur.com"
EMAIL_HOST_PASSWORD = "support@dev01.digitale-agentur.com"
DEFAULT_FROM_EMAIL = "support@dev01.digitale-agentur.com"
# FOR DATEPICKER
BOOTSTRAP4 = {
@ -198,4 +205,6 @@ OPTIONS={
'libraries': {
'counter_tag': 'standards.tags',
},
}
}

View File

@ -87,6 +87,10 @@ def mainmessageview(request):
@login_required
def singelmessageview(request, pk):
#Notification delete
unknownnotification = UserNotification.objects.filter(touser__pk=request.user.pk, elementid=pk).delete()
context = {
'active_link' : 'messages',
'mess' : Message.objects.get(pk=pk)

View File

@ -1,6 +1,6 @@
from django import forms
from django.forms import ModelForm
from .models import QuickLinks, AGContacts, AGPassword
from .models import QuickLinks, AGContacts, AGPassword, AGContactsCagetory
class OrganizerAddQlForm(forms.ModelForm):
@ -15,6 +15,15 @@ class OrganizerAddQlForm(forms.ModelForm):
#fields = ['name', 'link', 'logo']
fields = ['name', 'link']
class OrganizerAddCategoryForm(forms.ModelForm):
class Meta:
model = AGContactsCagetory
labels = {
"name" : "Name der Kategorie",
}
fields = ['name']
# CONTACTS
class OrganizerAddContact(forms.ModelForm):
@ -30,21 +39,23 @@ class OrganizerAddContact(forms.ModelForm):
'street' : "Straße und Hausnummer",
'city' : "Stadt",
'plz' : "PLZ",
'category' : "Kategorie",
'desc' : "Anmerkungen"
}
fields = ['company', 'personname', 'mail', 'phone1', 'phone2', 'street', 'plz', 'city', 'desc']
fields = ['company', 'personname', 'mail', 'phone1', 'phone2', 'street', 'plz', 'city', "category", 'desc']
def __init__(self, *args, **kwargs):
def __init__(self, user, *args, **kwargs):
super(OrganizerAddContact, self).__init__(*args, **kwargs)
self.fields['company'].required = False
self.fields['personname'].required = False
self.fields['mail'].required = False
self.fields['phone1'].required = False
self.fields['phone2'].required = False
self.fields['desc'].widget.attrs['rows'] = 4
self.fields['phone2'].required = False
self.fields['category'].queryset = AGContactsCagetory.objects.filter(agency=user.profile.agency).order_by('name')
self.fields['category'].required = False
self.fields['desc'].widget.attrs['rows'] = 2
@ -61,12 +72,13 @@ class OrganizerUpdateContact(forms.ModelForm):
'street' : "Straße und Hausnummer",
'city' : "Stadt",
'plz' : "PLZ",
'category' : "Kategorie",
'desc' : "Anmerkungen"
}
fields = ['company', 'personname', 'mail', 'phone1', 'phone2', 'street', 'plz', 'city', 'desc']
fields = ['company', 'personname', 'mail', 'phone1', 'phone2', 'street', 'plz', 'city', "category", 'desc']
def __init__(self, *args, **kwargs):
def __init__(self, user, *args, **kwargs):
super(OrganizerUpdateContact, self).__init__(*args, **kwargs)
self.fields['company'].required = False
@ -74,7 +86,9 @@ class OrganizerUpdateContact(forms.ModelForm):
self.fields['mail'].required = False
self.fields['phone1'].required = False
self.fields['phone2'].required = False
self.fields['desc'].widget.attrs['rows'] = 4
self.fields['category'].queryset = AGContactsCagetory.objects.filter(agency=user.profile.agency).order_by('name')
self.fields['category'].required = False
self.fields['desc'].widget.attrs['rows'] = 2
# PASSWORDS
class AddAGPassword(forms.ModelForm):

View File

@ -37,6 +37,12 @@ class QuickLinks(models.Model):
else:
return "/media/agencymain/linkdefault.png"
class AGContactsCagetory(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.PROTECT)
name = models.CharField(default="", max_length=200, blank=False)
def __str__(self):
return f'{self.name}'
class AGContacts(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.PROTECT)
@ -49,9 +55,10 @@ class AGContacts(models.Model):
city = models.CharField(default="", max_length=200, blank=True)
plz = models.CharField(default="", max_length=5, blank=True)
desc = models.TextField(max_length=3000, blank=True)
category = models.ForeignKey("AGContactsCagetory", default=None, on_delete=models.SET_DEFAULT, null=True, blank=True)
def __str__(self):
return f'{self.first_name}'
return f'{self.company}'
def get_absolute_url(self):
return reverse('cont-update', kwargs={'pk':self.pk})

View File

@ -0,0 +1,25 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% if request.user.profile.agency.module_organizer %}
<div class="content-section">
<div class="media">
<div class="media-body">
<h2 class="account-heading">Kategorie {{ object.name }} löschen?</h2>
Achtung! Alle Kontakte mit dieser Kategorie erhalten keine Kategorie mehr!
<hr>
</div>
</div>
<!-- Für das Speichern der Bilder enctype -->
<form method="POST">
{% csrf_token %}
<div class="form-group">
<button type="submit" class="btn btn-danger">Kategorie löschen</button>&nbsp;
<a href="{% url 'category-management' %}" class="btn btn-success">Abbrechen</a>
</div>
</form>
</div>
{% else %}
<h3>Das Modul Organizer wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -0,0 +1,19 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% if request.user.profile.agency.module_organizer %}
<div class="content-section col-6">
<h3>Kategorie aktualisieren</h3>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<hr>
<button type="submit" class="btn btn-success">Kategorie aktualisieren</button>&nbsp;
<a class="btn" href="{% url 'category-management' %} ">Abbrechen</a>
</form>
</div>
{% else %}
<h3>Das Modul Organizer wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -0,0 +1,19 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% if request.user.profile.agency.module_organizer %}
<div class="content-section col-6">
<h3>Kategory anlegen</h3>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<hr>
<button type="submit" class="btn btn-success">Kategorie speichern</button>&nbsp;
<a class="btn" href="{% url 'organizer-management' %} ">Abbrechen</a>
</form>
</div>
{% else %}
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -0,0 +1,82 @@
{% extends "users/base.html" %}
{% load counter_tag %}
{% block content %}
{% if request.user.profile.agency.module_organizer %}
<div class="content-section col-12">
<h3>Kategorien{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Kategorien für Ihre Kontakte." class="far fa-question-circle"></i></small>{% endif %}
<a style="float: right" href="{% url 'organizer-management' %}" type="button" class="btn btn-secondary btn-sm"><i class="fas fa-chevron-circle-left"></i></a>
</h3>
<hr>
<a class="btn btn-primary" href="{% url 'ql-addcategory' %}"><i class="fas fa-plus"></i>&nbsp;Kategorie</a>
<div class="table-responsive mt-3">
<table class="table table-hover" id="category_table" >
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">&nbsp;</th>
</tr>
</thead>
<tbody>
{% for cat in categorys %}
<tr>
<td>
{{cat.name}}
</td>
<td>
{% if user|usergperm:"moduleorganizer" %}
<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">
<a class="dropdown-item" href="{% url 'cat-update' cat.pk%}">Bearbeiten</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'ql-cat-delete' cat.pk%}">Löschen</a>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<style>
/* DATATABLES */
.paginate_button {
padding: 0px !important;
border: 0px !important;
}
</style>
<script>
$(document).ready(function(){
$('#category_table').DataTable({
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"buttons" : {
"className" : "btn-danger"
}
});
});
</script>
{% else %}
<h3>Das Modul Organizer wurden in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -3,42 +3,63 @@
<div class="row">
<div class="content-section col-12">
<div class="row"><div class="content-section col-12">
{% if user|usergperm:"moduleorganizer" %}
<a class="btn btn-primary mb-3" href="{% url 'addcontact' %}"><i class="fas fa-plus"></i>&nbsp;Kontakt</a>
{% if user|usergperm:"moduleorganizer" %}
<a class="btn btn-primary" href="{% url 'addcontact' %}"><i class="fas fa-plus"></i>&nbsp;Kontakt</a>
<a class="btn btn-secondary mr-l btn-sm" style="vertical-align: bottom;" href="{% url 'category-management' %}"><i class="fas fa-pen"></i>&nbsp;Kategorien</a>
{% endif %}
<div class="form-group mb-2">
<input class="form-control" id="contacts_search" style="max-width: 400px;" size="20" type="text" onkeyup="javascript:checkSearchContactCards()" placeholder="Suche nach Kontakt...">
</div>
<hr>
<hr>
</div></div>
{% for agc in contacts %}
<div class="card col-3 mr-1 mb-2 contactscards" style="float: left;" id="card_{{agc.pk}}" name="{{agc.personname}} {{agc.company}}">
<div class="card-body">
<h5 class="card-title" data-toggle="modal" data-target="#infos_{{agc.pk}}"><a href="#">{{agc.company}}
</a>
</h5>
<p class="card-text">
{% if agc.personname|length > 0 %}
Ansprechpartner: {{agc.personname}}<br/>
<div class="table-responsive ">
<table class="table table-hover" id="table_contactsall" >
<thead>
<tr>
<th scope="col">Firma</th>
<th scope="col">E-Mail</th>
<th scope="col">Telefon</th>
<th scope="col">Kategorie</th>
{% if user|usergperm:"moduleorganizer" %}
<th scope="col">&nbsp;</th>
{% endif %}
{% if agc.mail|length > 0 %}
E-Mailadresse: <a href="mailto:{{agc.mail}}">{{agc.mail}}</a><br/>
{% endif %}
{% if agc.phone1|length > 0 %}
Telefon 1: <a href="tel::{{agc.phone1}}">{{agc.phone1}}</a>
{% endif %}
</p>
<span style="float: right">
{% if user|usergperm:"moduleorganizer" %}
<a style="float: right" class="btn btn-secondary btn-sm ml-2" href="{% url 'cont-delete' agc.pk %}"><small><i class="fas fa-trash"></i></small></a>
<a style="float: right" class="btn btn-secondary btn-sm " href="{% url 'cont-update' agc.pk %}"><small><i class="fas fa-pen"></i></small></a>
{% endif %}
</span>
</div>
</tr>
</thead>
<tbody id="table_contacts" >
{% for agc in contacts %}
<tr>
<td>
<a href="#" onclick="javascript:$('#infos_{{agc.pk}}').modal('toggle');">{{agc.company}}</a>
</td>
<td>
{% if agc.mail|length > 0 %}
<a href="mailto:{{agc.mail}}">{{agc.mail}}</a><br/>
{% endif %}
</td>
<td>
{% if agc.phone1|length > 0 %}
<a href="tel::{{agc.phone1}}">{{agc.phone1}}</a>
{% endif %}
</td>
<td>
{% if agc.category != None%} {{agc.category}} {% endif%}
</td>
<td>
{% if user|usergperm:"moduleorganizer" %}
<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">
<a class="dropdown-item" href="{% url 'cont-update' agc.pk %}">Bearbeiten</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'cont-delete' agc.pk %}">Löschen</a>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</div>
@ -80,30 +101,36 @@
</div>
{% endfor %}
<style>
/* DATATABLES */
.paginate_button {
padding: 0px !important;
border: 0px !important;
}
</style>
<script>
//SEARCH CONTACTS
var contactscards = $(".contactscards");
function checkSearchContactCards(){
if($("#contacts_search").val().length > 0)
{
for(i = 0; i < contactscards.length; i++){
var cardname = contactscards[i].getAttribute("name").toLowerCase();
var value = $("#contacts_search").val().toLowerCase();
if(cardname.indexOf(value) == -1){
$("#" + contactscards[i].getAttribute("id")).hide();
}
else{
$("#" + contactscards[i].getAttribute("id")).show();
}
}
}else{
for(i = 0; i < contactscards.length; i++){
$("#" + contactscards[i].getAttribute("id")).show();
}
}
}
$(document).ready(function(){
$('#table_contactsall').DataTable({
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"buttons" : {
"className" : "btn-danger"
}
});
});
</script>

View File

@ -0,0 +1,180 @@
{% load counter_tag %}
<div class="row">
<div class="content-section col-12">
<div class="row"><div class="content-section col-12">
{% if user|usergperm:"moduleorganizer" %}
<a class="btn btn-primary" href="{% url 'addcontact' %}"><i class="fas fa-plus"></i>&nbsp;Kontakt</a>
<a class="btn btn-secondary mr-l btn-sm" style="vertical-align: bottom;" href=""><i class="fas fa-pen"></i>&nbsp;Kategorien</a>
{% endif %}
<hr>
</div></div>
<div class="row col-12 " >
<ul class="nav nav-tabs" id="contacts_tabs_content" role="tablist">
<li class="nav-item active">
<a class="nav-link " id="contacts_all-tab"href="#contacts_all" >Alle</a>
</li>
<li class="nav-item ">
<a class="nav-link " id="addcategory-tab" data-toggle="tab" href="" role="tab" aria-selected="false" ><i class="fas fa-plus"></i>&nbsp;Kategorie</a>
</li>
</ul>
</div>
<div class="tab-content" id="contacts_tab_contentarea">
<div class="tab-pane fade show" id="contacts_all" role="tabpanel" aria-labelledby="contacts_all-tab">
<div class="table-responsive mt-3">
<table class="table table-hover" id="table_contactsall" >
<thead>
<tr>
<th scope="col">Firma</th>
<th scope="col">E-Mail</th>
<th scope="col">Telefon</th>
<!--<th scope="col">Logo</th> -->
{% if user|usergperm:"moduleorganizer" %}
<th scope="col">&nbsp;</th>
{% endif %}
</tr>
</thead>
<tbody id="table_contacts" >
{% for agc in contacts %}
<tr>
<td>
<a href="#" onclick="javascript:$('#infos_{{agc.pk}}').modal('toggle');">{{agc.company}}</a>
</td>
<td>
{% if agc.mail|length > 0 %}
<a href="mailto:{{agc.mail}}">{{agc.mail}}</a><br/>
{% endif %}
</td>
<td>
{% if agc.phone1|length > 0 %}
<a href="tel::{{agc.phone1}}">{{agc.phone1}}</a>
{% endif %}
</td>
<td>
{% if user|usergperm:"moduleorganizer" %}
<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">
<a class="dropdown-item" href="{% url 'cont-update' agc.pk %}">Bearbeiten</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'cont-delete' agc.pk %}">Löschen</a>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% for agc in contacts %}
<div class="modal fade " id="infos_{{agc.pk}}" tabindex="-1" role="dialog" data-backdrop="static" aria-hidden="true">
<div class="modal-dialog " role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">{{agc.company}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{% if agc.personname|length > 0 %}
Ansprechpartner: {{agc.personname}}<br/>
{% endif %}
{% if agc.mail|length > 0 %}
E-Mailadresse: <a href="mailto:{{agc.mail}}">{{agc.mail}}</a><br />
{% endif %}
{% if agc.phone1|length > 0 %}
Telefon 1: <a href="tel::{{agc.phone1}}">{{agc.phone1}}</a><br />
{% endif %}
{% if agc.phone2|length > 0 %}
Telefon 1: <a href="tel::{{agc.phone2}}">{{agc.phone2}}</a><br />
{% endif %}
{% if agc.street|length > 0 %}
Adresse: {{agc.street}} {{agc.plz}} {{agc.city}} <br />
{% endif %}
{% if agc.desc|length > 0 %}
Anmerkungen: {{agc.desc}}<br />
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
{% endfor %}
<style>
/* DATATABLES */
.paginate_button {
padding: 0px !important;
border: 0px !important;
}
</style>
<script>
$('#contacts_tabs_content a').on('click', function (e) {
e.preventDefault();
$(this).tab('show');
lastview_name = $(this)[0]['hash'].substring(1);
localStorage.setItem('activeTabContacts', lastview_name);
});
$(document).ready(function(){
$('#table_contactsall').DataTable({
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"buttons" : {
"className" : "btn-danger"
}
});
var activeTabContacts = localStorage.getItem('activeTabContacts');
if(activeTabContacts){
if($('#' + activeTabContacts).find().prevObject.length != 0){
$('#' + activeTabContacts).tab('show');
$(".nav-link").removeClass("active");
$("#" + activeTabContacts + "-tab").addClass("active");
}
else{
$("#contacts_all-tab").addClass("active");
$('#contacts_all').tab('show');
}
}
else{
$("#contacts_all-tab").addClass("active");
$('#contacts_all').tab('show');
}
});
</script>

View File

@ -71,7 +71,7 @@ $(document).ready(function(){
if($('#' + activeTab).find().prevObject.length != 0){
$('#' + activeTab).tab('show');
$(".nav-link").removeClass("active");
$("#" + activeTab + "-tab").addClass("active");
$("#" + activeTab + "-tab").addClass("active");
}
else{
$("#quicklinks-tab").addClass("active");

View File

@ -49,14 +49,14 @@
<td><a href="{{ap.link }}" target="_blank">{{ap.link}}</a></td>
<td>
<span id="uname_cl_{{ap.pk}}">{{ap.agpass_username }}</span>
<a href="#" onclick="javascript:copyUsernameToCB({{ap.pk}})"><i class="far fa-copy"></i></a>
<a href="#\" onclick="javascript:copyUsernameToCB({{ap.pk}})"><i class="far fa-copy"></i></a>
<span id="uname_cl_cop_{{ap.pk}}" style="display: none;">Kopiert!</span>
</td>
<td><span id="pass_cl_{{ap.pk}}" style="display: none;">{{ap.compass}}</span><span id="pass_{{ap.pk}}">*********</span>
<a href="#" onclick="javascript:showAgPass({{ap.pk}})"><i class="far fa-eye"></i></a>&nbsp;&nbsp;&nbsp;
<a href="#" onclick="javascript:copyPassToCB({{ap.pk}})"><i class="far fa-copy"></i></a>
<a href="#\" onclick="javascript:showAgPass({{ap.pk}})"><i class="far fa-eye"></i></a>&nbsp;&nbsp;&nbsp;
<a href="#\" onclick="javascript:copyPassToCB({{ap.pk}})"><i class="far fa-copy"></i></a>
<span id="pass_cl_cop_{{ap.pk}}" style="display: none;">Kopiert!</span>
</td>
<td>

View File

@ -3,8 +3,6 @@
<div class="row">
<div class="content-section col-4">
<a class="btn btn-primary" href="{% url 'ql-addql' %}"><i class="fas fa-plus"></i>&nbsp;Quicklink</a>
</div>
</div>
{% endif %}

View File

@ -1,14 +1,18 @@
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 .views import OrganizerManagement, OrganizerAdd, OrganizerDeleteView, OrganizerUpdateView, OrganizerAddContact, OrganizerDelContact, OrganizerUpdateContact, OrganizerAddPassword, OrganizerDelPassword, OrganizerUpdatePassword
from .views import OrganizerManagement, OrganizerAdd, OrganizerDeleteView, OrganizerUpdateView, OrganizerAddContact, OrganizerDelContact, OrganizerUpdateContact, OrganizerAddPassword, OrganizerDelPassword, OrganizerUpdatePassword, CategoryManagement, CategoryAdd, CategoryUpdateView, CategoryDeleteView
from . import views
'''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
'''
urlpatterns = [
path('', OrganizerManagement.as_view(template_name="organizer/organizer_management.html"), name='organizer-management'),
path('addql/', permission_required('users.moduleorganizer')(OrganizerAdd.as_view(template_name="organizer/ql_add.html")), name='ql-addql'),
path('category/', CategoryManagement.as_view(template_name="organizer/category_management.html"), name='category-management'),
path('addcat/', permission_required('users.moduleorganizer')(CategoryAdd.as_view(template_name="organizer/category_add.html")), name='ql-addcategory'),
path('addcat/<int:pk>/delete', permission_required('users.moduleorganizer')(CategoryDeleteView.as_view()), name='ql-cat-delete'),
path('addcat/<int:pk>/', permission_required('users.moduleorganizer')(CategoryUpdateView.as_view()), name='cat-update'),
path('addql/', permission_required('users.moduleorganizer')(OrganizerAdd.as_view(template_name="organizer/ql_add.html")), name='ql-addql'),
path('addcontact/', permission_required('users.moduleorganizer')(OrganizerAddContact.as_view(template_name="organizer/contact_add.html")), name='addcontact'),
path('addql/<int:pk>/delete', permission_required('users.moduleorganizer')(OrganizerDeleteView.as_view()), name='ql-delete'),
path('remco/<int:pk>/delete', permission_required('users.moduleorganizer')(OrganizerDelContact.as_view()), name='cont-delete'),

View File

@ -1,8 +1,8 @@
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView
from .models import QuickLinks, AGContacts, AGPassword
from .forms import OrganizerAddQlForm, OrganizerAddContact, OrganizerUpdateContact, AddAGPassword
from .models import QuickLinks, AGContacts, AGPassword, AGContactsCagetory
from .forms import OrganizerAddQlForm, OrganizerAddContact, OrganizerUpdateContact, AddAGPassword, OrganizerAddCategoryForm
from django.contrib import messages
from django.shortcuts import redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
@ -11,7 +11,63 @@ from django.urls import reverse_lazy
from users.models import AgencyGroup
# Create your views here.
class CategoryManagement(LoginRequiredMixin, ListView):
model = AGContactsCagetory
# Adding active_link
# Loading only user same agency
# Change context and return for template-data
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'organizer', 'categorys' : AGContactsCagetory.objects.filter(agency=self.request.user.profile.agency).order_by('name') })
return context
class CategoryAdd(LoginRequiredMixin, CreateView):
model = AGContactsCagetory
success_url = reverse_lazy('category-management')
form_class = OrganizerAddCategoryForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({"active_link" : "organizer"})
return context
def form_valid(self, form):
messages.success(self.request, f'Kategorie angelegt!')
form.instance.agency = self.request.user.profile.agency
return super().form_valid(form)
class CategoryUpdateView(LoginRequiredMixin, UpdateView):
model = AGContactsCagetory
template_name = 'organizer/cat_update.html'
success_url = reverse_lazy('category-management')
form_class = OrganizerAddCategoryForm
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Kategorie aktualisiert!')
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(CategoryUpdateView, self).get_context_data(**kwargs)
context['active_link'] = 'organizer'
return context
class CategoryDeleteView(LoginRequiredMixin, DeleteView):
model = AGContactsCagetory
success_url = reverse_lazy('category-management')
template_name = 'organizer/cat_confirm_delete.html'
def delete(self, request, *args, **kwargs):
response = super(CategoryDeleteView, self).delete(request, *args, **kwargs)
messages.success(request, f'Kategorie wurde gelöscht!')
return response
def get_context_data(self, **kwargs):
context = super(CategoryDeleteView, self).get_context_data(**kwargs)
context['active_link'] = 'organizer'
return context
class OrganizerManagement(LoginRequiredMixin, ListView):
model = QuickLinks
# Adding active_link
@ -31,7 +87,7 @@ class OrganizerAdd(LoginRequiredMixin, CreateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'organizer'})
return context
return get_context_data
def form_valid(self, form):
# Send message to the site
@ -84,7 +140,13 @@ class OrganizerAddContact(LoginRequiredMixin, CreateView):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'organizer'})
return context
# Pass User to Form to get only categorys from agency
def get_form_kwargs(self):
kwargs = super(OrganizerAddContact, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Kontakt angelegt!')
@ -120,6 +182,12 @@ class OrganizerUpdateContact(LoginRequiredMixin, UpdateView):
messages.success(self.request, f'Kontakt aktualisiert!')
return super().form_valid(form)
# Pass User to Form to get only categorys from agency
def get_form_kwargs(self):
kwargs = super(OrganizerUpdateContact, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
def get_context_data(self, **kwargs):
context = super(OrganizerUpdateContact, self).get_context_data(**kwargs)
context['active_link'] = 'organizer'

View File

@ -24,7 +24,7 @@
{% ifaginadminagn agn.pk request.user.profile.agency.pk as is_adminag %}
<tr id="agn_{{agn.pk}}">
<td><a href="{% url 'standard-agn' agn.pk %}">{{agn.name}}</a></td>
<td>{{agn.creator_agency.name }}&nbsp;<button style="float: right" class="btn btn-secondary btn-sm" onclick="javascript:$('#showAgencyInfo_{{agn.creator_agency.pk}}').modal('toggle');"><i class="fas fa-info-circle"></i></button> </td>
<td>{{agn.creator_agency.name }}&nbsp;<i style="float: right; " class="fas fa-info-circle" onclick="javascript:$('#showAgencyInfo_{{agn.creator_agency.pk}}').modal('toggle');"></i></td>
<td>{{agn.lastactivity}}</td>
<td>{{agsum}}</td>
<td>{{agn.standards.all|length}}</td>

View File

@ -327,11 +327,35 @@
</div>
<div class="modal-body">
<i class="fas fa-spinner fa-spin"></i> Datei wird hochgeladen...
<div class="progress">
<div class="progress-bar" id="uploadprocessbar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
<!-- CONFIRMA DOUBLE FILE -->
<div class="modal fade" id="doubleFileChoiceModal" 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">Datei bereits vorhanden</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Die Datei <b><span id="doublefile_name"></span></b> ist bereits vorhanden. Soll die Datei ersetzt oder beide behalten werden?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 1)">Alte Datei ersetzen</button>&nbsp;&nbsp;
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 0)">Beide behalten</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var ua = window.navigator.userAgent;
@ -500,7 +524,7 @@ $('#directdiv').on('dragleave', function (e) {
$("#directdiv").removeClass('bg-secondary');
});
allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*, image/x-png, image/gif, image/jpg, image/jpeg, image/JPEG, image/JPG, docx, JPEG, JPG, doc, odt, ODT, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
allowedtypes = ['doc','docx','odt','ods','xls','xlsx','xlsm','ppt','pptx','mov','avi','svg','png','jpg','jpeg','mp3', 'wav', 'zip', 'rar', 'mp4', 'mwv', 'flv', 'eps', 'txt', 'pdf']
function uploadButtonPush(){
@ -515,12 +539,58 @@ function hideUpload(){
$("#uploadModalProgress").modal("hide");
}
function replaceFileDirectChoice(filetodo, choice){
$("#doubleFileChoiceModal").modal("toggle");
doUploadAction(filetodo_ex, choice);
}
function uploadAction(filetodo){
filetodo_ex = filetodo;
$.ajax(
{
type: "GET",
url: "{% url 'cloud-adddir' parentid %}",
data:{
action : "check_doublefile",
name : filetodo.name
},
success: function( data )
{
if(data["data"]["found"]){
$("#doubleFileChoiceModal").modal("toggle");
$("#doublefile_name").html(filetodo.name);
}
else{
doUploadAction(filetodo, 0);
}
}
});
}
function getFileExtension1(filename) {
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}
function doUploadAction(filetodo, replacestat){
var formData = new FormData();
formData.append("uploadedfile", filetodo);
formData.append("uploadsource", "standards");
console.log(filetodo.type);
if(allowedtypes.indexOf(filetodo.type) != -1 && filetodo.type.length > 0){
formData.append("replace", replacestat);
var c = false;
for (i = 0; i < allowedtypes.length; i++) {
if (allowedtypes[i].localeCompare(getFileExtension1(filetodo.name)) == 0)
{
c = true;
}
}
if(c && filetodo.type.length > 0){
$.ajax({
url: "{% url 'cloud-adddir' parentid %}",
headers: {
@ -534,6 +604,16 @@ function uploadAction(filetodo){
beforeSend: function(){
$("#uploadModalProgress").modal("toggle");
},
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
$("#uploadprocessbar").css("width", percentComplete + "%");
}
}, false);
return xhr;
},
success: function(data) {
if(data["success"] == true){
setTimeout(function(){

View File

@ -1,6 +1,5 @@
{% extends "users/base.html" %}
{% load counter_tag %}
{% block content %}
<div class="content-section col-12">
@ -47,7 +46,7 @@
<p class="card-text text-secondary" data-toggle="popover" data-placement="top" data-trigger="hover" title="Zugriffsbeschränkung" data-content="Zugriff beschränkt auf {% for sgroup in standard.visibleby.all %}{{sgroup.agencygroupname}}{% if forloop.counter < standard.visibleby.all|length %},{%endif%}{% endfor %}"><i class="fas fa-lock"></i>&nbsp;{{standard.name|truncatechars:28}}</p>
{% endif %}
</td>
<td>{{standard.agency.name}}</td>
<td>{{standard.agency.name}} <i style="float: right; color: #000000;" class="fas fa-info-circle" onclick="javascript:$('#showAgencyInfo_{{standard.agency.pk}}').modal('toggle');"></i></td>
<td>{{standard.last_modified_on|date:"d.m.Y, H:i"}}</td>
<td>{{standard.agencynetworkcounter}}</td>
<td>{% if isshared %}Übernommen{% endif %}</td>
@ -56,12 +55,41 @@
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% for agn in standards_of_agency_network %}
<div class="modal fade" tabindex="-1" id="showAgencyInfo_{{agn.agency.pk}}" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Agenturinfo</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Agentur <b>{{agn.agency.name}}</b>
<hr>
{% if agn.agency.inhaber|length > 0 %}Inhaber: {{agn.agency.inhaber}}<br /> {% endif %}
{% if agn.agency.street|length > 0 %}Adresse: {{agn.agency.street}} {{agn.agency.plz}} {{agn.agency.city}}<br /> {% endif %}
{% if agn.agency.phone|length > 0 %}Telefon: {{agn.agency.phone}} <hr>{% endif %}
E-Mailadresse: <a href="mailto:{{agn.ail}}">{{agn.agency.agency_email}}</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Schliessen</button>
</div>
</div>
</div>
</div>
{% endfor %}
<script type="text/javascript">

View File

@ -4,15 +4,11 @@
{% block content %}
<div class="content-section col-12">
<h3>Standards{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Tätigkeiten." class="far fa-question-circle"></i></small>{% endif %}</h3>
<h3>Standards{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Tätigkeiten." class="far fa-question-circle"></i></small>{% endif %}
<a class="btn btn-primary" href="{% url 'standard-add' %}" style="float: right;"><i class="fas fa-plus"></i>&nbsp;Standard</a>
</h3>
<small>Sichtbar sind alle veröffentlichten und von {{ user.first_name }} {{ user.last_name}} erstellten Standards.</small>
<hr>
<div class="row">
<div class="content-section col-4">
<a class="btn btn-primary" href="{% url 'standard-add' %}"><i class="fas fa-plus"></i>&nbsp;Standard</a>
</div>
</div>
<hr>
<div class="row">
<div class="col-12">
<ul class="nav nav-tabs" id="area_tabs" role="tablist" >
@ -118,9 +114,9 @@
<a href="{% url 'standard-single' standard.pk %}">{{standard.name}}</a>
{% else %}
{% if standard.created_standard_by == request.user or perms.users.standard_management %}
<a href="{% url 'standard-update' standard.pk %}">{{standard.name}}</a> - In Bearbeitung
<a href="{% url 'standard-update' standard.pk %}">{{standard.name}}</a>&nbsp;<i class="fas fa-exclamation-circle"data-toggle="tooltip" data-placement="top" title="Es wurden nicht alle Pflichtfelder ausgefüllt."></i>
{% else %}
{{standard.name}} - In Bearbeitung
{{standard.name}}&nbsp;<i class="fas fa-exclamation-circle"data-toggle="tooltip" data-placement="top" title="Es wurden nicht alle Pflichtfelder ausgefüllt."></i>
{% endif %}
{% endif %}
</td>
@ -183,9 +179,9 @@
<a href="{% url 'standard-single' standard.pk %}">{{standard.name}}</a>
{% else %}
{% if standard.created_standard_by == request.user or perms.users.standard_management %}
<a href="{% url 'standard-update' standard.pk %}">{{standard.name}}</a> - In Bearbeitung
<a href="{% url 'standard-update' standard.pk %}">{{standard.name}}</a>&nbsp;<i class="fas fa-exclamation-circle"data-toggle="tooltip" data-placement="top" title="Es wurden nicht alle Pflichtfelder ausgefüllt."></i>
{% else %}
{{standard.name}} - In Bearbeitung
{{standard.name}}&nbsp;<i class="fas fa-exclamation-circle"data-toggle="tooltip" data-placement="top" title="Es wurden nicht alle Pflichtfelder ausgefüllt."></i>
{% endif %}
{% endif %}
</td>

View File

@ -345,11 +345,34 @@
</div>
<div class="modal-body">
<i class="fas fa-spinner fa-spin"></i> Datei wird hochgeladen...
<div class="progress">
<div class="progress-bar" id="uploadprocessbar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
<!-- CONFIRMA DOUBLE FILE -->
<div class="modal fade" id="doubleFileChoiceModal" 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">Datei bereits vorhanden</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Die Datei <b><span id="doublefile_name"></span></b> ist bereits vorhanden. Soll die Datei ersetzt oder beide behalten werden?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 1)">Alte Datei ersetzen</button>&nbsp;&nbsp;
<button type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:replaceFileDirectChoice(filetodo_ex, 0)">Beide behalten</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
@ -620,7 +643,8 @@ $('#directdiv').on('dragleave', function (e) {
$("#directdiv").removeClass('bg-secondary');
});
allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*, image/x-png, image/gif, image/jpg, image/jpeg, image/JPEG, image/JPG, docx, JPEG, JPG, doc, odt, ODT, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
allowedtypes = ['doc','docx','odt','ods','xls','xlsx','xlsm','ppt','pptx','mov','avi','svg','png','jpg','jpeg','mp3', 'wav', 'zip', 'rar', 'mp4', 'mwv', 'flv', 'eps', 'txt', 'pdf']
function uploadButtonPush(){
$("#uploadedfile").click();
@ -634,11 +658,65 @@ function hideUpload(){
$("#uploadModalProgress").modal("hide");
}
function uploadAction(filetodo){
var formData = new FormData();
function getFileExtension1(filename) {
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}
var filetodo_ex = "";
var parid_ex = "";
function replaceFileDirectChoice(filetodo, choice){
$("#doubleFileChoiceModal").modal("toggle");
doUploadAction(filetodo_ex, parid_ex, choice);
}
function uploadAction(filetodo, parid){
filetodo_ex = filetodo;
parid_ex = parid;
$.ajax(
{
type: "GET",
url: "{% url 'cloud-adddir' parentid %}",
data:{
action : "check_doublefile",
name : filetodo.name
},
success: function( data )
{
if(data["data"]["found"]){
$("#doubleFileChoiceModal").modal("toggle");
$("#doublefile_name").html(filetodo.name);
}
else{
doUploadAction(filetodo, parid, 0);
}
}
});
}
function doUploadAction(filetodo, parid, replacestat){
var formData = new FormData($("#uploadFileForm")[0]);
formData.append("uploadedfile", filetodo);
formData.append("uploadsource", "standards");
if(allowedtypes.indexOf(filetodo.type) != -1 && filetodo.type.length > 0){
formData.append("uploadsource", "cloud");
formData.append("replace", replacestat);
var bar = $('.bar');
var percent = $('.percent');
var c = false;
for (i = 0; i < allowedtypes.length; i++) {
if (allowedtypes[i].localeCompare(getFileExtension1(filetodo.name)) == 0)
{
c = true;
}
}
if(c && filetodo.type.length > 0){
$.ajax({
url: "{% url 'cloud-adddir' parentid %}",
headers: {
@ -652,6 +730,16 @@ function uploadAction(filetodo){
beforeSend: function(){
$("#uploadModalProgress").modal("toggle");
},
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
$("#uploadprocessbar").css("width", percentComplete + "%");
}
}, false);
return xhr;
},
/* success: function(data) {
if(data["success"] == true){
setTimeout(function(){

View File

@ -4,6 +4,8 @@ from users.models import AgencyGroup, Agency, AgencyNetwork, AgencyNetworkPreper
from standards.models import Standards, StandardCommentRate, StandardComments
from message.models import Message
import os
from django.conf import settings
register = template.Library()
b = 0
@ -213,5 +215,3 @@ def getifuserdidcomment(standard, user):
didcomment = True
return didcomment

View File

@ -526,11 +526,10 @@ def StandardFromAgn(request, pk):
# View for SingleStandard from AgencyNetwork
@login_required
def StandardSingleAgn(request, pk):
def StandardSingleAgn(request, pk):
context = {
'active_link':'standards',
'standard' : Standards.objects.get(pk=pk),
'standard' : Standards.objects.get(pk=pk),
'comments' : StandardComments.objects.filter(standard=Standards.objects.get(pk=pk)).order_by("-last_modified_on")
}
return render(request, 'standards/standards_single_agn.html', context)