8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-26 22:52:26 +00:00

Merge branch 'massive_use_bft_tag' into 'master'

Massive use bft tag

See merge request rezo/re2o!15
This commit is contained in:
Gabriel Detraz 2017-10-14 01:47:29 +02:00
commit 93733c654f
16 changed files with 256 additions and 155 deletions

View file

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load bootstrap3 %} {% load bootstrap3 %}
{% load staticfiles%} {% load staticfiles%}
{% load bootstrap_form_typeahead %}
{% block title %}Création et modification de factures{% endblock %} {% block title %}Création et modification de factures{% endblock %}
@ -34,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
<h3>Editer la facture</h3> <h3>Editer la facture</h3>
{% bootstrap_form factureform %} {% bootstrap_form_typeahead factureform 'user' %}
{{ venteform.management_form }} {{ venteform.management_form }}
<h3>Articles de la facture</h3> <h3>Articles de la facture</h3>
<table class="table table-striped"> <table class="table table-striped">

View file

@ -210,17 +210,17 @@ class NsForm(ModelForm):
class DelNsForm(Form): class DelNsForm(Form):
ns = forms.ModelMultipleChoiceField(queryset=Ns.objects.all(), label="Enregistrements NS actuels", widget=forms.CheckboxSelectMultiple) ns = forms.ModelMultipleChoiceField(queryset=Ns.objects.all(), label="Enregistrements NS actuels", widget=forms.CheckboxSelectMultiple)
class TextForm(ModelForm): class TxtForm(ModelForm):
class Meta: class Meta:
model = Text model = Text
fields = '__all__' fields = '__all__'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(TextForm, self).__init__(*args, prefix=prefix, **kwargs) super(TxtForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelTextForm(Form): class DelTxtForm(Form):
text = forms.ModelMultipleChoiceField(queryset=Text.objects.all(), label="Enregistrements Text actuels", widget=forms.CheckboxSelectMultiple) txt = forms.ModelMultipleChoiceField(queryset=Text.objects.all(), label="Enregistrements Txt actuels", widget=forms.CheckboxSelectMultiple)
class NasForm(ModelForm): class NasForm(ModelForm):
class Meta: class Meta:

View file

@ -25,21 +25,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
<th>Zone concernée</th> <th>Zone concernée</th>
<th>Enregistrement</th> <th>Enregistrement</th>
<th></th> <th></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
{% for text in text_list %} {% for txt in txt_list %}
<tr> <tr>
<td>{{ text.zone }}</td> <td>{{ txt.zone }}</td>
<td>{{ text.dns_entry }}</td> <td>{{ txt.dns_entry }}</td>
<td class="text-right"> <td class="text-right">
{% if is_infra %} {% if is_infra %}
{% include 'buttons/edit.html' with href='machines:edit-text' id=text.id %} {% include 'buttons/edit.html' with href='machines:edit-txt' id=txt.id %}
{% endif %} {% endif %}
{% include 'buttons/history.html' with href='machines:history' name='text' id=text.id %} {% include 'buttons/history.html' with href='machines:history' name='txt' id=txt.id %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View file

@ -47,12 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-ns' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un enregistrement NS</a> <a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-ns' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un enregistrement NS</a>
{% endif %} {% endif %}
{% include "machines/aff_ns.html" with ns_list=ns_list %} {% include "machines/aff_ns.html" with ns_list=ns_list %}
<h2>Liste des enregistrements Text</h2> <h2>Liste des enregistrements TXT</h2>
{% if is_infra %} {% if is_infra %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:add-text' %}"><i class="glyphicon glyphicon-plus"></i> Ajouter un enregistrement TXT</a> <a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:add-txt' %}"><i class="glyphicon glyphicon-plus"></i> Ajouter un enregistrement TXT</a>
<a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-text' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un enregistrement TXT</a> <a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-txt' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un enregistrement TXT</a>
{% endif %} {% endif %}
{% include "machines/aff_text.html" with text_list=text_list %} {% include "machines/aff_txt.html" with txt_list=txt_list %}
<br /> <br />
<br /> <br />
<br /> <br />

View file

@ -39,6 +39,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if domainform %} {% if domainform %}
{% bootstrap_form_errors domainform %} {% bootstrap_form_errors domainform %}
{% endif %} {% endif %}
{% if iptypeform %}
{% bootstrap_form_errors iptypeform %}
{% endif %}
{% if machinetypeform %}
{% bootstrap_form_errors machinetypeform %}
{% endif %}
{% if extensionform %}
{% bootstrap_form_errors extensionform %}
{% endif %}
{% if mxform %}
{% bootstrap_form_errors mxform %}
{% endif %}
{% if nsform %}
{% bootstrap_form_errors nsform %}
{% endif %}
{% if txtform %}
{% bootstrap_form_errors txtform %}
{% endif %}
{% if aliasform %}
{% bootstrap_form_errors aliasform %}
{% endif %}
{% if serviceform %}
{% bootstrap_form_errors serviceform %}
{% endif %}
{% if vlanform %}
{% bootstrap_form_errors vlanform %}
{% endif %}
{% if nasform %}
{% bootstrap_form_errors nasform %}
{% endif %}
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
@ -49,23 +79,55 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if interfaceform %} {% if interfaceform %}
<h3>Interface</h3> <h3>Interface</h3>
{% if i_bft_param %} {% if i_bft_param %}
{% if 'machine' in interfaceform.fields %}
{% bootstrap_form_typeahead interfaceform 'ipv4,machine' bft_param=i_bft_param %} {% bootstrap_form_typeahead interfaceform 'ipv4,machine' bft_param=i_bft_param %}
{% else %}
{% bootstrap_form_typeahead interfaceform 'ipv4' bft_param=i_bft_param %}
{% endif %}
{% else %} {% else %}
{% if 'machine' in interfaceform.fields %}
{% bootstrap_form_typeahead interfaceform 'ipv4,machine' %} {% bootstrap_form_typeahead interfaceform 'ipv4,machine' %}
{% else %}
{% bootstrap_form_typeahead interfaceform 'ipv4' %}
{% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if domainform %} {% if domainform %}
<h3>Domaine</h3> <h3>Domaine</h3>
{% bootstrap_form domainform %} {% bootstrap_form domainform %}
{% endif %} {% endif %}
{% if iptypeform %}
<h3>Type d'IP</h3>
{% bootstrap_form iptypeform %}
{% endif %}
{% if machinetypeform %}
<h3>Type de machine</h3>
{% bootstrap_form machinetypeform %}
{% endif %}
{% if extensionform %}
<h3>Extension</h3>
{% bootstrap_form_typeahead extensionform 'origin' %}
{% endif %}
{% if mxform %}
<h3>Enregistrement MX</h3>
{% bootstrap_form_typeahead mxform 'name' %}
{% endif %}
{% if nsform %}
<h3>Enregistrement NS</h3>
{% bootstrap_form_typeahead nsform 'ns' %}
{% endif %}
{% if txtform %}
<h3>Enregistrement TXT</h3>
{% bootstrap_form txtform %}
{% endif %}
{% if aliasform %}
<h3>Alias</h3>
{% bootstrap_form aliasform %}
{% endif %}
{% if serviceform %}
<h3>Service</h3>
{% bootstrap_form serviceform %}
{% endif %}
{% if vlanform %}
<h3>Vlan</h3>
{% bootstrap_form vlanform %}
{% endif %}
{% if nasform %}
<h3>NAS</h3>
{% bootstrap_form nasform %}
{% endif %}
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
</form> </form>
<br /> <br />

