Commit b47acb093b139c8fd93f8081afdd4a81de2da2c4

Authored by Zambom
1 parent ac46279c

Adding groups create/edit/replicate

amadeus/static/css/base/amadeus.css
... ... @@ -73,7 +73,7 @@ a:focus {
73 73 /* side bar menu ends*/
74 74  
75 75 /* category app starts */
76   -.category-panel > .panel-heading, .subject-panel > .panel-heading, .special-panel > .panel-heading, .topic-panel > .panel-heading {
  76 +.category-panel > .panel-heading, .subject-panel > .panel-heading, .special-panel > .panel-heading, .topic-panel > .panel-heading, .group-panel > .panel-heading {
77 77 padding: 2px 0px;
78 78 }
79 79  
... ...
amadeus/static/css/themes/green.css
... ... @@ -59,6 +59,14 @@ a, a:focus, a:hover {
59 59 background-color: #039BE5 !important;
60 60 }
61 61  
  62 +.group-panel > .panel-heading {
  63 + background-color: #FFFFFF !important;
  64 +}
  65 +
  66 +.group-panel .panel-title, .group-panel .category-header i, .group-panel .category-course-link {
  67 + color: #000000 !important;
  68 +}
  69 +
62 70 .topic-panel > .panel-heading {
63 71 background-color: #7BA5B9 !important;
64 72 }
... ...
students_group/forms.py
... ... @@ -2,6 +2,8 @@
2 2 from django import forms
3 3 from django.utils.translation import ugettext_lazy as _
4 4  
  5 +from subjects.models import Subject
  6 +
5 7 from .models import StudentsGroup
6 8  
7 9 class StudentsGroupForm(forms.ModelForm):
... ... @@ -11,6 +13,11 @@ class StudentsGroupForm(forms.ModelForm):
11 13 super(StudentsGroupForm, self).__init__(*args, **kwargs)
12 14  
13 15 self.subject = kwargs['initial'].get('subject', None)
  16 +
  17 + if self.instance.id:
  18 + self.subject = self.instance.subject
  19 +
  20 + self.fields['participants'].queryset = self.subject.students.all()
14 21  
15 22 def clean_name(self):
16 23 name = self.cleaned_data.get('name', '')
... ...
students_group/migrations/0002_auto_20170118_1800.py 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2017-01-18 21:00
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations
  6 +
  7 +from django.contrib.postgres.operations import UnaccentExtension
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + dependencies = [
  12 + ('students_group', '0001_initial'),
  13 + ]
  14 +
  15 + operations = [
  16 + UnaccentExtension()
  17 + ]
... ...
students_group/templates/groups/_form.html 0 → 100644
... ... @@ -0,0 +1,113 @@
  1 +{% load widget_tweaks static i18n %}
  2 +
  3 +<form method="post" action="" enctype="multipart/form-data">
  4 + {% csrf_token %}
  5 + {% for field in form %}
  6 + {% if field.auto_id == 'id_participants' %}
  7 + <div class="panel-group" id="professors_accordion" role="tablist" aria-multiselectable="true">
  8 + <div class="panel panel-info">
  9 + <div class="panel-heading">
  10 + <div class="row">
  11 + <div class="col-md-12">
  12 + <a data-parent="#professors_accordion" data-toggle="collapse" href="#participants">
  13 + <h4 class="panel-title">
  14 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button><label for="{{ field.auto_id }}">{{ field.label }}</label>
  15 + </h4>
  16 + </a>
  17 + </div>
  18 + </div>
  19 + </div>
  20 + <div id="participants" class="panel-collapse collapse">
  21 + <p><em>{% trans 'Attribute students to group' %}:</em></p>
  22 + {% render_field field class='form-control' %}
  23 + </div>
  24 + </div>
  25 + </div>
  26 + {% else %}
  27 + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
  28 + <label for="{{ field.auto_id }}" class="control-label">{{ field.label }}</label>
  29 +
  30 + {% if field.auto_id == 'id_description' %}
  31 + {% render_field field class='form-control text_wysiwyg' %}
  32 + {% else %}
  33 + {% render_field field class='form-control' %}
  34 + {% endif %}
  35 + </div>
  36 + {% endif %}
  37 +
  38 + <span class="help-block">{{ field.help_text }}</span>
  39 +
  40 + {% if field.errors %}
  41 + <div class="row">
  42 + </br>
  43 + <div class="alert alert-danger alert-dismissible" role="alert">
  44 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  45 + <span aria-hidden="true">&times;</span>
  46 + </button>
  47 + <ul>
  48 + {% for error in field.errors %}
  49 + <li>{{ error }}</li>
  50 + {% endfor %}
  51 + </ul>
  52 + </div>
  53 + </div>
  54 + {% endif %}
  55 + {% endfor %}
  56 + <div class="row text-center">
  57 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-success btn-raised" />
  58 + </div>
  59 +</form>
  60 +
  61 +<script type="text/javascript">
  62 + $('#id_participants').multiSelect({
  63 + selectableHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=' '>",
  64 + selectionHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=''>",
  65 + afterInit: function(ms){
  66 + var that = this,
  67 + $selectableSearch = that.$selectableUl.prev(),
  68 + $selectionSearch = that.$selectionUl.prev(),
  69 + selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
  70 + selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';
  71 +
  72 + that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
  73 + .on('keydown', function(e){
  74 + if (e.which === 40){
  75 + that.$selectableUl.focus();
  76 + return false;
  77 + }
  78 + });
  79 +
  80 + that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
  81 + .on('keydown', function(e){
  82 + if (e.which == 40){
  83 + that.$selectionUl.focus();
  84 + return false;
  85 + }
  86 + });
  87 + },
  88 + afterSelect: function(){
  89 + this.qs1.cache();
  90 + this.qs2.cache();
  91 + },
  92 + afterDeselect: function(){
  93 + this.qs1.cache();
  94 + this.qs2.cache();
  95 + }
  96 + });// Used to create multi-select css style
  97 +
  98 + $('.collapse').on('show.bs.collapse', function (e) {
  99 + if($(this).is(e.target)){
  100 + var btn = $(this).parent().find('.fa-angle-right');
  101 +
  102 + btn.switchClass("fa-angle-right", "fa-angle-down", 250, "easeInOutQuad");
  103 + }
  104 + });
  105 +
  106 + $('.collapse').on('hide.bs.collapse', function (e) {
  107 + if($(this).is(e.target)){
  108 + var btn = $(this).parent().find('.fa-angle-down');
  109 +
  110 + btn.switchClass("fa-angle-down", "fa-angle-right", 250, "easeInOutQuad");
  111 + }
  112 + });
  113 +</script>
0 114 \ No newline at end of file
... ...
students_group/templates/groups/create.html
... ... @@ -4,15 +4,24 @@
4 4  
5 5 {% block breadcrumbs %}
6 6 {{ block.super }}
7   -
8   - {% trans 'Create Group' as bread %}
9   - {% breadcrumb bread 'groups:create' subject.slug %}
  7 +
  8 + {% if group %}
  9 + {% trans 'Replicate: ' as bread %}
  10 +
  11 + {% with bread|add:group.name as bread_slug %}
  12 + {% breadcrumb bread_slug 'groups:replicate' subject.slug group.slug %}
  13 + {% endwith %}
  14 + {% else %}
  15 + {% trans 'Create Group' as bread %}
  16 + {% breadcrumb bread 'groups:create' subject.slug %}
  17 + {% endif %}
10 18 {% endblock %}
11 19  
12 20 {% block content %}
13 21 <div class="card">
14 22 <div class="card-content">
15 23 <div class="card-body">
  24 + {% include 'groups/_form.html' %}
16 25 </div>
17 26 </div>
18 27 </div>
... ...
students_group/templates/groups/index.html
... ... @@ -27,14 +27,43 @@
27 27 {% endif %}
28 28  
29 29 <div class='row'>
30   - <div class="col-md-offset-4 col-md-3">
31   - <a href="{% url 'groups:create' subject.slug %}" class="btn btn-raised btn-success btn-block">{% trans "Create Group" %}</a>
  30 + <div class="col-md-12 text-center">
  31 + <a href="{% url 'groups:create' subject.slug %}" class="btn btn-raised btn-success">{% trans "Create Group" %}</a>
32 32 </div>
33 33 </div>
34 34  
35 35 <div class="col-md-12 cards-content">
36 36 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
37 37 {% for group in groups %}
  38 + <div class="panel panel-info group-panel">
  39 + <div class="panel-heading">
  40 + <div class="row">
  41 + <div class="col-md-12 category-header">
  42 + <h4 class="panel-title">
  43 + <a class="category-course-link pull-left" data-parent="#accordion" data-toggle="collapse" href="#{{group.slug}}">
  44 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> {{ group }}
  45 + </a>
  46 + </h4>
  47 +
  48 + <div class="col-md-5 pull-right category-card-items">
  49 + <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  50 + <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
  51 + </a>
  52 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  53 + <li>
  54 + <a href="{% url 'groups:replicate' subject.slug group.slug %}">
  55 + <i class="fa fa-files-o" aria-hidden="true"></i> {% trans 'Replicate' %}
  56 + </a>
  57 + </li>
  58 + <li><a href="{% url 'groups:update' subject.slug group.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans 'Edit' %}</a></li>
  59 + <li><a href=""><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans 'Remove' %}</a></li>
  60 + </ul>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + </div>
  65 + </div>
  66 +
38 67 {% endfor %}
39 68  
40 69 {% pagination request paginator page_obj %}
... ...
students_group/templates/groups/update.html 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +{% extends 'groups/index.html' %}
  2 +
  3 +{% load i18n django_bootstrap_breadcrumbs %}
  4 +
  5 +{% block breadcrumbs %}
  6 + {{ block.super }}
  7 +
  8 + {% trans 'Update: ' as bread %}
  9 +
  10 + {% with bread|add:group.name as bread_slug %}
  11 + {% breadcrumb bread_slug 'groups:update' subject.slug group.slug %}
  12 + {% endwith %}
  13 +{% endblock %}
  14 +
  15 +{% block content %}
  16 + <div class="card">
  17 + <div class="card-content">
  18 + <div class="card-body">
  19 + {% include 'groups/_form.html' %}
  20 + </div>
  21 + </div>
  22 + </div>
  23 + <br clear="all" />
  24 + <br clear="all" />
  25 +{% endblock %}
... ...
students_group/urls.py
... ... @@ -4,4 +4,6 @@ from . import views
4 4 urlpatterns = [
5 5 url(r'^(?P<slug>[\w_-]+)/$', views.IndexView.as_view(), name='index'),
6 6 url(r'^create/(?P<slug>[\w_-]+)/$', views.CreateView.as_view(), name='create'),
  7 + url(r'^update/(?P<sub_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name='update'),
  8 + url(r'^replicate/(?P<slug>[\w_-]+)/(?P<group_slug>[\w_-]+)/$', views.CreateView.as_view(), name='replicate'),
7 9 ]
8 10 \ No newline at end of file
... ...
students_group/views.py
... ... @@ -70,6 +70,13 @@ class CreateView(LoginRequiredMixin, generic.edit.CreateView):
70 70 slug = self.kwargs.get('slug', '')
71 71  
72 72 initial['subject'] = get_object_or_404(Subject, slug = slug)
  73 +
  74 + if self.kwargs.get('group_slug'):
  75 + group = get_object_or_404(StudentsGroup, slug = self.kwargs['group_slug'])
  76 + initial = initial.copy()
  77 + initial['description'] = group.description
  78 + initial['name'] = group.name
  79 + initial['participants'] = group.participants.all()
73 80  
74 81 return initial
75 82  
... ... @@ -95,9 +102,51 @@ class CreateView(LoginRequiredMixin, generic.edit.CreateView):
95 102  
96 103 context['subject'] = subject
97 104  
  105 + if self.kwargs.get('group_slug'):
  106 + group = get_object_or_404(StudentsGroup, slug = self.kwargs['group_slug'])
  107 +
  108 + context['title'] = _('Replicate Group')
  109 +
  110 + context['group'] = group
  111 +
98 112 return context
99 113  
100 114 def get_success_url(self):
101 115 messages.success(self.request, _('The group "%s" was created successfully!')%(self.object.name))
102 116  
  117 + return reverse_lazy('groups:index', kwargs = {'slug': self.object.subject.slug})
  118 +
  119 +class UpdateView(LoginRequiredMixin, generic.UpdateView):
  120 + login_url = reverse_lazy("users:login")
  121 + redirect_field_name = 'next'
  122 +
  123 + template_name = 'groups/update.html'
  124 + model = StudentsGroup
  125 + form_class = StudentsGroupForm
  126 + context_object_name = 'group'
  127 +
  128 + def dispatch(self, request, *args, **kwargs):
  129 + slug = self.kwargs.get('sub_slug', '')
  130 + subject = get_object_or_404(Subject, slug = slug)
  131 +
  132 + if not has_subject_permissions(request.user, subject):
  133 + return redirect(reverse_lazy('subjects:home'))
  134 +
  135 + return super(UpdateView, self).dispatch(request, *args, **kwargs)
  136 +
  137 + def get_context_data(self, **kwargs):
  138 + context = super(UpdateView, self).get_context_data(**kwargs)
  139 +
  140 + context['title'] = _('Update Group')
  141 +
  142 + slug = self.kwargs.get('sub_slug', '')
  143 + subject = get_object_or_404(Subject, slug = slug)
  144 +
  145 + context['subject'] = subject
  146 +
  147 + return context
  148 +
  149 + def get_success_url(self):
  150 + messages.success(self.request, _('The group "%s" was updated successfully!')%(self.object.name))
  151 +
103 152 return reverse_lazy('groups:index', kwargs = {'slug': self.object.subject.slug})
104 153 \ No newline at end of file
... ...