djgentelella 0.4.30__py3-none-any.whl → 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- djgentelella/__init__.py +4 -1
- djgentelella/admin.py +41 -2
- djgentelella/firmador_digital/consumers/sign.py +24 -3
- djgentelella/firmador_digital/forms.py +140 -0
- djgentelella/firmador_digital/models.py +19 -24
- djgentelella/firmador_digital/utils.py +11 -0
- djgentelella/firmador_digital/views.py +31 -0
- djgentelella/firmador_digital/viewsets.py +15 -4
- djgentelella/forms/forms.py +10 -2
- djgentelella/groute.py +4 -1
- djgentelella/history/api.py +145 -0
- djgentelella/history/filterset.py +23 -0
- djgentelella/history/serializers.py +50 -0
- djgentelella/history/utils.py +70 -0
- djgentelella/locale/es/LC_MESSAGES/django.mo +0 -0
- djgentelella/locale/es/LC_MESSAGES/django.po +105 -0
- djgentelella/locale/es/LC_MESSAGES/djangojs.mo +0 -0
- djgentelella/locale/es/LC_MESSAGES/djangojs.po +46 -0
- djgentelella/migrations/0014_trash.py +31 -0
- djgentelella/migrations/0015_trash_deleted_by.py +21 -0
- djgentelella/migrations/0016_trash_created_at.py +20 -0
- djgentelella/migrations/0017_alter_chunkedupload_status.py +18 -0
- djgentelella/migrations/0018_alter_chunkedupload_status.py +18 -0
- djgentelella/models.py +97 -0
- djgentelella/models_manager.py +40 -0
- djgentelella/serializers/firmador_digital.py +9 -1
- djgentelella/serializers/selects.py +14 -0
- djgentelella/static/djgentelella.readonly.vendors.min.css +9 -5
- djgentelella/static/djgentelella.readonly.vendors.min.js +1 -1
- djgentelella/static/gentelella/css/custom.css +23 -2
- djgentelella/static/gentelella/css/modern.css +15 -0
- djgentelella/static/gentelella/css/modern_black_white.css +15 -0
- djgentelella/static/gentelella/css/pdfviewer.css +43 -1
- djgentelella/static/gentelella/images/default.png +0 -0
- djgentelella/static/gentelella/js/base/digital_signature.js +318 -79
- djgentelella/static/gentelella/js/base/form.common.js +9 -4
- djgentelella/static/gentelella/js/base/select2_wrap.js +15 -1
- djgentelella/static/gentelella/js/base/select2related.js +5 -0
- djgentelella/static/gentelella/js/base.js +347 -83
- djgentelella/static/gentelella/js/custom.js +6 -1
- djgentelella/static/gentelella/js/datatables.js +15 -0
- djgentelella/static/gentelella/js/digital_signature_update.js +29 -0
- djgentelella/static/gentelella/js/obj_api_management.js +403 -344
- djgentelella/static/gentelella/js/widgets.js +10 -1
- djgentelella/static/vendors/timeline/css/timeline.css +9 -5
- djgentelella/static/vendors/timeline/js/timeline.js +1 -1
- djgentelella/templates/forms/as_grid.html +2 -2
- djgentelella/templates/forms/as_inline.html +3 -5
- djgentelella/templates/gentelella/app/sidebar.html +16 -13
- djgentelella/templates/gentelella/digital_signature/update_signature_settings.html +45 -0
- djgentelella/templates/gentelella/registration/reset_done.html +24 -0
- djgentelella/templates/gentelella/widgets/digital_signature.html +47 -11
- djgentelella/trash/api.py +77 -0
- djgentelella/trash/filterset.py +20 -0
- djgentelella/trash/serializer.py +45 -0
- djgentelella/urls.py +13 -2
- djgentelella/views/select2autocomplete.py +40 -0
- djgentelella/widgets/core.py +6 -5
- djgentelella/widgets/digital_signature.py +5 -21
- djgentelella/widgets/selects.py +47 -0
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/METADATA +2 -2
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/RECORD +66 -48
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/AUTHORS +0 -0
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/LICENSE.txt +0 -0
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/WHEEL +0 -0
- {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/top_level.txt +0 -0
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
{% endif %}
|
|
15
15
|
{% for column in form.grid %}
|
|
16
16
|
<div class="row">{% for row in column %}
|
|
17
|
-
<div class="col">{% for field in row %}
|
|
17
|
+
<div class="col">{% for field, errors in row %}
|
|
18
18
|
<div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }} asgrid gtformfield" {% else %}
|
|
19
19
|
class="mb-3 asgrid gtformfield"
|
|
20
20
|
{% endif %}
|
|
21
21
|
{% endwith %}>
|
|
22
|
-
{{ errors }}
|
|
22
|
+
{% if errors %}{{ errors }}{% endif %}
|
|
23
23
|
{% if field.label %}{{ field.label_tag }}{% endif %}
|
|
24
24
|
{{ field }}
|
|
25
25
|
{% if field.help_text %}
|
|
@@ -21,15 +21,13 @@
|
|
|
21
21
|
|
|
22
22
|
{{ field }}
|
|
23
23
|
{% if field.help_text %}
|
|
24
|
-
{% if forloop.last %}
|
|
25
|
-
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
26
|
-
{% endif %}
|
|
27
|
-
|
|
28
24
|
<div class="feedback text-info" {% if field.auto_id %} id="{{ field.auto_id }}_helptext" {% endif %}>
|
|
29
25
|
{{ field.help_text|safe }}
|
|
30
26
|
</div>
|
|
31
27
|
{% endif %}
|
|
32
|
-
|
|
28
|
+
{% if forloop.last %}
|
|
29
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
30
|
+
{% endif %}
|
|
33
31
|
</div>
|
|
34
32
|
{% endfor %}
|
|
35
33
|
{% if not fields and not errors %}
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
{% load gentelellamenu gtsettings %}
|
|
2
|
+
|
|
2
3
|
<div class="left_col overflow-hidden">
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
<div class="navbar nav_title mb-4" style="border: 0;">
|
|
4
6
|
<a href="{% url 'home' %}" class="site_title"><i class="{% get_settings 'sidebar_icon' 'fa fa-spinner' %}"></i> <span>{% get_settings 'sidebar_title' 'My Site' %}</span></a>
|
|
5
7
|
</div>
|
|
6
8
|
|
|
9
|
+
<div class="clearfix"></div>
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
<!-- sidebar menu -->
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
<div id="sidebar-menu" class="main_menu_side d-print-none main_menu">
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
{% sidebar_menu %}
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
</div>
|
|
18
|
+
<!-- /sidebar menu -->
|
|
15
19
|
|
|
16
|
-
</div>
|
|
17
|
-
<!-- /sidebar menu -->
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
<!-- /menu footer buttons -->
|
|
22
|
+
<div class="sidebar-footer d-print-none nohidden">
|
|
23
|
+
{% footer_sidebar_menu %}
|
|
24
|
+
</div>
|
|
25
|
+
<!-- /menu footer buttons -->
|
|
26
|
+
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{% extends 'gentelella/base.html' %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
{% load static %}
|
|
4
|
+
{% load gtsettings %}
|
|
5
|
+
{% block title %} {% trans 'Signature settings' %} {% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block pre_head %}
|
|
8
|
+
{% endblock %}
|
|
9
|
+
|
|
10
|
+
{% block content %}
|
|
11
|
+
<div class="card mt-2">
|
|
12
|
+
<div class="card-body">
|
|
13
|
+
|
|
14
|
+
<div class="card-title titles">
|
|
15
|
+
<h1 class="text-center">
|
|
16
|
+
{% trans 'Signature settings' %}
|
|
17
|
+
</h1>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="row justify-content-center my-4">
|
|
21
|
+
<div class="col-lg-6 col-md-10 col-12">
|
|
22
|
+
|
|
23
|
+
<form action="" id="form_signature" method="POST" enctype="multipart/form-data">
|
|
24
|
+
{% csrf_token %}
|
|
25
|
+
{{ form.as_grid }}
|
|
26
|
+
|
|
27
|
+
<div class="text-center">
|
|
28
|
+
<button type="submit" name="action" value="update" class="btn btn-success btn-sm">
|
|
29
|
+
{% trans 'Save' %}
|
|
30
|
+
<i class="fa fa-floppy-o" aria-hidden="true"></i>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
</form>
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
{% endblock %}
|
|
42
|
+
|
|
43
|
+
{% block js %}
|
|
44
|
+
<script src="{% static 'gentelella/js/digital_signature_update.js' %}?v={% get_version %}"></script>
|
|
45
|
+
{% endblock %}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{% extends 'gentelella/base.html' %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
|
|
4
|
+
{% block body_class %}login{% endblock body_class %}
|
|
5
|
+
{% block body %}
|
|
6
|
+
|
|
7
|
+
<div class="main_container">
|
|
8
|
+
|
|
9
|
+
<div class="col-md-8 offset-md-2">
|
|
10
|
+
<div class="col-middle">
|
|
11
|
+
<div class="text-center ">
|
|
12
|
+
<h1>{% trans 'Password changed' %}</h1>
|
|
13
|
+
<p>{% trans "You updated correctly your password please login again." %}</p>
|
|
14
|
+
<br>
|
|
15
|
+
<a href="/"> {% trans 'Go to home' %}</a>
|
|
16
|
+
{% include 'gentelella/registration/footer.html' %}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
{% endblock %}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
{% endif %}
|
|
14
14
|
|
|
15
15
|
{# digital signature card #}
|
|
16
|
-
<div class="col-12 col-md-4">
|
|
16
|
+
<div class="col-12 col-md-4 digital-signature-card" id="digital-signature-card">
|
|
17
17
|
|
|
18
18
|
<div id="container_select_card_tem">
|
|
19
19
|
<div class="d-flex justify-content-end">
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
<li>
|
|
126
126
|
<a class="small"
|
|
127
127
|
title="{% trans 'Run Firmador Libre' %}"
|
|
128
|
-
href="firmador:
|
|
128
|
+
href="firmador:localhost" data-widget="FirmadorCORS" data-port="3516">
|
|
129
129
|
{% trans 'Run app' %}
|
|
130
130
|
<i class="fa fa-cog" aria-hidden="true"></i>
|
|
131
131
|
</a>
|
|
@@ -140,13 +140,41 @@
|
|
|
140
140
|
</div>
|
|
141
141
|
|
|
142
142
|
{# preview file #}
|
|
143
|
-
<div class="col-12 col-md-8">
|
|
143
|
+
<div class="col-12 col-md-8" id="signature-viewer">
|
|
144
144
|
<div class="pdf-signature-container" id="pdf-signature-container">
|
|
145
145
|
{# actions for change page#}
|
|
146
146
|
<div class="my-3 d-flex align-items-center justify-content-evenly">
|
|
147
147
|
<input type="hidden" name="{{ widget.name }}_page_number" class="page_number">
|
|
148
|
-
<input type="hidden"
|
|
149
|
-
{% if widget.value != None %}
|
|
148
|
+
<input type="hidden" name="{{ widget.name }}"
|
|
149
|
+
{% if widget.value != None %}
|
|
150
|
+
value="{{ widget.value|stringformat:'s' }}"{% endif %} {% include "gentelella/widgets/attrs.html" %}>
|
|
151
|
+
|
|
152
|
+
{# select card #}
|
|
153
|
+
<div id="container_select_card_expanded"
|
|
154
|
+
class="container_select_card_expanded hide d-flex flex-row align-items-center px-2 py-1 rounded shadow-sm bg-white"
|
|
155
|
+
style="z-index: 2000; position: sticky; top: 0; min-height: 42px;">
|
|
156
|
+
|
|
157
|
+
<div id="container_select_card_expanded_hide"
|
|
158
|
+
class="container_select_card_expanded_hide hide d-flex flex-row align-items-center gap-2 flex-grow-1">
|
|
159
|
+
<label for="select_card_{{ widget.attrs.id }}" class="fw-semibold mb-0 me-2 small"
|
|
160
|
+
style="white-space: nowrap;">
|
|
161
|
+
{% trans 'Choose your signature card' %}
|
|
162
|
+
</label>
|
|
163
|
+
<div class="select-container m-0 p-0" style="width: 220px; max-width: 380px;">
|
|
164
|
+
<select id="select_card_expand{{ widget.attrs.id }}"
|
|
165
|
+
class="form-select form-select-sm select_card px-2"
|
|
166
|
+
style="font-size: 0.9em; padding-left: 32px;"
|
|
167
|
+
name="{{ widget.name }}_select"></select>
|
|
168
|
+
</div>
|
|
169
|
+
<button class="btn btn-primary btn-sm px-2 py-1 ms-2 formadd btn_signer"
|
|
170
|
+
type="button" style="font-size: 0.85em;">
|
|
171
|
+
{% trans 'Sign' %}
|
|
172
|
+
</button>
|
|
173
|
+
</div>
|
|
174
|
+
<i class="fa fa-refresh text-muted fs-6 cursor-pointer btn_signer_refresh ms-2"
|
|
175
|
+
title="{% trans 'Reload' %}" aria-hidden="true" style="font-size: 1.1em;"></i>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
150
178
|
|
|
151
179
|
{# button to change page #}
|
|
152
180
|
<div>
|
|
@@ -159,14 +187,21 @@
|
|
|
159
187
|
</div>
|
|
160
188
|
|
|
161
189
|
{# number of pages #}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
<
|
|
190
|
+
|
|
191
|
+
<div class="d-flex align-items-center gap-2">
|
|
192
|
+
<button id="btn_expand" type="button" class="btn btn-light px-3 shadow-sm border btn-sm prev btn_expand"
|
|
193
|
+
title="{% trans 'Expand' %} ">
|
|
194
|
+
<i class="fa fa-arrows-alt" aria-hidden="true"></i>
|
|
195
|
+
</button>
|
|
196
|
+
<div class="border rounded px-3 py-1 shadow-sm">
|
|
197
|
+
<i class="fa fa-file-o me-1" aria-hidden="true" title="{% trans 'Page' %}"></i>
|
|
198
|
+
<span class="page_num"></span> / <span class="page_count"></span>
|
|
199
|
+
</div>
|
|
165
200
|
</div>
|
|
166
201
|
</div>
|
|
167
202
|
|
|
168
203
|
{# preview document #}
|
|
169
|
-
<div class="d-flex justify-content-center canvas_container">
|
|
204
|
+
<div class="d-flex justify-content-center canvas_container mt-10">
|
|
170
205
|
<div class="sub_canvas_container">
|
|
171
206
|
<div class="signature">
|
|
172
207
|
<div class="image"></div>
|
|
@@ -177,7 +212,7 @@
|
|
|
177
212
|
</div>
|
|
178
213
|
|
|
179
214
|
{# warning message #}
|
|
180
|
-
<div class="text-muted text-center my-3">
|
|
215
|
+
<div class="text-muted text-center my-3 expand-help-message" id="expand-help-message">
|
|
181
216
|
<p class="small">
|
|
182
217
|
<i class="fa fa-exclamation-circle me-2" aria-hidden="true"></i>
|
|
183
218
|
{% trans "Please go to the last page, in the signature space, try to place your signature vertically centered." %}
|
|
@@ -187,7 +222,8 @@
|
|
|
187
222
|
</div>
|
|
188
223
|
</div>
|
|
189
224
|
{# loading #}
|
|
190
|
-
<div class="modal fade" id="loading_sign" style="background-color: rgba(0, 0, 0, 0.3);" data-bs-backdrop="static"
|
|
225
|
+
<div class="modal fade" id="loading_sign" style="background-color: rgba(0, 0, 0, 0.3);" data-bs-backdrop="static"
|
|
226
|
+
data-bs-keyboard="false" tabindex="-1"
|
|
191
227
|
aria-hidden="true">
|
|
192
228
|
<div class="modal-dialog modal-dialog-centered">
|
|
193
229
|
<div class="modal-content bg-transparent border-0">
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from djgentelella.objectmanagement import AuthAllPermBaseObjectManagement
|
|
2
|
+
from djgentelella.trash.serializer import TrashSerializer, TrashDataTableSerializer
|
|
3
|
+
from djgentelella.models import Trash
|
|
4
|
+
from djgentelella.trash.filterset import TrashFilter
|
|
5
|
+
from rest_framework.filters import SearchFilter, OrderingFilter
|
|
6
|
+
from rest_framework.pagination import LimitOffsetPagination
|
|
7
|
+
from django_filters.rest_framework import DjangoFilterBackend
|
|
8
|
+
from rest_framework.decorators import action
|
|
9
|
+
from rest_framework.response import Response
|
|
10
|
+
from rest_framework import status
|
|
11
|
+
from django.shortcuts import get_object_or_404
|
|
12
|
+
from django.utils.translation import gettext_lazy as _
|
|
13
|
+
from djgentelella.history.utils import add_log, HARD_DELETION, RESTORE
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TrashViewSet(AuthAllPermBaseObjectManagement):
|
|
17
|
+
serializer_class = {
|
|
18
|
+
"list": TrashDataTableSerializer,
|
|
19
|
+
"destroy": TrashSerializer,
|
|
20
|
+
"create": None,
|
|
21
|
+
"update": None,
|
|
22
|
+
"restore": None,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
perms = {
|
|
26
|
+
"list": ["djgentelella.view_trash"],
|
|
27
|
+
"create": ["djgentelella.add_trash"],
|
|
28
|
+
"update": ["djgentelella.change_trash"],
|
|
29
|
+
"destroy": ["djgentelella.delete_trash"],
|
|
30
|
+
"restore": ["djgentelella.change_trash"],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
queryset = Trash.objects.all()
|
|
34
|
+
pagination_class = LimitOffsetPagination
|
|
35
|
+
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
|
|
36
|
+
search_fields = ["content_type__model", "object_id", "deleted_by__username"]
|
|
37
|
+
filterset_class = TrashFilter
|
|
38
|
+
ordering_fields = ["created_at"]
|
|
39
|
+
ordering = ("-created_at",)
|
|
40
|
+
|
|
41
|
+
def perform_destroy(self, instance):
|
|
42
|
+
add_log(
|
|
43
|
+
self.request.user,
|
|
44
|
+
instance,
|
|
45
|
+
HARD_DELETION,
|
|
46
|
+
instance._meta.verbose_name.title().lower(),
|
|
47
|
+
[],
|
|
48
|
+
change_message=_("Hard deleted"),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
instance.hard_delete()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@action(detail=True, methods=["POST"])
|
|
55
|
+
def restore(self, request, org_pk=None, pk=None):
|
|
56
|
+
try:
|
|
57
|
+
trash = get_object_or_404(Trash, pk=pk)
|
|
58
|
+
|
|
59
|
+
if not trash:
|
|
60
|
+
return Response({"result": False, "detail": _("This registry of trash does not exist.")},
|
|
61
|
+
status=status.HTTP_400_BAD_REQUEST)
|
|
62
|
+
|
|
63
|
+
add_log(
|
|
64
|
+
self.request.user,
|
|
65
|
+
trash.content_object,
|
|
66
|
+
RESTORE,
|
|
67
|
+
"trash",
|
|
68
|
+
[],
|
|
69
|
+
change_message=_("Restored"),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
trash.restore()
|
|
73
|
+
|
|
74
|
+
return Response({"result": True, "detail": _("The registry was successfully restored.")}, status=status.HTTP_200_OK)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
print(str(e))
|
|
77
|
+
return Response({"result": False, "detail": _("The registry could not be restored.")}, status=status.HTTP_400_BAD_REQUEST)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from django.contrib.contenttypes.models import ContentType
|
|
2
|
+
from django_filters import DateTimeFromToRangeFilter
|
|
3
|
+
from django_filters.rest_framework import FilterSet
|
|
4
|
+
from djgentelella.fields.drfdatetime import DateTimeRangeTextWidget
|
|
5
|
+
|
|
6
|
+
from djgentelella.models import Trash
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TrashFilter(FilterSet):
|
|
10
|
+
created_at = DateTimeFromToRangeFilter(
|
|
11
|
+
widget=DateTimeRangeTextWidget(attrs={"placeholder": "DD/MM/YYYY/"})
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
class Meta:
|
|
15
|
+
model = Trash
|
|
16
|
+
fields = {
|
|
17
|
+
'content_type__model': ['exact'],
|
|
18
|
+
'object_id': ['exact'],
|
|
19
|
+
'created_at': ['exact'],
|
|
20
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
|
+
from djgentelella.models import Trash
|
|
4
|
+
from djgentelella.serializers import GTDateTimeField
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TrashSerializer(serializers.ModelSerializer):
|
|
8
|
+
actions = serializers.SerializerMethodField()
|
|
9
|
+
object_id = serializers.IntegerField(read_only=True)
|
|
10
|
+
model_name = serializers.SerializerMethodField()
|
|
11
|
+
created_at = GTDateTimeField()
|
|
12
|
+
deleted_by = serializers.SerializerMethodField()
|
|
13
|
+
|
|
14
|
+
def get_actions(self, obj):
|
|
15
|
+
user = self.context["request"].user
|
|
16
|
+
return {
|
|
17
|
+
"restore": user.has_perm("djgentelella.update_trash"),
|
|
18
|
+
"destroy": user.has_perm("djgentelella.delete_trash"),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
def get_model_name(self, obj):
|
|
22
|
+
if obj.content_object is None:
|
|
23
|
+
return _("Deleted object")
|
|
24
|
+
|
|
25
|
+
if obj.content_type.model:
|
|
26
|
+
return obj.content_type.model
|
|
27
|
+
|
|
28
|
+
return "-"
|
|
29
|
+
|
|
30
|
+
def get_deleted_by(self, obj):
|
|
31
|
+
if obj.deleted_by:
|
|
32
|
+
return str(obj.deleted_by)
|
|
33
|
+
return "-"
|
|
34
|
+
|
|
35
|
+
class Meta:
|
|
36
|
+
model = Trash
|
|
37
|
+
fields = "__all__"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TrashDataTableSerializer(serializers.Serializer):
|
|
41
|
+
data = serializers.ListField(child=TrashSerializer(), required=True)
|
|
42
|
+
draw = serializers.IntegerField(required=True)
|
|
43
|
+
recordsFiltered = serializers.IntegerField(required=True)
|
|
44
|
+
recordsTotal = serializers.IntegerField(required=True)
|
|
45
|
+
|
djgentelella/urls.py
CHANGED
|
@@ -13,9 +13,12 @@ from djgentelella.notification.base import NotificacionAPIView, NotificationView
|
|
|
13
13
|
from djgentelella.permission_management import views as permissions
|
|
14
14
|
from djgentelella.widgets.helper import HelperWidgetView
|
|
15
15
|
from djgentelella.wysiwyg import views as wysiwyg
|
|
16
|
+
from djgentelella.firmador_digital import views as firmador_digital
|
|
16
17
|
from .groute import routes
|
|
17
18
|
from .templatetags.gtsettings import get_version
|
|
18
19
|
from .views import auth
|
|
20
|
+
from .trash.api import TrashViewSet
|
|
21
|
+
from .history.api import HistoryViewSet
|
|
19
22
|
|
|
20
23
|
auth_urls = [
|
|
21
24
|
path('accounts/login/', auth.GentelellaLoginView.as_view(), name="login"),
|
|
@@ -45,7 +48,7 @@ auth_urls = [
|
|
|
45
48
|
template_name='gentelella/registration/password_reset_confirm.html'
|
|
46
49
|
), name='password_reset_confirm'),
|
|
47
50
|
path('accounts/reset/done/', auth_views.PasswordResetDoneView.as_view(
|
|
48
|
-
template_name='gentelella/registration/
|
|
51
|
+
template_name='gentelella/registration/reset_done.html'
|
|
49
52
|
), name="password_reset_complete")
|
|
50
53
|
]
|
|
51
54
|
wysiwyg_urls = [
|
|
@@ -55,6 +58,7 @@ wysiwyg_urls = [
|
|
|
55
58
|
name="tinymce_upload_video"),
|
|
56
59
|
]
|
|
57
60
|
|
|
61
|
+
|
|
58
62
|
def import_module_app_gt(app, name):
|
|
59
63
|
try:
|
|
60
64
|
__import__(app + '.' + name)
|
|
@@ -71,6 +75,11 @@ for app in settings.INSTALLED_APPS:
|
|
|
71
75
|
|
|
72
76
|
router = DefaultRouter()
|
|
73
77
|
router.register('notificationtableview', NotificationViewSet, 'api-notificationtable')
|
|
78
|
+
router_trash = DefaultRouter()
|
|
79
|
+
router_trash.register("api_trash", TrashViewSet, basename="api-trash")
|
|
80
|
+
history_router = DefaultRouter()
|
|
81
|
+
history_router.register("api_history", HistoryViewSet, basename="api-history")
|
|
82
|
+
|
|
74
83
|
|
|
75
84
|
base_urlpatterns = [
|
|
76
85
|
re_path('gtapis/', include(routes.urls)),
|
|
@@ -87,6 +96,9 @@ base_urlpatterns = [
|
|
|
87
96
|
re_path('^notification/list/$', notification_list_view,
|
|
88
97
|
name="notification_list"),
|
|
89
98
|
path('tableapi/', include(router.urls)),
|
|
99
|
+
path("update_config/", firmador_digital.update_signature_settings, name="signature_config"),
|
|
100
|
+
path("api/trash/", include(router_trash.urls)),
|
|
101
|
+
path("api/history/", include(history_router.urls)),
|
|
90
102
|
]
|
|
91
103
|
|
|
92
104
|
permission_management_urls = [
|
|
@@ -96,7 +108,6 @@ permission_management_urls = [
|
|
|
96
108
|
name="permissionsmanagement-list"),
|
|
97
109
|
path('permissionsmanagement/save', permissions.save_permcategorymanagement,
|
|
98
110
|
name="permcategorymanagement-save"),
|
|
99
|
-
|
|
100
111
|
]
|
|
101
112
|
|
|
102
113
|
urlpatterns = auth_urls + base_urlpatterns + wysiwyg_urls + permission_management_urls
|
|
@@ -59,6 +59,29 @@ class GSerializerBase(serializers.Serializer):
|
|
|
59
59
|
selected = serializers.SerializerMethodField()
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
class GSerializerImgBase(serializers.Serializer):
|
|
63
|
+
def get_id(self, obj):
|
|
64
|
+
return self.view.get_id_display(obj)
|
|
65
|
+
|
|
66
|
+
def get_text(self, obj):
|
|
67
|
+
return self.view.get_text_display(obj)
|
|
68
|
+
|
|
69
|
+
def get_url(self, obj):
|
|
70
|
+
return self.view.get_url(obj)
|
|
71
|
+
|
|
72
|
+
def get_selected(self, obj):
|
|
73
|
+
return self.view.get_selected_display(obj)
|
|
74
|
+
|
|
75
|
+
def get_disabled(self, obj):
|
|
76
|
+
return self.view.get_disabled_display(obj)
|
|
77
|
+
|
|
78
|
+
id = serializers.SerializerMethodField()
|
|
79
|
+
text = serializers.SerializerMethodField()
|
|
80
|
+
url = serializers.SerializerMethodField()
|
|
81
|
+
disabled = serializers.SerializerMethodField()
|
|
82
|
+
selected = serializers.SerializerMethodField()
|
|
83
|
+
|
|
84
|
+
|
|
62
85
|
class BaseSelect2View(generics.ListAPIView, viewsets.GenericViewSet):
|
|
63
86
|
model = None
|
|
64
87
|
fields = []
|
|
@@ -165,3 +188,20 @@ class BaseSelect2View(generics.ListAPIView, viewsets.GenericViewSet):
|
|
|
165
188
|
|
|
166
189
|
def get_disabled_display(self, obj):
|
|
167
190
|
return False
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class BaseSelectImg2View(BaseSelect2View):
|
|
194
|
+
model = None
|
|
195
|
+
fields = []
|
|
196
|
+
pagination_class = GPaginator
|
|
197
|
+
serializer_class = GSerializerImgBase
|
|
198
|
+
|
|
199
|
+
def get_serializer_class(self):
|
|
200
|
+
class S(self.serializer_class, serializers.ModelSerializer):
|
|
201
|
+
view = self
|
|
202
|
+
|
|
203
|
+
class Meta:
|
|
204
|
+
model = self.model
|
|
205
|
+
fields = ['id', 'text', 'url', 'disabled', 'selected']
|
|
206
|
+
|
|
207
|
+
return S
|
djgentelella/widgets/core.py
CHANGED
|
@@ -194,11 +194,12 @@ class FileInput(DJFileInput):
|
|
|
194
194
|
def value_from_datadict(self, data, files, name):
|
|
195
195
|
dev = None
|
|
196
196
|
token = data.get(name)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
197
|
+
if token:
|
|
198
|
+
load_token = json.loads(token)
|
|
199
|
+
tmpupload = ChunkedUpload.objects.filter(upload_id=load_token['token']).first()
|
|
200
|
+
if tmpupload:
|
|
201
|
+
dev = tmpupload.get_uploaded_file()
|
|
202
|
+
tmpupload.delete()
|
|
202
203
|
return dev
|
|
203
204
|
|
|
204
205
|
def value_omitted_from_data(self, data, files, name):
|
|
@@ -22,15 +22,13 @@ class DigitalSignatureInput(HiddenInput, ValueDSParser):
|
|
|
22
22
|
def is_hidden(self):
|
|
23
23
|
return True
|
|
24
24
|
|
|
25
|
-
def __init__(self, attrs=None, extraskwargs=True,
|
|
25
|
+
def __init__(self, attrs=None, extraskwargs=True,
|
|
26
26
|
title=None, render_basename=None, icon_url=None,
|
|
27
27
|
extra_render_args=None,
|
|
28
28
|
default_page="first"):
|
|
29
29
|
attrs = attrs or {}
|
|
30
|
-
attrs['data-ws-url'] = ws_url
|
|
31
|
-
attrs['cors'] = cors
|
|
32
30
|
attrs['title'] = title
|
|
33
|
-
|
|
31
|
+
attrs['data-ws-url'] = settings.FIRMADOR_WS_URL
|
|
34
32
|
self.render_basename = render_basename
|
|
35
33
|
self.icon_url = icon_url
|
|
36
34
|
self.extra_render_args = extra_render_args or []
|
|
@@ -40,31 +38,17 @@ class DigitalSignatureInput(HiddenInput, ValueDSParser):
|
|
|
40
38
|
if self.render_basename is None:
|
|
41
39
|
logger.warning(
|
|
42
40
|
"No base name for DigitalSignatureInput, this will generate a 500 error in the future")
|
|
43
|
-
self.validate_attrs(attrs,
|
|
41
|
+
self.validate_attrs(attrs, default_page)
|
|
44
42
|
|
|
45
43
|
if extraskwargs:
|
|
46
44
|
attrs = update_kwargs(
|
|
47
45
|
attrs, self.__class__.__name__, )
|
|
48
46
|
super().__init__(attrs)
|
|
49
47
|
|
|
50
|
-
def validate_attrs(self, attrs,
|
|
51
|
-
if not ws_url:
|
|
52
|
-
if not ws_url and settings.FIRMADOR_WS_URL:
|
|
53
|
-
attrs['data-ws-url'] = settings.FIRMADOR_WS_URL
|
|
54
|
-
else:
|
|
55
|
-
raise ValueError(
|
|
56
|
-
"Must provide a ws_url in attrs of DigitalSignatureInput.")
|
|
57
|
-
|
|
58
|
-
if not cors:
|
|
59
|
-
if not cors and settings.FIRMADOR_CORS:
|
|
60
|
-
attrs['cors'] = settings.FIRMADOR_CORS
|
|
61
|
-
else:
|
|
62
|
-
raise ValueError(
|
|
63
|
-
"Must provide a cors in attrs of DigitalSignatureInput.")
|
|
48
|
+
def validate_attrs(self, attrs, default_page):
|
|
64
49
|
|
|
65
50
|
if isinstance(default_page, int) and default_page > 0:
|
|
66
|
-
attrs['data-default-page'] = str(
|
|
67
|
-
default_page)
|
|
51
|
+
attrs['data-default-page'] = str(default_page)
|
|
68
52
|
elif default_page in ["first", "last"]:
|
|
69
53
|
attrs['data-default-page'] = default_page
|
|
70
54
|
else:
|
djgentelella/widgets/selects.py
CHANGED
|
@@ -80,3 +80,50 @@ def AutocompleteSelectMultiple(url, url_suffix="-list", url_args=[], url_kwargs=
|
|
|
80
80
|
extra_url_args = url_args.copy()
|
|
81
81
|
|
|
82
82
|
return AutocompleteSelectMultiple
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def AutocompleteSelectImage(url, url_suffix="-list", url_args=[], url_kwargs={},
|
|
86
|
+
attrs={}):
|
|
87
|
+
class ImgAutocompleteSelect(AutocompleteSelectBase):
|
|
88
|
+
baseurl = url + url_suffix
|
|
89
|
+
extra_attrs = attrs.copy()
|
|
90
|
+
extra_url_kwargs = url_kwargs.copy()
|
|
91
|
+
extra_url_args = url_args.copy()
|
|
92
|
+
|
|
93
|
+
def __init__(self, attrs=None, choices=(), extraskwargs=False):
|
|
94
|
+
if attrs is None:
|
|
95
|
+
attrs = {}
|
|
96
|
+
attrs = update_kwargs(attrs, 'AutocompleteSelectImage',
|
|
97
|
+
base_class='form-control ')
|
|
98
|
+
if 'templateresult' not in attrs:
|
|
99
|
+
attrs['data-templateresult'] = 'decore_img_select2'
|
|
100
|
+
super().__init__(attrs=attrs, choices=choices, extraskwargs=extraskwargs)
|
|
101
|
+
|
|
102
|
+
def optgroups(self, name, value, attrs=None):
|
|
103
|
+
return super().optgroups(name, value, attrs=attrs)
|
|
104
|
+
|
|
105
|
+
return ImgAutocompleteSelect
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def AutocompleteSelectMultipleImage(url, url_suffix="-list", url_args=[], url_kwargs={},
|
|
109
|
+
attrs={}):
|
|
110
|
+
class ImgAutocompleteSelectMultiple(AutocompleteSelectMultipleBase):
|
|
111
|
+
baseurl = url + url_suffix
|
|
112
|
+
extra_attrs = attrs.copy()
|
|
113
|
+
extra_url_kwargs = url_kwargs.copy()
|
|
114
|
+
extra_url_args = url_args.copy()
|
|
115
|
+
|
|
116
|
+
def __init__(self, attrs=None, choices=(), extraskwargs=True):
|
|
117
|
+
if attrs is None:
|
|
118
|
+
attrs = {}
|
|
119
|
+
attrs['data-widget'] = 'AutocompleteSelectMultipleImage'
|
|
120
|
+
attrs['class'] = "form-control select2_multiple"
|
|
121
|
+
if 'templateresult' not in attrs:
|
|
122
|
+
attrs['data-templateresult'] = 'decore_img_select2'
|
|
123
|
+
if self.baseurl is None:
|
|
124
|
+
raise ValueError('Autocomplete requires baseurl to work')
|
|
125
|
+
else:
|
|
126
|
+
self.baseurl = self.baseurl
|
|
127
|
+
super(SelectMultiple, self).__init__(attrs, choices=choices)
|
|
128
|
+
|
|
129
|
+
return ImgAutocompleteSelectMultiple
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: djgentelella
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Help building extra widgets for forms and speciall methods to render forms in templates
|
|
5
5
|
Author-email: Solvosoft <info@solvosoft.com>
|
|
6
6
|
Maintainer-email: Luis Zarate Montero <luis.zarate@solvosoft.com>
|
|
@@ -387,7 +387,7 @@ Requires-Dist: uvicorn==0.32.1; extra == "firmador"
|
|
|
387
387
|
Requires-Dist: uvicorn-worker==0.2.0; extra == "firmador"
|
|
388
388
|
Requires-Dist: channels==4.2.0; extra == "firmador"
|
|
389
389
|
Requires-Dist: wsproto==1.2.0; extra == "firmador"
|
|
390
|
-
Requires-Dist: requests==2.32.
|
|
390
|
+
Requires-Dist: requests==2.32.4; extra == "firmador"
|
|
391
391
|
Provides-Extra: test
|
|
392
392
|
|
|
393
393
|
Django Gentelella widgets
|