View file

@ -47,9 +47,9 @@ urlpatterns = [
url(r'^add_mx/$', views.add_mx, name='add-mx'), url(r'^add_mx/$', views.add_mx, name='add-mx'),
url(r'^edit_mx/(?P<mxid>[0-9]+)$', views.edit_mx, name='edit-mx'), url(r'^edit_mx/(?P<mxid>[0-9]+)$', views.edit_mx, name='edit-mx'),
url(r'^del_mx/$', views.del_mx, name='del-mx'), url(r'^del_mx/$', views.del_mx, name='del-mx'),
url(r'^add_text/$', views.add_text, name='add-text'), url(r'^add_txt/$', views.add_txt, name='add-txt'),
url(r'^edit_text/(?P<textid>[0-9]+)$', views.edit_text, name='edit-text'), url(r'^edit_txt/(?P<textid>[0-9]+)$', views.edit_txt, name='edit-txt'),
url(r'^del_text/$', views.del_text, name='del-text'), url(r'^del_txt/$', views.del_txt, name='del-txt'),
url(r'^add_ns/$', views.add_ns, name='add-ns'), url(r'^add_ns/$', views.add_ns, name='add-ns'),
url(r'^edit_ns/(?P<nsid>[0-9]+)$', views.edit_ns, name='edit-ns'), url(r'^edit_ns/(?P<nsid>[0-9]+)$', views.edit_ns, name='edit-ns'),
url(r'^del_ns/$', views.del_ns, name='del-ns'), url(r'^del_ns/$', views.del_ns, name='del-ns'),
@ -76,7 +76,7 @@ urlpatterns = [
url(r'^history/(?P<object>extension)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>extension)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>mx)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>mx)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>ns)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>ns)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>text)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>txt)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>iptype)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>iptype)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>alias)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>alias)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>vlan)/(?P<id>[0-9]+)$', views.history, name='history'), url(r'^history/(?P<object>vlan)/(?P<id>[0-9]+)$', views.history, name='history'),

View file

@ -49,13 +49,13 @@ from reversion.models import Version
import re import re
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TxtForm, DelTxtForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm
from .forms import EditOuverturePortListForm, EditOuverturePortConfigForm from .forms import EditOuverturePortListForm, EditOuverturePortConfigForm
from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, OuverturePortList, OuverturePort from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, OuverturePortList, OuverturePort
from users.models import User from users.models import User
from users.models import all_has_access from users.models import all_has_access
from preferences.models import GeneralOption, OptionalMachine from preferences.models import GeneralOption, OptionalMachine
from .templatetags.bootstrap_form_typeahead import hidden_id, input_id from re2o.templatetags.bootstrap_form_typeahead import hidden_id, input_id
def all_active_interfaces(): def all_active_interfaces():
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """ """Renvoie l'ensemble des machines autorisées à sortir sur internet """
@ -340,7 +340,7 @@ def add_iptype(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Ce type d'ip a été ajouté") messages.success(request, "Ce type d'ip a été ajouté")
return redirect("/machines/index_iptype") return redirect("/machines/index_iptype")
return form({'machineform': iptype, 'interfaceform': None}, 'machines/machine.html', request) return form({'iptypeform': iptype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -359,7 +359,7 @@ def edit_iptype(request, iptypeid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in iptype.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in iptype.changed_data))
messages.success(request, "Type d'ip modifié") messages.success(request, "Type d'ip modifié")
return redirect("/machines/index_iptype/") return redirect("/machines/index_iptype/")
return form({'machineform': iptype}, 'machines/machine.html', request) return form({'iptypeform': iptype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -377,7 +377,7 @@ def del_iptype(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Le type d'ip %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % iptype_del) messages.error(request, "Le type d'ip %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % iptype_del)
return redirect("/machines/index_iptype") return redirect("/machines/index_iptype")
return form({'machineform': iptype, 'interfaceform': None}, 'machines/machine.html', request) return form({'iptypeform': iptype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -390,7 +390,7 @@ def add_machinetype(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Ce type de machine a été ajouté") messages.success(request, "Ce type de machine a été ajouté")
return redirect("/machines/index_machinetype") return redirect("/machines/index_machinetype")
return form({'machineform': machinetype, 'interfaceform': None}, 'machines/machine.html', request) return form({'machinetypeform': machinetype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -408,7 +408,7 @@ def edit_machinetype(request, machinetypeid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machinetype.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machinetype.changed_data))
messages.success(request, "Type de machine modifié") messages.success(request, "Type de machine modifié")
return redirect("/machines/index_machinetype/") return redirect("/machines/index_machinetype/")
return form({'machineform': machinetype}, 'machines/machine.html', request) return form({'machinetypeform': machinetype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -425,7 +425,7 @@ def del_machinetype(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Le type de machine %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % machinetype_del) messages.error(request, "Le type de machine %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % machinetype_del)
return redirect("/machines/index_machinetype") return redirect("/machines/index_machinetype")
return form({'machineform': machinetype, 'interfaceform': None}, 'machines/machine.html', request) return form({'machinetypeform': machinetype}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -438,7 +438,7 @@ def add_extension(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cette extension a été ajoutée") messages.success(request, "Cette extension a été ajoutée")
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': extension, 'interfaceform': None}, 'machines/machine.html', request) return form({'extensionform': extension}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -456,7 +456,7 @@ def edit_extension(request, extensionid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in extension.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in extension.changed_data))
messages.success(request, "Extension modifiée") messages.success(request, "Extension modifiée")
return redirect("/machines/index_extension/") return redirect("/machines/index_extension/")
return form({'machineform': extension}, 'machines/machine.html', request) return form({'extensionform': extension}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -473,7 +473,7 @@ def del_extension(request):
except ProtectedError: except ProtectedError:
messages.error(request, "L'extension %s est affectée à au moins un type de machine, vous ne pouvez pas la supprimer" % extension_del) messages.error(request, "L'extension %s est affectée à au moins un type de machine, vous ne pouvez pas la supprimer" % extension_del)
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': extension, 'interfaceform': None}, 'machines/machine.html', request) return form({'extensionform': extension}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -486,7 +486,7 @@ def add_mx(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement mx a été ajouté") messages.success(request, "Cet enregistrement mx a été ajouté")
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': mx, 'interfaceform': None}, 'machines/machine.html', request) return form({'mxform': mx}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -504,7 +504,7 @@ def edit_mx(request, mxid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in mx.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in mx.changed_data))
messages.success(request, "Mx modifié") messages.success(request, "Mx modifié")
return redirect("/machines/index_extension/") return redirect("/machines/index_extension/")
return form({'machineform': mx}, 'machines/machine.html', request) return form({'mxform': mx}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -521,7 +521,7 @@ def del_mx(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le Mx suivant %s ne peut être supprimé" % mx_del) messages.error(request, "Erreur le Mx suivant %s ne peut être supprimé" % mx_del)
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': mx, 'interfaceform': None}, 'machines/machine.html', request) return form({'mxform': mx}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -534,7 +534,7 @@ def add_ns(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement ns a été ajouté") messages.success(request, "Cet enregistrement ns a été ajouté")
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': ns, 'interfaceform': None}, 'machines/machine.html', request) return form({'nsform': ns}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -552,7 +552,7 @@ def edit_ns(request, nsid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in ns.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in ns.changed_data))
messages.success(request, "Ns modifié") messages.success(request, "Ns modifié")
return redirect("/machines/index_extension/") return redirect("/machines/index_extension/")
return form({'machineform': ns}, 'machines/machine.html', request) return form({'nsform': ns}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -569,55 +569,55 @@ def del_ns(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le Ns suivant %s ne peut être supprimé" % ns_del) messages.error(request, "Erreur le Ns suivant %s ne peut être supprimé" % ns_del)
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': ns, 'interfaceform': None}, 'machines/machine.html', request) return form({'nsform': ns}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
def add_text(request): def add_txt(request):
text = TextForm(request.POST or None) txt = TxtForm(request.POST or None)
if text.is_valid(): if txt.is_valid():
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
text.save() txt.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement text a été ajouté") messages.success(request, "Cet enregistrement text a été ajouté")
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': text, 'interfaceform': None}, 'machines/machine.html', request) return form({'txtform': txt}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
def edit_text(request, textid): def edit_txt(request, txtid):
try: try:
text_instance = Text.objects.get(pk=textid) txt_instance = Text.objects.get(pk=txtid)
except Text.DoesNotExist: except Text.DoesNotExist:
messages.error(request, u"Entrée inexistante" ) messages.error(request, u"Entrée inexistante" )
return redirect("/machines/index_extension/") return redirect("/machines/index_extension/")
text = TextForm(request.POST or None, instance=text_instance) txt = TxtForm(request.POST or None, instance=txt_instance)
if text.is_valid(): if txt.is_valid():
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
text.save() txt.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in text.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in txt.changed_data))
messages.success(request, "Text modifié") messages.success(request, "Txt modifié")
return redirect("/machines/index_extension/") return redirect("/machines/index_extension/")
return form({'machineform': text}, 'machines/machine.html', request) return form({'txtform': txt}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
def del_text(request): def del_txt(request):
text = DelTextForm(request.POST or None) txt = DelTxtForm(request.POST or None)
if text.is_valid(): if txt.is_valid():
text_dels = text.cleaned_data['text'] txt_dels = txt.cleaned_data['txt']
for text_del in text_dels: for txt_del in txt_dels:
try: try:
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
text_del.delete() txt_del.delete()
reversion.set_user(request.user) reversion.set_user(request.user)
messages.success(request, "Le text a été supprimé") messages.success(request, "Le txt a été supprimé")
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le Text suivant %s ne peut être supprimé" % text_del) messages.error(request, "Erreur le Txt suivant %s ne peut être supprimé" % txt_del)
return redirect("/machines/index_extension") return redirect("/machines/index_extension")
return form({'machineform': text, 'interfaceform': None}, 'machines/machine.html', request) return form({'txtform': txt}, 'machines/machine.html', request)
@login_required @login_required
def add_alias(request, interfaceid): def add_alias(request, interfaceid):
@ -645,7 +645,7 @@ def add_alias(request, interfaceid):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet alias a été ajouté") messages.success(request, "Cet alias a été ajouté")
return redirect("/machines/index_alias/" + str(interfaceid)) return redirect("/machines/index_alias/" + str(interfaceid))
return form({'machineform': alias, 'interfaceform': None}, 'machines/machine.html', request) return form({'aliasform': alias}, 'machines/machine.html', request)
@login_required @login_required
def edit_alias(request, aliasid): def edit_alias(request, aliasid):
@ -665,7 +665,7 @@ def edit_alias(request, aliasid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in alias.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in alias.changed_data))
messages.success(request, "Alias modifié") messages.success(request, "Alias modifié")
return redirect("/machines/index_alias/" + str(alias_instance.cname.interface_parent.id)) return redirect("/machines/index_alias/" + str(alias_instance.cname.interface_parent.id))
return form({'machineform': alias}, 'machines/machine.html', request) return form({'aliasform': alias}, 'machines/machine.html', request)
@login_required @login_required
def del_alias(request, interfaceid): def del_alias(request, interfaceid):
@ -689,7 +689,7 @@ def del_alias(request, interfaceid):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur l'alias suivant %s ne peut être supprimé" % alias_del) messages.error(request, "Erreur l'alias suivant %s ne peut être supprimé" % alias_del)
return redirect("/machines/index_alias/" + str(interfaceid)) return redirect("/machines/index_alias/" + str(interfaceid))
return form({'machineform': alias, 'interfaceform': None}, 'machines/machine.html', request) return form({'aliasform': alias}, 'machines/machine.html', request)
@login_required @login_required
@ -703,7 +703,7 @@ def add_service(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement service a été ajouté") messages.success(request, "Cet enregistrement service a été ajouté")
return redirect("/machines/index_service") return redirect("/machines/index_service")
return form({'machineform': service}, 'machines/machine.html', request) return form({'serviceform': service}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -721,7 +721,7 @@ def edit_service(request, serviceid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in service.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in service.changed_data))
messages.success(request, "Service modifié") messages.success(request, "Service modifié")
return redirect("/machines/index_service/") return redirect("/machines/index_service/")
return form({'machineform': service}, 'machines/machine.html', request) return form({'serviceform': service}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -738,7 +738,7 @@ def del_service(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le service suivant %s ne peut être supprimé" % service_del) messages.error(request, "Erreur le service suivant %s ne peut être supprimé" % service_del)
return redirect("/machines/index_service") return redirect("/machines/index_service")
return form({'machineform': service}, 'machines/machine.html', request) return form({'serviceform': service}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -751,7 +751,7 @@ def add_vlan(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement vlan a été ajouté") messages.success(request, "Cet enregistrement vlan a été ajouté")
return redirect("/machines/index_vlan") return redirect("/machines/index_vlan")
return form({'machineform': vlan, 'interfaceform': None}, 'machines/machine.html', request) return form({'vlanform': vlan}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -769,7 +769,7 @@ def edit_vlan(request, vlanid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in vlan.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in vlan.changed_data))
messages.success(request, "Vlan modifié") messages.success(request, "Vlan modifié")
return redirect("/machines/index_vlan/") return redirect("/machines/index_vlan/")
return form({'machineform': vlan}, 'machines/machine.html', request) return form({'vlanform': vlan}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -786,7 +786,7 @@ def del_vlan(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le Vlan suivant %s ne peut être supprimé" % vlan_del) messages.error(request, "Erreur le Vlan suivant %s ne peut être supprimé" % vlan_del)
return redirect("/machines/index_vlan") return redirect("/machines/index_vlan")
return form({'machineform': vlan, 'interfaceform': None}, 'machines/machine.html', request) return form({'vlanform': vlan}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -799,7 +799,7 @@ def add_nas(request):
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Cet enregistrement nas a été ajouté") messages.success(request, "Cet enregistrement nas a été ajouté")
return redirect("/machines/index_nas") return redirect("/machines/index_nas")
return form({'machineform': nas, 'interfaceform': None}, 'machines/machine.html', request) return form({'nasform': nas}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -817,7 +817,7 @@ def edit_nas(request, nasid):
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in nas.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in nas.changed_data))
messages.success(request, "Nas modifié") messages.success(request, "Nas modifié")
return redirect("/machines/index_nas/") return redirect("/machines/index_nas/")
return form({'machineform': nas}, 'machines/machine.html', request) return form({'nasform': nas}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -834,7 +834,7 @@ def del_nas(request):
except ProtectedError: except ProtectedError:
messages.error(request, "Erreur le Nas suivant %s ne peut être supprimé" % nas_del) messages.error(request, "Erreur le Nas suivant %s ne peut être supprimé" % nas_del)
return redirect("/machines/index_nas") return redirect("/machines/index_nas")
return form({'machineform': nas, 'interfaceform': None}, 'machines/machine.html', request) return form({'nasform': nas}, 'machines/machine.html', request)
@login_required @login_required
@permission_required('cableur') @permission_required('cableur')
@ -960,11 +960,11 @@ def history(request, object, id):
except Mx.DoesNotExist: except Mx.DoesNotExist:
messages.error(request, "Mx inexistant") messages.error(request, "Mx inexistant")
return redirect("/machines/") return redirect("/machines/")
elif object == 'text' and request.user.has_perms(('cableur',)): elif object == 'txt' and request.user.has_perms(('cableur',)):
try: try:
object_instance = Text.objects.get(pk=id) object_instance = Text.objects.get(pk=id)
except Text.DoesNotExist: except Text.DoesNotExist:
messages.error(request, "Text inexistant") messages.error(request, "Txt inexistant")
return redirect("/machines/") return redirect("/machines/")
elif object == 'ns' and request.user.has_perms(('cableur',)): elif object == 'ns' and request.user.has_perms(('cableur',)):
try: try:

View file

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% load bootstrap_form_typeahead %}
{% block title %}Création et modification des préférences{% endblock %} {% block title %}Création et modification des préférences{% endblock %}
@ -34,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form options %} {% bootstrap_form_typeahead options 'utilisateur_asso' %}
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
</form> </form>
<br /> <br />

View file

@ -209,7 +209,7 @@ def hidden_tag( f_bound, f_name ):
'input', 'input',
attrs={ attrs={
'id': hidden_id( f_bound ), 'id': hidden_id( f_bound ),
'name': f_name, 'name': f_bound.html_name,
'type': 'hidden', 'type': 'hidden',
'value': f_bound.value() or "" 'value': f_bound.value() or ""
} }

View file

@ -207,6 +207,9 @@ var Sapphire = function () {
} }
}, },
columns: undefined,
alpha: undefined,
drops: undefined,
canvas: undefined, canvas: undefined,
init: function() { init: function() {
@ -214,44 +217,56 @@ var Sapphire = function () {
for (var e in sapphire.elts) { sapphire.elts[e].get(main); } for (var e in sapphire.elts) { sapphire.elts[e].get(main); }
}, },
resize: function() {
var ctx = sapphire.canvas.getContext("2d");
var img = ctx.getImageData( 0, 0, sapphire.canvas.width, sapphire.canvas.height );
sapphire.canvas.width = window.innerWidth;
sapphire.canvas.height = window.innerHeight;
ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
ctx.putImageData( img, 0, 0 );
sapphire.columns = sapphire.canvas.width/FONT_SIZE;
sapphire.alpha = Math.max( 0, Math.min( 1, TRAIL_TIME / ( sapphire.canvas.height/FONT_SIZE ) ) );
var newDrops = [];
for(var x = 0; x < sapphire.columns; x++) {
if ( sapphire.drops && sapphire.drops[x] ) { newDrops[x] = sapphire.drops[x] }
else {
newDrops[x] = [];
var nb = Math.floor(Math.random()*MAX_CHAR);
for (var y = 0; y < nb; y++)
newDrops[x][y] = 0;
}
}
sapphire.drops = newDrops;
},
run: function() { run: function() {
sapphire.canvas = document.createElement("canvas"); sapphire.canvas = document.createElement("canvas");
document.body.appendChild(sapphire.canvas); document.body.appendChild(sapphire.canvas);
sapphire.canvas.width = window.innerWidth;
sapphire.canvas.height = window.innerHeight;
sapphire.canvas.style.position = "fixed"; sapphire.canvas.style.position = "fixed";
sapphire.canvas.style.zIndex = -1; sapphire.canvas.style.zIndex = -1;
sapphire.canvas.style.left = 0; sapphire.canvas.style.left = 0;
sapphire.canvas.style.top = 0; sapphire.canvas.style.top = 0;
var ctx = sapphire.canvas.getContext("2d"); var ctx = sapphire.canvas.getContext("2d");
ctx.fillStyle = "rgba(0, 0, 0, 1)";
var columns = sapphire.canvas.width/FONT_SIZE; ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
var alpha = Math.max( 0, Math.min( 1, TRAIL_TIME / ( sapphire.canvas.height/FONT_SIZE ) ) );
var drops = [];
for(var x = 0; x < columns; x++)
{
drops[x] = [];
var nb = Math.floor(Math.random()*MAX_CHAR);
for (var y = 0; y < nb; y++)
drops[x][y] = 1;
}
function attenuateBackground() { function attenuateBackground() {
ctx.fillStyle = "rgba(0, 0, 0, "+alpha+")"; ctx.fillStyle = "rgba(0, 0, 0, "+sapphire.alpha+")";
ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height); ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
} }
function drawMatrixRainDrop() { function drawMatrixRainDrop() {
ctx.fillStyle = RAIN_COLOR; ctx.fillStyle = RAIN_COLOR;
ctx.font = FONT_SIZE + "px arial"; ctx.font = FONT_SIZE + "px arial";
for(var i = 0; i < drops.length; i++) { for(var i = 0; i < sapphire.drops.length; i++) {
for (var j = 0; j < drops[i].length; j++) { for (var j = 0; j < sapphire.drops[i].length; j++) {
var text = CHARACTERS[Math.floor(Math.random()*CHARACTERS.length)]; var text = CHARACTERS[Math.floor(Math.random()*CHARACTERS.length)];
ctx.fillText(text, i*FONT_SIZE, drops[i][j]*FONT_SIZE); ctx.fillText(text, i*FONT_SIZE, sapphire.drops[i][j]*FONT_SIZE);
if(drops[i][j]*FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975) if(sapphire.drops[i][j]*FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975)
drops[i][j] = 0; sapphire.drops[i][j] = 0;
drops[i][j]++; sapphire.drops[i][j]++;
} }
} }
} }
@ -261,11 +276,15 @@ var Sapphire = function () {
drawMatrixRainDrop(); drawMatrixRainDrop();
} }
sapphire.resize();
window.addEventListener('resize', sapphire.resize);
sapphire.triggerHandle = setInterval(drawEverything, 1000/FPS); sapphire.triggerHandle = setInterval(drawEverything, 1000/FPS);
}, },
stop: function() { stop: function() {
sapphire.canvas.parentNode.removeChild(sapphire.canvas); window.removeEventListener('resize', sapphire.resize);
clearInterval(sapphire.triggerHandle); clearInterval(sapphire.triggerHandle);
sapphire.canvas.parentNode.removeChild(sapphire.canvas);
}, },
alterElts: function() { for (var e in sapphire.elts) { sapphire.elts[e].alter(main); } }, alterElts: function() { for (var e in sapphire.elts) { sapphire.elts[e].alter(main); } },

View file

@ -30,32 +30,53 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th>Details</th> <th>Details</th>
<th>Membres</th> <th>Membres</th>
</tr> </tr>
</thead> </thead>
{% for stack in stack_list %} {% for stack in stack_list %}
{% for switch in stack.switch_set.all %} {% for switch in stack.switch_set.all %}
<tr class="active"> <tbody>
{% if forloop.first %} <tr class="active">
<td rowspan="{{ stack.switch_set.all|length }}">{{stack.name}}</td> {% if forloop.first %}
<td rowspan="{{ stack.switch_set.all|length }}">{{stack.stack_id}}</td> <td rowspan="{{ stack.switch_set.all|length }}">{{stack.name}}</td>
<td rowspan="{{ stack.switch_set.all|length }}" >{{stack.details}}</td> <td rowspan="{{ stack.switch_set.all|length }}">{{stack.stack_id}}</td>
{% endif %} <td rowspan="{{ stack.switch_set.all|length }}" >{{stack.details}}</td>
<td><a href="{% url 'topologie:index-port' switch.pk %}">{{switch}}</a></td> {% endif %}
{% if forloop.first %} <td><a href="{% url 'topologie:index-port' switch.pk %}">{{switch}}</a></td>
<td rowspan="{{ stack.switch_set.all|length }}"> {% if forloop.first %}
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'stack' stack.pk %}"> <td rowspan="{{ stack.switch_set.all|length }}">
<i class="glyphicon glyphicon-time"></i> <a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'stack' stack.pk %}">
</a> <i class="glyphicon glyphicon-time"></i>
{% if is_infra %} </a>
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-stack' stack.id %}"> {% if is_infra %}
<i class="glyphicon glyphicon-edit"></i> <a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-stack' stack.id %}">
</a> <i class="glyphicon glyphicon-edit"></i>
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'topologie:del-stack' stack.pk %}"> </a>
<i class="glyphicon glyphicon-trash"></i> <a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'topologie:del-stack' stack.pk %}">
</a> <i class="glyphicon glyphicon-trash"></i>
{% endif %} </a>
</td> {% endif %}
{% endif %} </td>
</tr> {% endif %}
{% endfor %} </tr>
{% endfor %} {% empty %}
<tr class="active">
<td>{{stack.name}}</td>
<td>{{stack.stack_id}}</td>
<td>{{stack.details}}</td>
<td>Aucun</td>
<td>
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'stack' stack.pk %}">
<i class="glyphicon glyphicon-time"></i>
</a>
{% if is_infra %}
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-stack' stack.id %}">
<i class="glyphicon glyphicon-edit"></i>
</a>
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'topologie:del-stack' stack.pk %}">
<i class="glyphicon glyphicon-trash"></i>
</a>
{% endif %}
</td>
{% endfor %}
</tbody>
{% endfor %}
</table> </table>

View file

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% load bootstrap_form_typeahead %}
{% block title %}Création et modification d'un switch{% endblock %} {% block title %}Création et modification d'un switch{% endblock %}
@ -46,13 +47,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% if topoform %} {% if topoform %}
{% bootstrap_form topoform %} {% bootstrap_form_typeahead topoform 'switch_interface' %}
{% endif %} {% endif %}
{% if machineform %} {% if machineform %}
{% bootstrap_form machineform %} {% bootstrap_form_typeahead machineform 'user' %}
{% endif %} {% endif %}
{% if interfaceform %} {% if interfaceform %}
{% bootstrap_form interfaceform %} {% if i_bft_param %}
{% bootstrap_form_typeahead interfaceform 'ipv4,machine' bft_param=i_bft_param %}
{% else %}
{% bootstrap_form_typeahead interfaceform 'ipv4,machine' %}
{% endif %}
{% endif %} {% endif %}
{% if domainform %} {% if domainform %}
{% bootstrap_form domainform %} {% bootstrap_form domainform %}

View file

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% load bootstrap_form_typeahead %}
{% block title %}Création et modificationd 'utilisateur{% endblock %} {% block title %}Création et modificationd 'utilisateur{% endblock %}
@ -32,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form topoform %} {% bootstrap_form_typeahead topoform 'room,related,machine_interface' %}
{%bootstrap_button "Créer ou modifier" button_type="submit" icon="ok" %} {%bootstrap_button "Créer ou modifier" button_type="submit" icon="ok" %}
</form> </form>
<br /> <br />

View file

@ -50,8 +50,8 @@ from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm
from topologie.forms import AddPortForm, EditRoomForm, StackForm from topologie.forms import AddPortForm, EditRoomForm, StackForm
from users.views import form from users.views import form
from machines.forms import AliasForm, NewMachineForm, EditMachineForm from machines.forms import AliasForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm
from machines.forms import EditInterfaceForm, AddInterfaceForm from machines.views import generate_ipv4_bft_param
from preferences.models import AssoOption, GeneralOption from preferences.models import AssoOption, GeneralOption
@ -379,15 +379,10 @@ def new_switch(request):
new_switch_instance.save() new_switch_instance.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
messages.success(request, "Le switch a été crée") messages.success(request, "Le switch a été créé")
return redirect("/topologie/") return redirect("/topologie/")
return form({ i_bft_param = generate_ipv4_bft_param( interface, False )
'topoform': switch, return form({'topoform':switch, 'machineform': machine, 'interfaceform': interface, 'domainform': domain, 'i_bft_param': i_bft_param}, 'topologie/switch.html', request)
'machineform': machine,
'interfaceform': interface,
'domainform': domain
}, 'topologie/switch.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')
@ -447,13 +442,8 @@ def edit_switch(request, switch_id):
) )
messages.success(request, "Le switch a bien été modifié") messages.success(request, "Le switch a bien été modifié")
return redirect("/topologie/") return redirect("/topologie/")
return form({ i_bft_param = generate_ipv4_bft_param( interface_form, False )
'topoform': switch_form, return form({'topoform':switch_form, 'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form, 'i_bft_param': i_bft_param}, 'topologie/switch.html', request)
'machineform': machine_form,
'interfaceform': interface_form,
'domainform': domain_form
}, 'topologie/switch.html', request)
@login_required @login_required
@permission_required('infra') @permission_required('infra')

View file

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% load bootstrap_form_typeahead %}
{% block title %}Création et modification d'utilisateur{% endblock %} {% block title %}Création et modification d'utilisateur{% endblock %}
@ -32,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form userform %} {% bootstrap_form_typeahead userform 'room' %}
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
</form> </form>
<br /> <br />