diff --git a/cotisations/templates/cotisations/edit_facture.html b/cotisations/templates/cotisations/edit_facture.html index 2d6663f7..11e454f5 100644 --- a/cotisations/templates/cotisations/edit_facture.html +++ b/cotisations/templates/cotisations/edit_facture.html @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} {% load staticfiles%} +{% load bootstrap_form_typeahead %} {% 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.,
{% csrf_token %}

Editer la facture

- {% bootstrap_form factureform %} + {% bootstrap_form_typeahead factureform 'user' %} {{ venteform.management_form }}

Articles de la facture

diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index d34dccb9..4f68b6ee 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -39,6 +39,36 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if domainform %} {% bootstrap_form_errors domainform %} {% 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 %} {% csrf_token %} @@ -49,23 +79,55 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if interfaceform %}

Interface

{% if i_bft_param %} - {% if 'machine' in interfaceform.fields %} {% bootstrap_form_typeahead interfaceform 'ipv4,machine' bft_param=i_bft_param %} - {% else %} - {% bootstrap_form_typeahead interfaceform 'ipv4' bft_param=i_bft_param %} - {% endif %} {% else %} - {% if 'machine' in interfaceform.fields %} {% bootstrap_form_typeahead interfaceform 'ipv4,machine' %} - {% else %} - {% bootstrap_form_typeahead interfaceform 'ipv4' %} - {% endif %} {% endif %} {% endif %} {% if domainform %}

Domaine

{% bootstrap_form domainform %} {% endif %} + {% if iptypeform %} +

Type d'IP

+ {% bootstrap_form iptypeform %} + {% endif %} + {% if machinetypeform %} +

Type de machine

+ {% bootstrap_form machinetypeform %} + {% endif %} + {% if extensionform %} +

Extension

+ {% bootstrap_form_typeahead extensionform 'origin' %} + {% endif %} + {% if mxform %} +

Enregistrement MX

+ {% bootstrap_form_typeahead mxform 'name' %} + {% endif %} + {% if nsform %} +

Enregistrement NS

+ {% bootstrap_form_typeahead nsform 'ns' %} + {% endif %} + {% if txtform %} +

Enregistrement TXT

+ {% bootstrap_form txtform %} + {% endif %} + {% if aliasform %} +

Alias

+ {% bootstrap_form aliasform %} + {% endif %} + {% if serviceform %} +

Service

+ {% bootstrap_form serviceform %} + {% endif %} + {% if vlanform %} +

Vlan

+ {% bootstrap_form vlanform %} + {% endif %} + {% if nasform %} +

NAS

