zwischenpush
This commit is contained in:
commit
919039201c
|
|
@ -1,3 +1,4 @@
|
||||||
|
media/agencydata/*
|
||||||
media/agencymain/*
|
media/agencymain/*
|
||||||
!media/agencymain/default.jpg
|
!media/agencymain/default.jpg
|
||||||
!media/agencymain/linkdefault.png
|
!media/agencymain/linkdefault.png
|
||||||
|
|
@ -32,3 +33,4 @@ users/migrations/*
|
||||||
users/__pycache__/*
|
users/__pycache__/*
|
||||||
|
|
||||||
orga/__pycache__/*
|
orga/__pycache__/*
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,22 +0,0 @@
|
||||||
{% 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 %}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
{% 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 %}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
{% 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 %}
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
{% 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 %}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from .views import AreasManagement, AreasAddArea, AreaDeleteView, AreaUpdateView
|
|
||||||
from . import views
|
from . import views
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
@ -12,11 +12,7 @@ Permissions definiert in models.py bei USERS und dann hier vor die View geschrie
|
||||||
'''
|
'''
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', permission_required('users.areas_management')(AreasManagement.as_view(template_name="areas/areas_management.html")), name='areas-management'),
|
path('areaajax/', views.area_addareas_ajax, name="area-ajaxview"),
|
||||||
path('addarea/', permission_required('users.areas_management')(AreasAddArea.as_view(template_name="areas/areas_add.html")), name='areas-addarea'),
|
|
||||||
path('areas/<int:pk>/delete', permission_required('users.areas_management')(AreaDeleteView.as_view()), name='areas-delete'),
|
|
||||||
path('area/<int:pk>/', permission_required('users.areas_management')(AreaUpdateView.as_view()), name='areas-manage'),
|
|
||||||
path('areaajax/', views.area_addareas_ajax, name="area-ajaxview"),
|
|
||||||
path('updateorder/', views.area_neworder, name="area-ajaxorder")
|
path('updateorder/', views.area_neworder, name="area-ajaxorder")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
134
areas/views.py
134
areas/views.py
|
|
@ -7,129 +7,41 @@ from .forms import AreaAddAreaForm
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
import json
|
import json
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
|
@login_required
|
||||||
class AreasManagement(LoginRequiredMixin, ListView):
|
|
||||||
model = Areas
|
|
||||||
# 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)
|
|
||||||
# # Get all Users of the Same Agency as logged user
|
|
||||||
areas_of_agency = Areas.objects.filter(agency__pk=self.request.user.profile.agency.pk).order_by('areaorder')
|
|
||||||
|
|
||||||
context.update({'active_link' : 'areasmanagement', 'areas_of_agency':areas_of_agency})
|
|
||||||
return context
|
|
||||||
|
|
||||||
class AreasAddArea(LoginRequiredMixin, CreateView):
|
|
||||||
model = Areas
|
|
||||||
success_url = '/areas'
|
|
||||||
#fields = ['name', 'color', 'desc', 'usersfield']
|
|
||||||
form_class = AreaAddAreaForm
|
|
||||||
|
|
||||||
#def get(self,request,*args, **kwargs):
|
|
||||||
# # User ist der hier Aufgerufene, bzw. das Profil!
|
|
||||||
# return render (request, self.template_name, {'form':self.form_class(self.request.user), 'active_link': 'areasmanagement'})
|
|
||||||
|
|
||||||
|
|
||||||
# Adding active_link
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context.update({'active_link' : 'areasmanagement'})
|
|
||||||
return context
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
# Send message to the site
|
|
||||||
messages.success(self.request, f'Bereich angelegt!')
|
|
||||||
# SAVE OBJECTS TO SIGNALE!
|
|
||||||
form.instance.agency = self.request.user.profile.agency
|
|
||||||
form.instance.created_area_by = self.request.user
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class AreaDeleteView(LoginRequiredMixin, DeleteView):
|
|
||||||
model = Areas
|
|
||||||
success_url = '/areas'
|
|
||||||
template_name = 'areas/area_confirm_delete.html'
|
|
||||||
|
|
||||||
def delete(self, request, *args, **kwargs):
|
|
||||||
area = Areas.objects.get(pk=kwargs['pk'])
|
|
||||||
response = super(AreaDeleteView, self).delete(request, *args, **kwargs)
|
|
||||||
name = area.name
|
|
||||||
messages.success(request, f'Bereich ' +name+ ' wurde gelöscht!')
|
|
||||||
return response
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(AreaDeleteView, self).get_context_data(**kwargs)
|
|
||||||
context['active_link'] = 'areasmanagement'
|
|
||||||
return context
|
|
||||||
|
|
||||||
# Hier andere Nutzer ändern, wenn man Usersmanagement darf!
|
|
||||||
class AreaUpdateView(LoginRequiredMixin, UpdateView):
|
|
||||||
model = Areas
|
|
||||||
template_name = 'areas/areas_update.html'
|
|
||||||
success_url = '/areas'
|
|
||||||
form_class = AreaAddAreaForm
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
# Send message to the site
|
|
||||||
messages.success(self.request, f'Bereich aktualisiert!')
|
|
||||||
print(form)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
# Form wird geladen; Checkboxen werden vorbereitet und hier rausgerendert.
|
|
||||||
#def get(self,request,*args, **kwargs):
|
|
||||||
# # User ist der hier Aufgerufene, bzw. das Profil!
|
|
||||||
# loggeduser = request.user
|
|
||||||
#
|
|
||||||
# return render (request, self.template_name, {'form':self.form_class(loggeduser), 'active_link': 'usersmanagement'})
|
|
||||||
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(AreaUpdateView, self).get_context_data(**kwargs)
|
|
||||||
area = Areas.objects.get(pk=context['object'].pk)
|
|
||||||
# User still in Area
|
|
||||||
context['added_users'] = area.usersfield.all()
|
|
||||||
# Get all Users from same Agency which are NOT in context_added_users
|
|
||||||
possible_users = User.objects.filter(profile__agency__pk=self.request.user.profile.agency.pk).exclude(pk__in=context['added_users'])
|
|
||||||
context['possible_users'] = possible_users
|
|
||||||
# Active-Link for Base-Design
|
|
||||||
context['active_link'] = 'areasmanagement'
|
|
||||||
# Area ID
|
|
||||||
context['objectid'] = context['object'].pk
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
def area_addareas_ajax(request):
|
def area_addareas_ajax(request):
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
|
||||||
# ADD USER TO MANY-TO-MANY USERSFIELD
|
# ADD USER TO MANY-TO-MANY USERSFIELD
|
||||||
if request.GET['action'] == 'adduser':
|
if request.GET['action'] == 'adduser':
|
||||||
area = Areas.objects.get(pk=request.GET['objectid'])
|
area = Areas.objects.get(pk=request.GET['objectid'])
|
||||||
area.usersfield.add(User.objects.get(pk=request.GET['userid']))
|
|
||||||
area.save()
|
if(area.agency == request.user.profile.agency):
|
||||||
|
area.usersfield.add(User.objects.get(pk=request.GET['userid']))
|
||||||
|
area.save()
|
||||||
# REMOVE USER TO MANY-TO-MANY USERSFIELD
|
# REMOVE USER TO MANY-TO-MANY USERSFIELD
|
||||||
elif request.GET['action'] == 'remuser':
|
elif request.GET['action'] == 'remuser':
|
||||||
area = Areas.objects.get(pk=request.GET['objectid'])
|
area = Areas.objects.get(pk=request.GET['objectid'])
|
||||||
area.usersfield.remove(User.objects.get(pk=request.GET['userid']))
|
if(area.agency == request.user.profile.agency):
|
||||||
area.save()
|
area.usersfield.remove(User.objects.get(pk=request.GET['userid']))
|
||||||
|
area.save()
|
||||||
userid = request.GET['userid']
|
userid = request.GET['userid']
|
||||||
workinguser = User.objects.get(pk=userid)
|
workinguser = User.objects.get(pk=userid)
|
||||||
username_clean = workinguser.first_name + " " + workinguser.last_name
|
username_clean = workinguser.first_name + " " + workinguser.last_name
|
||||||
|
|
||||||
# Getting Remaining-Users
|
# Getting Remaining-Users
|
||||||
area = Areas.objects.get(pk=request.GET['objectid'])
|
area = Areas.objects.get(pk=request.GET['objectid'])
|
||||||
added_users = area.usersfield.all()
|
if(area.agency == request.user.profile.agency):
|
||||||
possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).exclude(pk__in=added_users)
|
added_users = area.usersfield.all()
|
||||||
possible_users_js = list(possible_users.values())
|
possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).exclude(pk__in=added_users)
|
||||||
# Cleaned out, that only data is neede will send to the side (first/last-name and id)
|
possible_users_js = list(possible_users.values())
|
||||||
final_possible_users = {}
|
# Cleaned out, that only data is neede will send to the side (first/last-name and id)
|
||||||
for ele in possible_users_js:
|
final_possible_users = {}
|
||||||
final_possible_users.update({'first_name':ele['first_name'],'last_name':ele['last_name'],'id':ele['id']})
|
for ele in possible_users_js:
|
||||||
# Counter for remaining users to show/hide "Keine Mitarbeiter"-Div
|
final_possible_users.update({'first_name':ele['first_name'],'last_name':ele['last_name'],'id':ele['id']})
|
||||||
remaining_users_counter = len(added_users)
|
# Counter for remaining users to show/hide "Keine Mitarbeiter"-Div
|
||||||
return JsonResponse({'userid' : userid, 'username_clean' : username_clean, 'remaining_users':possible_users_js, 'remaining_users_counter' : final_possible_users})
|
remaining_users_counter = len(added_users)
|
||||||
|
return JsonResponse({'userid' : userid, 'username_clean' : username_clean, 'remaining_users':possible_users_js, 'remaining_users_counter' : final_possible_users})
|
||||||
else:
|
else:
|
||||||
return HttpResponse("Request method is not a GET")
|
return HttpResponse("Request method is not a GET")
|
||||||
|
|
||||||
|
|
@ -146,14 +58,16 @@ def area_addareas_ajax(request):
|
||||||
Save all areas after drag n drop elements in table
|
Save all areas after drag n drop elements in table
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@login_required
|
||||||
def area_neworder(request):
|
def area_neworder(request):
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
if request.GET['action'] == 'newareaorder':
|
if request.GET['action'] == 'newareaorder':
|
||||||
neworderdata = json.loads(request.GET['finalod'])
|
neworderdata = json.loads(request.GET['finalod'])
|
||||||
for ele in neworderdata:
|
for ele in neworderdata:
|
||||||
area = Areas.objects.get(pk=ele['id'])
|
area = Areas.objects.get(pk=ele['id'])
|
||||||
area.areaorder = ele['neworder']
|
if(area.agency == request.user.profile.agency):
|
||||||
area.save()
|
area.areaorder = ele['neworder']
|
||||||
|
area.save()
|
||||||
return HttpResponse("UPDATED")
|
return HttpResponse("UPDATED")
|
||||||
else:
|
else:
|
||||||
return HttpResponse("Request method is not a GET")
|
return HttpResponse("Request method is not a GET")
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
Version 2, December 2004
|
|
||||||
|
|
||||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified
|
|
||||||
copies of this license document, and changing it is allowed as long
|
|
||||||
as the name is changed.
|
|
||||||
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
||||||
Youtube Plugin for CKEditor 4
|
|
||||||
=============================
|
|
||||||
|
|
||||||
Copyright © 2017 Jonnas Fonini <jonnasfonini@gmail.com>.
|
|
||||||
|
|
||||||
This work is free. You can redistribute it and/or modify it under the
|
|
||||||
terms of the Do What The Fuck You Want To Public License, Version 2,
|
|
||||||
as published by Sam Hocevar. See the LICENSE file for more details.
|
|
||||||
|
|
||||||
This plugin allow you to insert Youtube videos using embed code or just the video URL.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### With NPM
|
|
||||||
|
|
||||||
1. npm install ckeditor-youtube-plugin
|
|
||||||
|
|
||||||
2. Add the plugin to CKEditor (config.js):
|
|
||||||
|
|
||||||
````js
|
|
||||||
CKEDITOR.plugins.addExternal('youtube', '../node_modules/ckeditor-youtube-plugin/youtube/');
|
|
||||||
|
|
||||||
config.extraPlugins = 'youtube';
|
|
||||||
````
|
|
||||||
|
|
||||||
You may need to adjust the plugin path. The example is assuming that you have the following directory structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
project
|
|
||||||
└───ckeditor
|
|
||||||
│ └───config.js
|
|
||||||
└───node_modules
|
|
||||||
└───ckeditor-youtube-plugin
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual
|
|
||||||
|
|
||||||
Follow these steps:
|
|
||||||
|
|
||||||
1. Download the latest version of the plugin from Github.
|
|
||||||
2. Extract the downloaded file into the CKEditor's **plugins** folder.
|
|
||||||
3. Enable the plugin by changing or adding the extraPlugins line in your configuration (config.js):
|
|
||||||
|
|
||||||
````js
|
|
||||||
config.extraPlugins = 'youtube';
|
|
||||||
````
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
The default options can be overriden on config.js.
|
|
||||||
|
|
||||||
Video width:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_width = '640';
|
|
||||||
```
|
|
||||||
|
|
||||||
Video height:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_height = '480';
|
|
||||||
```
|
|
||||||
|
|
||||||
Make responsive (ignore width and height, fit to width):
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_responsive = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
Show related videos:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_related = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
Use old embed code:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_older = false;
|
|
||||||
```
|
|
||||||
|
|
||||||
Enable privacy-enhanced mode:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_privacy = false;
|
|
||||||
```
|
|
||||||
|
|
||||||
Start video automatically:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_autoplay = false;
|
|
||||||
```
|
|
||||||
|
|
||||||
Show player controls:
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_controls = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
Disable the change of settings. The elements on the list will be disabled (but still visible).
|
|
||||||
See the available element list below.
|
|
||||||
|
|
||||||
```js
|
|
||||||
config.youtube_disabled_fields = ['txtEmbed', 'chkAutoplay'];
|
|
||||||
```
|
|
||||||
|
|
||||||
#### List of UI elements
|
|
||||||
|
|
||||||
* txtEmbed
|
|
||||||
* txtUrl
|
|
||||||
* txtWidth
|
|
||||||
* txtHeight
|
|
||||||
* chkResponsive
|
|
||||||
* chkNoEmbed
|
|
||||||
* chkRelated
|
|
||||||
* chkOlderCode
|
|
||||||
* chkPrivacy
|
|
||||||
* chkAutoplay
|
|
||||||
* txtStartAt
|
|
||||||
* chkControls
|
|
||||||
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
If everything is ok, a Youtube icon should appear on the CKEditor toolbar. Click it,
|
|
||||||
paste your embed code or video URL and the video will be inserted.
|
|
||||||
|
|
||||||
## Translators
|
|
||||||
Thanks to those who helped translate the plugin
|
|
||||||
|
|
||||||
* Eyed Farra (ar)
|
|
||||||
* N. Petkov (bg)
|
|
||||||
* Lukáš Říha (cs)
|
|
||||||
* Sven Jansen (de)
|
|
||||||
* Dimitris Kotsakis (el)
|
|
||||||
* Victor (pollin14) (es)
|
|
||||||
* Kevin Rudissaar (et)
|
|
||||||
* Asier Iturralde Sarasola (eu)
|
|
||||||
* Jami Pietilä (fi)
|
|
||||||
* BiomanRouge (fr)
|
|
||||||
* Moshe Simantov (he)
|
|
||||||
* Karmacsi Gábor (hu)
|
|
||||||
* Francesco Zanoni (it)
|
|
||||||
* Yayoshi Nobuhide (ja)
|
|
||||||
* MinSoo Kim (ko)
|
|
||||||
* Holger Lockertsen (nb, nn)
|
|
||||||
* Patrick van Lier (nl)
|
|
||||||
* Michał Zalewski, Wirek (pl)
|
|
||||||
* Samuel Diogo (pt-br)
|
|
||||||
* Alexander Ustimenko (ru)
|
|
||||||
* ivanbarlog (sk)
|
|
||||||
* Çağdaş Yiğit (tr)
|
|
||||||
* Mykola Pukhalskyi (uk)
|
|
||||||
* Vu Thao (vi)
|
|
||||||
* trowa (zh)
|
|
||||||
|
|
||||||
|
|
||||||
[](http://www.wtfpl.net)
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ckeditor-youtube-plugin",
|
|
||||||
"version": "2.1.13",
|
|
||||||
"homepage": "https://github.com/fonini/ckeditor-youtube-plugin",
|
|
||||||
"authors": [
|
|
||||||
"Jonnas Fonini"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"ckeditor": ">= 4.0.0"
|
|
||||||
},
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"bower_components",
|
|
||||||
"test",
|
|
||||||
"tests"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ckeditor-youtube-plugin",
|
|
||||||
"description": "Youtube plugin for CKEditor",
|
|
||||||
"version": "2.1.13",
|
|
||||||
"author": "fonini",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/fonini/ckeditor-youtube-plugin"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"CKEditor",
|
|
||||||
"youtube",
|
|
||||||
"embed"
|
|
||||||
],
|
|
||||||
"files": [
|
|
||||||
"youtube/",
|
|
||||||
"LICENSE.md",
|
|
||||||
"README.md",
|
|
||||||
"bower.json",
|
|
||||||
"package.json"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'ar', {
|
|
||||||
button : 'شيفرة تضمين اليوتيوب',
|
|
||||||
title : 'شيفرة تضمين اليوتيوب',
|
|
||||||
txtEmbed : 'الصق شيفرة التضمين هنا',
|
|
||||||
txtUrl : 'الصق رابط فيديو اليوتيوب',
|
|
||||||
txtWidth : 'العرض',
|
|
||||||
txtHeight : 'الطول',
|
|
||||||
chkRelated : 'اظهر الفيديوهات المقترحة في نهاية الفيديو',
|
|
||||||
txtStartAt : 'ابدأ عند (ss او mm:ss او hh:mm:ss)',
|
|
||||||
chkPrivacy : 'تفعيل وضع تحسين الخصوصية',
|
|
||||||
chkOlderCode : 'استخدم شيفرة التضمين القديمة',
|
|
||||||
chkAutoplay : 'Autoplay',
|
|
||||||
chkControls: 'إظهار عناصر التحكم بالمشغّل',
|
|
||||||
noCode : 'يجب عليك ادخال شيفرة التضمين او الرابط',
|
|
||||||
invalidEmbed : 'شيفرة التضمين التي قمت بإدخالها تبدو غير صحيحة',
|
|
||||||
invalidUrl : 'الرابط الذي قمت بإدخاله يبدو غير صحيح',
|
|
||||||
or : 'او',
|
|
||||||
noWidth : 'يجب عليك ادخال العرض',
|
|
||||||
invalidWidth : 'يجب عليك ادخال عرض صحيح',
|
|
||||||
noHeight : 'يجب عليك ادخال الطول',
|
|
||||||
invalidHeight : 'يجب عليك ادخال طول صحيح',
|
|
||||||
invalidTime : 'يجب عليك ادخال وقت بداية صحيح',
|
|
||||||
txtResponsive : 'Responsive video'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'bg', {
|
|
||||||
button : 'Вмъкни YouTube видео',
|
|
||||||
title : 'Вграждане на YouTube видео',
|
|
||||||
txtEmbed : 'Въведете кода за вграждане тук',
|
|
||||||
txtUrl : 'Въведете YouTube видео URL',
|
|
||||||
txtWidth : 'Ширина',
|
|
||||||
txtHeight : 'Височина',
|
|
||||||
chkRelated : 'Показва предложени видеоклипове в края на клипа',
|
|
||||||
txtStartAt : 'Стартирай в (ss или mm:ss или hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Активирай режим за поверителност',
|
|
||||||
chkOlderCode : 'Използвай стар код за вграждане',
|
|
||||||
chkAutoplay: 'Авто стартиране',
|
|
||||||
chkControls: 'Показва контролите на плейъра',
|
|
||||||
noCode : 'Трябва да въведете код за вграждане или URL адрес',
|
|
||||||
invalidEmbed : 'Кодът за вграждане, който сте въвели, не изглежда валиден',
|
|
||||||
invalidUrl : 'Въведеният URL адрес не изглежда валиден',
|
|
||||||
or : 'или',
|
|
||||||
noWidth : 'Трябва да заложите ширината',
|
|
||||||
invalidWidth : 'Заложете валидна ширина',
|
|
||||||
noHeight : 'Трябва да заложите височина',
|
|
||||||
invalidHeight : 'Заложете валидна височина',
|
|
||||||
invalidTime : 'Заложете валидно време за стартиране',
|
|
||||||
txtResponsive : 'Напасва по ширина (игнорира Ширина и Височина)',
|
|
||||||
txtNoEmbed : 'Само видео изображение и връзка'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'cs', {
|
|
||||||
button : 'Vložit video YouTube',
|
|
||||||
title : 'Vložit video YouTube',
|
|
||||||
txtEmbed : 'Zde vložte kód pro vložení',
|
|
||||||
txtUrl : 'Vložte adresu URL videa YouTube',
|
|
||||||
txtWidth : 'Šířka',
|
|
||||||
txtHeight : 'Výška',
|
|
||||||
chkRelated : 'Po dohrání videa zobrazit navrhovaná videa',
|
|
||||||
txtStartAt : 'Začít přehrávat v čase (ss nebo mm:ss nebo hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Povolit režim s rozšířeným soukromím',
|
|
||||||
chkOlderCode : 'Použít starý kód pro vložení',
|
|
||||||
chkAutoplay : 'Automatické spuštění přehrávání',
|
|
||||||
chkControls : 'Zobrazit ovladače přehrávání',
|
|
||||||
noCode : 'Musíte vložit kód pro vložení nebo adresu URL',
|
|
||||||
invalidEmbed : 'Vložený kód pro vložení zřejmě není platný',
|
|
||||||
invalidUrl : 'Zadaná adresa URL zřejmě není platná',
|
|
||||||
or : 'nebo',
|
|
||||||
noWidth : 'Musíte zadat šířku',
|
|
||||||
invalidWidth : 'Zadejte platnou šířku',
|
|
||||||
noHeight : 'Musíte zadat výšku',
|
|
||||||
invalidHeight : 'Zadejte platnou výšku',
|
|
||||||
invalidTime : 'Zadejte platný počáteční čas',
|
|
||||||
txtResponsive : 'Responzivní design (ignorovat výšku a šířku, uzpůsobit šířce)',
|
|
||||||
txtNoEmbed : 'Pouze obrázek videa s odkazem'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'de', {
|
|
||||||
button : 'YouTube Video einbinden',
|
|
||||||
title : 'YouTube Video einbinden',
|
|
||||||
txtEmbed : 'Embed Code hier einfügen',
|
|
||||||
txtUrl : 'YouTube Video URL hier einfügen',
|
|
||||||
txtWidth : 'Breite',
|
|
||||||
txtHeight : 'Höhe',
|
|
||||||
chkRelated : 'Vorschläge am Ende des Videos einblenden',
|
|
||||||
txtStartAt : 'Start bei Position (ss oder mm:ss oder hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Erweiterten Datenschutzmodus aktivieren',
|
|
||||||
chkOlderCode : 'Benutze alten Embed Code',
|
|
||||||
chkAutoplay : 'Autoplay',
|
|
||||||
chkControls : 'Player-Steuerelemente anzeigen',
|
|
||||||
noCode : 'Sie müssen einen Embed Code oder URL angeben',
|
|
||||||
invalidEmbed : 'Der angegebene Embed Code scheint nicht gültig zu sein.',
|
|
||||||
invalidUrl : 'Die angegebene URL scheint nicht gültig zu sein.',
|
|
||||||
or : 'oder',
|
|
||||||
noWidth : 'Geben Sie eine Breite an',
|
|
||||||
invalidWidth : 'Geben Sie eine gültige Breite an',
|
|
||||||
noHeight : 'Geben Sie eine Höhe an',
|
|
||||||
invalidHeight : 'Geben Sie eine gültige Höhe an',
|
|
||||||
invalidTime : 'Geben Sie eine gültige Startzeit an',
|
|
||||||
txtResponsive : 'Automatische Größe (ignoriert Breite und Höhe)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'el', {
|
|
||||||
button: 'Ενσωμάτωση Youtube βίντεο',
|
|
||||||
title: 'Ενσωμάτωση Youtube βίντεο',
|
|
||||||
txtEmbed: 'Επικόλλησε τον κώδικα ενσωμάτωσης',
|
|
||||||
txtUrl: 'Επικόλλησε το URL του βίντεο',
|
|
||||||
txtWidth: 'Πλάτος',
|
|
||||||
txtHeight: 'Ύψος',
|
|
||||||
chkRelated: 'Εμφάνιση προτεινόμενων βίντεο μόλις ολοκληρωθεί',
|
|
||||||
txtStartAt: 'Χρόνος εκκίνησης (ss or mm:ss or hh:mm:ss)',
|
|
||||||
chkPrivacy: 'Ενεργοποίηση λειτουργίας ενισχυμένου απορρήτου',
|
|
||||||
chkOlderCode: 'Χρήση παλαιού κώδικα ενσωμάτωσης',
|
|
||||||
chkAutoplay: 'Αυτόματη εκκίνηση',
|
|
||||||
chkControls: 'Εμφάνιση στοιχείων ελέγχου προγράμματος αναπαραγωγής',
|
|
||||||
noCode: 'Χρειάζεται κώδικας ενσωμάτωσης ή URL',
|
|
||||||
invalidEmbed: 'Ο κώδικας ενσωμάτωσης που εισήγατε δεν μοιάζει σωστός',
|
|
||||||
invalidUrl: 'Το URL που εισήγατε δεν μοιάζει σωστό',
|
|
||||||
or: 'ή',
|
|
||||||
noWidth: 'Συμπληρώστε το πλάτος',
|
|
||||||
invalidWidth: 'Λανθασμένο πλάτος',
|
|
||||||
noHeight: 'Συμπληρώστε το ύψος',
|
|
||||||
invalidHeight: 'Λανθασμένο ύψος',
|
|
||||||
invalidTime: 'Λανθασμένος χρόνος εκκίνησης'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'en', {
|
|
||||||
button : 'Embed YouTube Video',
|
|
||||||
title : 'Embed YouTube Video',
|
|
||||||
txtEmbed : 'Paste Embed Code Here',
|
|
||||||
txtUrl : 'Paste YouTube Video URL',
|
|
||||||
txtWidth : 'Width',
|
|
||||||
txtHeight : 'Height',
|
|
||||||
chkRelated : 'Show suggested videos at the video\'s end',
|
|
||||||
txtStartAt : 'Start at (ss or mm:ss or hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Enable privacy-enhanced mode',
|
|
||||||
chkOlderCode : 'Use old embed code',
|
|
||||||
chkAutoplay: 'Autoplay',
|
|
||||||
chkControls: 'Show player controls',
|
|
||||||
noCode : 'You must input an embed code or URL',
|
|
||||||
invalidEmbed : 'The embed code you\'ve entered doesn\'t appear to be valid',
|
|
||||||
invalidUrl : 'The URL you\'ve entered doesn\'t appear to be valid',
|
|
||||||
or : 'or',
|
|
||||||
noWidth : 'You must inform the width',
|
|
||||||
invalidWidth : 'Inform a valid width',
|
|
||||||
noHeight : 'You must inform the height',
|
|
||||||
invalidHeight : 'Inform a valid height',
|
|
||||||
invalidTime : 'Inform a valid start time',
|
|
||||||
txtResponsive : 'Make Responsive (ignore width and height, fit to width)',
|
|
||||||
txtNoEmbed : 'Video image and link only'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'es', {
|
|
||||||
button : 'Embed YouTube video',
|
|
||||||
title : 'Embed YouTube video',
|
|
||||||
txtEmbed : 'Pegar el código embed',
|
|
||||||
txtUrl : 'Pegar la URL al video de Youtube',
|
|
||||||
txtWidth : 'Anchura',
|
|
||||||
txtHeight : 'Altura',
|
|
||||||
chkRelated : 'Mostrar videos sugeridos al final de este video',
|
|
||||||
txtStartAt : 'Comenzar en (ss or mm:ss or hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Habilitar el modo privacy-enhanced',
|
|
||||||
chkOlderCode : 'Usar código embed viejo',
|
|
||||||
chkAutoplay: 'Autoplay',
|
|
||||||
chkControls: 'Mostrar controles del reproductor',
|
|
||||||
noCode : 'Debes de introducir un código embed o URL',
|
|
||||||
invalidEmbed : 'El código embed introducido parece no ser valido',
|
|
||||||
invalidUrl : 'La URL introducida parece no ser valida',
|
|
||||||
or : 'o',
|
|
||||||
noWidth : 'Debes de dar la anchura',
|
|
||||||
invalidWidth : 'Da una anchura valida',
|
|
||||||
noHeight : 'Debes dar una altura valida',
|
|
||||||
invalidHeight : 'Da una altura valida',
|
|
||||||
invalidTime : 'Da un tiempo de valido',
|
|
||||||
txtResponsive : 'Hacer responsivo (ignorar anchura y altura, ajustar a la anchura)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'et', {
|
|
||||||
button : 'Lisa YouTube video',
|
|
||||||
title : 'YouTube video lisamine',
|
|
||||||
txtEmbed : 'Kleepige manustatud kood siia',
|
|
||||||
txtUrl : 'Kleepige YouTube video veebiaadress',
|
|
||||||
txtWidth : 'Laius',
|
|
||||||
txtHeight : 'Kõrgus',
|
|
||||||
chkRelated : 'Näita soovitatud videosi antud video lõppus',
|
|
||||||
txtStartAt : 'Alguskoht: (ss või mm:ss või hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Aktiveerige privaatsust täiendav režiim',
|
|
||||||
chkOlderCode : 'Kasutage vana manuskoodi',
|
|
||||||
chkAutoplay: 'Automaatesitlus',
|
|
||||||
chkControls : 'Kuva pleieri nupud',
|
|
||||||
noCode : 'Te peate sisestama video manuskoodi või veebiaadressi',
|
|
||||||
invalidEmbed : 'Manuskood mille sisestasite ei paista olevat korrektne',
|
|
||||||
invalidUrl : 'Veebiaadress mille sisestasite ei paista olevat korrektne',
|
|
||||||
or : 'või',
|
|
||||||
noWidth : 'Te peate sisestama video laiuse',
|
|
||||||
invalidWidth : 'Sisestage korrektne laius',
|
|
||||||
noHeight : 'Te peate sisestama video kõrguse',
|
|
||||||
invalidHeight : 'Sisestage korrektne kõrgus',
|
|
||||||
invalidTime : 'Sisestage korrektne algusaeg',
|
|
||||||
txtResponsive : 'Aktiveerige ekraani laiusega ühilduv režiim'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'eu', {
|
|
||||||
button : 'Kapsulatu YouTube-ko bideoa',
|
|
||||||
title : 'Kapsulatu YouTube-ko bideoa',
|
|
||||||
txtEmbed : 'Itsatsi kapsulatzeko kodea hemen',
|
|
||||||
txtUrl : 'Itsatsi YouTube-ko bideoaren URLa',
|
|
||||||
txtWidth : 'Zabalera',
|
|
||||||
txtHeight : 'Altuera',
|
|
||||||
chkRelated : 'Erakutsi gomendatutako bideoak amaieran',
|
|
||||||
txtStartAt : 'Hasi hemendik (ss edo mm:ss edo hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Gaitu pribatutasun hobetuko modua',
|
|
||||||
chkOlderCode : 'Erabili kapsulatzeko kode zaharra',
|
|
||||||
chkAutoplay: 'Erreproduzitu automatikoki',
|
|
||||||
chkControls: 'Erakutsi erreproduzigailuaren kontrolak',
|
|
||||||
noCode : 'Kapsulatzeko kode bat edo URL bat sartu behar duzu',
|
|
||||||
invalidEmbed : 'Sartu duzun kapsulatzeko kodea ez da baliozkoa',
|
|
||||||
invalidUrl : 'Sartu duzun URLa ez da baliozkoa',
|
|
||||||
or : 'edo',
|
|
||||||
noWidth : 'Zabalera sartu behar duzu',
|
|
||||||
invalidWidth : 'Sartu baliozko zabalera bat',
|
|
||||||
noHeight : 'Altuera sartu behar duzu',
|
|
||||||
invalidHeight : 'Sartu baliozko altuera bat',
|
|
||||||
invalidTime : 'Sartu baliozko hasierako denbora bat',
|
|
||||||
txtResponsive : 'Egin moldagarria (ez ikusia egin zabalera eta altuerari, zabalerara doitu)',
|
|
||||||
txtNoEmbed : 'Bideoaren irudia eta esteka soilik'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'fi', {
|
|
||||||
button : 'Upota YouTube-video',
|
|
||||||
title : 'Upota YouTube-video',
|
|
||||||
txtEmbed : 'Syötä YouTube-videon upotuskoodi',
|
|
||||||
txtUrl : 'Syötä YouTube-videon www-osoite',
|
|
||||||
txtWidth : 'Leveys',
|
|
||||||
txtHeight : 'Korkeus',
|
|
||||||
chkRelated : 'Näytä suositukset lopussa',
|
|
||||||
txtStartAt : 'Aloitusaika (ss tai mm:ss tai tt:mm:ss)',
|
|
||||||
chkPrivacy : 'Aktivoi yksityisyyttä parantava tila',
|
|
||||||
chkOlderCode : 'Käytä vanhaa upotuskoodia',
|
|
||||||
chkAutoplay: 'Soita automaattisesti',
|
|
||||||
chkControls : 'Näytä soittimen ohjaimet',
|
|
||||||
noCode : 'Sinun täytyy syötää upotuskoodi tai www-osoite',
|
|
||||||
invalidEmbed : 'Upotuskoodi on virheellinen',
|
|
||||||
invalidUrl : 'Www-osoite on virheellinen',
|
|
||||||
or : 'tai',
|
|
||||||
noWidth : 'Syötä leveys',
|
|
||||||
invalidWidth : 'Leveys on virheellinen',
|
|
||||||
noHeight : 'Syötä korkeus',
|
|
||||||
invalidHeight : 'Korkeus on virheellinen',
|
|
||||||
invalidTime : 'Aloitusaika on virheellinen',
|
|
||||||
txtResponsive : 'Responsiivinen leveys (sovita leveys)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'fr', {
|
|
||||||
button : 'Insérer une vidéo Youtube',
|
|
||||||
title : 'Insérer une vidéo youtube',
|
|
||||||
txtEmbed : 'Coller le code embed ici',
|
|
||||||
txtUrl : 'Coller l\'url de la vidéo ici',
|
|
||||||
txtWidth : 'Largeur',
|
|
||||||
txtHeight : 'Hauteur',
|
|
||||||
chkRelated : 'Montrer les suggestions de vidéo à la fin',
|
|
||||||
txtStartAt : 'Commencer à (ss ou mm:ss ou hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Activer la protection de la vie privée',
|
|
||||||
chkOlderCode : 'Utiliser l\'ancien code embed',
|
|
||||||
chkAutoplay : 'Autoplay',
|
|
||||||
chkControls : 'Afficher les commandes du lecteur',
|
|
||||||
noCode : 'Vous devez entrer un code embed ou une url',
|
|
||||||
invalidEmbed : 'Le code embed est invalide',
|
|
||||||
invalidUrl : 'L\'url est invalide',
|
|
||||||
or : 'ou',
|
|
||||||
noWidth : 'Vous devez saisir une largeur',
|
|
||||||
invalidWidth : 'La largeur saisie est invalide',
|
|
||||||
noHeight : 'Vous devez saisir une hauteur',
|
|
||||||
invalidHeight : 'La hauteur saisie est invalide',
|
|
||||||
invalidTime : 'Le temps de départ de la vidéo est invalide',
|
|
||||||
txtResponsive : 'Responsive video'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'he', {
|
|
||||||
button : 'שבץ וידאו של YouTube',
|
|
||||||
title : 'שבץ וידאו של YouTube',
|
|
||||||
txtEmbed : 'הדבק את קוד השיבוץ כאן',
|
|
||||||
txtUrl : 'הדבק כתובת וידאו YouTube',
|
|
||||||
txtWidth : 'אורך',
|
|
||||||
txtHeight : 'גובה',
|
|
||||||
chkRelated : 'הצג סרטונים מומלצים בסוף הודיאו',
|
|
||||||
txtStartAt : 'התחל ב (ss או mm:ss או hh:mm:ss)',
|
|
||||||
chkPrivacy : 'הפעל מצב פרטיות המשופרת',
|
|
||||||
chkOlderCode : 'השתמש בקוד הטמעה ישן',
|
|
||||||
chkAutoplay: 'הפעלה אוטומטית',
|
|
||||||
chkControls : 'הצג פקדי נגן',
|
|
||||||
noCode : 'אתה חייב להזין קוד embed כתובת וידאו אתר',
|
|
||||||
invalidEmbed : 'קוד ההטמעה שהוזן אינו נראה חוקי',
|
|
||||||
invalidUrl : 'כתובת הוידאו אינה נראת חוקית',
|
|
||||||
or : 'או',
|
|
||||||
noWidth : 'חובה להזין אורך',
|
|
||||||
invalidWidth : 'האורך שהוזן שגוי',
|
|
||||||
noHeight : 'חובה להזין גובה',
|
|
||||||
invalidHeight : 'הגובה שהוזן שגוי',
|
|
||||||
invalidTime : 'זמן התחלה שהוזן שגוי',
|
|
||||||
txtResponsive : 'הפוך לרספונסיבי (התעלם מרוחב וגובה, התאם לרוחב)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'hu', {
|
|
||||||
button : 'Youtube videó beillesztése',
|
|
||||||
title : 'Youtube videó beillesztése',
|
|
||||||
txtEmbed : 'Illessze be a beágyazott kódot',
|
|
||||||
txtUrl : 'Illessze be a Youtube videó URL-jét',
|
|
||||||
txtWidth : 'Szélesség',
|
|
||||||
txtHeight : 'Magasság',
|
|
||||||
txtStartAt : 'Kezdő időpont (ss vagy mm:ss vagy hh:mm:ss)',
|
|
||||||
chkRelated : 'Ajánlott videók megjelenítése, amikor a videó befejeződik',
|
|
||||||
chkPrivacy : 'Fokozott adatvédelmi mód engedélyezése',
|
|
||||||
chkOlderCode : 'Régi beágyazott kód használata',
|
|
||||||
chkAutoplay : 'Automatikus lejátszás',
|
|
||||||
chkControls : 'Lejátszásvezérlők mutatása',
|
|
||||||
noCode : 'A beágyazott kód, vagy az URL megadása kötelező',
|
|
||||||
invalidEmbed : 'A beágyazott kód érvénytelen',
|
|
||||||
invalidUrl : 'A megadott URL érvénytelen',
|
|
||||||
or : 'vagy',
|
|
||||||
noWidth : 'A szélesség megadása kötelező',
|
|
||||||
invalidWidth : 'Érvényes szélességet adjon meg',
|
|
||||||
noHeight : 'A magasság megadása kötelező',
|
|
||||||
invalidHeight : 'Érvényes magasságot adjon meg',
|
|
||||||
invalidTime : 'Érvényes kezdő időpontot adjon meg',
|
|
||||||
txtResponsive : 'Reszponzív videó',
|
|
||||||
txtNoEmbed : 'Csak kép és hivatkozás jelenjen meg'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'it', {
|
|
||||||
button : 'Incorpora video Youtube',
|
|
||||||
title : 'Incorpora video Youtube',
|
|
||||||
txtEmbed : 'Incolla qui il codice di incorporamento',
|
|
||||||
txtUrl : 'Incolla l\'URL del video Youtube',
|
|
||||||
txtWidth : 'Larghezza',
|
|
||||||
txtHeight : 'Altezza',
|
|
||||||
chkRelated : 'Mostra i video suggeriti dopo il video',
|
|
||||||
txtStartAt : 'Inizia a (ss o mm:ss o hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Abilita la protezione della privacy',
|
|
||||||
chkOlderCode : 'Usa il vecchio codice di incorporamento',
|
|
||||||
chkAutoplay : 'Autoplay',
|
|
||||||
chkControls : 'Mostra i controlli del player',
|
|
||||||
noCode : 'Devi inserire un codice di incorporamento o un URL',
|
|
||||||
invalidEmbed : 'Il codice di incorporamento inserito non sembra valido',
|
|
||||||
invalidUrl : 'L\'URL inserito non sembra valido',
|
|
||||||
or : 'o',
|
|
||||||
noWidth : 'Devi indicare la larghezza',
|
|
||||||
invalidWidth : 'Indica una larghezza valida',
|
|
||||||
noHeight : 'Devi indicare l\'altezza',
|
|
||||||
invalidHeight : 'Indica un\'altezza valida',
|
|
||||||
invalidTime : 'Indica un tempo di inizio valido',
|
|
||||||
txtResponsive : 'Responsive video'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'ja', {
|
|
||||||
button : 'Youtube動画埋め込み',
|
|
||||||
title : 'Youtube動画埋め込み',
|
|
||||||
txtEmbed : '埋め込みコードを貼り付けてください',
|
|
||||||
txtUrl : 'URLを貼り付けてください',
|
|
||||||
txtWidth : '幅',
|
|
||||||
txtHeight : '高さ',
|
|
||||||
chkRelated : '動画が終わったら関連動画を表示する',
|
|
||||||
txtStartAt : '開始時間(秒)',
|
|
||||||
chkPrivacy : 'プライバシー強化モードを有効にする',
|
|
||||||
chkOlderCode : '以前の埋め込みコードを使用する',
|
|
||||||
chkAutoplay : '自動再生',
|
|
||||||
chkControls: 'プレーヤーのコントロールを表示する',
|
|
||||||
noCode : '埋め込みコードまたはURLを入力してください',
|
|
||||||
invalidEmbed : '不適切な埋め込みコードが入力されました',
|
|
||||||
invalidUrl : '不適切なURLが入力されました',
|
|
||||||
or : 'または',
|
|
||||||
noWidth : '幅を指定してください',
|
|
||||||
invalidWidth : '幅指定に誤りがあります',
|
|
||||||
noHeight : '高さを指定してください',
|
|
||||||
invalidHeight : '高さ指定に誤りがあります',
|
|
||||||
invalidTime : '開始時間を正の整数で入力してください',
|
|
||||||
txtResponsive : 'レスポンシブ表示'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'ko', {
|
|
||||||
button : '유투브 비디오 삽입',
|
|
||||||
title : '유투브 비디오 삽입',
|
|
||||||
txtEmbed : '여기 embed 코드를 붙여넣으세요',
|
|
||||||
txtUrl : '유투브 주소(URL)를 붙여넣으세요',
|
|
||||||
txtWidth : '너비',
|
|
||||||
txtHeight : '높이',
|
|
||||||
chkRelated : '비디오 마지막에 추천 영상 보이기',
|
|
||||||
txtStartAt : '시작 시점 (ss 또는 mm:ss 또는 hh:mm:ss)',
|
|
||||||
chkPrivacy : '개인정보 보호 모드 활성화',
|
|
||||||
chkOlderCode : '옛날 embed 코드 사용',
|
|
||||||
chkAutoplay: '자동 재생',
|
|
||||||
chkControls: '플레이어 컨트롤 표시',
|
|
||||||
noCode : 'embed 코드 또는 URL을 입력해야 합니다',
|
|
||||||
invalidEmbed : '입력하신 embed 코드가 유효하지 않습니다',
|
|
||||||
invalidUrl : '입력하신 주소(URL)가 유효하지 않습니다',
|
|
||||||
or : '또는',
|
|
||||||
noWidth : '너비를 알려주세요',
|
|
||||||
invalidWidth : '너비가 유효하지 않습니다',
|
|
||||||
noHeight : '높이를 알려주세요',
|
|
||||||
invalidHeight : '높이가 유효하지 않습니다',
|
|
||||||
invalidTime : '시작 시점이 유효하지 않습니다',
|
|
||||||
txtResponsive : '반응형 너비 (입력한 너비와 높이를 무시하고 창 너비에 맞춤)',
|
|
||||||
txtNoEmbed : '비디오 이미지와 링크만 달기'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'nb', {
|
|
||||||
button : 'Bygg inn YouTube-video',
|
|
||||||
title : 'Bygg inn YouTube-video',
|
|
||||||
txtEmbed : 'Lim inn embed-kode her',
|
|
||||||
txtUrl : 'Lim inn YouTube video-URL',
|
|
||||||
txtWidth : 'Bredde',
|
|
||||||
txtHeight : 'Høyde',
|
|
||||||
chkRelated : 'Vis foreslåtte videoer når videoen er ferdig',
|
|
||||||
txtStartAt : 'Start ved (ss eller mm:ss eller hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Bruk personverntilpasset modus',
|
|
||||||
chkOlderCode : 'Bruk gammel embedkode',
|
|
||||||
chkAutoplay: 'Spill automatisk',
|
|
||||||
chkControls: 'Vis spillerkontrollene',
|
|
||||||
noCode : 'Du må legge inn en embed-kode eller URL',
|
|
||||||
invalidEmbed : 'Emded-koden du la inn ser ikke ut til å være gyldig',
|
|
||||||
invalidUrl : 'URLen du la inn ser ikke ut til å være gyldig',
|
|
||||||
or : 'eller',
|
|
||||||
noWidth : 'Du må legge inn bredde',
|
|
||||||
invalidWidth : 'Legg inn en gyldig bredde',
|
|
||||||
noHeight : 'Du må legge inn høyde',
|
|
||||||
invalidHeight : 'Legg inn en gyldig høyde',
|
|
||||||
invalidTime : 'Legg inn gyldig starttid',
|
|
||||||
txtResponsive : 'Gjør responsiv (ignorer bredde og høyde, tilpass bredde på sida)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'nl', {
|
|
||||||
button : 'Youtube video insluiten',
|
|
||||||
title : 'Youtube video insluiten',
|
|
||||||
txtEmbed : 'Plak embedcode hier',
|
|
||||||
txtUrl : 'Plak video URL',
|
|
||||||
txtWidth : 'Breedte',
|
|
||||||
txtHeight : 'Hoogte',
|
|
||||||
chkRelated : 'Toon gesuggereerde video aan het einde van de video',
|
|
||||||
txtStartAt : 'Starten op (ss of mm:ss of hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Privacy-enhanced mode inschakelen',
|
|
||||||
chkOlderCode : 'Gebruik oude embedcode',
|
|
||||||
chkAutoplay: 'Automatisch starten',
|
|
||||||
chkControls: 'Afspeelbediening weergeven',
|
|
||||||
noCode : 'U moet een embedcode of url ingeven',
|
|
||||||
invalidEmbed : 'De ingegeven embedcode lijkt niet geldig',
|
|
||||||
invalidUrl : 'De ingegeven url lijkt niet geldig',
|
|
||||||
or : 'of',
|
|
||||||
noWidth : 'U moet een breedte ingeven',
|
|
||||||
invalidWidth : 'U moet een geldige breedte ingeven',
|
|
||||||
noHeight : 'U moet een hoogte ingeven',
|
|
||||||
invalidHeight : 'U moet een geldige starttijd ingeven',
|
|
||||||
invalidTime : 'Inform a valid start time',
|
|
||||||
txtResponsive : 'Responsive video',
|
|
||||||
txtNoEmbed : 'Alleen video afbeelding en link'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'nn', {
|
|
||||||
button : 'Bygg inn YouTube-video',
|
|
||||||
title : 'Bygg inn YouTube-video',
|
|
||||||
txtEmbed : 'Lim inn embed-kode her',
|
|
||||||
txtUrl : 'Lim inn YouTube video-URL',
|
|
||||||
txtWidth : 'Breidde',
|
|
||||||
txtHeight : 'Høgde',
|
|
||||||
chkRelated : 'Vis foreslåtte videoar når videoen er ferdig',
|
|
||||||
txtStartAt : 'Start ved (ss eller mm:ss eller hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Bruk personverntilpassa modus',
|
|
||||||
chkOlderCode : 'Bruk gamal embedkode',
|
|
||||||
chkAutoplay: 'Spel automatisk',
|
|
||||||
chkControls: 'Vis spillerkontrollene',
|
|
||||||
noCode : 'Du må leggja inn ein embed-kode eller URL',
|
|
||||||
invalidEmbed : 'Emded-koden du la inn ser ikkje ut til å vera gyldig',
|
|
||||||
invalidUrl : 'URLen du la inn ser ikkje ut til å vera gyldig',
|
|
||||||
or : 'eller',
|
|
||||||
noWidth : 'Du må leggja inn breidde',
|
|
||||||
invalidWidth : 'Legg inn ei gyldig breidde',
|
|
||||||
noHeight : 'Du må leggja inn høgde',
|
|
||||||
invalidHeight : 'Legg inn ei gyldig høgde',
|
|
||||||
invalidTime : 'Legg inn gyldig starttid',
|
|
||||||
txtResponsive : 'Gjer responsiv (ignorer breidde og høgde, tilpass breidda på sida)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'pl', {
|
|
||||||
button : 'Załącznik wideo z YouTube',
|
|
||||||
title : 'Załącznik wideo z YouTube',
|
|
||||||
txtEmbed : 'Wklej kod do umieszczenia',
|
|
||||||
txtUrl : 'Wklej adres URL do wideo z YouTube',
|
|
||||||
txtWidth : 'Szerokość',
|
|
||||||
txtHeight : 'Wysokość',
|
|
||||||
chkRelated : 'Pokaż sugerowane filmy po zakończeniu odtwarzania',
|
|
||||||
txtStartAt : 'Rozpocznij od (ss lub mm:ss lub gg:mm:ss)',
|
|
||||||
chkPrivacy : 'Włącz rozszerzony tryb prywatności',
|
|
||||||
chkOlderCode : 'Użyj starego kodu',
|
|
||||||
chkAutoplay: 'Autoodtwarzanie',
|
|
||||||
chkControls: 'Pokaż elementy sterujące odtwarzacza',
|
|
||||||
noCode : 'Musisz wprowadzić kod lub adres URL',
|
|
||||||
invalidEmbed : 'Wprowadzony kod nie jest poprawny',
|
|
||||||
invalidUrl : 'Wprowadzony adres URL nie jest poprawny',
|
|
||||||
or : 'lub',
|
|
||||||
noWidth : 'Musisz wpisać szerokość',
|
|
||||||
invalidWidth : 'Wprowadzona szerokość nie jest poprawna',
|
|
||||||
noHeight : 'Musisz wprowadzić wysokość',
|
|
||||||
invalidHeight : 'Wprowadzona wysokość nie jest poprawna',
|
|
||||||
invalidTime : 'Musisz wprowadzić poprawny czas rozpoczęcia',
|
|
||||||
txtResponsive : 'El. responsywny (ignoruj szerokość i wysokość, dopasuj do szerokości)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'pt-br', {
|
|
||||||
button : 'Inserir Vídeo do Youtube',
|
|
||||||
title : 'Inserir Vídeo do Youtube',
|
|
||||||
txtEmbed : 'Cole aqui o código embed de um vídeo do Youtube',
|
|
||||||
txtUrl : 'Cole aqui uma URL de um vídeo do Youtube',
|
|
||||||
txtWidth : 'Largura',
|
|
||||||
txtHeight : 'Altura',
|
|
||||||
chkRelated : 'Mostrar vídeos sugeridos ao final do vídeo',
|
|
||||||
txtStartAt : 'Iniciar em (ss ou mm:ss ou hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Ativar o modo de privacidade aprimorada',
|
|
||||||
chkOlderCode : 'Usar código de incorporação antigo',
|
|
||||||
chkAutoplay : 'Reproduzir automaticamente',
|
|
||||||
chkControls: 'Mostrar controles do player',
|
|
||||||
noCode : 'Você precisa informar um código embed ou uma URL',
|
|
||||||
invalidEmbed : 'O código informado não parece ser válido',
|
|
||||||
invalidUrl : 'A URL informada não parece ser válida',
|
|
||||||
or : 'ou',
|
|
||||||
noWidth : 'Você deve informar a largura do vídeo',
|
|
||||||
invalidWidth : 'Informe uma largura válida',
|
|
||||||
noHeight : 'Você deve informar a altura do vídeo',
|
|
||||||
invalidHeight : 'Informe uma altura válida',
|
|
||||||
invalidTime : 'O tempo informado é inválido',
|
|
||||||
txtResponsive : 'Vídeo responsivo',
|
|
||||||
txtNoEmbed : 'Somente imagem e link para o vídeo'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'pt', {
|
|
||||||
button : 'Inserir Vídeo do Youtube',
|
|
||||||
title : 'Inserir Vídeo do Youtube',
|
|
||||||
txtEmbed : 'Cole aqui o código embed de um vídeo do Youtube',
|
|
||||||
txtUrl : 'Cole aqui uma URL de um vídeo do Youtube',
|
|
||||||
txtWidth : 'Largura',
|
|
||||||
txtHeight : 'Altura',
|
|
||||||
chkRelated : 'Mostrar vídeos sugeridos quando o vídeo terminar',
|
|
||||||
txtStartAt : 'Iniciar em (ss ou mm:ss ou hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Ativar o modo de privacidade otimizada',
|
|
||||||
chkOlderCode : 'Usar código de incorporação antigo',
|
|
||||||
chkAutoplay : 'Reproduzir automaticamente',
|
|
||||||
chkControls: 'Mostrar controles do player',
|
|
||||||
noCode : 'Você precisa informar um código embed ou uma URL',
|
|
||||||
invalidEmbed : 'O código informado não parece ser válido',
|
|
||||||
invalidUrl : 'A URL informada não parece ser válida',
|
|
||||||
or : 'ou',
|
|
||||||
noWidth : 'Você deve informar a largura do vídeo',
|
|
||||||
invalidWidth : 'Informe uma largura válida',
|
|
||||||
noHeight : 'Você deve informar a altura do vídeo',
|
|
||||||
invalidHeight : 'Informe uma altura válida',
|
|
||||||
invalidTime : 'O tempo informado é inválido',
|
|
||||||
txtResponsive : 'Vídeo responsivo',
|
|
||||||
txtNoEmbed : 'Somente imagem e link para o vídeo'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'ru', {
|
|
||||||
button : 'Вставить YouTube видео',
|
|
||||||
title : 'Вставить YouTube видео',
|
|
||||||
txtEmbed : 'Вставьте HTML-код сюда',
|
|
||||||
txtUrl : 'Вставьте адрес видео (URL)',
|
|
||||||
txtWidth : 'Ширина',
|
|
||||||
txtHeight : 'Высота',
|
|
||||||
chkRelated : 'Показать похожие видео после завершения просмотра',
|
|
||||||
txtStartAt : 'Начать с (сс или мм:сс или чч:мм:сс)',
|
|
||||||
chkPrivacy : 'Включить режим повышенной конфиденциальности',
|
|
||||||
chkOlderCode : 'Использовать старый код вставки',
|
|
||||||
chkAutoplay: 'Автозапуск',
|
|
||||||
chkControls: 'Показать панель управления',
|
|
||||||
noCode : 'Вы должны ввести HTML-код или адрес',
|
|
||||||
invalidEmbed : 'Ваш HTML-код не похож на правильный',
|
|
||||||
invalidUrl : 'Ваш адрес видео не похож на правильный',
|
|
||||||
or : 'или',
|
|
||||||
noWidth : 'Вы должны указать ширину',
|
|
||||||
invalidWidth : 'Укажите правильную ширину',
|
|
||||||
noHeight : 'Вы должны указать высоту',
|
|
||||||
invalidHeight : 'Укажите правильную высоту',
|
|
||||||
invalidTime : 'Укажите правильное время начала',
|
|
||||||
txtResponsive : 'Растягиваемое видео',
|
|
||||||
txtNoEmbed : 'Не встраивать видео (обложка-ссылка на YouTube)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'sk', {
|
|
||||||
button : 'Vložiť YouTube video',
|
|
||||||
title : 'Vložiť YouTube video',
|
|
||||||
txtEmbed : 'Vložiť Youtube Embed Video kódu',
|
|
||||||
txtUrl : 'Vložiť pomocou YouTube video URL',
|
|
||||||
txtWidth : 'Šírka',
|
|
||||||
txtHeight : 'Výška',
|
|
||||||
chkRelated : 'Zobraziť odporúčané videá po prehratí',
|
|
||||||
txtStartAt : 'Začať prehrávanie videa (ss alebo mm:ss alebo hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Povoliť pokročilý mód súkromia',
|
|
||||||
chkOlderCode : 'Použiť starú metódu vkladania',
|
|
||||||
chkAutoplay: 'Automatické prehrávanie',
|
|
||||||
chkControls: 'Zobraziť ovládacie prvky prehrávača',
|
|
||||||
noCode : 'Musíte vložiť Youtube Embed kód alebo URL',
|
|
||||||
invalidEmbed : 'Vložený kód nie je valídny',
|
|
||||||
invalidUrl : 'Vložená URL nie je platná',
|
|
||||||
or : 'alebo',
|
|
||||||
noWidth : 'Prosím, zadajte šírku videa',
|
|
||||||
invalidWidth : 'Zadajte valídnu šírku videa',
|
|
||||||
noHeight : 'Prosím, zadajte výšku videa',
|
|
||||||
invalidHeight : 'Zadajte valídnu výšku videa',
|
|
||||||
invalidTime : 'Zadajte valídny formát začiatku prehrávania videa',
|
|
||||||
txtResponsive : 'Prispôsobit rozmery videa rozmerom obrazovky (ignoruje šírku a výšku, prispôsobí sa šírke obrazovky)'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'tr', {
|
|
||||||
button : 'Youtube Video Gömün (Embed)',
|
|
||||||
title : 'Youtube Video',
|
|
||||||
txtEmbed : 'Youtube gömülü kodu (embed) buraya yapıştırınız',
|
|
||||||
txtUrl : 'Youtube linkinizi buraya yapıştırınız',
|
|
||||||
txtWidth : 'Genişlik',
|
|
||||||
txtHeight : 'Yükseklik',
|
|
||||||
chkRelated : 'Önerilen videoları video bitiminde göster',
|
|
||||||
txtStartAt : 'Video başlangıç anı (ss ya da dd:ss ya da ss:dd:ss)',
|
|
||||||
chkPrivacy : 'Gizlilik modunu etkinleştir',
|
|
||||||
chkOlderCode : 'Eski gömülü kodu (embed) kullan',
|
|
||||||
chkAutoplay: 'Otomatik',
|
|
||||||
chkControls: 'Oynatıcı kontrollerini göster',
|
|
||||||
noCode : 'Gömülü kod (embed) veya url yapıştırmak zorundasınız',
|
|
||||||
invalidEmbed : 'Verdiğiniz gömülü kod (embed) ile video bulunamadı',
|
|
||||||
invalidUrl : 'Verdiğiniz linkte video bulunamadı',
|
|
||||||
or : 'ya da',
|
|
||||||
noWidth : 'Genişliği belirtmek zorundasınız',
|
|
||||||
invalidWidth : 'Bir genişlik belirtin',
|
|
||||||
noHeight : 'Yükseliği belirtmek zorundasınız',
|
|
||||||
invalidHeight : 'Yükseklik belirtin',
|
|
||||||
invalidTime : 'Başlangıç anını doğru girin, örneğin: 13 (13. saniye) ya da 12:25 (12. dakika 25. saniye) ya da 01.25.33 (1 saat 25 dakika 33 saniye)',
|
|
||||||
txtResponsive : 'Responsive video'
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'uk', {
|
|
||||||
button : 'Вставити YouTube-відео',
|
|
||||||
title : 'Вставити YouTube-відео',
|
|
||||||
txtEmbed : 'Вставте HTML-код сюди',
|
|
||||||
txtUrl : 'Вставте URL-адресу сюди',
|
|
||||||
txtWidth : 'Ширина',
|
|
||||||
txtHeight : 'Висота',
|
|
||||||
chkRelated : 'Показати пропоновані відео в кінці',
|
|
||||||
txtStartAt : 'Почати з (сс або хх:сс або гг:хх:сс)',
|
|
||||||
chkPrivacy : 'Увімкнути режим підвищеної конфіденційності',
|
|
||||||
chkOlderCode : 'Використовувати старий код вставки',
|
|
||||||
chkAutoplay: 'Автовідтворення',
|
|
||||||
chkControls: 'Показувати елементи управління плеєром',
|
|
||||||
noCode : 'Ви повинні ввести HTML-код або URL-адресу',
|
|
||||||
invalidEmbed : 'Код вставки, який ви додали не вірний',
|
|
||||||
invalidUrl : 'URL-адреса, яку ви додали не вірна',
|
|
||||||
or : 'або',
|
|
||||||
noWidth : 'Укажіть ширину',
|
|
||||||
invalidWidth : 'Укажіть правильну ширину',
|
|
||||||
noHeight : 'Укажіть висоту',
|
|
||||||
invalidHeight : 'Укажіть правильну висоту',
|
|
||||||
invalidTime : 'Укажіть правильний час початку',
|
|
||||||
txtResponsive : 'Адаптивне (таке, яке розтягується) відео',
|
|
||||||
txtNoEmbed : 'Додати лише обкладинку та посилання на YouTube'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'vi', {
|
|
||||||
button : 'Embed Youtube Video',
|
|
||||||
title : 'Nhúng Video Youtube',
|
|
||||||
txtEmbed : 'Dãn mã nhúng Embed vào đây',
|
|
||||||
txtUrl : 'Dãn đường dẫn video Youtube',
|
|
||||||
txtWidth : 'Rộng',
|
|
||||||
txtHeight : 'Cao',
|
|
||||||
chkRelated : 'Hiển thị các video được đề xuất khi video kết thúc',
|
|
||||||
txtStartAt : 'Bắt đầu (ss hoặc mm:ss hoặc hh:mm:ss)',
|
|
||||||
chkPrivacy : 'Kích hoạt chế độ bảo mật nâng cao',
|
|
||||||
chkOlderCode : 'Sử dụng mã nhúng cũ',
|
|
||||||
chkAutoplay: 'Tự động chạy video',
|
|
||||||
chkControls: 'Hiển thị các điều khiển trình phát',
|
|
||||||
noCode : 'Bạn phải nhập mã nhúng hoặc URL',
|
|
||||||
invalidEmbed : 'Mã nhúng bạn đã nhập không đúng',
|
|
||||||
invalidUrl : 'URL bạn đã nhập không đúng',
|
|
||||||
or : 'hoặc',
|
|
||||||
noWidth : 'Bạn phải chiều rộng',
|
|
||||||
invalidWidth : 'Chiều rộng hợp lệ',
|
|
||||||
noHeight : 'Bạn phải chiều cao',
|
|
||||||
invalidHeight : 'Chiều cao hợp lệ',
|
|
||||||
invalidTime : 'Thời gian bắt đầu không đúng',
|
|
||||||
txtResponsive : 'Responsive video'
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
CKEDITOR.plugins.setLang('youtube', 'zh', {
|
|
||||||
button: '嵌入 Youtube 影片',
|
|
||||||
title: '嵌入 Youtube 影片',
|
|
||||||
txtEmbed: '貼上嵌入碼',
|
|
||||||
txtUrl: '貼上 Youtube 影片 URL',
|
|
||||||
txtWidth: '寬',
|
|
||||||
txtHeight: '高',
|
|
||||||
txtResponsive: '使用自適應縮放模式 (忽略設定的長寬, 以寬為基準縮放)',
|
|
||||||
chkRelated: '影片結束時顯示建議影片',
|
|
||||||
txtStartAt: '開始時間 (ss or mm:ss or hh:mm:ss)',
|
|
||||||
chkPrivacy: '啟用加強隱私模式',
|
|
||||||
chkOlderCode: '使用舊的嵌入碼',
|
|
||||||
chkAutoplay: '自動播放',
|
|
||||||
chkControls: '显示播放器控件',
|
|
||||||
noCode: '必須輸入嵌入碼',
|
|
||||||
invalidEmbed: '錯誤的嵌入碼',
|
|
||||||
invalidUrl: '錯誤的URL',
|
|
||||||
or: '或',
|
|
||||||
noWidth: '必須設定寬',
|
|
||||||
invalidWidth: '寬設定錯誤',
|
|
||||||
noHeight: '必須設定高',
|
|
||||||
invalidHeight: '高設定錯誤',
|
|
||||||
invalidTime: '開始時間設定錯誤'
|
|
||||||
});
|
|
||||||
|
|
@ -1,449 +0,0 @@
|
||||||
/*
|
|
||||||
* Youtube Embed Plugin
|
|
||||||
*
|
|
||||||
* @author Jonnas Fonini <jonnasfonini@gmail.com>
|
|
||||||
* @version 2.1.13
|
|
||||||
*/
|
|
||||||
(function () {
|
|
||||||
CKEDITOR.plugins.add('youtube', {
|
|
||||||
lang: [ 'en', 'bg', 'pt', 'pt-br', 'ja', 'hu', 'it', 'fr', 'tr', 'ru', 'de', 'ar', 'nl', 'pl', 'vi', 'zh', 'el', 'he', 'es', 'nb', 'nn', 'fi', 'et', 'sk', 'cs', 'ko', 'eu', 'uk'],
|
|
||||||
init: function (editor) {
|
|
||||||
editor.addCommand('youtube', new CKEDITOR.dialogCommand('youtube', {
|
|
||||||
allowedContent: 'div{*}(*); iframe{*}[!width,!height,!src,!frameborder,!allowfullscreen,!allow]; object param[*]; a[*]; img[*]'
|
|
||||||
}));
|
|
||||||
|
|
||||||
editor.ui.addButton('Youtube', {
|
|
||||||
label : editor.lang.youtube.button,
|
|
||||||
toolbar : 'insert',
|
|
||||||
command : 'youtube',
|
|
||||||
icon : this.path + 'images/icon.png'
|
|
||||||
});
|
|
||||||
|
|
||||||
CKEDITOR.dialog.add('youtube', function (instance) {
|
|
||||||
var video,
|
|
||||||
disabled = editor.config.youtube_disabled_fields || [];
|
|
||||||
|
|
||||||
return {
|
|
||||||
title : editor.lang.youtube.title,
|
|
||||||
minWidth : 510,
|
|
||||||
minHeight : 200,
|
|
||||||
onShow: function () {
|
|
||||||
for (var i = 0; i < disabled.length; i++) {
|
|
||||||
this.getContentElement('youtubePlugin', disabled[i]).disable();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
contents :
|
|
||||||
[{
|
|
||||||
id : 'youtubePlugin',
|
|
||||||
expand : true,
|
|
||||||
elements :
|
|
||||||
[{
|
|
||||||
id : 'txtEmbed',
|
|
||||||
type : 'textarea',
|
|
||||||
label : editor.lang.youtube.txtEmbed,
|
|
||||||
onChange : function (api) {
|
|
||||||
handleEmbedChange(this, api);
|
|
||||||
},
|
|
||||||
onKeyUp : function (api) {
|
|
||||||
handleEmbedChange(this, api);
|
|
||||||
},
|
|
||||||
validate : function () {
|
|
||||||
if (this.isEnabled()) {
|
|
||||||
if (!this.getValue()) {
|
|
||||||
alert(editor.lang.youtube.noCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (this.getValue().length === 0 || this.getValue().indexOf('//') === -1) {
|
|
||||||
alert(editor.lang.youtube.invalidEmbed);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'html',
|
|
||||||
html : editor.lang.youtube.or + '<hr>'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'hbox',
|
|
||||||
widths : [ '70%', '15%', '15%' ],
|
|
||||||
children :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id : 'txtUrl',
|
|
||||||
type : 'text',
|
|
||||||
label : editor.lang.youtube.txtUrl,
|
|
||||||
onChange : function (api) {
|
|
||||||
handleLinkChange(this, api);
|
|
||||||
},
|
|
||||||
onKeyUp : function (api) {
|
|
||||||
handleLinkChange(this, api);
|
|
||||||
},
|
|
||||||
validate : function () {
|
|
||||||
if (this.isEnabled()) {
|
|
||||||
if (!this.getValue()) {
|
|
||||||
alert(editor.lang.youtube.noCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
video = ytVidId(this.getValue());
|
|
||||||
|
|
||||||
if (this.getValue().length === 0 || video === false)
|
|
||||||
{
|
|
||||||
alert(editor.lang.youtube.invalidUrl);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'text',
|
|
||||||
id : 'txtWidth',
|
|
||||||
width : '60px',
|
|
||||||
label : editor.lang.youtube.txtWidth,
|
|
||||||
'default' : editor.config.youtube_width != null ? editor.config.youtube_width : '640',
|
|
||||||
validate : function () {
|
|
||||||
if (this.getValue()) {
|
|
||||||
var width = parseInt (this.getValue()) || 0;
|
|
||||||
|
|
||||||
if (width === 0) {
|
|
||||||
alert(editor.lang.youtube.invalidWidth);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(editor.lang.youtube.noWidth);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'text',
|
|
||||||
id : 'txtHeight',
|
|
||||||
width : '60px',
|
|
||||||
label : editor.lang.youtube.txtHeight,
|
|
||||||
'default' : editor.config.youtube_height != null ? editor.config.youtube_height : '360',
|
|
||||||
validate : function () {
|
|
||||||
if (this.getValue()) {
|
|
||||||
var height = parseInt(this.getValue()) || 0;
|
|
||||||
|
|
||||||
if (height === 0) {
|
|
||||||
alert(editor.lang.youtube.invalidHeight);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(editor.lang.youtube.noHeight);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'hbox',
|
|
||||||
widths : [ '55%', '45%' ],
|
|
||||||
children :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id : 'chkResponsive',
|
|
||||||
type : 'checkbox',
|
|
||||||
label : editor.lang.youtube.txtResponsive,
|
|
||||||
'default' : editor.config.youtube_responsive != null ? editor.config.youtube_responsive : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id : 'chkNoEmbed',
|
|
||||||
type : 'checkbox',
|
|
||||||
label : editor.lang.youtube.txtNoEmbed,
|
|
||||||
'default' : editor.config.youtube_noembed != null ? editor.config.youtube_noembed : false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'hbox',
|
|
||||||
widths : [ '55%', '45%' ],
|
|
||||||
children :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id : 'chkRelated',
|
|
||||||
type : 'checkbox',
|
|
||||||
'default' : editor.config.youtube_related != null ? editor.config.youtube_related : true,
|
|
||||||
label : editor.lang.youtube.chkRelated
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id : 'chkOlderCode',
|
|
||||||
type : 'checkbox',
|
|
||||||
'default' : editor.config.youtube_older != null ? editor.config.youtube_older : false,
|
|
||||||
label : editor.lang.youtube.chkOlderCode
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'hbox',
|
|
||||||
widths : [ '55%', '45%' ],
|
|
||||||
children :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id : 'chkPrivacy',
|
|
||||||
type : 'checkbox',
|
|
||||||
label : editor.lang.youtube.chkPrivacy,
|
|
||||||
'default' : editor.config.youtube_privacy != null ? editor.config.youtube_privacy : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id : 'chkAutoplay',
|
|
||||||
type : 'checkbox',
|
|
||||||
'default' : editor.config.youtube_autoplay != null ? editor.config.youtube_autoplay : false,
|
|
||||||
label : editor.lang.youtube.chkAutoplay
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : 'hbox',
|
|
||||||
widths : [ '55%', '45%'],
|
|
||||||
children :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id : 'txtStartAt',
|
|
||||||
type : 'text',
|
|
||||||
label : editor.lang.youtube.txtStartAt,
|
|
||||||
validate : function () {
|
|
||||||
if (this.getValue()) {
|
|
||||||
var str = this.getValue();
|
|
||||||
|
|
||||||
if (!/^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$/i.test(str)) {
|
|
||||||
alert(editor.lang.youtube.invalidTime);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id : 'chkControls',
|
|
||||||
type : 'checkbox',
|
|
||||||
'default' : editor.config.youtube_controls != null ? editor.config.youtube_controls : true,
|
|
||||||
label : editor.lang.youtube.chkControls
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onOk: function()
|
|
||||||
{
|
|
||||||
var content = '';
|
|
||||||
var responsiveStyle = '';
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'txtEmbed').isEnabled()) {
|
|
||||||
content = this.getValueOf('youtubePlugin', 'txtEmbed');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var url = 'https://', params = [], startSecs, paramAutoplay='';
|
|
||||||
var width = this.getValueOf('youtubePlugin', 'txtWidth');
|
|
||||||
var height = this.getValueOf('youtubePlugin', 'txtHeight');
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkPrivacy').getValue() === true) {
|
|
||||||
url += 'www.youtube-nocookie.com/';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
url += 'www.youtube.com/';
|
|
||||||
}
|
|
||||||
|
|
||||||
url += 'embed/' + video;
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkRelated').getValue() === false) {
|
|
||||||
params.push('rel=0');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkAutoplay').getValue() === true) {
|
|
||||||
params.push('autoplay=1');
|
|
||||||
paramAutoplay='autoplay';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkControls').getValue() === false) {
|
|
||||||
params.push('controls=0');
|
|
||||||
}
|
|
||||||
|
|
||||||
startSecs = this.getValueOf('youtubePlugin', 'txtStartAt');
|
|
||||||
|
|
||||||
if (startSecs) {
|
|
||||||
var seconds = hmsToSeconds(startSecs);
|
|
||||||
|
|
||||||
params.push('start=' + seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.length > 0) {
|
|
||||||
url = url + '?' + params.join('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkResponsive').getValue() === true) {
|
|
||||||
content += '<div class="youtube-embed-wrapper" style="position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden">';
|
|
||||||
responsiveStyle = 'style="position:absolute;top:0;left:0;width:100%;height:100%"';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkOlderCode').getValue() === true) {
|
|
||||||
url = url.replace('embed/', 'v/');
|
|
||||||
url = url.replace(/&/g, '&');
|
|
||||||
|
|
||||||
if (url.indexOf('?') === -1) {
|
|
||||||
url += '?';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
url += '&';
|
|
||||||
}
|
|
||||||
url += 'hl=' + (this.getParentEditor().config.language ? this.getParentEditor().config.language : 'en') + '&version=3';
|
|
||||||
|
|
||||||
content += '<object width="' + width + '" height="' + height + '" ' + responsiveStyle + '>';
|
|
||||||
content += '<param name="movie" value="' + url + '"></param>';
|
|
||||||
content += '<param name="allowFullScreen" value="true"></param>';
|
|
||||||
content += '<param name="allowscriptaccess" value="always"></param>';
|
|
||||||
content += '<embed src="' + url + '" type="application/x-shockwave-flash" ';
|
|
||||||
content += 'width="' + width + '" height="' + height + '" '+ responsiveStyle + ' allowscriptaccess="always" ';
|
|
||||||
content += 'allowfullscreen="true"></embed>';
|
|
||||||
content += '</object>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkNoEmbed').getValue() === true) {
|
|
||||||
var imgSrc = '//img.youtube.com/vi/' + video + '/sddefault.jpg';
|
|
||||||
content += '<a href="' + url + '" ><img width="' + width + '" height="' + height + '" src="' + imgSrc + '" ' + responsiveStyle + '/></a>';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
content += '<iframe allow="' + paramAutoplay + ';" width="' + width + '" height="' + height + '" src="' + url + '" ' + responsiveStyle;
|
|
||||||
content += 'frameborder="0" allowfullscreen></iframe>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getContentElement('youtubePlugin', 'chkResponsive').getValue() === true) {
|
|
||||||
content += '</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var element = CKEDITOR.dom.element.createFromHtml(content);
|
|
||||||
var instance = this.getParentEditor();
|
|
||||||
instance.insertElement(element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
function handleLinkChange(el, api) {
|
|
||||||
var video = ytVidId(el.getValue());
|
|
||||||
var time = ytVidTime(el.getValue());
|
|
||||||
|
|
||||||
if (el.getValue().length > 0) {
|
|
||||||
el.getDialog().getContentElement('youtubePlugin', 'txtEmbed').disable();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
el.getDialog().getContentElement('youtubePlugin', 'txtEmbed').enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video && time) {
|
|
||||||
var seconds = timeParamToSeconds(time);
|
|
||||||
var hms = secondsToHms(seconds);
|
|
||||||
el.getDialog().getContentElement('youtubePlugin', 'txtStartAt').setValue(hms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleEmbedChange(el, api) {
|
|
||||||
if (el.getValue().length > 0) {
|
|
||||||
el.getDialog().getContentElement('youtubePlugin', 'txtUrl').disable();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
el.getDialog().getContentElement('youtubePlugin', 'txtUrl').enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JavaScript function to match (and return) the video Id
|
|
||||||
* of any valid Youtube Url, given as input string.
|
|
||||||
* @author: Stephan Schmitz <eyecatchup@gmail.com>
|
|
||||||
* @url: http://stackoverflow.com/a/10315969/624466
|
|
||||||
*/
|
|
||||||
function ytVidId(url) {
|
|
||||||
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
|
||||||
return (url.match(p)) ? RegExp.$1 : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Matches and returns time param in YouTube Urls.
|
|
||||||
*/
|
|
||||||
function ytVidTime(url) {
|
|
||||||
var p = /t=([0-9hms]+)/;
|
|
||||||
return (url.match(p)) ? RegExp.$1 : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts time in hms format to seconds only
|
|
||||||
*/
|
|
||||||
function hmsToSeconds(time) {
|
|
||||||
var arr = time.split(':'), s = 0, m = 1;
|
|
||||||
|
|
||||||
while (arr.length > 0) {
|
|
||||||
s += m * parseInt(arr.pop(), 10);
|
|
||||||
m *= 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts seconds to hms format
|
|
||||||
*/
|
|
||||||
function secondsToHms(seconds) {
|
|
||||||
var h = Math.floor(seconds / 3600);
|
|
||||||
var m = Math.floor((seconds / 60) % 60);
|
|
||||||
var s = seconds % 60;
|
|
||||||
|
|
||||||
var pad = function (n) {
|
|
||||||
n = String(n);
|
|
||||||
return n.length >= 2 ? n : "0" + n;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (h > 0) {
|
|
||||||
return pad(h) + ':' + pad(m) + ':' + pad(s);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return pad(m) + ':' + pad(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts time in youtube t-param format to seconds
|
|
||||||
*/
|
|
||||||
function timeParamToSeconds(param) {
|
|
||||||
var componentValue = function (si) {
|
|
||||||
var regex = new RegExp('(\\d+)' + si);
|
|
||||||
return param.match(regex) ? parseInt(RegExp.$1, 10) : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
return componentValue('h') * 3600
|
|
||||||
+ componentValue('m') * 60
|
|
||||||
+ componentValue('s');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts seconds into youtube t-param value, e.g. 1h4m30s
|
|
||||||
*/
|
|
||||||
function secondsToTimeParam(seconds) {
|
|
||||||
var h = Math.floor(seconds / 3600);
|
|
||||||
var m = Math.floor((seconds / 60) % 60);
|
|
||||||
var s = seconds % 60;
|
|
||||||
var param = '';
|
|
||||||
|
|
||||||
if (h > 0) {
|
|
||||||
param += h + 'h';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m > 0) {
|
|
||||||
param += m + 'm';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s > 0) {
|
|
||||||
param += s + 's';
|
|
||||||
}
|
|
||||||
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
from .models import Data
|
from .models import Data, DataFile
|
||||||
|
|
||||||
class CloudAddFileForm(forms.ModelForm):
|
class CloudAddFileForm(forms.ModelForm):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from users.models import Agency
|
from users.models import Agency, AgencyGroup
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
def user_directory_path(instance, filename):
|
def user_directory_path(instance, filename):
|
||||||
# file will be uploaded to MEDIA_ROOT/agency_<id>/<subdirs>/<filename>
|
# file will be uploaded to MEDIA_ROOT/agency_<id>/files/<subdirs>/<filename>
|
||||||
return 'agency_{0}/{1}/{2}'.format(instance.agency.pk, instance.subdir, filename)
|
return 'agencydata/agency_{0}/files/{1}'.format(instance.agency.pk, filename)
|
||||||
|
|
||||||
|
|
||||||
class Data(models.Model):
|
class Data(models.Model):
|
||||||
|
|
@ -21,3 +21,33 @@ class Data(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.file.name)
|
return str(self.file.name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DataDir(models.Model):
|
||||||
|
name = models.CharField(max_length=2000, default="", blank=True, null=True)
|
||||||
|
is_root = models.BooleanField(default=False)
|
||||||
|
dirs = models.ManyToManyField('self', blank=True, related_name='dirs_in_dirs', symmetrical = False)
|
||||||
|
visibleby = models.ManyToManyField(AgencyGroup, blank=True, related_name='visible_by_user')
|
||||||
|
date_created = models.DateTimeField(default = timezone.now)
|
||||||
|
date_last_modified = models.DateTimeField(default = timezone.now)
|
||||||
|
owner = models.ForeignKey(User, on_delete=models.PROTECT, blank=True, null=True)
|
||||||
|
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
|
||||||
|
parent = models.ForeignKey('DataDir', on_delete=models.CASCADE, blank=True, null=True, related_name='dir_in_dir')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.name)
|
||||||
|
|
||||||
|
|
||||||
|
class DataFile(models.Model):
|
||||||
|
name = models.CharField(max_length=2000, default="", blank=True, null=True)
|
||||||
|
file = models.FileField(null=True, max_length=255, upload_to=user_directory_path, blank=True)
|
||||||
|
date_created = models.DateTimeField(default = timezone.now)
|
||||||
|
date_last_modified = models.DateTimeField(default = timezone.now)
|
||||||
|
owner = models.ForeignKey(User, on_delete=models.PROTECT, default=None, blank=True, null=True)
|
||||||
|
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None, blank=True, null=True)
|
||||||
|
parent = models.ForeignKey(DataDir, on_delete=models.PROTECT, related_name='thisfileindir', blank=True, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,741 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
{% load counter_tag %}
|
||||||
|
{% load static %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-12">
|
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||||
<h3>Dateien</h3>
|
<script src="{% static 'users/js/jsLists.js' %}"></script>
|
||||||
<hr>
|
<link href="{% static 'users/css/jsLists.css' %}" rel="stylesheet">
|
||||||
<p>
|
<style>
|
||||||
Hier können Sie Dateien und Ordner für ihre Agentur verwalten.
|
.icon-hover:hover{
|
||||||
</p>
|
color: gray;
|
||||||
<form method="POST" id="fileuploadform" enctype="multipart/form-data" class="col-6">
|
}
|
||||||
{% csrf_token %}
|
a.disabled {
|
||||||
{{form.media}}
|
pointer-events: none;
|
||||||
{{form|crispy}}
|
cursor: default;
|
||||||
<div class="mt-2">
|
}
|
||||||
<button class="btn btn-primary" type="submit">Hochladen</button>
|
</style>
|
||||||
|
|
||||||
|
<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="fileerr" class="toast alert-danger" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Daten gefunden</strong>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
<div id="toast_errcontent">Achtung! In Unterverzeichnissen befinden sich Dateien. Es können nur Ordner ohne Unterordner gelöscht werden!</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="content-section col-12">
|
||||||
<p>
|
<h3>Dateien <small><i data-toggle="tooltip" data-placement="top" title="Hier können Sie Dateien und Ordner für ihre Agentur verwalten." class="far fa-question-circle"></i></small></h3>
|
||||||
{% if all_files %}
|
<hr>
|
||||||
<table class="table table-hover">
|
</div>
|
||||||
|
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item" aria-current="page"><a href="{% url 'cloud-main' 'first' %}"><i class="fas fa-home"></i></a></li>
|
||||||
|
{% for cr in breadcrump %}
|
||||||
|
{% if forloop.last %}
|
||||||
|
<li class="breadcrumb-item" active>{{cr}}</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="breadcrumb-item"><a href="{% url 'cloud-main' cr.pk %}">{{cr.name}}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if user|usergperm:"filedirmanager" %}
|
||||||
|
<li class="breadcrumb-item" active><i onclick="javascript:addDirModal()" class="fas fa-folder-plus icon-hover"></i></li>
|
||||||
|
{% endif %}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
{% if user|usergperm:"filesviewer" %}
|
||||||
|
<table class="table table-hover" id="dirfilestable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#</th>
|
<th scope="col"><small><i data-toggle="tooltip" data-placement="top" title="Ziehen Sie Dateien direkt auf die Ordner, um sie in die Ordner hochzuladen oder in den unteren Bereich, um Dateien in diesen Ordner hochzuladen." class="far fa-question-circle"></i></small></th>
|
||||||
<th scope="col">Name</th>
|
<th scope="col">Name</th>
|
||||||
<th scope="col">Eigentümer</th>
|
<th scope="col">Eigentümer</th>
|
||||||
<th scope="col">Datum</th>
|
<th scope="col">Erstellt</th>
|
||||||
<th scope="col"></th>
|
<th scope="col">Geändert</th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for ele in all_files %}
|
{% for d in dirs %}
|
||||||
<tr>
|
|
||||||
<td>{{forloop.counter}}</td>
|
{% setbool False %}
|
||||||
<td>{{ele.file}}</td>
|
|
||||||
<td>{{ele.owner.first_name}} {{ele.owner.last_name}}</td>
|
{% for dirgroup in d.visibleby.all %}
|
||||||
<td>{{ele.date_created}}</td>
|
{% if user|has_group:dirgroup.group.name %}
|
||||||
<td>Optionen</td>
|
{% setbool True %}
|
||||||
</tr>
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% if d.visibleby.all|length == 0 %}
|
||||||
|
{% setbool True %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% getbool as groupchecker %}
|
||||||
|
|
||||||
|
<tr id="dir_{{d.pk}}" class="droppable_tr">
|
||||||
|
<td id="dir_{{d.pk}}_icon"><i class="fas fa-folder" ></i>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if groupchecker %}
|
||||||
|
<a href="{% url 'cloud-main' d.pk %}">{{d.name}}</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-secondary"><i class="fas fa-lock"></i> {{d.name}}</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{d.owner.first_name}} {{d.owner.last_name}}</td>
|
||||||
|
<td>{{d.date_created|date:"d.m.Y G:i"}}</td>
|
||||||
|
<td>{{d.date_last_modified|date:"d.m.Y G:i"}}</td>
|
||||||
|
<td>
|
||||||
|
{% if user|usergperm:"filedirmanager" and groupchecker%}
|
||||||
|
<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">Ordneroptionen</div>
|
||||||
|
<a class="dropdown-item" href="javascript:changeDirName({{d.pk}})">Umbenennen</a>
|
||||||
|
<a class="dropdown-item" href="javascript:showGroupChangeModal({{d.pk}})">Zugriff einschränken</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item text-danger" href="javascript:delDataDirObje({{d.pk}})" >Löschen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% for file in files %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i class="fas fa-file" ></i>
|
||||||
|
</td>
|
||||||
|
<td><a href="{{file.file.url}}" download>{{file.name}}</a></td>
|
||||||
|
<td>{{file.owner.first_name}} {{file.owner.last_name}}</td>
|
||||||
|
<td>{{file.date_created|date:"d.m.Y G:i"}}</td>
|
||||||
|
<td>{{file.date_last_modified|date:"d.m.Y G:i"}}</td>
|
||||||
|
<td>
|
||||||
|
{% if user|usergperm:"filesmanager" %}
|
||||||
|
<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">Dateioptionen</div>
|
||||||
|
<a class="dropdown-item" href="javascript:moveFile({{file.pk}})">Verschieben</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item text-danger" href="javascript:delDataFileObje({{file.pk}})" >Löschen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<div class="alert alert-primary" role="alert">
|
{% if user|usergperm:"filesmanager" %}
|
||||||
Für Ihre Agentur wurden noch keine Dateien hochgeladen.
|
<form method="POST" id="uploadFileForm" enctype="multipart/form-data">
|
||||||
</div>
|
<input type="file" id="uploadedfile" name="uploadedfile" style="display:none">
|
||||||
{% endif %}
|
</form>
|
||||||
</p>
|
<div class="alert alert-secondary droppable_div text-center mt-5" id="{{parentid}}_div" role="alert" style="line-height: 45px; text-align: center;">
|
||||||
|
<button type="button" class="btn btn-primary btn-sm" id="uploadButton" onclick="javascript:uploadButtonPush()"><i class="fas fa-plus"></i></button> zum Hochladen klicken oder neue Dateien hier hineinziehen.<p><small>Dateien werden im aktuellen Ordner
|
||||||
|
<b>{% if breadcrump|length == 0 %}
|
||||||
|
Heimverzeichnis
|
||||||
|
{% else %}
|
||||||
|
{{breadcrump.0}}
|
||||||
|
{% endif %}</b>
|
||||||
|
gespeichert.
|
||||||
|
</small></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<!-- MODAL CHANGE DIRNAME -->
|
||||||
|
<div class="modal fade" id="changeName" 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">
|
||||||
|
<span id="actualName"></span> Umbenennen
|
||||||
|
</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">Name:</label>
|
||||||
|
<input class="form-control" id="changename" type="text" value="" placeholder="Ordnername" onkeyup="javascript:validateNewName(this.value)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Abrechen</button>
|
||||||
|
<button id="doUpdateName" type="button" class="btn btn-success" data-dismiss="modal" onclick="javascript:updateName()" disabled="false">Speichern</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
|
||||||
|
<!-- CONFIRMA DELETE DIR -->
|
||||||
|
<div class="modal fade" id="delDataObj" 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">Ordner 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">
|
||||||
|
Mit 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>
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Abbrechen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- FILE FORBIDDEN DELETE FILE -->
|
||||||
|
<div class="modal fade" id="forbiddenFileType" 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 nicht erlaubt</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Diesen Dateitypen dürfen Sie nicht hochladen.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CONFIRMA DELETE FILE -->
|
||||||
|
<div class="modal fade" id="delDataFile" 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 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">
|
||||||
|
Datei <b><span id="filenametodel"></span></b> wirklich löschen?
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal" onclick="javascript:doDelDataFile()">Löschen</button>
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Abbrechen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CONFIRMA MOVE/DIR -->
|
||||||
|
<div class="modal fade" id="moveDataModal" 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 Verschieben</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Bitte neues Verzeichnis auswählen:
|
||||||
|
<div id="agencydirlist"></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Abbrechen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODEAL ADD DIR -->
|
||||||
|
<div class="modal fade" id="addDir" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="false">
|
||||||
|
<div class="modal-dialog " role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="mainmodalArea_title">
|
||||||
|
{% if breadcrump|length == 0 %}
|
||||||
|
Ordner in Heimverzeichnis der Agentur erstellen
|
||||||
|
{% else %}
|
||||||
|
Ordner in {{breadcrump.0}} erstellen
|
||||||
|
{% endif %}
|
||||||
|
</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">Name:</label>
|
||||||
|
<input class="form-control" id="newdirname" type="text" value="" placeholder="Ordnername" onkeyup="javascript:validateDirName(this.value, 0)">
|
||||||
|
</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:addDirAction()" disabled="true">Ordner anlegen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- CHANGE GROUPS -->
|
||||||
|
<div class="modal fade" id="changeGroupOfDataObj" 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">Zugriffe einschränken</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Welche Gruppen dürfen auf diese Daten Zugriff haben?
|
||||||
|
<p><small>Ist keine Gruppe ausgewählt, darf jeder der Agentur diese Daten sehen!</small></p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
{% for g in agencygroups %}
|
||||||
|
{% if forloop.counter|divisibleby:6 %}
|
||||||
|
</div> <div class="col-6">
|
||||||
|
<div class="custom-control custom-checkbox mb-2">
|
||||||
|
<input type="checkbox" class="custom-control-input groupclass" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:changeGroup({{g.pk}}, this.checked)">
|
||||||
|
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="custom-control custom-checkbox mb-2">
|
||||||
|
<input type="checkbox" class="custom-control-input groupclass" name="group_{{g.pk}}" id="group_{{g.pk}}" onchange="javascript:changeGroup({{g.pk}}, this.checked)">
|
||||||
|
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Beenden</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
$(".toast").toast({
|
||||||
|
autohide: true,
|
||||||
|
delay : 5000
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//GROUPS
|
||||||
|
function showGroupChangeModal(tochangeid){
|
||||||
|
$("#changeGroupOfDataObj").modal("toggle");
|
||||||
|
$(".groupclass").attr("checked", false);
|
||||||
|
workingdirid = tochangeid;
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "getgroupsofdir",
|
||||||
|
dirid : workingdirid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
for(i = 0; i < data["data"]["gdir"].length; i++){
|
||||||
|
$("#group_" + data["data"]["gdir"][i]['id']).attr("checked", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#changeGroupOfDataObj').on('hidden.bs.modal', function (e) {
|
||||||
|
window.location = window.location
|
||||||
|
})
|
||||||
|
|
||||||
|
function changeGroup(groupid, value){
|
||||||
|
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "changedirgroups",
|
||||||
|
groupid : groupid,
|
||||||
|
dirid : workingdirid,
|
||||||
|
value : value
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//MOVING OPERATIONS
|
||||||
|
function moveFile(fileid)
|
||||||
|
{
|
||||||
|
|
||||||
|
workingfileid = fileid;
|
||||||
|
workingdirid = false;
|
||||||
|
|
||||||
|
$("#moveDataModal").modal("toggle");
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "getdirlist"
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
$("#agencydirlist").html("");
|
||||||
|
html = ['<ul id="simple_list"><li><i class="fa fa-folder"></i> <a href="javascript:targetParentToMove({{rootid}})"><b><u>Heimverzeichnis<u></b></a>'];
|
||||||
|
createList(data["data"]["agencydirlist"], l);
|
||||||
|
$("#agencydirlist").html(html);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var html = ['<ul id="simple_list"><li><i class="fa fa-folder"></i> <a href="javascript:targetParentToMove({{rootid}})"><b><u>Heimverzeichnis<u></b></a>'];
|
||||||
|
|
||||||
|
let l = 2;
|
||||||
|
|
||||||
|
//Create UL-LI-List for tree
|
||||||
|
function createList(arr, l) {
|
||||||
|
html.push('<ul>');
|
||||||
|
$.each(arr, function(i, val) {
|
||||||
|
if(val.parent == ""){
|
||||||
|
|
||||||
|
html.push('<li><i class="fa fa-folder mt-2"></i> <a href="javascript:targetParentToMove('+val.id+')"><b>' + val.name + '</b></a>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
html.push('<li class="ml-'+l+' mt-2"><i class="fa fa-folder" ></i><a href="javascript:targetParentToMove('+val.id+')"> '+val.name+'</a></li>');
|
||||||
|
}
|
||||||
|
if (val.subdirs) {
|
||||||
|
createList(val.subdirs, l+1)
|
||||||
|
}
|
||||||
|
html.push('</li>');
|
||||||
|
});
|
||||||
|
html.push('</ul>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function targetParentToMove(parid){
|
||||||
|
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "movefile",
|
||||||
|
fileid : workingfileid,
|
||||||
|
newpar : parid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
window.location = window.location
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// preventing page from redirecting
|
||||||
|
$("html").on("dragover", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });
|
||||||
|
|
||||||
|
|
||||||
|
uploadtoparent = {{parentid}};
|
||||||
|
</script>
|
||||||
|
{% if user|usergperm:"filesmanager" %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$( ".droppable_tr" ).on('dragenter', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#" + currentid + "_icon").html("");
|
||||||
|
$("#" + currentid + "_icon").html('<i class="fas fa-folder-open"></i>');
|
||||||
|
$("#" + currentid).addClass('table-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('.droppable_tr').on('drop', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
uploadtoparent = e["currentTarget"]['id'].split("_")[1];
|
||||||
|
uploadAction(e.originalEvent.dataTransfer.files[0], e["currentTarget"]['id'].split("_")[1]);
|
||||||
|
$("#" + currentid).removeClass('table-secondary');
|
||||||
|
$("#" + currentid + "_icon").html("");
|
||||||
|
$("#" + currentid + "_icon").html('<i class="fas fa-folder"></i>');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.droppable_tr').on('dragleave', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#" + currentid + "_icon").html("");
|
||||||
|
$("#" + currentid + "_icon").html('<i class="fas fa-folder"></i>');
|
||||||
|
$("#" + currentid).removeClass('table-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$( ".droppable_div" ).on('dragenter', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#{{parentid}}_div").addClass('bg-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('.droppable_div').on('drop', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
$("#{{parentid}}_div").removeClass('bg-secondary');
|
||||||
|
uploadAction(e.originalEvent.dataTransfer.files[0], e["currentTarget"]['id'].split("_")[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.droppable_div').on('dragleave', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
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/*"
|
||||||
|
|
||||||
|
|
||||||
|
function uploadAction(filetodo, parid){
|
||||||
|
var formData = new FormData($("#uploadFileForm")[0]);
|
||||||
|
formData.append("uploadedfile", filetodo);
|
||||||
|
var bar = $('.bar');
|
||||||
|
var percent = $('.percent');
|
||||||
|
if(allowedtypes.includes(filetodo.type) && filetodo.type.length > 0){
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'cloud-adddir' %}" + parid,
|
||||||
|
headers: {
|
||||||
|
"X-CSRFTOKEN": "{{ csrf_token }}"
|
||||||
|
},
|
||||||
|
data: formData,
|
||||||
|
type: 'POST',
|
||||||
|
cache: false,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
beforeSend: function(){
|
||||||
|
$("#uploadModalProgress").modal("toggle");
|
||||||
|
},
|
||||||
|
uploadProgress: function(event, position, total, percentComplete){
|
||||||
|
var percentVal = percentComplete + '%';
|
||||||
|
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
if(data["success"] == true){
|
||||||
|
window.location = window.location;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
$('#uploadedfile').on('change', function() {
|
||||||
|
uploadAction($("#uploadedfile")[0]['files'][0], {{parentid}});
|
||||||
|
});
|
||||||
|
|
||||||
|
function uploadButtonPush(){
|
||||||
|
$("#uploadedfile").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILE OPERATIONS
|
||||||
|
workingfileid = false;
|
||||||
|
function delDataFileObje(fileid){
|
||||||
|
workingfileid = fileid;
|
||||||
|
$("#delDataFile").modal("toggle");
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "getname_file",
|
||||||
|
id : workingfileid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
$("#filenametodel").html("");
|
||||||
|
$("#filenametodel").html(data["data"]["filename"]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function doDelDataFile(){
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "del_file",
|
||||||
|
id : workingfileid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
window.location = window.location;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
workingdirid = false;
|
||||||
|
// DIR FUNCTIONS
|
||||||
|
|
||||||
|
function delDataDirObje(id){
|
||||||
|
workingdirid = id;
|
||||||
|
$("#delDataObj").modal("toggle");
|
||||||
|
}
|
||||||
|
|
||||||
|
function doDelDataDir(){
|
||||||
|
$("#delDataObj").modal("toggle");
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "del_dir",
|
||||||
|
id : workingdirid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
if(data["success"]){
|
||||||
|
window.location = window.location;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#fileerr").toast("show");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeDirName(dirid){
|
||||||
|
$("#changeName").modal("toggle");
|
||||||
|
workingdirid = dirid;
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "getname_dir",
|
||||||
|
id : dirid
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
$("#actualName").html("Ordner <b>" + data["data"]['dirname'] + "</b>");
|
||||||
|
$("#changename").val(data["data"]['dirname']);
|
||||||
|
$("#doUpdateName").attr("disabled", false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateName(){
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "change_dir_name",
|
||||||
|
id : workingdirid,
|
||||||
|
newdirname : $("#changename").val()
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
$("#changeName").modal("toggle");
|
||||||
|
window.location = window.location;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDirModal(){
|
||||||
|
$("#addDir").modal("toggle");
|
||||||
|
$("#newdirname").val("");
|
||||||
|
$("#doActionTaskModal").attr("disabled", true)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//VALIDATE FOR CORRECT INPUT IN GROUP
|
||||||
|
function validateNewName(newdirname){
|
||||||
|
var letters = /^[A-Za-zßäöüÄÖÜ_\-0-9 ]+$/;
|
||||||
|
if(newdirname.length > 0){
|
||||||
|
if(!newdirname.match(letters))
|
||||||
|
{
|
||||||
|
$("#doUpdateName").attr("disabled", true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#doUpdateName").attr("disabled", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#doUpdateName").attr("disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//VALIDATE FOR CORRECT INPUT IN GROUP
|
||||||
|
function validateDirName(newdirname){
|
||||||
|
var letters = /^[A-Za-zßäöüÄÖÜ_\-0-9 ]+$/;
|
||||||
|
if(newdirname.length > 0){
|
||||||
|
if(!newdirname.match(letters))
|
||||||
|
{
|
||||||
|
$("#doActionTaskModal").attr("disabled", true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#doActionTaskModal").attr("disabled", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#doActionTaskModal").attr("disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDirAction(){
|
||||||
|
$.ajax(
|
||||||
|
{
|
||||||
|
type: "GET",
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
data:{
|
||||||
|
action : "adddir",
|
||||||
|
parent : {{parentid}},
|
||||||
|
newdirname : $("#newdirname").val()
|
||||||
|
},
|
||||||
|
success: function( data )
|
||||||
|
{
|
||||||
|
window.location = window.location;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from .views import CloudMain
|
from .views import CloudMain
|
||||||
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', CloudMain.as_view(template_name="cloud/cloud_main.html"), name='cloud-main'),
|
path('<slug:pk>', CloudMain, name='cloud-main'),
|
||||||
|
path('clajax/', views.adddirbyajax, name="cloud-adddir"),
|
||||||
|
path('clajax/<slug:parent>', views.adddirbyajax, name="cloud-adddir"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
234
cloud/views.py
234
cloud/views.py
|
|
@ -9,25 +9,225 @@ from django.views.generic.edit import FormView
|
||||||
from .forms import CloudAddFileForm
|
from .forms import CloudAddFileForm
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
|
from digitaleagentur.settings import BASE_DIR
|
||||||
# Create your views here.
|
from django.http import JsonResponse
|
||||||
|
import os
|
||||||
class CloudMain(LoginRequiredMixin, FormView):
|
from .models import DataDir, DataFile
|
||||||
form_class = CloudAddFileForm
|
from datetime import datetime
|
||||||
success_url = '/cloud/'
|
from users.models import AgencyGroup
|
||||||
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
'''
|
||||||
form = CloudAddFileForm(self.request.POST, self.request.FILES['file'])
|
|
||||||
|
|
||||||
tempdata = Data(file=self.request.FILES['file'], subdir="subdir1/subdir2", agency=self.request.user.profile.agency, owner=self.request.user)
|
Prüft, ob ein Nutzer in diesen Ordner Zugriffsrechte hat. Läuft den gesamten Strang bis nach oben,
|
||||||
tempdata.save()
|
ob ein Übergeordneter Ordner Rechte einschränkt.
|
||||||
return super().form_valid(form)
|
|
||||||
|
'''
|
||||||
|
@login_required
|
||||||
|
def checkUserDirRights(request, startdir, userid):
|
||||||
|
canview = True
|
||||||
|
user = User.objects.get(pk=userid, profile__agency=request.user.profile.agency)
|
||||||
|
usergroups=list(user.groups.all())
|
||||||
|
grouptomach = []
|
||||||
|
singleObj = DataDir.objects.get(pk=startdir.pk, agency=request.user.profile.agency)
|
||||||
|
# AGENCYCHECK
|
||||||
|
if(singleObj.agency.pk == user.profile.agency.pk):
|
||||||
|
|
||||||
|
# Get dirs to check
|
||||||
|
while( singleObj.is_root != True and canview == True):
|
||||||
|
|
||||||
|
|
||||||
# Change context and return for template-data
|
for g in singleObj.visibleby.all():
|
||||||
def get_context_data(self, **kwargs):
|
grouptomach.append(g.group)
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
all_files = Data.objects.filter(agency__pk=self.request.user.profile.agency.pk)
|
if(len(grouptomach) == 0):
|
||||||
context.update({'active_link' : 'cloud', 'all_files': all_files})
|
canview = True
|
||||||
return context
|
else:
|
||||||
|
if(len(set(usergroups).intersection(grouptomach)) > 0):
|
||||||
|
canview = True
|
||||||
|
else:
|
||||||
|
canview = False
|
||||||
|
|
||||||
|
grouptomach = []
|
||||||
|
singleObj = DataDir.objects.get(pk=singleObj.parent.pk, agency=request.user.profile.agency)
|
||||||
|
|
||||||
|
else:
|
||||||
|
canview = False
|
||||||
|
return canview
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def CloudMain(request, pk):
|
||||||
|
diragency = []
|
||||||
|
alldirs = []
|
||||||
|
context = {}
|
||||||
|
breadcrump = []
|
||||||
|
files = []
|
||||||
|
rootid = list(DataDir.objects.filter(is_root=True, agency=request.user.profile.agency))[0].pk
|
||||||
|
if(pk == "first"):
|
||||||
|
diragency = list(DataDir.objects.filter(is_root=True, agency=request.user.profile.agency))[0]
|
||||||
|
|
||||||
|
alldirs = DataDir.objects.filter(is_root=False, agency=request.user.profile.agency, parent=diragency).order_by("name")
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'active_link' : 'cloud',
|
||||||
|
'dirs' : alldirs,
|
||||||
|
'parentid' : diragency.pk,
|
||||||
|
'files' : DataFile.objects.filter(parent=diragency, agency=request.user.profile.agency).order_by("name"),
|
||||||
|
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency).order_by("agencygroupname"),
|
||||||
|
"rootid" : rootid
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
|
||||||
|
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR
|
||||||
|
groupsofdir = DataDir.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
|
if checkUserDirRights(request, groupsofdir, request.user.pk):
|
||||||
|
alldirs = DataDir.objects.filter(is_root=False, agency=request.user.profile.agency, parent=pk).order_by("name")
|
||||||
|
vieweddir = list(DataDir.objects.filter(pk=pk, agency=request.user.profile.agency))[0]
|
||||||
|
|
||||||
|
singleObj = DataDir.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
|
while( singleObj.is_root != True):
|
||||||
|
breadcrump.append(singleObj)
|
||||||
|
singleObj = DataDir.objects.get(pk=singleObj.parent.pk, agency=request.user.profile.agency)
|
||||||
|
|
||||||
|
breadcrump = breadcrump[::-1]
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'active_link' : 'cloud',
|
||||||
|
'dirs' : alldirs,
|
||||||
|
'parentid' : pk,
|
||||||
|
'breadcrump' : breadcrump,
|
||||||
|
'files' : DataFile.objects.filter(parent=vieweddir, agency=request.user.profile.agency).order_by("name"),
|
||||||
|
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency).order_by("agencygroupname"),
|
||||||
|
"rootid" : rootid
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
context = {
|
||||||
|
'active_link' : 'cloud',
|
||||||
|
}
|
||||||
|
return render(request, 'cloud/noentrie.html', context)
|
||||||
|
|
||||||
|
return render(request, 'cloud/cloud_main.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def adddirbyajax(request, parent):
|
||||||
|
success = True
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
if(request.method == "GET"):
|
||||||
|
# NEW DIR
|
||||||
|
if(request.GET.get("action") == "adddir"):
|
||||||
|
parentid = request.GET.get("parent")
|
||||||
|
newdirname = request.GET.get("newdirname")
|
||||||
|
parent_obj = DataDir.objects.get(pk=parentid, agency=request.user.profile.agency)
|
||||||
|
tempdir = DataDir(name=newdirname, parent=parent_obj, agency=request.user.profile.agency, owner=request.user)
|
||||||
|
tempdir.save()
|
||||||
|
parent_obj.dirs.add(tempdir)
|
||||||
|
parent_obj.save()
|
||||||
|
# RETURN DIRNAME
|
||||||
|
elif(request.GET.get("action") == "getname_dir"):
|
||||||
|
dirobj = DataDir.objects.get(pk=request.GET.get('id'), agency=request.user.profile.agency)
|
||||||
|
data = {'dirname' : dirobj.name}
|
||||||
|
# RETURN COMPLETE AGENCY DIR LIST
|
||||||
|
elif(request.GET.get("action") == "getdirlist"):
|
||||||
|
data = {'agencydirlist' : loadAgencyDirList(request)}
|
||||||
|
# RETURN FILENAME
|
||||||
|
elif(request.GET.get("action") == "getname_file"):
|
||||||
|
fileobj = DataFile.objects.get(pk=request.GET.get('id'), agency=request.user.profile.agency)
|
||||||
|
data = {'filename' : fileobj.name}
|
||||||
|
# DELETE FILE
|
||||||
|
elif(request.GET.get("action") == "del_file"):
|
||||||
|
DataFile.objects.filter(pk=request.GET.get('id'), agency=request.user.profile.agency).delete()
|
||||||
|
# CHANGE DIR NAME
|
||||||
|
elif(request.GET.get("action") == "change_dir_name"):
|
||||||
|
dirobj = DataDir.objects.get(pk=request.GET.get('id'), agency=request.user.profile.agency)
|
||||||
|
dirobj.name = request.GET.get("newdirname")
|
||||||
|
dirobj.date_last_modified = datetime.now()
|
||||||
|
dirobj.save()
|
||||||
|
# DELETE DIR
|
||||||
|
elif(request.GET.get("action") == "del_dir"):
|
||||||
|
try:
|
||||||
|
DataFile.objects.filter(parent=request.GET.get('id'), agency=request.user.profile.agency).delete()
|
||||||
|
DataDir.objects.filter(parent=request.GET.get('id'), agency=request.user.profile.agency).delete()
|
||||||
|
DataDir.objects.get(pk=request.GET.get('id'), agency=request.user.profile.agency).delete()
|
||||||
|
except:
|
||||||
|
success = False
|
||||||
|
# MOVE FILE
|
||||||
|
elif(request.GET.get("action") == "movefile"):
|
||||||
|
tempdatafile = DataFile.objects.get(pk=request.GET.get('fileid'), agency=request.user.profile.agency)
|
||||||
|
tempdatafile.parent = DataDir.objects.get(pk=request.GET.get('newpar'), agency=request.user.profile.agency)
|
||||||
|
tempdatafile.date_last_modified = datetime.now()
|
||||||
|
tempdatafile.save()
|
||||||
|
# GROUPS
|
||||||
|
# DIR
|
||||||
|
elif(request.GET.get("action") == "changedirgroups"):
|
||||||
|
dirid = request.GET.get('dirid')
|
||||||
|
groupid = request.GET.get('groupid')
|
||||||
|
value = request.GET.get('value')
|
||||||
|
if(value == "true"):
|
||||||
|
DataDir.objects.get(pk=dirid, agency=request.user.profile.agency).visibleby.add(AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency))
|
||||||
|
else:
|
||||||
|
DataDir.objects.get(pk=dirid, agency=request.user.profile.agency).visibleby.remove(AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency))
|
||||||
|
# GET GROUPS
|
||||||
|
|
||||||
|
elif(request.GET.get("action") == "getgroupsofdir"):
|
||||||
|
dirid = request.GET.get('dirid')
|
||||||
|
allgroupsofdir = DataDir.objects.get(pk=dirid, agency=request.user.profile.agency).visibleby.all()
|
||||||
|
|
||||||
|
grouopsid = []
|
||||||
|
for ag in allgroupsofdir:
|
||||||
|
grouopsid.append({"id" : ag.pk})
|
||||||
|
print(grouopsid)
|
||||||
|
data = {"gdir" : grouopsid}
|
||||||
|
|
||||||
|
elif request.method == 'POST':
|
||||||
|
tempdir = False
|
||||||
|
tempdir = DataDir.objects.get(pk=parent)
|
||||||
|
|
||||||
|
# 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"]
|
||||||
|
file_ok = False
|
||||||
|
for t in allowed_types:
|
||||||
|
if t == file_ext:
|
||||||
|
file_ok = True
|
||||||
|
|
||||||
|
if(file_ok):
|
||||||
|
tempdatafile = DataFile(file=request.FILES['uploadedfile'], name=request.FILES['uploadedfile'].name, owner=request.user, parent=tempdir, agency=request.user.profile.agency)
|
||||||
|
tempdatafile.save()
|
||||||
|
data = {'savedobj_id' : tempdatafile.pk, 'savedobj_name' : tempdatafile.name}
|
||||||
|
else:
|
||||||
|
success = False
|
||||||
|
|
||||||
|
return JsonResponse({"success" : success, "data" : data})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def loadAgencyDirList(request):
|
||||||
|
alldirs = []
|
||||||
|
|
||||||
|
diragency = list(DataDir.objects.filter(is_root=True, agency=request.user.profile.agency))[0]
|
||||||
|
alldirs_root = DataDir.objects.filter(is_root=False, agency=request.user.profile.agency, parent=diragency).order_by("name")
|
||||||
|
|
||||||
|
for d in alldirs_root:
|
||||||
|
alldirs.append({"id" : d.pk, "parent" : "", "name" : d.name, 'subdirs' : getsubdirs(request, d.pk)})
|
||||||
|
|
||||||
|
return alldirs
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def getsubdirs(request, dirid):
|
||||||
|
subdirs = []
|
||||||
|
actid = False
|
||||||
|
if(isinstance(dirid, DataDir)):
|
||||||
|
actid = dirid.pk
|
||||||
|
else:
|
||||||
|
actid = dirid
|
||||||
|
alldirs_sub = DataDir.objects.filter(is_root=False, agency=request.user.profile.agency, parent=dirid).order_by("name")
|
||||||
|
|
||||||
|
for subdir in alldirs_sub:
|
||||||
|
tempsubsubdir = DataDir.objects.filter(is_root=False, agency=request.user.profile.agency, parent=subdir).order_by("name")
|
||||||
|
if(len(tempsubsubdir) > 0):
|
||||||
|
subdirs.append({"id" : subdir.pk, "parent" : actid, "name" : subdir.name, 'subdirs' : getsubdirs(request, subdir)})
|
||||||
|
else:
|
||||||
|
subdirs.append({"id" : subdir.pk, "parent" : actid, "name" : subdir.name, 'subdirs' : []})
|
||||||
|
return subdirs
|
||||||
Binary file not shown.
|
|
@ -29,9 +29,13 @@ DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['digitale-agentur.com', 'www.digitale-agentur.com', 'localhost']
|
ALLOWED_HOSTS = ['digitale-agentur.com', 'www.digitale-agentur.com', 'localhost']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'notificsys.apps.NotificsysConfig',
|
||||||
'users.apps.UsersConfig',
|
'users.apps.UsersConfig',
|
||||||
|
'dasettings.apps.DASettingsConfig',
|
||||||
'areas.apps.AreasConfig',
|
'areas.apps.AreasConfig',
|
||||||
'orga.apps.OrgaConfig',
|
'orga.apps.OrgaConfig',
|
||||||
'cloud.apps.CloudConfig',
|
'cloud.apps.CloudConfig',
|
||||||
|
|
@ -41,16 +45,18 @@ INSTALLED_APPS = [
|
||||||
'news.apps.NewsConfig',
|
'news.apps.NewsConfig',
|
||||||
'crispy_forms',
|
'crispy_forms',
|
||||||
'colorful',
|
'colorful',
|
||||||
'ckeditor',
|
|
||||||
'django_summernote',
|
'django_summernote',
|
||||||
'ckeditor_uploader',
|
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
|
'mathfilters',
|
||||||
|
'django.contrib.humanize',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'bootstrap_datepicker_plus'
|
'bootstrap_datepicker_plus',
|
||||||
|
'django_cleanup',
|
||||||
|
'django_user_agents',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
@ -61,6 +67,7 @@ MIDDLEWARE = [
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'django_user_agents.middleware.UserAgentMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'digitaleagentur.urls'
|
ROOT_URLCONF = 'digitaleagentur.urls'
|
||||||
|
|
@ -83,41 +90,6 @@ TEMPLATES = [
|
||||||
|
|
||||||
WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
|
WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
|
||||||
|
|
||||||
# CKEDITOR
|
|
||||||
CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
|
|
||||||
|
|
||||||
CKEDITOR_UPLOAD_PATH = "uploadsCK/" # <-- this folder you uploaded image saved in s3 under media folder
|
|
||||||
CKEDITOR_RESTRICT_BY_USER = False
|
|
||||||
CKEDITOR_REQUIRE_STAFF=False
|
|
||||||
AWS_QUERYSTRING_AUTH = True
|
|
||||||
CKEDITOR_IMAGE_BACKEND = "pillow"
|
|
||||||
#CKEDITOR_PLUGINS.addExternal('youtube', "../ckeditorplugins/youtube/youtube/plugin.js");
|
|
||||||
|
|
||||||
CKEDITOR_CONFIGS = {
|
|
||||||
'default': {
|
|
||||||
'skin': 'moono-lisa',
|
|
||||||
'toolbar_Basic': [
|
|
||||||
['Source', '-', 'Bold', 'Italic']
|
|
||||||
],
|
|
||||||
'toolbar_YourCustomToolbarConfig': [
|
|
||||||
{'name': 'basicstyles',
|
|
||||||
'items': ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']},
|
|
||||||
{'name': 'paragraph',
|
|
||||||
'items': ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-',
|
|
||||||
'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl',
|
|
||||||
'Language']},
|
|
||||||
{'name': 'links', 'items': ['Link', 'Unlink']},
|
|
||||||
{'name': 'styles', 'items': ['Styles', 'Format', 'Font', 'FontSize']},
|
|
||||||
{'name': 'colors', 'items': ['TextColor', 'BGColor']},
|
|
||||||
{'name': 'tools', 'items': ['Maximize', 'ShowBlocks']},
|
|
||||||
{'name': 'insert',
|
|
||||||
'items': ['Image', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak']},
|
|
||||||
'/', # put this to force next toolbar on new line
|
|
||||||
],
|
|
||||||
'toolbar': 'YourCustomToolbarConfig', # put selected toolbar config here
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||||
|
|
||||||
|
|
@ -130,6 +102,8 @@ DATABASES = {
|
||||||
'PORT' : 3306
|
'PORT' : 3306
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
|
@ -202,7 +176,15 @@ EMAIL_HOST_USER = "support@digitale-agentur.com"
|
||||||
EMAIL_HOST_PASSWORD = "aPx9m3!7x3m@8o!t"
|
EMAIL_HOST_PASSWORD = "aPx9m3!7x3m@8o!t"
|
||||||
DEFAULT_FROM_EMAIL = "support@digitale-agentur.com"
|
DEFAULT_FROM_EMAIL = "support@digitale-agentur.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# FOR DATEPICKER
|
# FOR DATEPICKER
|
||||||
BOOTSTRAP4 = {
|
BOOTSTRAP4 = {
|
||||||
'include_jquery': True,
|
'include_jquery': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPTIONS={
|
||||||
|
'libraries': {
|
||||||
|
'counter_tag': 'standards.tags',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -5,9 +5,7 @@ from django.conf import settings
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from users.views import AgencyCreateView
|
from users.views import AgencyCreateView
|
||||||
from . import views
|
from . import views
|
||||||
from ckeditor_uploader.views import upload
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Main URLS
|
Main URLS
|
||||||
|
|
@ -27,6 +25,7 @@ urlpatterns = [
|
||||||
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
|
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
|
||||||
path('', include('users.urls'), name="dashboard-first"),
|
path('', include('users.urls'), name="dashboard-first"),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('dasettings/', include('dasettings.urls'), name="dasettings"),
|
||||||
path('dashboard/', include('users.urls'), name="dashboard"),
|
path('dashboard/', include('users.urls'), name="dashboard"),
|
||||||
path('areas/', include('areas.urls'), name="areas-management"),
|
path('areas/', include('areas.urls'), name="areas-management"),
|
||||||
path('tasks/', include('tasks.urls'), name="tasks-management"),
|
path('tasks/', include('tasks.urls'), name="tasks-management"),
|
||||||
|
|
@ -42,11 +41,7 @@ urlpatterns = [
|
||||||
path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'),
|
path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'),
|
||||||
path('register/done', views.registerdone, name='register-done'),
|
path('register/done', views.registerdone, name='register-done'),
|
||||||
path('summernote/', include('django_summernote.urls')),
|
path('summernote/', include('django_summernote.urls')),
|
||||||
|
path('notifications/', include('notificsys.urls'), name="notifications")
|
||||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
||||||
#urlpatterns += [
|
|
||||||
# path('ckeditor/upload/', login_required(upload), name='ckeditor_upload'),
|
|
||||||
# path('ckeditor/', include('ckeditor_uploader.urls')),
|
|
||||||
#]
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
3D-Druck
|
|
||||||
+ Gute Struktur
|
|
||||||
+ Shortucts
|
|
||||||
+ Planemodellierung - Als VIdeo noch ein
|
|
||||||
|
|
||||||
HTML
|
|
||||||
- Erweiterten Kurs
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
3D-Druck
|
|
||||||
+ Gute Struktur
|
|
||||||
+ Shortucts
|
|
||||||
+ Planemodellierung - Als VIdeo noch ein
|
|
||||||
|
|
||||||
HTML
|
|
||||||
- Erweiterten Kurs
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
3D-Druck
|
|
||||||
+ Gute Struktur
|
|
||||||
+ Shortucts
|
|
||||||
+ Planemodellierung - Als VIdeo noch ein
|
|
||||||
|
|
||||||
HTML
|
|
||||||
- Erweiterten Kurs
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_news %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-6">
|
||||||
<h3>News anlegen</h3>
|
<h3>News anlegen</h3>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -20,4 +21,7 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul News wurde in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_news %}
|
||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
|
|
@ -16,4 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul News wurde in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_news %}
|
||||||
<div class="content-section col-12">
|
<div class="content-section col-12">
|
||||||
<h3>News</h3>
|
<h3>News <small><i data-toggle="tooltip" data-placement="top" title="Hier können aktuelle Nachrichten für die Agentur erstellt und verwaltet werden." class="far fa-question-circle"></i></small></h3>
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
|
||||||
Hier können aktuelle Nachrichten für die Agentur erstellt und verwaltet werden.
|
|
||||||
</p>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="content-section col-4">
|
<div class="content-section col-4">
|
||||||
<a class="btn btn-primary" href="{% url 'news-add' %} ">News anlegen</a>
|
<a class="btn btn-primary" href="{% url 'news-add' %} " data-toggle="tooltip" data-placement="top" title="Neue News für Ihre Agentur erstellen"><i class="fas fa-plus"></i> News</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -162,4 +160,7 @@ $('#news_tabs a').on('click', function (e) {
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul News wurde in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_news %}
|
||||||
<div class="content-section col-12">
|
<div class="content-section col-12">
|
||||||
<small>
|
<small>
|
||||||
<h2>{{news.name}}</h2>
|
<h2>{{news.name}}</h2>
|
||||||
|
|
@ -12,4 +13,7 @@
|
||||||
{{news.media}}
|
{{news.media}}
|
||||||
{{news.content|safe}}
|
{{news.content|safe}}
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul News wurde in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_news %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-6">
|
||||||
<h3>News bearbeiten</h3>
|
<h3>News bearbeiten</h3>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -20,4 +21,7 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul News wurde in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from .views import NewsManagement, NewsAdd, NewsDeleteView
|
from .views import NewsManagement, NewsAdd, NewsDeleteView
|
||||||
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from . import views
|
from . import views
|
||||||
'''
|
'''
|
||||||
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
||||||
|
|
@ -7,9 +8,9 @@ Permissions definiert in models.py bei USERS und dann hier vor die View geschrie
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', NewsManagement.as_view(template_name="news/news_management.html"), name='news-management'),
|
path('', NewsManagement.as_view(template_name="news/news_management.html"), name='news-management'),
|
||||||
path('newsadd/', views.NewsAdd, name='news-add'),
|
path('newsadd/', permission_required('users.modulenews')(views.NewsAdd), name='news-add'),
|
||||||
path('newsupdate/<int:id>/', views.NewsUpdate, name='news-update'),
|
path('newsupdate/<int:id>/', permission_required('users.modulenews')(views.NewsUpdate), name='news-update'),
|
||||||
path('news/<int:pk>/delete', NewsDeleteView.as_view(), name='news-delete'),
|
path('news/<int:pk>/delete', permission_required('users.modulenews')(NewsDeleteView.as_view()), name='news-delete'),
|
||||||
#path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'),
|
#path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'),
|
||||||
#path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
|
#path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
|
||||||
path('news/<int:pk>/single', views.NewsSingle, name="news-single"),
|
path('news/<int:pk>/single', views.NewsSingle, name="news-single"),
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class NewsManagement(LoginRequiredMixin, ListView):
|
||||||
news = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-created_date')
|
news = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-created_date')
|
||||||
news_arch = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_offline_on__lt=filterdate).order_by('-created_date')
|
news_arch = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_offline_on__lt=filterdate).order_by('-created_date')
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context.update({'active_link' : 'newsmanagement', 'news' : news, 'news_arch' : news_arch})
|
context.update({'active_link' : 'dashboard', 'news' : news, 'news_arch' : news_arch})
|
||||||
return context
|
return context
|
||||||
'''
|
'''
|
||||||
class NewsAddNews(LoginRequiredMixin, CreateView):
|
class NewsAddNews(LoginRequiredMixin, CreateView):
|
||||||
|
|
@ -57,7 +57,7 @@ def NewsAdd(request):
|
||||||
|
|
||||||
new_news.save()
|
new_news.save()
|
||||||
messages.success(request, f'News gespeichert!')
|
messages.success(request, f'News gespeichert!')
|
||||||
return redirect('news-management')
|
return redirect('users-dashboard')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
normalForm = NewsAddNews(instance=request.user)
|
normalForm = NewsAddNews(instance=request.user)
|
||||||
|
|
@ -67,19 +67,19 @@ def NewsAdd(request):
|
||||||
context = {
|
context = {
|
||||||
'normalForm' : normalForm,
|
'normalForm' : normalForm,
|
||||||
#'editorForm' : editorForm,
|
#'editorForm' : editorForm,
|
||||||
'active_link' : 'newsmanagement'
|
'active_link' : 'dashboard'
|
||||||
}
|
}
|
||||||
return render(request, 'news/news_addnews.html', context)
|
return render(request, 'news/news_addnews.html', context)
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def NewsUpdate(request, id):
|
def NewsUpdate(request, id):
|
||||||
news = News.objects.get(pk=id)
|
news = News.objects.get(pk=id, agency=request.user.profile.agency)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
normalForm = NewsAddNews(request.POST, instance=news)
|
normalForm = NewsAddNews(request.POST, instance=news)
|
||||||
#editorForm = NewsAddNewsEditor(request.POST, instance=news)
|
#editorForm = NewsAddNewsEditor(request.POST, instance=news)
|
||||||
|
|
||||||
if normalForm.is_valid():
|
if normalForm.is_valid():
|
||||||
news = News.objects.get(pk=id)
|
news = News.objects.get(pk=id, agency=request.user.profile.agency)
|
||||||
news.last_modified_by = request.user
|
news.last_modified_by = request.user
|
||||||
news.last_modified_on = datetime.now()
|
news.last_modified_on = datetime.now()
|
||||||
news.go_online_on = normalForm.cleaned_data['go_online_on']
|
news.go_online_on = normalForm.cleaned_data['go_online_on']
|
||||||
|
|
@ -98,7 +98,7 @@ def NewsUpdate(request, id):
|
||||||
context = {
|
context = {
|
||||||
'normalForm' : normalForm,
|
'normalForm' : normalForm,
|
||||||
#'editorForm' : editorForm,
|
#'editorForm' : editorForm,
|
||||||
'active_link' : 'newsmanagement',
|
'active_link' : 'dashboard',
|
||||||
'news_id' : news.pk,
|
'news_id' : news.pk,
|
||||||
}
|
}
|
||||||
return render(request, 'news/news_update.html', context)
|
return render(request, 'news/news_update.html', context)
|
||||||
|
|
@ -116,9 +116,10 @@ class NewsDeleteView(LoginRequiredMixin, DeleteView):
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def NewsSingle(request, pk):
|
def NewsSingle(request, pk):
|
||||||
news = News.objects.get(pk=pk)
|
news = News.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
context = {
|
context = {
|
||||||
'active_link':'newsmanagement',
|
'active_link':'dashboard',
|
||||||
'news' : news
|
'news' : news
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'news/news_single.html', context)
|
return render(request, 'news/news_single.html', context)
|
||||||
Binary file not shown.
|
|
@ -50,6 +50,7 @@ for(i = 0; i < data.length; i++){
|
||||||
|
|
||||||
//Creates nested array from data
|
//Creates nested array from data
|
||||||
function unflatten(arr) {
|
function unflatten(arr) {
|
||||||
|
console.log(arr);
|
||||||
var tree = [],
|
var tree = [],
|
||||||
mappedArr = {},
|
mappedArr = {},
|
||||||
arrElem,
|
arrElem,
|
||||||
|
|
@ -78,7 +79,7 @@ function unflatten(arr) {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
var html = ['<ul class="tree">'];
|
var html = ['<ul class="tree" >'];
|
||||||
|
|
||||||
//Create UL-LI-List for tree
|
//Create UL-LI-List for tree
|
||||||
function createList(arr) {
|
function createList(arr) {
|
||||||
|
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
{% extends "users/base.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<script src="https://cdn.syncfusion.com/ej2/dist/ej2.min.js" type="text/javascript"></script>
|
|
||||||
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet">
|
|
||||||
<div class="content-section">
|
|
||||||
<h3>{{request.user.profile.agency.name}}</h3>
|
|
||||||
<hr>
|
|
||||||
<h4>Organigramm</h4>
|
|
||||||
<div class="text-center">
|
|
||||||
<div id="diagram"></div>
|
|
||||||
</div>
|
|
||||||
<div id="spinner" class="text-center" style="margin-top: 15%; width: 100%; height: 100%; display: none;">
|
|
||||||
<div class="spinner-border text-danger" role="status">
|
|
||||||
<span class="sr-only">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var data = [
|
|
||||||
{ 'id': 'parent', 'role': "", 'name': '{{request.user.profile.agency.name}}', 'color': '#71AF17', "imageUrl": ""},
|
|
||||||
{% for u in agencyuser %}
|
|
||||||
{% if u.profile.parent == u %}
|
|
||||||
{ 'id': '{{u.pk}}' , 'name': "{{u.first_name}} {{u.last_name}}",'role': '{{u.profile.get_func_display}}\n{{u.profile.compfunc}}', 'manager': 'parent', 'color': '#1859B7', "imageUrl": "{{u.profile.get_photo_url}}", 'userid' : '{{u.pk}}' },
|
|
||||||
{% else %}
|
|
||||||
{ 'id': '{{u.pk}}', 'name': "{{u.first_name}} {{u.last_name}}", 'role': '{{u.profile.get_func_display}}\n{{u.profile.compfunc}}', 'manager': '{{u.profile.parent.pk}}', 'color': '#1859B7', "imageUrl": "{{u.profile.get_photo_url }}", 'userid' : '{{u.pk}}'},
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
];
|
|
||||||
|
|
||||||
var items = new ej.data.DataManager(data);
|
|
||||||
|
|
||||||
var diagram = new ej.diagrams.Diagram({
|
|
||||||
width: "1350px", height: "800px",
|
|
||||||
/*tool: ej.diagrams.DiagramTools.ZoomPan,*/
|
|
||||||
dataSourceSettings: {
|
|
||||||
// set the unique field from data source
|
|
||||||
id: 'id',
|
|
||||||
// set the field which is used to identify the reporting person
|
|
||||||
parentId: 'manager',
|
|
||||||
// define the employee data
|
|
||||||
dataManager: items
|
|
||||||
},
|
|
||||||
layout: {
|
|
||||||
// set the layout type
|
|
||||||
type: 'OrganizationalChart',
|
|
||||||
},
|
|
||||||
getConnectorDefaults: connectorDefaults,
|
|
||||||
setNodeTemplate: setNodeTemplate,
|
|
||||||
// hide the gridlines in the diagram
|
|
||||||
snapSettings: { constraints: ej.diagrams.SnapConstraints.None }
|
|
||||||
});
|
|
||||||
diagram.appendTo('#diagram');
|
|
||||||
|
|
||||||
diagram.selectionChange = goToUser
|
|
||||||
|
|
||||||
function goToUser(){
|
|
||||||
if(diagram.selectedItems['nodes'][0] != undefined){
|
|
||||||
selected_id = diagram.selectedItems['nodes'][0]['properties']['data']['id'];
|
|
||||||
if(selected_id != 'parent'){
|
|
||||||
$("#diagram").hide();
|
|
||||||
$("#spinner").show();
|
|
||||||
window.location.href = "/orga/single/"+selected_id;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$("#diagram").hide();
|
|
||||||
$("#spinner").show();
|
|
||||||
window.location.href = "/orga/";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Define the common settings for connectors.
|
|
||||||
function connectorDefaults(connector) {
|
|
||||||
connector.targetDecorator.shape = 'None';
|
|
||||||
connector.type = 'Orthogonal';
|
|
||||||
connector.style.strokeColor = 'gray';
|
|
||||||
return connector;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Funtion to add the Template of the Node.
|
|
||||||
function setNodeTemplate(obj, diagram) {
|
|
||||||
// create the stack panel
|
|
||||||
var content = new ej.diagrams.StackPanel();
|
|
||||||
content.id = obj.id + '_outerstack';
|
|
||||||
content.orientation = 'Horizontal';
|
|
||||||
content.style.strokeColor = 'gray';
|
|
||||||
content.padding = { left: 5, right: 10, top: 5, bottom: 5 };
|
|
||||||
|
|
||||||
// create the image element to map the image data from the data source
|
|
||||||
var image = new ej.diagrams.ImageElement();
|
|
||||||
|
|
||||||
if(obj['properties']['data']['id'] == 'parent'){
|
|
||||||
image.id = obj.id + '_pic';
|
|
||||||
image.width = 0; image.height = 0; image.style.strokeColor = 'none';
|
|
||||||
image.source = obj.data.imageUrl;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
image.id = obj.id + '_pic';
|
|
||||||
image.width = 75; image.height = 75; image.style.strokeColor = 'none';
|
|
||||||
image.source = obj.data.imageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the stack panel to append the text elements.
|
|
||||||
var innerStack = new ej.diagrams.StackPanel();
|
|
||||||
innerStack.style.strokeColor = 'none';
|
|
||||||
innerStack.margin = { left: 5, right: 0, top: 0, bottom: 0 };
|
|
||||||
innerStack.id = obj.id + '_innerstack';
|
|
||||||
|
|
||||||
if(obj['properties']['data']['id'] == 'parent'){
|
|
||||||
var text = new ej.diagrams.TextElement();
|
|
||||||
text.style.bold = true;
|
|
||||||
text.style.fontSize = 24;
|
|
||||||
text.id = obj.id + '_name';
|
|
||||||
text.content = obj.data.name;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
var text = new ej.diagrams.TextElement();
|
|
||||||
text.style.bold = true;
|
|
||||||
text.style.fontSize = 18;
|
|
||||||
text.id = obj.id + '_name';
|
|
||||||
text.content = obj.data.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the text element to map the name data from the data source
|
|
||||||
|
|
||||||
if(obj['properties']['data']['id'] == 'parent'){
|
|
||||||
var desigText = new ej.diagrams.TextElement();
|
|
||||||
desigText.id = obj.id + '_desig';
|
|
||||||
desigText.style.fontSize = 0;
|
|
||||||
desigText.content = obj.data.role;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
var desigText = new ej.diagrams.TextElement();
|
|
||||||
desigText.id = obj.id + '_desig';
|
|
||||||
desigText.style.fontSize = 16;
|
|
||||||
desigText.content = obj.data.role;
|
|
||||||
}
|
|
||||||
// create the text element to map the role data from the data source
|
|
||||||
|
|
||||||
|
|
||||||
// append the text elements
|
|
||||||
innerStack.children = [text, desigText];
|
|
||||||
|
|
||||||
// append the image and inner stack elements
|
|
||||||
content.children = [image, innerStack];
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endblock content %}
|
|
||||||
|
|
@ -17,9 +17,12 @@ def mainorga(request):
|
||||||
# Check, if parented users are invisible. Remove them and give user an info!
|
# Check, if parented users are invisible. Remove them and give user an info!
|
||||||
for ele in nonvisibleuser:
|
for ele in nonvisibleuser:
|
||||||
for vis in agencyuser:
|
for vis in agencyuser:
|
||||||
if vis.profile.parent.profile.pk == ele.pk:
|
try:
|
||||||
agencyuser.remove(vis)
|
if vis.profile.parent.profile.pk == ele.pk:
|
||||||
invisible_users += 1
|
agencyuser.remove(vis)
|
||||||
|
invisible_users += 1
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'active_link' : 'orga',
|
'active_link' : 'orga',
|
||||||
|
|
@ -32,7 +35,7 @@ def mainorga(request):
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def singleorga(request, pk):
|
def singleorga(request, pk):
|
||||||
user = User.objects.get(pk=pk)
|
user = User.objects.get(pk=pk, profile__agency=request.user.profile.agency)
|
||||||
'''
|
'''
|
||||||
VON GROß NACH KLEIN - SINNLOS
|
VON GROß NACH KLEIN - SINNLOS
|
||||||
prios = Prio.objects.filter(user__pk=pk).order_by('-prio')[::-1]
|
prios = Prio.objects.filter(user__pk=pk).order_by('-prio')[::-1]
|
||||||
|
|
@ -64,7 +67,7 @@ def singleorga(request, pk):
|
||||||
'user_id' : user_id,
|
'user_id' : user_id,
|
||||||
'prios' : prios,
|
'prios' : prios,
|
||||||
'mail' : user.email,
|
'mail' : user.email,
|
||||||
'userfunc' : user.profile.get_func_display,
|
'userfunc' : "CHANGE",
|
||||||
'imageurl' : user.profile.get_photo_url,
|
'imageurl' : user.profile.get_photo_url,
|
||||||
'compfunc' : user.profile.compfunc,
|
'compfunc' : user.profile.compfunc,
|
||||||
'phoneland' : user.profile.phoneland,
|
'phoneland' : user.profile.phoneland,
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_quicklinks %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-6">
|
||||||
<h3>Quicklink anlegen</h3>
|
<h3>Quicklink anlegen</h3>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -13,4 +14,7 @@
|
||||||
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
|
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_quicklinks %}
|
||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
|
|
@ -17,4 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
|
{% load counter_tag %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_quicklinks %}
|
||||||
<div class="content-section col-12">
|
<div class="content-section col-12">
|
||||||
<h3>Quicklinks</h3>
|
<h3>Quicklinks <small><i data-toggle="tooltip" data-placement="top" title="Quicklinks helfen zur schnellen Verlinkung von oft genutzten Diensten." class="far fa-question-circle"></i></small></h3>
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
{% if user|usergperm:"modulequicklinks" %}
|
||||||
Quicklinks helfen zur schnellen Verlinkung von oft genutzten Diensten.
|
|
||||||
</p>
|
|
||||||
{% if perms.users.ql_management %}
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="content-section col-4">
|
<div class="content-section col-4">
|
||||||
<a class="btn btn-primary" href="{% url 'ql-addql' %}">Quicklink anlegen</a>
|
<a class="btn btn-primary" href="{% url 'ql-addql' %}"><i class="fas fa-plus"></i> Quicklink</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
@ -86,4 +85,7 @@ function saveDefQL(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if request.user.profile.agency.module_quicklinks %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-6">
|
||||||
<h3>Quicklink aktualisieren</h3>
|
<h3>Quicklink aktualisieren</h3>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -15,4 +16,7 @@
|
||||||
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
|
<a class="btn" href="{% url 'ql-management' %} ">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3>Das Modul Quicklinks wurden in ihrer Agentur deaktiviert.</h3>
|
||||||
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ from . import views
|
||||||
'''
|
'''
|
||||||
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
|
||||||
'''
|
'''
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', QlManagement.as_view(template_name="quicklinks/ql_management.html"), name='ql-management'),
|
path('', QlManagement.as_view(template_name="quicklinks/ql_management.html"), name='ql-management'),
|
||||||
path('addql/', permission_required('users.ql_management')(QlAdd.as_view(template_name="quicklinks/ql_add.html")), name='ql-addql'),
|
path('addql/', permission_required('users.modulequicklinks')(QlAdd.as_view(template_name="quicklinks/ql_add.html")), name='ql-addql'),
|
||||||
path('addql/<int:pk>/delete', permission_required('users.ql_management')(QlDeleteView.as_view()), name='ql-delete'),
|
path('addql/<int:pk>/delete', permission_required('users.modulequicklinks')(QlDeleteView.as_view()), name='ql-delete'),
|
||||||
path('addql/<int:pk>/', permission_required('users.ql_management')(QlUpdateView.as_view()), name='ql-update'),
|
path('addql/<int:pk>/', permission_required('users.modulequicklinks')(QlUpdateView.as_view()), name='ql-update'),
|
||||||
path('lerg/', views.loaddefaultql, name="ql-ajaxloaddef"),
|
path('lerg/', views.loaddefaultql, name="ql-ajaxloaddef"),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ from .models import QuickLinks
|
||||||
from .forms import QlAddQlForm
|
from .forms import QlAddQlForm
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class QlManagement(LoginRequiredMixin, ListView):
|
class QlManagement(LoginRequiredMixin, ListView):
|
||||||
model = QuickLinks
|
model = QuickLinks
|
||||||
|
|
||||||
# Adding active_link
|
# Adding active_link
|
||||||
# Loading only user same agency
|
# Loading only user same agency
|
||||||
# Change context and return for template-data
|
# Change context and return for template-data
|
||||||
|
|
@ -68,6 +68,7 @@ class QlUpdateView(LoginRequiredMixin, UpdateView):
|
||||||
context['active_link'] = 'quicklinks'
|
context['active_link'] = 'quicklinks'
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@login_required
|
||||||
def loaddefaultql(request):
|
def loaddefaultql(request):
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
if request.GET['action'] == 'adddefql':
|
if request.GET['action'] == 'adddefql':
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -3,6 +3,8 @@ from django.forms import ModelForm
|
||||||
from .models import Standards
|
from .models import Standards
|
||||||
from areas.models import Areas
|
from areas.models import Areas
|
||||||
from tasks.models import Tasks
|
from tasks.models import Tasks
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from users.models import Profile, UserFullName
|
||||||
from django_summernote.widgets import SummernoteInplaceWidget
|
from django_summernote.widgets import SummernoteInplaceWidget
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,16 +14,19 @@ class StandardAddStandard(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model =Standards
|
model =Standards
|
||||||
widgets = {
|
widgets = {
|
||||||
'content': SummernoteInplaceWidget(),
|
'content': SummernoteInplaceWidget()
|
||||||
}
|
}
|
||||||
labels = {
|
labels = {
|
||||||
"name" : "Titel",
|
"name" : "Titel",
|
||||||
"area" : "Übergeordneter Bereich",
|
"area" : "Übergeordneter Bereich",
|
||||||
"task" : "Aufgabenbereich",
|
"task" : "Aufgabenbereich",
|
||||||
"content": "Inhalt",
|
"content": "Inhalt",
|
||||||
"public" : "Direkt veröffentlichen?"
|
"public" : "Direkt veröffentlichen?",
|
||||||
|
"representative" : "Vertreter",
|
||||||
|
"executor" : "Ausführender",
|
||||||
|
"authority" : "Verantwortlicher",
|
||||||
}
|
}
|
||||||
fields = ['name', 'area', 'task', 'content', 'public']
|
fields = ['name', 'area', 'task', 'content', 'public', "authority", "executor", "representative"]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Hier werden die Elemente für die DropDowns erstellt, damit
|
Hier werden die Elemente für die DropDowns erstellt, damit
|
||||||
|
|
@ -45,6 +50,13 @@ class StandardAddStandard(forms.ModelForm):
|
||||||
elif self.instance.pk:
|
elif self.instance.pk:
|
||||||
self.fields['task'].queryset = Tasks.objects.none()
|
self.fields['task'].queryset = Tasks.objects.none()
|
||||||
|
|
||||||
|
self.fields['representative'].queryset = UserFullName.objects.filter(profile__agency__pk=kwargs['instance'].profile.agency.pk)
|
||||||
|
self.fields['executor'].queryset = UserFullName.objects.filter(profile__agency__pk=kwargs['instance'].profile.agency.pk)
|
||||||
|
self.fields['authority'].queryset = UserFullName.objects.filter(profile__agency__pk=kwargs['instance'].profile.agency.pk)
|
||||||
|
|
||||||
|
self.fields['checked_groups'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
|
||||||
|
self.fields['added_files'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
|
||||||
|
self.fields['added_standards'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
|
||||||
|
|
||||||
|
|
||||||
class StandardAddStandardEditor(forms.ModelForm):
|
class StandardAddStandardEditor(forms.ModelForm):
|
||||||
|
|
@ -70,9 +82,12 @@ class StandardUpdateStandard(forms.ModelForm):
|
||||||
"name" : "Titel",
|
"name" : "Titel",
|
||||||
"area" : "Übergeordneter Bereich",
|
"area" : "Übergeordneter Bereich",
|
||||||
"task" : "Aufgabenbereich",
|
"task" : "Aufgabenbereich",
|
||||||
"content": "Inhalt"
|
"content": "Inhalt",
|
||||||
|
"representative" : "Vertreter",
|
||||||
|
"executor" : "Ausführender",
|
||||||
|
"authority" : "Verantwortlicher",
|
||||||
}
|
}
|
||||||
fields = ['name', 'area', 'task', 'content']
|
fields = ['name', 'area', 'task', 'content', "authority", "executor", "representative"]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Hier werden die Elemente für die DropDowns erstellt, damit
|
Hier werden die Elemente für die DropDowns erstellt, damit
|
||||||
|
|
@ -99,6 +114,9 @@ class StandardUpdateStandard(forms.ModelForm):
|
||||||
elif loggeduser.pk:
|
elif loggeduser.pk:
|
||||||
self.fields['task'].queryset = Tasks.objects.filter(area__pk=standard.area.pk)
|
self.fields['task'].queryset = Tasks.objects.filter(area__pk=standard.area.pk)
|
||||||
|
|
||||||
|
self.fields['representative'].queryset = UserFullName.objects.filter(profile__agency__pk=loggeduser.profile.agency.pk)
|
||||||
|
self.fields['executor'].queryset = UserFullName.objects.filter(profile__agency__pk=loggeduser.profile.agency.pk)
|
||||||
|
self.fields['authority'].queryset = UserFullName.objects.filter(profile__agency__pk=loggeduser.profile.agency.pk)
|
||||||
|
|
||||||
|
|
||||||
class StandardUpdateStandardEditor(forms.ModelForm):
|
class StandardUpdateStandardEditor(forms.ModelForm):
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ from users.models import Agency
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from areas.models import Areas
|
from areas.models import Areas
|
||||||
from tasks.models import Tasks
|
from tasks.models import Tasks
|
||||||
|
from cloud.models import DataFile
|
||||||
|
from users.models import AgencyGroup
|
||||||
import datetime
|
import datetime
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
#from ckeditor_uploader.fields import RichTextUploadingField
|
#from ckeditor_uploader.fields import RichTextUploadingField
|
||||||
|
|
@ -14,9 +16,7 @@ class Standards(models.Model):
|
||||||
area = models.ForeignKey(Areas, on_delete=models.CASCADE)
|
area = models.ForeignKey(Areas, on_delete=models.CASCADE)
|
||||||
task = models.ForeignKey(Tasks, on_delete=models.CASCADE)
|
task = models.ForeignKey(Tasks, on_delete=models.CASCADE)
|
||||||
name = models.CharField(max_length=200, blank=False, default="")
|
name = models.CharField(max_length=200, blank=False, default="")
|
||||||
#content = RichTextUploadingField(blank=True, verbose_name='Inhalt')
|
|
||||||
content = models.TextField(blank=True, verbose_name='Inhalt', default="")
|
content = models.TextField(blank=True, verbose_name='Inhalt', default="")
|
||||||
#content = models.CharField(max_length=200000, blank=True, verbose_name='Inhalt')
|
|
||||||
|
|
||||||
created_standard_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
created_standard_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
||||||
created_standard_date = models.DateTimeField(default=timezone.now, blank=True)
|
created_standard_date = models.DateTimeField(default=timezone.now, blank=True)
|
||||||
|
|
@ -29,6 +29,21 @@ class Standards(models.Model):
|
||||||
|
|
||||||
public = models.BooleanField(default=False)
|
public = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
|
# USER
|
||||||
|
# VERTRETER
|
||||||
|
representative = models.ForeignKey(User, on_delete=models.PROTECT, related_name="user_repr", blank=True, null=True)
|
||||||
|
# AUSFÜHRENDER
|
||||||
|
executor = models.ForeignKey(User, on_delete=models.PROTECT, related_name="user_executor", blank=True, null=True)
|
||||||
|
# VERANTWORTLICHER
|
||||||
|
authority = models.ForeignKey(User, on_delete=models.PROTECT, related_name="user_authority", blank=True, null=True)
|
||||||
|
# FILES
|
||||||
|
addedfiles = models.ManyToManyField(DataFile, blank=True)
|
||||||
|
# VERLINKTE STANDARDS
|
||||||
|
linked_standards = models.ManyToManyField('Standards', blank=True)
|
||||||
|
# GORUPS
|
||||||
|
visibleby = models.ManyToManyField(AgencyGroup, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.name}'
|
return f'{self.name}'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,307 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
{% load counter_tag %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-12">
|
||||||
<h3>Neuen Standard anlegen</h3>
|
<h3>Neuen Standard anlegen <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie hier einen neuen Standard an." class="far fa-question-circle"></i></small></h3>
|
||||||
<hr>
|
<hr>
|
||||||
<form method="POST" id="taskareaform">
|
<form method="POST" id="addstandardform">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{normalForm|crispy}}
|
<div class="row"><div class="col-8">
|
||||||
|
{% for field in normalForm %}
|
||||||
|
{% if forloop.counter|divisibleby:6 %}
|
||||||
|
</div><div class="col-3">
|
||||||
|
{{field|as_crispy_field }}
|
||||||
|
{% else %}
|
||||||
|
{{field|as_crispy_field }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
<!-- COLLAPSE AREA FOR GROUPS FILES AND LINKED STANDARDS -->
|
||||||
|
<div class="accordion" style="margin-top: 47px" id="additionalStandardInfos">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_groups">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#stgroups_content" aria-expanded="false" aria-controls="stgroups_content">
|
||||||
|
Gruppen <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie fest, welche Gruppe diesen Standard sehen kann. Ist keine ausgewählt, ist der Standard für alle sichtbar." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="stgroups_content" class="collapse" aria-labelledby="st_groups" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
{% for g in agencygroups %}
|
||||||
|
<div class="custom-control custom-checkbox mb-2">
|
||||||
|
<input type="checkbox" class="custom-control-input groupclass" onclick="javascript:groupsChange({{g.pk}}, this.checked)" name="group_{{g.pk}}" id="group_{{g.pk}}">
|
||||||
|
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if request.user.profile.agency.module_files %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_files">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#st_files_content" aria-expanded="false" aria-controls="st_files_content">
|
||||||
|
Dateien <small><i data-toggle="tooltip" data-placement="top" title="Fügen Sie ihren Standards Dateien zu. Diese liegen entweder bereits unter Dateien oder können iher direkt hochgeladen werden. Neu hochgeladene Dateien werden im Heimverzeichnis gespeichert." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div id="st_files_content" class="collapse" aria-labelledby="st_files" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input class="form-control searchuserfieldstask" list="possfiles" id="searchfiles" type="text" onkeyup="javascript:updateLinkedFiles()" >
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" onclick="javascript:clearSearchfieldAddFile()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
<datalist id="possfiles">
|
||||||
|
{% for f in files %}
|
||||||
|
<option id="file_{{f.pk}}" value="{{f.name}}">{{f.name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
Verlinkte Dateien:
|
||||||
|
<table id="linkedfiles" class="table table-hover table-sm">
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<input type="file" id="uploadedfile" name="uploadedfile" style="display:none">
|
||||||
|
{% if user|usergperm:"filesmanager" %}
|
||||||
|
<div class="alert alert-secondary text-center mt-5" id="directdiv" role="alert" style="line-height: 17px; text-align: center;">
|
||||||
|
<button type="button" class="btn btn-primary btn-sm" id="uploadButton" onclick="javascript:uploadButtonPush()"><i class="fas fa-plus"></i></button> <small>klicken/hineinziehen<p class="mt-2">Dateien werden im <b>Heimverzeichnis</b>gespeichert.
|
||||||
|
</small></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_linked">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#st_linked_content" aria-expanded="false" aria-controls="st_linked_content">
|
||||||
|
Standards <small><i data-toggle="tooltip" data-placement="top" title="Verlinken Sie hier andere Standards, die etwas mit diesem Standard zutun haben." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div id="st_linked_content" class="collapse" aria-labelledby="st_linked" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input class="form-control" list="possstandards" id="searchstandards" type="text" onkeyup="javascript:updateLinkedStandards()" >
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" onclick="javascript:clearSearchfieldAddStandard()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
<datalist id="possstandards">
|
||||||
|
{% for s in standards %}
|
||||||
|
<option id="standard_{{s.pk}}" value="{{s.name|truncatechars:30}}">{{s.name|truncatechars:30}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
Verlinkte Standards:
|
||||||
|
<table id="linkedstandards" class="table table-hover table-sm">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div></div>
|
||||||
<p>Wenn ein Standard erstellt wurde, kann er nur von einer Person mit dem Recht <i>Standards bearbeiten und freischalten</i> veröffentlicht werden.</p>
|
<p>Wenn ein Standard erstellt wurde, kann er nur von einer Person mit dem Recht <i>Standards bearbeiten und freischalten</i> veröffentlicht werden.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<button type="submit" class="btn btn-success" href="{% url 'standard-add' %} ">Standard anlegen</button>
|
<button type="submit" class="btn btn-success">Standard anlegen</button>
|
||||||
<a class="btn" href="{% url 'standards' %} ">Abbrechen</a>
|
<a class="btn" href="{% url 'standards' %} ">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- FILE FORBIDDEN DELETE FILE -->
|
||||||
|
<div class="modal fade" id="forbiddenFileType" 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 nicht erlaubt</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Diesen Dateitypen dürfen Sie nicht hochladen.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- FILE FORBIDDEN DELETE FILE -->
|
||||||
|
<div class="modal fade" id="forbiddenFileType" 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 nicht erlaubt</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Diesen Dateitypen dürfen Sie nicht hochladen.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
//STANDARDS
|
||||||
|
actualStandards = [];
|
||||||
|
|
||||||
|
function clearSearchfieldAddStandard(){
|
||||||
|
$("#searchstandards").val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinkedStandards(){
|
||||||
|
var g = $('#searchstandards').val();
|
||||||
|
var id = $('#possstandards').find('option[value="' + g + '"]').attr('id');
|
||||||
|
if(id != undefined && id.length > 0){
|
||||||
|
tempid_standard = id.split("_")[1];
|
||||||
|
actualStandards.push(tempid_standard);
|
||||||
|
clearSearchfieldAddStandard();
|
||||||
|
$("#" + id).remove();
|
||||||
|
$("#linkedstandards").append('<tr id="standardadded_'+tempid_standard+'"><td>' + g + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remStandard('+tempid_standard+', \''+g+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#id_added_standards").val(actualStandards);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remStandard(id, name){
|
||||||
|
index_to_rem = actualStandards.indexOf(id);
|
||||||
|
actualStandards.splice(index_to_rem,1);
|
||||||
|
$('#possstandards').append('<option id="standard_'+id+'" value="'+ name +'">'+ name +'</option>');
|
||||||
|
$("#standardadded_" + id).remove();
|
||||||
|
$("#id_added_standards").val(actualStandards);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILES
|
||||||
|
// preventing page from redirecting
|
||||||
|
$("html").on("dragover", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
$("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });
|
||||||
|
|
||||||
|
$( "#directdiv" ).on('dragenter', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#directdiv").addClass('bg-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#directdiv').on('drop', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
$("#directdiv").removeClass('bg-secondary');
|
||||||
|
uploadAction(e.originalEvent.dataTransfer.files[0], e["currentTarget"]['id'].split("_")[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#directdiv').on('dragleave', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#directdiv").removeClass('bg-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*"
|
||||||
|
|
||||||
|
|
||||||
|
function uploadButtonPush(){
|
||||||
|
$("#uploadedfile").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#uploadedfile').on('change', function() {
|
||||||
|
uploadAction($("#uploadedfile")[0]['files'][0], {{parentid}});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function uploadAction(filetodo){
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append("uploadedfile", filetodo);
|
||||||
|
if(allowedtypes.includes(filetodo.type) && filetodo.type.length > 0){
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
headers: {
|
||||||
|
"X-CSRFTOKEN": "{{ csrf_token }}"
|
||||||
|
},
|
||||||
|
data: formData,
|
||||||
|
type: 'POST',
|
||||||
|
cache: false,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data) {
|
||||||
|
if(data["success"] == true){
|
||||||
|
actualFiles.push(String(data["data"]["savedobj_id"]));
|
||||||
|
$("#id_added_files").val(actualFiles);
|
||||||
|
$("#linkedfiles") .append('<tr id="fileadded_'+data["data"]["savedobj_id"]+'"><td>' + data["data"]["savedobj_name"] + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remFile('+data["data"]["savedobj_id"]+', \''+data["data"]["savedobj_name"]+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actualFiles = [];
|
||||||
|
|
||||||
|
function clearSearchfieldAddFile(){
|
||||||
|
$("#searchfiles").val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateLinkedFiles(){
|
||||||
|
var g = $('#searchfiles').val();
|
||||||
|
var id = $('#possfiles').find('option[value="' + g + '"]').attr('id');
|
||||||
|
if(id != undefined && id.length > 0){
|
||||||
|
tempid_file = id.split("_")[1];
|
||||||
|
actualFiles.push(tempid_file);
|
||||||
|
$("#id_added_files").val(actualFiles)
|
||||||
|
clearSearchfieldAddFile();
|
||||||
|
$("#" + id).remove();
|
||||||
|
$("#linkedfiles") .append('<tr id="fileadded_'+tempid_file+'"><td>' + g + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remFile('+tempid_file+', \''+g+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remFile(id, name){
|
||||||
|
index_to_rem = actualFiles.indexOf(id);
|
||||||
|
actualFiles.splice(index_to_rem,1);
|
||||||
|
$('#possfiles').append('<option id="file_'+id+'" value="'+ name +'">'+ name +'</option>');
|
||||||
|
$("#fileadded_" + id).remove();
|
||||||
|
$("#id_added_files").val(actualFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
//GROUPS
|
||||||
|
actualGroups = [];
|
||||||
|
|
||||||
|
function groupsChange(groupid, value){
|
||||||
|
if(value){
|
||||||
|
actualGroups.push(groupid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
index_to_rem = actualGroups.indexOf(groupid)
|
||||||
|
actualGroups.splice(index_to_rem,1);
|
||||||
|
}
|
||||||
|
$("#id_checked_groups").val(actualGroups);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Ajax-Request zum nachladen der Aufgaben nach Auswahl der Bereiche
|
Ajax-Request zum nachladen der Aufgaben nach Auswahl der Bereiche
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,12 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-12">
|
<div class="content-section col-12">
|
||||||
<h3>Standards</h3>
|
<h3>Standards <small><i data-toggle="tooltip" data-placement="top" title="Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Aufgaben." class="far fa-question-circle"></i></small></h3>
|
||||||
<small>Sichtbar sind alle veröffentlichten und von {{ user.first_name }} {{ user.last_name}} erstellten Standards.</small>
|
<small>Sichtbar sind alle veröffentlichten und von {{ user.first_name }} {{ user.last_name}} erstellten Standards.</small>
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
|
||||||
Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Aufgaben.
|
|
||||||
</p>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="content-section col-4">
|
<div class="content-section col-4">
|
||||||
<a class="btn btn-primary" href="{% url 'standard-add' %}">Standard anlegen</a>
|
<a class="btn btn-primary" href="{% url 'standard-add' %}"><i class="fas fa-plus"></i> Standard</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
@ -57,10 +54,27 @@
|
||||||
</h5>
|
</h5>
|
||||||
{% setvar 0 %}
|
{% setvar 0 %}
|
||||||
{% for standard in standards_of_agency %}
|
{% for standard in standards_of_agency %}
|
||||||
|
<!-- CHECK FOR GROUPVISIBLE -->
|
||||||
|
{% setbool False %}
|
||||||
|
{% for ag in standard.visibleby.all %}
|
||||||
|
{% if request.user|has_group:ag.group.name %}
|
||||||
|
{% setbool True %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if standard.visibleby.all|length == 0 %}
|
||||||
|
{% setbool True %}
|
||||||
|
{% endif %}
|
||||||
|
{% getbool as groupchecker %}
|
||||||
|
|
||||||
{% getvar as varcounter %}
|
{% getvar as varcounter %}
|
||||||
{% if standard.task == task and standard.area == area and varcounter < 3 %}
|
{% if standard.task == task and standard.area == area and varcounter < 3 %}
|
||||||
{% incvar %}
|
{% incvar %}
|
||||||
<p class="card-text"><a href="{% url 'standard-single' standard.pk %}">{{standard.name}}</a></p>
|
{% if groupchecker %}
|
||||||
|
<p class="card-text"><a href="{% url 'standard-single' standard.pk %}">{{standard.name|truncatechars:28}}</a></p>
|
||||||
|
{% else %}
|
||||||
|
<p class="card-text text-secondary"><i class="fas fa-lock"></i> {{standard.name|truncatechars:28}}</p>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
|
{% load counter_tag %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-12">
|
<div class="content-section col-12">
|
||||||
<nav aria-label="breadcrumb">
|
<nav aria-label="breadcrumb">
|
||||||
|
|
@ -19,12 +20,90 @@
|
||||||
<small><br />
|
<small><br />
|
||||||
Ansprechpartner:
|
Ansprechpartner:
|
||||||
{% for taskuser in standard.task.usersfield.all %}
|
{% for taskuser in standard.task.usersfield.all %}
|
||||||
|
|
||||||
<span class="badge badge-pill badge-primary" style="font-size: 1.1em; background-color: {{standard.task.area.color}}"><a href="{% url 'orga-single' taskuser.pk%}" style="color: #ffffff">{{taskuser.first_name}} {{taskuser.last_name}}</a></span>
|
<span class="badge badge-pill badge-primary" style="font-size: 1.1em; background-color: {{standard.task.area.color}}"><a href="{% url 'orga-single' taskuser.pk%}" style="color: #ffffff">{{taskuser.first_name}} {{taskuser.last_name}}</a></span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if standard.authority %}
|
||||||
|
Verantwortlicher: <a href="{% url 'orga-single' standard.authority.pk%}"> {{standard.authority.first_name}} {{standard.authority.last_name}}</a> |
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if standard.executor %}
|
||||||
|
Ausführende Person: <a href="{% url 'orga-single' standard.executor.pk%}">{{standard.executor.first_name}} {{standard.executor.last_name}}</a> |
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if standard.representative %}
|
||||||
|
Vertreter: <a href="{% url 'orga-single' standard.representative.pk%}">{{standard.representative.first_name}} {{standard.representative.last_name}}</a> |
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
</small>
|
</small>
|
||||||
<hr>
|
<hr>
|
||||||
{{standard.media}}
|
<div class="row col">
|
||||||
{{standard.content|safe}}
|
|
||||||
|
{% if standard.addedfiles.all|length == 0 and standard.linked_standards.all|length == 0 %}
|
||||||
|
<div class="card col-12" style="min-height: 500px">
|
||||||
|
{% else %}
|
||||||
|
<div class="card col-9" style="min-height: 500px">
|
||||||
|
{% endif %}
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title"></h5>
|
||||||
|
<p class="card-text">
|
||||||
|
{{standard.media}}
|
||||||
|
{{standard.content|safe}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- FILES -->
|
||||||
|
<div class="col-3">
|
||||||
|
{% if standard.addedfiles.all|length > 0 %}
|
||||||
|
<div class="card col-14 ml-2 mb-3" style="">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Dateien</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
{% for files in standard.addedfiles.all %}
|
||||||
|
<a href="{{files.file.url}}" download>{{files.name|truncatechars:30}}</a><br />
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<!-- STANDARDS -->
|
||||||
|
{% if standard.linked_standards.all|length > 0 %}
|
||||||
|
<div class="card col-14 ml-2" style="">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Verwandte Standards</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
{% for standard in standard.linked_standards.all %}
|
||||||
|
|
||||||
|
|
||||||
|
{% setbool False %}
|
||||||
|
{% for ag in standard.visibleby.all %}
|
||||||
|
{% if request.user|has_group:ag.group.name %}
|
||||||
|
{% setbool True %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if standard.visibleby.all|length == 0 %}
|
||||||
|
{% setbool True %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% getbool as groupchecker %}
|
||||||
|
|
||||||
|
{% if groupchecker %}
|
||||||
|
<a href="{% url 'standard-single' standard.pk %}">{{standard.name|truncatechars:30}}</a><br />
|
||||||
|
{% else %}
|
||||||
|
<i class="fas fa-lock"></i> {{standard.name|truncatechars:30}}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% for g in standard.visibleby.all %}
|
||||||
|
{{g.agencygroupname}}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
@ -1,13 +1,122 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
{% load counter_tag %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-12">
|
||||||
<h3>Standard bearbeiten</h3>
|
<h3>Standard bearbeiten <small><i data-toggle="tooltip" data-placement="top" title="Aktualisieren Sie hier die Informationen des Standards." class="far fa-question-circle"></i></small></h3>
|
||||||
<hr>
|
<hr>
|
||||||
<form method="POST" id="taskareaform">
|
<form method="POST" id="taskareaform">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{normalForm|crispy}}
|
|
||||||
|
|
||||||
|
<div class="row"><div class="col-8">
|
||||||
|
{% for field in normalForm %}
|
||||||
|
{% if forloop.counter|divisibleby:5 %}
|
||||||
|
</div><div class="col-3">
|
||||||
|
{{field|as_crispy_field }}
|
||||||
|
{% else %}
|
||||||
|
{{field|as_crispy_field }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<!-- COLLAPSE AREA FOR GROUPS FILES AND LINKED STANDARDS -->
|
||||||
|
<div class="accordion" style="margin-top: 47px" id="additionalStandardInfos">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_groups">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#stgroups_content" aria-expanded="false" aria-controls="stgroups_content">
|
||||||
|
Gruppen <small><i data-toggle="tooltip" data-placement="top" title="Legen Sie fest, welche Gruppe diesen Standard sehen kann. Ist keine ausgewählt, ist der Standard für alle sichtbar." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div id="stgroups_content" class="collapse" aria-labelledby="st_groups" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
{% for g in agencygroups %}
|
||||||
|
<div class="custom-control custom-checkbox mb-2">
|
||||||
|
{% if g in standard.visibleby.all %}
|
||||||
|
<input type="checkbox" class="custom-control-input groupclass" onclick="javascript:groupsChange({{g.pk}}, this.checked)" name="group_{{g.pk}}" id="group_{{g.pk}}" checked="true">
|
||||||
|
{% else %}
|
||||||
|
<input type="checkbox" class="custom-control-input groupclass" onclick="javascript:groupsChange({{g.pk}}, this.checked)" name="group_{{g.pk}}" id="group_{{g.pk}}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<label class="custom-control-label" for="group_{{g.pk}}" >{{g.agencygroupname}}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if request.user.profile.agency.module_files %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_files">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#st_files_content" aria-expanded="false" aria-controls="st_files_content">
|
||||||
|
Dateien <small><i data-toggle="tooltip" data-placement="top" title="Fügen Sie ihren Standards Dateien zu. Diese liegen entweder bereits unter Dateien oder können iher direkt hochgeladen werden. Neu hochgeladene Dateien werden im Heimverzeichnis gespeichert." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div id="st_files_content" class="collapse" aria-labelledby="st_files" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input class="form-control searchuserfieldstask" list="possfiles" id="searchfiles" type="text" onkeyup="javascript:updateLinkedFiles()" >
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" onclick="javascript:clearSearchfieldAddFile()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
<datalist id="possfiles">
|
||||||
|
{% for f in possibleFilesByVisible %}
|
||||||
|
<option id="file_{{f.pk}}" value="{{f.name}}">{{f.name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
Verlinkte Dateien:
|
||||||
|
<table id="linkedfiles" class="table table-hover table-sm">
|
||||||
|
{% for f in standard.addedfiles.all %}
|
||||||
|
<tr id="fileadded_{{f.pk}}"><td>{{f.name|truncatechars:30}}</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remFile({{f.pk}}, '{{f.name}}')"><i class="fas fa-trash-alt"></i></button></td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<input type="file" id="uploadedfile" name="uploadedfile" style="display:none">
|
||||||
|
{% if user|usergperm:"filesmanager" %}
|
||||||
|
<div class="alert alert-secondary text-center mt-5" id="directdiv" role="alert" style="line-height: 17px; text-align: center;">
|
||||||
|
<button type="button" class="btn btn-primary btn-sm" id="uploadButton" onclick="javascript:uploadButtonPush()"><i class="fas fa-plus"></i></button> <small>klicken/hineinziehen<p class="mt-2">Dateien werden im <b>Heimverzeichnis</b>gespeichert.
|
||||||
|
</small></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="st_linked">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#st_linked_content" aria-expanded="false" aria-controls="st_linked_content">
|
||||||
|
Standards <small><i data-toggle="tooltip" data-placement="top" title="Verlinken Sie hier andere Standards, die etwas mit diesem Standard zutun haben." class="far fa-question-circle"></i></small>
|
||||||
|
</button>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div id="st_linked_content" class="collapse" aria-labelledby="st_linked" data-parent="#additionalStandardInfos">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input class="form-control" list="possstandards" id="searchstandards" type="text" onkeyup="javascript:updateLinkedStandards()" >
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" onclick="javascript:clearSearchfieldAddStandard()" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
<datalist id="possstandards">
|
||||||
|
{% for s in possiblestandards %}
|
||||||
|
<option id="standard_{{s.pk}}" value="{{s.name|truncatechars:30}}">{{s.name|truncatechars:30}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
Verlinkte Standards:
|
||||||
|
<table id="linkedstandards" class="table table-hover table-sm">
|
||||||
|
{% for s in standard.linked_standards.all %}
|
||||||
|
<tr id="standardadded_{{s.pk}}"><td>{{s.name|truncatechars:30}}</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remStandard({{s.pk}}, '{{s.name|truncatechars:30}}')"><i class="fas fa-trash-alt"></i></button></td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<p>Wenn ein Standard bearbeitet wurde, kann er nur von einer Person mit dem Recht <i>Standards bearbeiten und freischalten</i> wieder veröffentlicht werden. Ein Standard wird nach Bearbeitung als <i>Nicht veröffentlicht</i> gesetzt.</p>
|
<p>Wenn ein Standard bearbeitet wurde, kann er nur von einer Person mit dem Recht <i>Standards bearbeiten und freischalten</i> wieder veröffentlicht werden. Ein Standard wird nach Bearbeitung als <i>Nicht veröffentlicht</i> gesetzt.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<button type="submit" class="btn btn-success" href="{% url 'standard-update' standard_id %} ">Aktualisieren</button>
|
<button type="submit" class="btn btn-success" href="{% url 'standard-update' standard_id %} ">Aktualisieren</button>
|
||||||
|
|
@ -22,7 +131,211 @@
|
||||||
<a class="btn" href="{% url 'standards' %} ">Abbrechen</a>
|
<a class="btn" href="{% url 'standards' %} ">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- FILE FORBIDDEN DELETE FILE -->
|
||||||
|
<div class="modal fade" id="forbiddenFileType" 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 nicht erlaubt</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Diesen Dateitypen dürfen Sie nicht hochladen.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-success" data-dismiss="modal">Schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
//STANDARD
|
||||||
|
function clearSearchfieldAddStandard(){
|
||||||
|
$("#searchstandards").val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function remStandard(id, name){
|
||||||
|
$('#possstandards').append('<option id="standard_'+id+'" value="'+ name +'">'+ name +'</option>');
|
||||||
|
$("#standardadded_" + id).remove();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_remstandard',
|
||||||
|
standardid : id
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinkedStandards(){
|
||||||
|
var g = $('#searchstandards').val();
|
||||||
|
var id = $('#possstandards').find('option[value="' + g + '"]').attr('id');
|
||||||
|
if(id != undefined && id.length > 0){
|
||||||
|
tempid_standard = id.split("_")[1];
|
||||||
|
clearSearchfieldAddStandard();
|
||||||
|
$("#" + id).remove();
|
||||||
|
$("#linkedstandards").append('<tr id="standardadded_'+tempid_standard+'"><td>' + g + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remStandard('+tempid_standard+', \''+g+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_addstandard',
|
||||||
|
standardid : tempid_standard
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILES
|
||||||
|
function remFile(fileid, filename){
|
||||||
|
console.log(fileid);
|
||||||
|
$("#fileadded_" + fileid).remove();
|
||||||
|
$('#possfiles').append('<option id="file_'+fileid+'" value="'+ filename +'">'+ filename +'</option>');
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_remfile',
|
||||||
|
fileid : fileid
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSearchfieldAddFile(){
|
||||||
|
$("#searchfiles").val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinkedFiles(){
|
||||||
|
var g = $('#searchfiles').val();
|
||||||
|
var id = $('#possfiles').find('option[value="' + g + '"]').attr('id');
|
||||||
|
if(id != undefined && id.length > 0){
|
||||||
|
tempid_file = id.split("_")[1];
|
||||||
|
clearSearchfieldAddFile();
|
||||||
|
$("#" + id).remove();
|
||||||
|
$("#linkedfiles") .append('<tr id="fileadded_'+tempid_file+'"><td>' + g + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remFile('+tempid_file+', \''+g+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_addfile',
|
||||||
|
fileid : tempid_file
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//FILES
|
||||||
|
// preventing page from redirecting
|
||||||
|
$("html").on("dragover", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
$("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });
|
||||||
|
|
||||||
|
$( "#directdiv" ).on('dragenter', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#directdiv").addClass('bg-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#directdiv').on('drop', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
$("#directdiv").removeClass('bg-secondary');
|
||||||
|
uploadAction(e.originalEvent.dataTransfer.files[0], e["currentTarget"]['id'].split("_")[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#directdiv').on('dragleave', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
currentid = e["currentTarget"]['id'];
|
||||||
|
$("#directdiv").removeClass('bg-secondary');
|
||||||
|
});
|
||||||
|
|
||||||
|
allowedtypes = "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, text/plain, application/pdf, image/*"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function uploadButtonPush(){
|
||||||
|
$("#uploadedfile").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#uploadedfile').on('change', function() {
|
||||||
|
uploadAction($("#uploadedfile")[0]['files'][0], {{parentid}});
|
||||||
|
});
|
||||||
|
|
||||||
|
function uploadAction(filetodo){
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append("uploadedfile", filetodo);
|
||||||
|
if(allowedtypes.includes(filetodo.type) && filetodo.type.length > 0){
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'cloud-adddir' parentid %}",
|
||||||
|
headers: {
|
||||||
|
"X-CSRFTOKEN": "{{ csrf_token }}"
|
||||||
|
},
|
||||||
|
data: formData,
|
||||||
|
type: 'POST',
|
||||||
|
cache: false,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data) {
|
||||||
|
if(data["success"] == true){
|
||||||
|
$("#linkedfiles") .append('<tr id="fileadded_'+data["data"]["savedobj_id"]+'"><td>' + data["data"]["savedobj_name"] + '</td><td><button type="button" class="btn btn-danger btn-sm" onclick="javascript:remFile('+data["data"]["savedobj_id"]+', \''+data["data"]["savedobj_name"]+'\')"><i class="fas fa-trash-alt"></i></button></td></tr>');
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_addfile',
|
||||||
|
fileid : data["data"]["savedobj_id"]
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$("#forbiddenFileType").modal("toggle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//GROUP CHANGE
|
||||||
|
function groupsChange(groupid, value){
|
||||||
|
if(value){
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_addgroup',
|
||||||
|
groupid : groupid
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url 'update_standard_by_ajax' standard.pk %}",
|
||||||
|
data: {
|
||||||
|
action : 's_remgroup',
|
||||||
|
groupid : groupid
|
||||||
|
},
|
||||||
|
success: function (data) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Ajax-Request zum nachladen der Aufgaben nach Auswahl der Bereiche
|
Ajax-Request zum nachladen der Aufgaben nach Auswahl der Bereiche
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,9 +1,13 @@
|
||||||
from django import template
|
from django import template
|
||||||
|
from django.contrib.auth.models import Group, User
|
||||||
|
from users.models import AgencyGroup
|
||||||
|
import os
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
b = 0
|
b = 0
|
||||||
|
|
||||||
|
groupbool = False
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def setvar(value):
|
def setvar(value):
|
||||||
global b
|
global b
|
||||||
|
|
@ -22,6 +26,62 @@ def incvar():
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='has_group')
|
||||||
|
def has_group(user, group_name):
|
||||||
|
group = Group.objects.get(name=group_name)
|
||||||
|
in_group = False
|
||||||
|
for g in user.groups.all():
|
||||||
|
if g.name == group_name:
|
||||||
|
in_group = True
|
||||||
|
return in_group
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def setbool(value):
|
||||||
|
global groupbool
|
||||||
|
groupbool = value
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def getbool():
|
||||||
|
global groupbool
|
||||||
|
return groupbool
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# usergperm
|
||||||
|
'''
|
||||||
|
|
||||||
|
Gibt TRUE zurück, wenn der User über eine Gruppe das gewünschte Recht hat.
|
||||||
|
Gibt FALSE zurück, wenn der User über eine Gruppe das gewünschte Recht NICHT hat.
|
||||||
|
|
||||||
|
@param:
|
||||||
|
user - einglogger Nutzer
|
||||||
|
perm - recht
|
||||||
|
|
||||||
|
'''
|
||||||
|
@register.filter(name="usergperm")
|
||||||
|
def usergperm(user, perm):
|
||||||
|
stat = False
|
||||||
|
if user.has_perm('users.'+perm):
|
||||||
|
stat = True
|
||||||
|
return stat
|
||||||
|
|
||||||
|
@register.filter(name="useringroupbyid")
|
||||||
|
def is_member(id, groupname):
|
||||||
|
usertocheck = User.objects.get(pk=id)
|
||||||
|
return usertocheck.groups.filter(name=groupname).exists()
|
||||||
|
|
||||||
|
# Return a Filename splitted to only see the LAST element!
|
||||||
|
@register.filter(name="splitdirstyle")
|
||||||
|
def split_dir_style(dirtosplit):
|
||||||
|
tempsplit = dirtosplit.split("\\")
|
||||||
|
return tempsplit[len(tempsplit)-1]
|
||||||
|
|
||||||
|
@register.filter(name="filename")
|
||||||
|
def filename(value):
|
||||||
|
return os.path.basename(value.file.name)
|
||||||
'''
|
'''
|
||||||
class Counter:
|
class Counter:
|
||||||
count = 0
|
count = 0
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ urlpatterns = [
|
||||||
path('standardadd/', views.StandardAdd, name='standard-add'),
|
path('standardadd/', views.StandardAdd, name='standard-add'),
|
||||||
path('standardupdate/<int:id>', views.StandardUpdate, name='standard-update'),
|
path('standardupdate/<int:id>', views.StandardUpdate, name='standard-update'),
|
||||||
path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'),
|
path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'),
|
||||||
|
path('ajups/<int:pk>', views.updatesbyajax, name='update_standard_by_ajax'),
|
||||||
path('standards/<int:pk>/delete', StandardDeleteView.as_view(), name='standard-delete'),
|
path('standards/<int:pk>/delete', StandardDeleteView.as_view(), name='standard-delete'),
|
||||||
path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
|
path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
|
||||||
path('standard/<int:pk>/single', views.StandardSingle, name="standard-single"),
|
path('standard/<int:pk>/single', views.StandardSingle, name="standard-single"),
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ from django.contrib.auth.decorators import login_required
|
||||||
from tasks.models import Tasks
|
from tasks.models import Tasks
|
||||||
from areas.models import Areas
|
from areas.models import Areas
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from users.models import AgencyGroup
|
||||||
|
from cloud.models import DataFile, DataDir
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
# ALLE STANDARDS EINER AGENTUR
|
# ALLE STANDARDS EINER AGENTUR
|
||||||
class StandardsManagement(LoginRequiredMixin, ListView):
|
class StandardsManagement(LoginRequiredMixin, ListView):
|
||||||
|
|
@ -28,6 +31,42 @@ class StandardsManagement(LoginRequiredMixin, ListView):
|
||||||
context.update({'active_link' : 'standards', 'tasks': tasks, 'unpubstandards_of_user' : unpubstandards_of_user, 'standards_of_agency' : standards_of_agency, 'areas' : areas, 'standards_of_user' : standards_of_user})
|
context.update({'active_link' : 'standards', 'tasks': tasks, 'unpubstandards_of_user' : unpubstandards_of_user, 'standards_of_agency' : standards_of_agency, 'areas' : areas, 'standards_of_user' : standards_of_user})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def checkUserDirRights(request, startdir, userid):
|
||||||
|
canview = True
|
||||||
|
user = User.objects.get(pk=userid)
|
||||||
|
usergroups=list(user.groups.all())
|
||||||
|
grouptomach = []
|
||||||
|
singleObj = DataDir.objects.get(pk=startdir.pk)
|
||||||
|
# AGENCYCHECK
|
||||||
|
if(singleObj.agency.pk == user.profile.agency.pk):
|
||||||
|
|
||||||
|
# Get dirs to check
|
||||||
|
while( singleObj.is_root != True and canview == True):
|
||||||
|
|
||||||
|
for g in singleObj.visibleby.all():
|
||||||
|
grouptomach.append(g.group)
|
||||||
|
|
||||||
|
if(len(grouptomach) == 0):
|
||||||
|
canview = True
|
||||||
|
else:
|
||||||
|
if(len(set(usergroups).intersection(grouptomach)) > 0):
|
||||||
|
canview = True
|
||||||
|
else:
|
||||||
|
canview = False
|
||||||
|
|
||||||
|
grouptomach = []
|
||||||
|
singleObj = DataDir.objects.get(pk=singleObj.parent.pk)
|
||||||
|
|
||||||
|
else:
|
||||||
|
canview = False
|
||||||
|
return canview
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def StandardAdd(request):
|
def StandardAdd(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
|
@ -53,9 +92,31 @@ def StandardAdd(request):
|
||||||
new_standard.name = normalForm.cleaned_data['name']
|
new_standard.name = normalForm.cleaned_data['name']
|
||||||
new_standard.content = editorForm.cleaned_data['content']
|
new_standard.content = editorForm.cleaned_data['content']
|
||||||
new_standard.public = normalForm.cleaned_data['public']
|
new_standard.public = normalForm.cleaned_data['public']
|
||||||
|
|
||||||
|
new_standard.representative = normalForm.cleaned_data['representative']
|
||||||
|
new_standard.executor = normalForm.cleaned_data['executor']
|
||||||
|
new_standard.authority = normalForm.cleaned_data['authority']
|
||||||
|
|
||||||
|
# GROUPS
|
||||||
new_standard.save()
|
new_standard.save()
|
||||||
|
|
||||||
|
# ADD GROUPS
|
||||||
|
groups = normalForm.cleaned_data['checked_groups'].split(",")
|
||||||
|
for g in groups:
|
||||||
|
new_standard.visibleby.add(AgencyGroup.objects.get(pk=g))
|
||||||
|
|
||||||
|
# ADD STANDARDS
|
||||||
|
standards = normalForm.cleaned_data['added_standards'].split(",")
|
||||||
|
for s in standards:
|
||||||
|
new_standard.linked_standards.add(Standards.objects.get(pk=s))
|
||||||
|
|
||||||
|
# ADD FILES
|
||||||
|
files = normalForm.cleaned_data['added_files'].split(",")
|
||||||
|
for f in files:
|
||||||
|
new_standard.addedfiles.add(DataFile.objects.get(pk=f))
|
||||||
|
|
||||||
tempstandardname = normalForm.cleaned_data['name']
|
tempstandardname = normalForm.cleaned_data['name']
|
||||||
if(new_standard.public and request.user.has_perm('users.standard_management')):
|
if(new_standard.public and request.user.has_perm('users.standardmanager')):
|
||||||
messages.success(request, f'Standard {tempstandardname} hinzugefügt und veröffentlicht.')
|
messages.success(request, f'Standard {tempstandardname} hinzugefügt und veröffentlicht.')
|
||||||
else:
|
else:
|
||||||
new_standard.public = False
|
new_standard.public = False
|
||||||
|
|
@ -67,18 +128,41 @@ def StandardAdd(request):
|
||||||
normalForm = StandardAddStandard(instance=request.user)
|
normalForm = StandardAddStandard(instance=request.user)
|
||||||
editorForm = StandardAddStandardEditor(instance=request.user)
|
editorForm = StandardAddStandardEditor(instance=request.user)
|
||||||
|
|
||||||
|
'''
|
||||||
|
Hier werden nur die Dateien dem aktuellen User zur Auswahl gestellt, auf die er auch Zugriff hat.
|
||||||
|
Das geht NICHT rekursiv! Es wird nur das oberste Verzeichnis geprüft! SPÄTER!
|
||||||
|
'''
|
||||||
|
|
||||||
|
possibleFilesByVisible = []
|
||||||
|
|
||||||
|
allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
|
||||||
|
|
||||||
|
for f in allfiles:
|
||||||
|
actParent = DataDir.objects.get(pk=f.parent.pk)
|
||||||
|
if actParent.is_root:
|
||||||
|
possibleFilesByVisible.append(f)
|
||||||
|
else:
|
||||||
|
if(checkUserDirRights(request, actParent, request.user.pk)):
|
||||||
|
possibleFilesByVisible.append(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'normalForm' : normalForm,
|
'normalForm' : normalForm,
|
||||||
'editorForm' : editorForm,
|
'editorForm' : editorForm,
|
||||||
'active_link' : 'standards'
|
'active_link' : 'standards',
|
||||||
|
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency),
|
||||||
|
'files' : possibleFilesByVisible,
|
||||||
|
'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk,
|
||||||
|
'standards' : Standards.objects.filter(agency=request.user.profile.agency, public=True)
|
||||||
}
|
}
|
||||||
return render(request, 'standards/standards_add.html', context)
|
return render(request, 'standards/standards_add.html', context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def StandardUpdate(request, id):
|
def StandardUpdate(request, id):
|
||||||
standard = Standards.objects.get(pk=id)
|
standard = Standards.objects.get(pk=id, agency=request.user.profile.agency)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
#normalForm = StandardUpdateStandard(request.POST, instance=standard)
|
#normalForm = StandardUpdateStandard(request.POST, instance=standard)
|
||||||
normalForm = StandardUpdateStandard(request.POST, instance=standard)
|
normalForm = StandardUpdateStandard(request.POST, instance=standard)
|
||||||
|
|
@ -92,6 +176,11 @@ def StandardUpdate(request, id):
|
||||||
existing_standard.area = normalForm.cleaned_data['area']
|
existing_standard.area = normalForm.cleaned_data['area']
|
||||||
existing_standard.name = normalForm.cleaned_data['name']
|
existing_standard.name = normalForm.cleaned_data['name']
|
||||||
existing_standard.content = editorForm.cleaned_data['content']
|
existing_standard.content = editorForm.cleaned_data['content']
|
||||||
|
|
||||||
|
existing_standard.representative = normalForm.cleaned_data['representative']
|
||||||
|
existing_standard.executor = normalForm.cleaned_data['executor']
|
||||||
|
existing_standard.authority = normalForm.cleaned_data['authority']
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
AKTUALISIERUNG
|
AKTUALISIERUNG
|
||||||
|
|
@ -101,7 +190,7 @@ def StandardUpdate(request, id):
|
||||||
aber keine Rechte und ist der Standarf public, wird er auf public=false gesetzt!
|
aber keine Rechte und ist der Standarf public, wird er auf public=false gesetzt!
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if request.user.has_perm('users.standard_management'):
|
if request.user.has_perm('users.standardmanager'):
|
||||||
messages.success(request, f'Standard {existing_standard.name} aktualisiert!')
|
messages.success(request, f'Standard {existing_standard.name} aktualisiert!')
|
||||||
else:
|
else:
|
||||||
if existing_standard.public:
|
if existing_standard.public:
|
||||||
|
|
@ -117,20 +206,50 @@ def StandardUpdate(request, id):
|
||||||
normalForm = StandardUpdateStandard(instance=standard)
|
normalForm = StandardUpdateStandard(instance=standard)
|
||||||
editorForm = StandardUpdateStandardEditor(instance=standard)
|
editorForm = StandardUpdateStandardEditor(instance=standard)
|
||||||
|
|
||||||
|
'''
|
||||||
|
Hier werden nur die Dateien dem aktuellen User zur Auswahl gestellt, auf die er auch Zugriff hat.
|
||||||
|
Das geht NICHT rekursiv! Es wird nur das oberste Verzeichnis geprüft! SPÄTER!
|
||||||
|
'''
|
||||||
|
|
||||||
|
possibleFilesByVisible = []
|
||||||
|
|
||||||
|
allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
|
||||||
|
|
||||||
|
for f in allfiles:
|
||||||
|
actParent = DataDir.objects.get(pk=f.parent.pk, agency=request.user.profile.agency)
|
||||||
|
if actParent.is_root:
|
||||||
|
possibleFilesByVisible.append(f)
|
||||||
|
else:
|
||||||
|
if(checkUserDirRights(request, actParent, request.user.pk) and f not in standard.addedfiles.all()):
|
||||||
|
possibleFilesByVisible.append(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
possiblestandards = Standards.objects.filter(agency=request.user.profile.agency, public=True)
|
||||||
|
possiblestandards_final = []
|
||||||
|
for s in possiblestandards:
|
||||||
|
if s not in standard.linked_standards.all():
|
||||||
|
possiblestandards_final.append(s)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'normalForm' : normalForm,
|
'normalForm' : normalForm,
|
||||||
'editorForm' : editorForm,
|
'editorForm' : editorForm,
|
||||||
|
'standard' : standard,
|
||||||
'active_link' : 'standards',
|
'active_link' : 'standards',
|
||||||
'standard_id' : standard.pk,
|
'standard_id' : standard.pk,
|
||||||
'standard_status' : standard.public
|
'standard_status' : standard.public,
|
||||||
|
'possibleFilesByVisible' : possibleFilesByVisible,
|
||||||
|
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency),
|
||||||
|
'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk,
|
||||||
|
'possiblestandards' : possiblestandards_final
|
||||||
}
|
}
|
||||||
return render(request, 'standards/standards_update.html', context)
|
return render(request, 'standards/standards_update.html', context)
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def load_tasks(request):
|
def load_tasks(request):
|
||||||
areaid = request.GET.get('areaid')
|
areaid = request.GET.get('areaid')
|
||||||
tasks = Tasks.objects.filter(area__id=areaid).order_by('name')
|
tasks = Tasks.objects.filter(area__id=areaid, agency=request.user.profile.agency).order_by('name')
|
||||||
return render(request, 'standards/standards_tasklist.html', {'tasks': tasks})
|
return render(request, 'standards/standards_tasklist.html', {'tasks': tasks})
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,7 +259,7 @@ class StandardDeleteView(LoginRequiredMixin, DeleteView):
|
||||||
template_name = 'standards/standard_confirm_delete.html'
|
template_name = 'standards/standard_confirm_delete.html'
|
||||||
|
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
standard = Standards.objects.get(pk=kwargs['pk'])
|
standard = Standards.objects.get(pk=kwargs['pk'], agency=request.user.profile.agency)
|
||||||
response = super(StandardDeleteView, self).delete(request, *args, **kwargs)
|
response = super(StandardDeleteView, self).delete(request, *args, **kwargs)
|
||||||
names = standard.name
|
names = standard.name
|
||||||
messages.success(request, f'Standard ' +names+ ' wurde gelöscht!')
|
messages.success(request, f'Standard ' +names+ ' wurde gelöscht!')
|
||||||
|
|
@ -165,18 +284,37 @@ def StandardChangePublic(request, pk):
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def StandardSingle(request, pk):
|
def StandardSingle(request, pk):
|
||||||
standard = Standards.objects.get(pk=pk)
|
|
||||||
context = {
|
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR
|
||||||
'active_link':'standards',
|
groupsofstandard = Standards.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
'standard' : standard
|
|
||||||
}
|
userisingroup = False
|
||||||
return render(request, 'standards/standards_single.html', context)
|
|
||||||
|
if len(groupsofstandard.visibleby.all()) == 0:
|
||||||
|
userisingroup = True
|
||||||
|
else:
|
||||||
|
for ag in groupsofstandard.visibleby.all():
|
||||||
|
if ag.group in request.user.groups.all():
|
||||||
|
userisingroup = True
|
||||||
|
|
||||||
|
if userisingroup:
|
||||||
|
standard = Standards.objects.get(pk=pk)
|
||||||
|
context = {
|
||||||
|
'active_link':'standards',
|
||||||
|
'standard' : standard
|
||||||
|
}
|
||||||
|
return render(request, 'standards/standards_single.html', context)
|
||||||
|
else:
|
||||||
|
context = {
|
||||||
|
'active_link':'standards'
|
||||||
|
}
|
||||||
|
return render(request, 'standards/standards_noentrie.html', context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def StandardArea(request, pk):
|
def StandardArea(request, pk):
|
||||||
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(area__pk=pk)
|
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(area__pk=pk)
|
||||||
area = Areas.objects.get(pk=pk)
|
area = Areas.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
context = {
|
context = {
|
||||||
'active_link':'standards',
|
'active_link':'standards',
|
||||||
'standards_of_agency_area' : standards,
|
'standards_of_agency_area' : standards,
|
||||||
|
|
@ -188,8 +326,8 @@ def StandardArea(request, pk):
|
||||||
@login_required
|
@login_required
|
||||||
def StandardTask(request, pk):
|
def StandardTask(request, pk):
|
||||||
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(task__pk=pk)
|
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(task__pk=pk)
|
||||||
task = Tasks.objects.get(pk=pk)
|
task = Tasks.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
area = Areas.objects.get(pk=task.area.pk)
|
area = Areas.objects.get(pk=task.area.pk, agency=request.user.profile.agency)
|
||||||
context = {
|
context = {
|
||||||
'active_link':'standards',
|
'active_link':'standards',
|
||||||
'standards_of_agency_task' : standards,
|
'standards_of_agency_task' : standards,
|
||||||
|
|
@ -201,3 +339,35 @@ def StandardTask(request, pk):
|
||||||
return render(request, 'standards/standard_task.html', context)
|
return render(request, 'standards/standard_task.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def updatesbyajax(request, pk):
|
||||||
|
if(request.method == "GET"):
|
||||||
|
success = True
|
||||||
|
workingstandard = Standards.objects.get(pk=pk, agency=request.user.profile.agency)
|
||||||
|
# Check for correct user and userrights
|
||||||
|
if(request.user.profile.agency == workingstandard.agency and request.user.has_perm("standardmanager")):
|
||||||
|
# CHANGE GROUP
|
||||||
|
# ADD
|
||||||
|
if(request.GET["action"] == "s_addgroup"):
|
||||||
|
workingstandard.visibleby.add(AgencyGroup.objects.get(pk=request.GET["groupid"], agency=request.user.profile.agency))
|
||||||
|
# REMOVE
|
||||||
|
elif(request.GET["action"] == "s_remgroup"):
|
||||||
|
workingstandard.visibleby.remove(AgencyGroup.objects.get(pk=request.GET["groupid"], agency=request.user.profile.agency))
|
||||||
|
# FILES
|
||||||
|
# REMOVE
|
||||||
|
elif(request.GET["action"] == "s_remfile"):
|
||||||
|
workingstandard.addedfiles.remove(DataFile.objects.get(pk=request.GET["fileid"], agency=request.user.profile.agency))
|
||||||
|
# ADD
|
||||||
|
elif(request.GET["action"] == "s_addfile"):
|
||||||
|
workingstandard.addedfiles.add(DataFile.objects.get(pk=request.GET["fileid"], agency=request.user.profile.agency))
|
||||||
|
# STANDARD
|
||||||
|
# REMOVE
|
||||||
|
elif(request.GET["action"] == "s_remstandard"):
|
||||||
|
workingstandard.linked_standards.remove(Standards.objects.get(pk=request.GET["standardid"], agency=request.user.profile.agency))
|
||||||
|
# ADD
|
||||||
|
elif(request.GET["action"] == "s_addstandard"):
|
||||||
|
workingstandard.linked_standards.add(Standards.objects.get(pk=request.GET["standardid"], agency=request.user.profile.agency))
|
||||||
|
else:
|
||||||
|
success = False
|
||||||
|
|
||||||
|
return JsonResponse({"success" : success})
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -10,10 +10,9 @@ class TasksAddTaskForm(forms.ModelForm):
|
||||||
labels = {
|
labels = {
|
||||||
"name" : "Aufgabenname",
|
"name" : "Aufgabenname",
|
||||||
"area" : "Übergeordneter Bereich",
|
"area" : "Übergeordneter Bereich",
|
||||||
"desc" : "Beschreibung",
|
|
||||||
"visible": "Im Organigramm sichtbar"
|
"visible": "Im Organigramm sichtbar"
|
||||||
}
|
}
|
||||||
fields = ['name', 'area', 'desc', 'visible']
|
fields = ['name', 'area', 'visible']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
user = kwargs.pop('user')
|
user = kwargs.pop('user')
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="content-section col-6">
|
<div class="content-section col-6">
|
||||||
<h3>Neue Aufgabe anlegen</h3>
|
<h3>Neue Tätigkeit anlegen</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<p>Nachdem Erstellen der Aufgabe können Mitarbeiter zugewiesen werden.</p>
|
<p>Nachdem Erstellen der Aufgabe können Mitarbeiter zugewiesen werden.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<button type="submit" class="btn btn-success" href="{% url 'areas-addarea' %} ">Aufgabe anlegen</button>
|
<button type="submit" class="btn btn-success" href="{% url 'dasettings' %} ">Tätigkeit anlegen</button>
|
||||||
<a class="btn" href="{% url 'tasks-management' %} ">Abbrechen</a>
|
<a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue