Commit d7541a252f958bd3cd08e093cb520a38fbd92490
1 parent
d4196f2e
Exists in
master
and in
3 other branches
Adding drag and drop in themes
Showing
11 changed files
with
276 additions
and
7 deletions
Show diff stats
amadeus/static/css/base/amadeus.css
... | ... | @@ -960,3 +960,24 @@ ul, li { |
960 | 960 | |
961 | 961 | /* subjects app ends */ |
962 | 962 | |
963 | +/* Themes */ | |
964 | +.page_selector h4 { | |
965 | + margin-bottom: 20px; | |
966 | + border-bottom: 1px solid #e5e5e5; | |
967 | +} | |
968 | +.page_selector:hover, .page_selector:focus { | |
969 | + text-decoration: none; | |
970 | +} | |
971 | + | |
972 | +.filedrag{ | |
973 | + display: none; | |
974 | + font-weight: bold; | |
975 | + text-align: center; | |
976 | + padding: 1em 0; | |
977 | + margin: 1em 0; | |
978 | + color: #555; | |
979 | + border: 2px dashed #555; | |
980 | + border-radius: 7px; | |
981 | + cursor: pointer; | |
982 | +} | |
983 | +/* End Themes */ | |
963 | 984 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +// check if browser supports drag n drop | |
2 | +// call initialization file | |
3 | +if (window.File && window.FileList && window.FileReader) { | |
4 | + Init(); | |
5 | +} | |
6 | + | |
7 | +// initialize | |
8 | +function Init() { | |
9 | + var small = $("#id_small_logo"), | |
10 | + large = $("#id_large_logo"), | |
11 | + filedrag = $(".filedrag"), | |
12 | + common = $(".common-file-input"); | |
13 | + | |
14 | + // file select | |
15 | + small.on("change", FileSelectHandler); | |
16 | + large.on("change", FileSelectHandler); | |
17 | + | |
18 | + // is XHR2 available? | |
19 | + var xhr = new XMLHttpRequest(); | |
20 | + if (xhr.upload) { | |
21 | + // file drop | |
22 | + filedrag.on("drop", FileSelectHandler); | |
23 | + filedrag.attr('style', 'display:block'); | |
24 | + common.attr('style', 'display:none'); | |
25 | + } | |
26 | +} | |
27 | + | |
28 | +// file selection | |
29 | +function FileSelectHandler(e) { | |
30 | + var files = e.target.files || e.dataTransfer.files, | |
31 | + parent = $(e.target.offsetParent); | |
32 | + | |
33 | + // process all File objects | |
34 | + for (var i = 0, f; f = files[i]; i++) { | |
35 | + parent.find('.filedrag').html(f.name); | |
36 | + } | |
37 | +} | |
0 | 38 | \ No newline at end of file | ... | ... |
amadeus/templates/base.html
... | ... | @@ -115,7 +115,7 @@ |
115 | 115 | <ul class="submenu"> |
116 | 116 | <li><a href="{% url 'mailsender:update' %}">{% trans 'Mail Sender' %}</a></li> |
117 | 117 | <li><a href="{% url 'security:update' %}">{% trans 'Security' %}</a></li> |
118 | - <li><a href="{% url 'categories:index' %}">{% trans 'Theme' %}</a></li> | |
118 | + <li><a href="{% url 'themes:manage' %}">{% trans 'Theme' %}</a></li> | |
119 | 119 | </ul> |
120 | 120 | </div> |
121 | 121 | </div> | ... | ... |
amadeus/urls.py
... | ... | @@ -29,6 +29,7 @@ urlpatterns = [ |
29 | 29 | url(r'^subjects/', include('subjects.urls', namespace = 'subjects')), |
30 | 30 | url(r'^mailsender/', include('mailsender.urls', namespace = 'mailsender')), |
31 | 31 | url(r'^security/', include('security.urls', namespace = 'security')), |
32 | + url(r'^themes/', include('themes.urls', namespace = 'themes')), | |
32 | 33 | #API |
33 | 34 | url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), |
34 | 35 | #S3Direct | ... | ... |
security/templates/security/update.html
... | ... | @@ -16,10 +16,25 @@ |
16 | 16 | <form method="post" action="" enctype="multipart/form-data"> |
17 | 17 | {% csrf_token %} |
18 | 18 | {% for field in form %} |
19 | - <div class="checkbox"> | |
20 | - <label for="{{ field.auto_id }}"> | |
21 | - {% render_field field %} {{field.label}} | |
22 | - </label> | |
19 | + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput"> | |
20 | + <div class="checkbox"> | |
21 | + <label for="{{ field.auto_id }}"> | |
22 | + {% render_field field %} {{field.label}} | |
23 | + </label> | |
24 | + </div> | |
25 | + <span id="helpBlock" class="help-block">{{ field.help_text }}</span> | |
26 | + {% if field.errors %} | |
27 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
28 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
29 | + <span aria-hidden="true">×</span> | |
30 | + </button> | |
31 | + <ul> | |
32 | + {% for error in field.errors %} | |
33 | + <li>{{ error }}</li> | |
34 | + {% endfor %} | |
35 | + </ul> | |
36 | + </div> | |
37 | + {% endif %} | |
23 | 38 | </div> |
24 | 39 | {% endfor %} |
25 | 40 | <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12"> | ... | ... |
themes/forms.py
... | ... | @@ -0,0 +1,88 @@ |
1 | +{% extends 'themes/index.html' %} | |
2 | + | |
3 | +{% load static i18n %} | |
4 | +{% load widget_tweaks %} | |
5 | +{% load django_bootstrap_breadcrumbs %} | |
6 | + | |
7 | +{% block breadcrumbs %} | |
8 | + {{ block.super }} | |
9 | + {% breadcrumb 'Basic Elements' 'themes:basic' %} | |
10 | +{% endblock %} | |
11 | + | |
12 | +{% block content %} | |
13 | + <div class="card"> | |
14 | + <div class="card-content"> | |
15 | + <div class="card-body"> | |
16 | + <a href="{% url 'themes:basic' %}" class="page_selector"><h4><i class="fa fa-angle-down"></i> {% trans 'Basic Elements' %}</h4></a> | |
17 | + | |
18 | + <form method="post" action="" enctype="multipart/form-data"> | |
19 | + {% csrf_token %} | |
20 | + {% for field in form %} | |
21 | + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput"> | |
22 | + {% if field.auto_id == 'id_small_logo' or field.auto_id == 'id_large_logo' %} | |
23 | + {% if field.field.required %} | |
24 | + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label> | |
25 | + {% else %} | |
26 | + <label for="{{ field.auto_id }}">{{ field.label }}</label> | |
27 | + {% endif %} | |
28 | + | |
29 | + {% render_field field class='form-control' %} | |
30 | + | |
31 | + <div class="input-group common-file-input"> | |
32 | + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}"> | |
33 | + <span class="input-group-btn input-group-sm"> | |
34 | + <button type="button" class="btn btn-fab btn-fab-mini"> | |
35 | + <i class="material-icons">attach_file</i> | |
36 | + </button> | |
37 | + </span> | |
38 | + </div> | |
39 | + <div class="filedrag">{% trans 'Click or drop files here' %}</div> | |
40 | + | |
41 | + {% elif field.auto_id == 'id_footer_note' %} | |
42 | + {% if field.field.required %} | |
43 | + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label> | |
44 | + {% else %} | |
45 | + <label for="{{ field.auto_id }}">{{ field.label }}</label> | |
46 | + {% endif %} | |
47 | + | |
48 | + {% render_field field class='form-control text_wysiwyg' %} | |
49 | + {% else %} | |
50 | + {% if field.field.required %} | |
51 | + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label> | |
52 | + {% else %} | |
53 | + <label for="{{ field.auto_id }}">{{ field.label }}</label> | |
54 | + {% endif %} | |
55 | + | |
56 | + {% render_field field class='form-control' %} | |
57 | + {% endif %} | |
58 | + | |
59 | + <span id="helpBlock" class="help-block">{{ field.help_text }}</span> | |
60 | + {% if field.errors %} | |
61 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
62 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
63 | + <span aria-hidden="true">×</span> | |
64 | + </button> | |
65 | + <ul> | |
66 | + {% for error in field.errors %} | |
67 | + <li>{{ error }}</li> | |
68 | + {% endfor %} | |
69 | + </ul> | |
70 | + </div> | |
71 | + {% endif %} | |
72 | + </div> | |
73 | + {% endfor %} | |
74 | + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12"> | |
75 | + <div class="text-center"> | |
76 | + <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-primary" /> | |
77 | + </div> | |
78 | + </div> | |
79 | + </form> | |
80 | + | |
81 | + <a href="{% url 'themes:css' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'CSS Selector' %}</h4></a> | |
82 | + </div> | |
83 | + </div> | |
84 | + </div> | |
85 | + <br clear="all" /> | |
86 | + <br clear="all" /> | |
87 | + <script type="text/javascript" src="{% static 'js/themes.js' %}"></script> | |
88 | +{% endblock %} | |
0 | 89 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +{% extends 'base.html' %} | |
2 | + | |
3 | +{% load static i18n %} | |
4 | +{% load widget_tweaks %} | |
5 | +{% load django_bootstrap_breadcrumbs %} | |
6 | + | |
7 | +{% block breadcrumbs %} | |
8 | + {{ block.super }} | |
9 | + {% breadcrumb 'Settings: Themes' 'themes:manage' %} | |
10 | +{% endblock %} | |
11 | + | |
12 | +{% block content %} | |
13 | + <div class="card"> | |
14 | + <div class="card-content"> | |
15 | + <div class="card-body"> | |
16 | + <a href="{% url 'themes:basic' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'Basic Elements' %}</h4></a> | |
17 | + <a href="{% url 'themes:css' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'CSS Selector' %}</h4></a> | |
18 | + </div> | |
19 | + </div> | |
20 | + </div> | |
21 | + <br clear="all" /> | |
22 | + <br clear="all" /> | |
23 | +{% endblock %} | |
0 | 24 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +from django.conf.urls import url | |
2 | +from . import views | |
3 | + | |
4 | +urlpatterns = [ | |
5 | + url(r'^$', views.IndexView.as_view(), name = 'manage'), | |
6 | + url(r'^basic_elements$', views.BasicElementsSettings.as_view(), name = 'basic'), | |
7 | + url(r'^css_selector$', views.CSSStyleSettings.as_view(), name = 'css'), | |
8 | +] | |
0 | 9 | \ No newline at end of file | ... | ... |
themes/views.py
1 | +from django.views import generic | |
1 | 2 | from django.shortcuts import render |
3 | +from django.contrib import messages | |
4 | +from django.core.urlresolvers import reverse, reverse_lazy | |
5 | +from django.utils.translation import ugettext_lazy as _ | |
2 | 6 | |
3 | -# Create your views here. | |
7 | +from braces import views as braces_mixins | |
8 | + | |
9 | +from .models import Themes | |
10 | +from .forms import BasicElemetsForm, CSSStyleForm | |
11 | + | |
12 | +class IndexView(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.TemplateView): | |
13 | + login_url = reverse_lazy("users:login") | |
14 | + redirect_field_name = 'next' | |
15 | + | |
16 | + template_name = 'themes/index.html' | |
17 | + | |
18 | + def get_context_data(self, **kwargs): | |
19 | + context = super(IndexView, self).get_context_data(**kwargs) | |
20 | + | |
21 | + context['title'] = _('Themes') | |
22 | + context['settings_menu_active'] = "settings_menu_active" | |
23 | + | |
24 | + return context | |
25 | + | |
26 | +class BasicElementsSettings(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.UpdateView): | |
27 | + login_url = reverse_lazy("users:login") | |
28 | + redirect_field_name = 'next' | |
29 | + | |
30 | + template_name = 'themes/basic_update.html' | |
31 | + model = Themes | |
32 | + form_class = BasicElemetsForm | |
33 | + success_url = reverse_lazy("subjects:home") | |
34 | + | |
35 | + def get_object(self, queryset = None): | |
36 | + return Themes.objects.get(id = 1) | |
37 | + | |
38 | + def form_valid(self, form): | |
39 | + form.save() | |
40 | + | |
41 | + messages.success(self.request, _("Theme settings updated successfully!")) | |
42 | + | |
43 | + return super(BasicElementsSettings, self).form_valid(form) | |
44 | + | |
45 | + def get_context_data(self, **kwargs): | |
46 | + context = super(BasicElementsSettings, self).get_context_data(**kwargs) | |
47 | + | |
48 | + context['title'] = _('Basic Elements') | |
49 | + context['settings_menu_active'] = "settings_menu_active" | |
50 | + | |
51 | + return context | |
52 | + | |
53 | + | |
54 | +class CSSStyleSettings(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.UpdateView): | |
55 | + login_url = reverse_lazy("users:login") | |
56 | + redirect_field_name = 'next' | |
57 | + | |
58 | + template_name = 'themes/css_update.html' | |
59 | + model = Themes | |
60 | + form_class = CSSStyleForm | |
61 | + success_url = reverse_lazy("subjects:home") | |
62 | + | |
63 | + def get_object(self, queryset = None): | |
64 | + return Themes.objects.get(id = 1) | |
65 | + | |
66 | + def form_valid(self, form): | |
67 | + form.save() | |
68 | + | |
69 | + messages.success(self.request, _("Theme settings updated successfully!")) | |
70 | + | |
71 | + return super(CSSStyleSettings, self).form_valid(form) | |
72 | + | |
73 | + def get_context_data(self, **kwargs): | |
74 | + context = super(CSSStyleSettings, self).get_context_data(**kwargs) | |
75 | + | |
76 | + context['title'] = _('CSS Selector') | |
77 | + context['settings_menu_active'] = "settings_menu_active" | |
78 | + | |
79 | + return context | ... | ... |