+ {% bootstrap_form nasform %} + {% endif %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
diff --git a/machines/views.py b/machines/views.py index 06b151f0..0e00dc67 100644 --- a/machines/views.py +++ b/machines/views.py @@ -340,7 +340,7 @@ def add_iptype(request): reversion.set_comment("Création") messages.success(request, "Ce type d'ip a été ajouté") 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 @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)) messages.success(request, "Type d'ip modifié") return redirect("/machines/index_iptype/") - return form({'machineform': iptype}, 'machines/machine.html', request) + return form({'iptypeform': iptype}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -377,7 +377,7 @@ def del_iptype(request): 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) 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 @permission_required('infra') @@ -390,7 +390,7 @@ def add_machinetype(request): reversion.set_comment("Création") messages.success(request, "Ce type de machine a été ajouté") 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 @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)) messages.success(request, "Type de machine modifié") return redirect("/machines/index_machinetype/") - return form({'machineform': machinetype}, 'machines/machine.html', request) + return form({'machinetypeform': machinetype}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -425,7 +425,7 @@ def del_machinetype(request): 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) 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 @permission_required('infra') @@ -438,7 +438,7 @@ def add_extension(request): reversion.set_comment("Création") messages.success(request, "Cette extension a été ajoutée") 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 @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)) messages.success(request, "Extension modifiée") return redirect("/machines/index_extension/") - return form({'machineform': extension}, 'machines/machine.html', request) + return form({'extensionform': extension}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -473,7 +473,7 @@ def del_extension(request): 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) 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 @permission_required('infra') @@ -486,7 +486,7 @@ def add_mx(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement mx a été ajouté") 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 @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)) messages.success(request, "Mx modifié") return redirect("/machines/index_extension/") - return form({'machineform': mx}, 'machines/machine.html', request) + return form({'mxform': mx}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -521,7 +521,7 @@ def del_mx(request): except ProtectedError: messages.error(request, "Erreur le Mx suivant %s ne peut être supprimé" % mx_del) 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 @permission_required('infra') @@ -534,7 +534,7 @@ def add_ns(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement ns a été ajouté") 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 @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)) messages.success(request, "Ns modifié") return redirect("/machines/index_extension/") - return form({'machineform': ns}, 'machines/machine.html', request) + return form({'nsform': ns}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -569,7 +569,7 @@ def del_ns(request): except ProtectedError: messages.error(request, "Erreur le Ns suivant %s ne peut être supprimé" % ns_del) 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 @permission_required('infra') @@ -582,7 +582,7 @@ def add_txt(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement text a été ajouté") 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 @permission_required('infra') @@ -600,7 +600,7 @@ def edit_txt(request, txtid): reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in txt.changed_data)) messages.success(request, "Txt modifié") return redirect("/machines/index_extension/") - return form({'machineform': text}, 'machines/machine.html', request) + return form({'txtform': txt}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -617,7 +617,7 @@ def del_txt(request): except ProtectedError: messages.error(request, "Erreur le Txt suivant %s ne peut être supprimé" % txt_del) 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 def add_alias(request, interfaceid): @@ -645,7 +645,7 @@ def add_alias(request, interfaceid): reversion.set_comment("Création") messages.success(request, "Cet alias a été ajouté") 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 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)) messages.success(request, "Alias modifié") 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 def del_alias(request, interfaceid): @@ -689,7 +689,7 @@ def del_alias(request, interfaceid): except ProtectedError: messages.error(request, "Erreur l'alias suivant %s ne peut être supprimé" % alias_del) 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 @@ -703,7 +703,7 @@ def add_service(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement service a été ajouté") return redirect("/machines/index_service") - return form({'machineform': service}, 'machines/machine.html', request) + return form({'serviceform': service}, 'machines/machine.html', request) @login_required @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)) messages.success(request, "Service modifié") return redirect("/machines/index_service/") - return form({'machineform': service}, 'machines/machine.html', request) + return form({'serviceform': service}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -738,7 +738,7 @@ def del_service(request): except ProtectedError: messages.error(request, "Erreur le service suivant %s ne peut être supprimé" % service_del) return redirect("/machines/index_service") - return form({'machineform': service}, 'machines/machine.html', request) + return form({'serviceform': service}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -751,7 +751,7 @@ def add_vlan(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement vlan a été ajouté") 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 @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)) messages.success(request, "Vlan modifié") return redirect("/machines/index_vlan/") - return form({'machineform': vlan}, 'machines/machine.html', request) + return form({'vlanform': vlan}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -786,7 +786,7 @@ def del_vlan(request): except ProtectedError: messages.error(request, "Erreur le Vlan suivant %s ne peut être supprimé" % vlan_del) 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 @permission_required('infra') @@ -799,7 +799,7 @@ def add_nas(request): reversion.set_comment("Création") messages.success(request, "Cet enregistrement nas a été ajouté") 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 @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)) messages.success(request, "Nas modifié") return redirect("/machines/index_nas/") - return form({'machineform': nas}, 'machines/machine.html', request) + return form({'nasform': nas}, 'machines/machine.html', request) @login_required @permission_required('infra') @@ -834,7 +834,7 @@ def del_nas(request): except ProtectedError: messages.error(request, "Erreur le Nas suivant %s ne peut être supprimé" % nas_del) 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 @permission_required('cableur') diff --git a/preferences/templates/preferences/edit_preferences.html b/preferences/templates/preferences/edit_preferences.html index 25fa4c02..610889dd 100644 --- a/preferences/templates/preferences/edit_preferences.html +++ b/preferences/templates/preferences/edit_preferences.html @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load bootstrap3 %} +{% load bootstrap_form_typeahead %} {% 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., {% csrf_token %} -{% bootstrap_form options %} +{% bootstrap_form_typeahead options 'utilisateur_asso' %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
diff --git a/static/js/sapphire.js b/static/js/sapphire.js index d5e0f897..db65fdd1 100644 --- a/static/js/sapphire.js +++ b/static/js/sapphire.js @@ -207,6 +207,9 @@ var Sapphire = function () { } }, + columns: undefined, + alpha: undefined, + drops: undefined, canvas: undefined, init: function() { @@ -214,44 +217,56 @@ var Sapphire = function () { 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() { sapphire.canvas = document.createElement("canvas"); document.body.appendChild(sapphire.canvas); - sapphire.canvas.width = window.innerWidth; - sapphire.canvas.height = window.innerHeight; sapphire.canvas.style.position = "fixed"; sapphire.canvas.style.zIndex = -1; sapphire.canvas.style.left = 0; sapphire.canvas.style.top = 0; var ctx = sapphire.canvas.getContext("2d"); - - var columns = sapphire.canvas.width/FONT_SIZE; - 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; - } + ctx.fillStyle = "rgba(0, 0, 0, 1)"; + ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height); 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); } function drawMatrixRainDrop() { ctx.fillStyle = RAIN_COLOR; ctx.font = FONT_SIZE + "px arial"; - for(var i = 0; i < drops.length; i++) { - for (var j = 0; j < drops[i].length; j++) { + for(var i = 0; i < sapphire.drops.length; i++) { + for (var j = 0; j < sapphire.drops[i].length; j++) { var text = CHARACTERS[Math.floor(Math.random()*CHARACTERS.length)]; - ctx.fillText(text, i*FONT_SIZE, drops[i][j]*FONT_SIZE); - if(drops[i][j]*FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975) - drops[i][j] = 0; - drops[i][j]++; + ctx.fillText(text, i*FONT_SIZE, sapphire.drops[i][j]*FONT_SIZE); + if(sapphire.drops[i][j]*FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975) + sapphire.drops[i][j] = 0; + sapphire.drops[i][j]++; } } } @@ -261,11 +276,15 @@ var Sapphire = function () { drawMatrixRainDrop(); } + sapphire.resize(); + window.addEventListener('resize', sapphire.resize); sapphire.triggerHandle = setInterval(drawEverything, 1000/FPS); }, + stop: function() { - sapphire.canvas.parentNode.removeChild(sapphire.canvas); + window.removeEventListener('resize', sapphire.resize); clearInterval(sapphire.triggerHandle); + sapphire.canvas.parentNode.removeChild(sapphire.canvas); }, alterElts: function() { for (var e in sapphire.elts) { sapphire.elts[e].alter(main); } }, diff --git a/topologie/templates/topologie/switch.html b/topologie/templates/topologie/switch.html index 51cec7f6..cb84e846 100644 --- a/topologie/templates/topologie/switch.html +++ b/topologie/templates/topologie/switch.html @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load bootstrap3 %} +{% load bootstrap_form_typeahead %} {% 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., {% csrf_token %} {% if topoform %} - {% bootstrap_form topoform %} + {% bootstrap_form_typeahead topoform 'switch_interface' %} {% endif %} {% if machineform %} - {% bootstrap_form machineform %} + {% bootstrap_form_typeahead machineform 'user' %} {% endif %} {% 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 %} {% if domainform %} {% bootstrap_form domainform %} diff --git a/topologie/views.py b/topologie/views.py index 42cd09e7..f3dedff8 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -38,6 +38,7 @@ from users.views import form from users.models import User from machines.forms import AliasForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm +from machines.views import generate_ipv4_bft_param from preferences.models import AssoOption, GeneralOption @@ -307,9 +308,10 @@ def new_switch(request): new_switch.save() reversion.set_user(request.user) 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 form({'topoform':switch, 'machineform': machine, 'interfaceform': interface, 'domainform': domain}, 'topologie/switch.html', request) + i_bft_param = generate_ipv4_bft_param( interface, False ) + return form({'topoform':switch, 'machineform': machine, 'interfaceform': interface, 'domainform': domain, 'i_bft_param': i_bft_param}, 'topologie/switch.html', request) @login_required @permission_required('infra') @@ -348,7 +350,8 @@ def edit_switch(request, switch_id): reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in switch_form.changed_data)) messages.success(request, "Le switch a bien été modifié") return redirect("/topologie/") - return form({'topoform':switch_form, 'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form}, 'topologie/switch.html', request) + i_bft_param = generate_ipv4_bft_param( interface_form, False ) + return form({'topoform':switch_form, 'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form, 'i_bft_param': i_bft_param}, 'topologie/switch.html', request) @login_required @permission_required('infra') diff --git a/users/templates/users/user.html b/users/templates/users/user.html index bbdc7fc5..62d05146 100644 --- a/users/templates/users/user.html +++ b/users/templates/users/user.html @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load bootstrap3 %} +{% load bootstrap_form_typeahead %} {% 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., {% csrf_token %} - {% bootstrap_form userform %} + {% bootstrap_form_typeahead userform 'room' %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}