mirror of https://github.com/Aidaho12/haproxy-wi
437 lines
20 KiB
HTML
437 lines
20 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{lang.menu_links.add_proxy.title}}{% endblock %}
|
|
{% block h2 %}{{lang.menu_links.add_proxy.title}}{% endblock %}
|
|
{% block content %}
|
|
{% from 'include/input_macros.html' import input, checkbox, select %}
|
|
{% set balance_params = {'roundrobin':'roundrobin','source':'source','leastconn':'leastconn','first':'first',
|
|
'rdp-cookie':'rdp-cookie', 'uri':'uri', 'uri whole':'uri whole', 'static-rr': 'static-rr',
|
|
'url_param userid':'url_param userid'} %}
|
|
{% set checks = {'':'Choose a custom health check','tcp-check':'Check a TCP Port', 'ssl-hello-chk':'Check a SSL Port',
|
|
'httpchk':'Check a HTTP service', 'ldap-check':'Check a LDAP service', 'mysql-check':'Check a MySql Service',
|
|
'pgsql-check':'Check a PgSQL Service', 'redis-check': 'Check a Redis Service', 'smtpchk':'Check a SMTP service'} %}
|
|
{% set observe = {'layer7':'layer7', 'layer4': 'layer4'} %}
|
|
{% set on_error = {'mark-down':'mark-down', 'fastinter': 'fastinter', 'fail-check':'fail-check',
|
|
'sudden-death':'sudden-death'} %}
|
|
{% set header_res = {'http-response': 'response', 'http-request': 'request'} %}
|
|
{% set header_params = {'add-header': 'add-header', 'set-header': 'set-header', 'del-header': 'del-header'} %}
|
|
{% set if_values = {'1':'Host name starts with','2':'Host name ends with','3':'Path starts with','4':'Path ends with', '6': 'Src ip'} %}
|
|
{% set force_close = {'0':'Off','1':'Server only','2':'Force close','3':'Pretend keep alive'} %}
|
|
|
|
<script src="/static/js/add.js"></script>
|
|
<script src="/static/js/edit_config.js"></script>
|
|
<script src="/static/js/le.js"></script>
|
|
<div id="tabs">
|
|
<ul>
|
|
<li><a href="#create" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.proxy}} - Roxy-WI">{{lang.words.create|title()}} {{lang.words.proxy}}</a></li>
|
|
<li><a href="#listen" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.listener|title()}} - Roxy-WI">{{lang.words.listener|title()}}</a></li>
|
|
<li><a href="#frontend" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.frontend|title()}} - Roxy-WI">{{lang.words.frontend|title()}}</a></li>
|
|
<li><a href="#backend" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.backend|title()}} - Roxy-WI">{{lang.words.backend|title()}}</a></li>
|
|
<li><a href="#ssl" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.upload|title()}} SSL {{lang.words.certs}} - Roxy-WI">SSL {{lang.words.certs}}</a></li>
|
|
<li><a href="#option" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.params|title()}} {{lang.words.templates}} - Roxy-WI">{{lang.words.params|title()}}</a></li>
|
|
<li><a href="#add-servers" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.servers|title()}} {{lang.words.templates}} - Roxy-WI">{{lang.words.servers|title()}}</a></li>
|
|
<li><a href="#userlist" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.userlists|title()}} - Roxy-WI">{{lang.words.userlists|title()}}</a></li>
|
|
<li><a href="#peers" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} peers - Roxy-WI">Peers</a></li>
|
|
<li><a href="#lists" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.and}} {{lang.words.upload}} {{lang.words.whitelists}} {{lang.words.or}} {{lang.words.blacklists}} - Roxy-WI">{{lang.words.lists|title()}}</a></li>
|
|
<li><a href="#maps" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.and}} {{lang.words.upload}} {{lang.words.maps}} - Roxy-WI">{{lang.words.maps|title()}}</a></li>
|
|
</ul>
|
|
<ul id='browse_histroy'></ul>
|
|
{% include 'include/add/add_proxy.html' %}
|
|
<div id="listen">
|
|
{% include 'include/add/listen.html' %}
|
|
</div>
|
|
|
|
<!-- Second tabs -->
|
|
|
|
<div id="frontend">
|
|
{% include 'include/add/frontend.html' %}
|
|
</div>
|
|
|
|
<!-- Third tabs -->
|
|
|
|
<div id="backend">
|
|
{% include 'include/add/backend.html' %}
|
|
</div>
|
|
|
|
<div id="ssl">
|
|
<table>
|
|
<caption><h3>SSL</h3></caption>
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn" style="width: 30%;">{{lang.words.view|title()}} {{lang.words.cert2}}</td>
|
|
<td>
|
|
{{lang.words.upload|title()}} {{lang.words.certs}}
|
|
</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn">
|
|
{{ select('serv5', values=g.user_params['servers'], is_servers='true') }}
|
|
<button id="ssl_key_view" title="{{lang.words.view|title()}} {{lang.words.certs}}">{{lang.words.view|title()}}</button>
|
|
</td>
|
|
<td colspan="2" style="padding: 10px 0 10px 0;">
|
|
<span id="ajax-show-ssl"></span>
|
|
</td>
|
|
</tr>
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn" style="width: 30%;">{{lang.words.upload|title()}} SSL {{lang.words.certs}}</td>
|
|
<td>
|
|
{{lang.words.cert_name|title()}}
|
|
</td>
|
|
<td>
|
|
<span title="{{lang.add_page.paste_cert_desc}}" class="help_cursor">{{lang.add_page.desc.paste_cert}}</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="first-collumn padding10" valign="top" style="padding-top: 15px;">
|
|
{{ select('serv4', values=g.user_params['servers'], is_servers='true') }}
|
|
</td>
|
|
<td valign="top" style="padding-top: 27px;">
|
|
{{ input('ssl_name') }}
|
|
</td>
|
|
<td style="padding-top: 15px; padding-bottom: 15px;">
|
|
<textarea id="ssl_cert" cols="50" rows="5"></textarea><br /><br />
|
|
<button id="ssl_key_upload" title="{{lang.words.upload|title()}} SSL {{lang.words.cert}}">{{lang.words.upload|title()}}</button>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table id="le_table">
|
|
<caption><h3>Let's Encrypt</h3></caption>
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn">{{lang.words.server|title()}}</td>
|
|
<td>{{lang.words.type|title()}}</td>
|
|
<td>{{lang.words.domains|title()}}</td>
|
|
<td>{{lang.words.desc|title()}}</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tbody id="le_table_body"></tbody>
|
|
</table>
|
|
<br /><span class="add-button" title="{{lang.words.create|title()}}" onclick="openLeDialog()">+ {{lang.words.create|title()}}</span>
|
|
<div id="ajax-ssl"></div>
|
|
</div>
|
|
<div id="option">
|
|
<table class="overview" id="option_table">
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn">Id</td>
|
|
<td class="padding10 first-collumn">{{lang.words.params|title()}}</td>
|
|
<td></td>
|
|
</tr>
|
|
{% for option in options %}
|
|
<tr id="option-{{ option.id }}" class="{{ loop.cycle('odd', 'even') }}">
|
|
{% if option.groups|string() == g.user_params['group_id']|string() or group|string() == '1' %}
|
|
<td class="padding10 first-collumn">
|
|
{{ option.id }}
|
|
</td>
|
|
<td class="padding10 first-collumn" style="width: 77%;">
|
|
<input type="text" id="option-body-{{ option.id }}" value="{{ option.options }}" size="60" class="form-control">
|
|
</td>
|
|
<td>
|
|
<a class="delete" onclick="confirmDeleteOption({{ option.id }})" title="{{lang.words.delete|title()}} {{lang.words.param}} {{option.options}}" style="cursor: pointer;"></a>
|
|
</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
<br /><span class="add-button" title="{{lang.words.add|title()}} {{lang.words.param}}" id="add-option-button">+ {{lang.words.add|title()}}</span>
|
|
<br /><br />
|
|
<table class="overview" id="option-add-table" style="display: none;">
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn"> </td>
|
|
<td>{{lang.words.param|title()}}</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn">
|
|
{{lang.words.enter|title()}} {{lang.words.w_an}} {{lang.words.param}}:
|
|
</td>
|
|
<td style="width: 77%;">
|
|
{{ input('new-option', size='60') }}
|
|
</td>
|
|
<td>
|
|
<span class="add-admin" id="add-option-new" title="{{lang.words.add|title()}} {{lang.words.new}} {{lang.words.param}}" style="cursor: pointer;"></span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div id="ajax-option"></div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.options}}
|
|
</div>
|
|
</div>
|
|
|
|
<div id="add-servers">
|
|
<table class="overview" id="servers_table">
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn">{{lang.words.server|title()}}</td>
|
|
<td class="padding10 first-collumn">{{lang.words.desc|title()}}</td>
|
|
<td></td>
|
|
</tr>
|
|
{% for s in saved_servers %}
|
|
<tr id="servers-saved-{{ s.id }}" class="{{ loop.cycle('odd', 'even') }}">
|
|
{% if s.groups|string() == g.user_params['group_id']|string() or group|string() == '1' %}
|
|
<td class="padding10 first-collumn">
|
|
<input type="text" id="servers-ip-{{ s.id }}" value="{{ s.server }}" size="15" class="form-control">
|
|
</td>
|
|
<td class="padding10 first-collumn" style="width: 77%;">
|
|
<input type="text" id="servers-desc-{{ s.id }}" value="{{ s.description }}" size="50" class="form-control">
|
|
</td>
|
|
<td>
|
|
<a class="delete" onclick="confirmDeleteSavedServer({{ s.id }})" title="{{lang.words.delete|title()}} {{lang.words.server}} {{s.server}}" style="cursor: pointer;"></a>
|
|
</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
<br /><span class="add-button" title="{{lang.words.add|title()}} {{lang.words.server}}" id="add-saved-server-button">+ {{lang.words.add|title()}}</span>
|
|
<br /><br />
|
|
<table class="overview" id="saved-server-add-table" style="display: none;">
|
|
<tr class="overviewHead">
|
|
<td class="padding10 first-collumn">{{lang.words.server|title()}}</td>
|
|
<td>{{lang.words.desc|title()}}</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn">
|
|
{{ input('new-saved-servers', size='15') }}
|
|
</td>
|
|
<td style="width: 77%;">
|
|
{{ input('new-saved-servers-description', size='50') }}
|
|
</td>
|
|
<td>
|
|
<span class="add-admin" id="add-saved-server-new" title="{{lang.words.add|title()}} {{lang.words.new|title()}} {{lang.words.server|title()}}" style="cursor: pointer;"></span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div id="ajax-servers"></div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.servers}}
|
|
</div>
|
|
</div>
|
|
<div id="userlist">
|
|
{% include 'include/add/userlist.html' %}
|
|
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.userlist}}
|
|
</div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.words.read|title()}}
|
|
<a href="https://roxy-wi.org/description/userlist" title="How to use userlists" target="_blank">
|
|
<b>{{lang.words.here}}</b>
|
|
</a>
|
|
{{lang.phrases.howto_user}} {{lang.words.userlists}}
|
|
</div>
|
|
</div>
|
|
<div id="peers">
|
|
{% include 'include/add/peers.html' %}
|
|
<div class="alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.peers_master}}
|
|
</div>
|
|
<div class="alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.peers_slave}}
|
|
</div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.words.read|title()}}
|
|
<a href="https://roxy-wi.org/howto/peers" title="How to use peers" target="_blank">
|
|
<b>{{lang.words.here}}</b>
|
|
</a>
|
|
{{lang.phrases.howto_user}} peers
|
|
</div>
|
|
</div>
|
|
<div id="lists">
|
|
<table class="overview">
|
|
<tr class="overviewHead">
|
|
<th class="padding10 first-collumn">{{lang.words.new|title()}} {{lang.words.blacklist}}</th>
|
|
<th>{{lang.words.server|title()}} {{lang.words.for}} {{lang.words.uploading}}</th>
|
|
<th>{{lang.words.existing|title()}} {{lang.words.blacklists}}</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn" style="width: 25%;">
|
|
{{lang.words.name|title()}}: {{ input('new_blacklist_name') }}
|
|
<button onclick="createList('black')">{{lang.words.create|title()}}</button>
|
|
</td>
|
|
<td class="first-collumn">
|
|
{{ select('serv-black-list', values=g.user_params['servers'], is_servers='true') }}
|
|
</td>
|
|
<td style="width: 30%; padding: 10px 0 10px 0;">
|
|
{% for list in black_lists %}
|
|
<span class="list_of_lists list_blacklists">
|
|
<a onclick="editList('{{ list }}', 'black')" title="{{lang.words.edit|title()}} {{lang.words.the}} {{ list }} {{lang.words.list}}">{{ list }}</a>
|
|
</span>
|
|
{% endfor %}
|
|
</td>
|
|
|
|
</tr>
|
|
{{ input('group', value=group, type='hidden') }}
|
|
</table>
|
|
<table>
|
|
<tr class="overviewHead">
|
|
<th class="padding10 first-collumn">{{lang.words.new|title()}} {{lang.words.whitelist}}</th>
|
|
<th>{{lang.words.server|title()}} {{lang.words.for}} {{lang.words.uploading}}</th>
|
|
<th>{{lang.words.existing|title()}} {{lang.words.whitelists}}</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn" style="width: 25%;">
|
|
{{lang.words.name|title()}}: {{ input('new_whitelist_name') }}
|
|
<button onclick="createList('white')">{{lang.words.create|title()}}</button>
|
|
</td>
|
|
<td class="first-collumn">
|
|
{{ select('serv-white-list', values=g.user_params['servers'], is_servers='true') }}
|
|
</td>
|
|
<td style="width: 30%; padding: 10px 0 10px 0;">
|
|
{% for list in white_lists %}
|
|
<span class="list_of_lists list_whitelists">
|
|
<a onclick="editList('{{ list }}', 'white')" title="{{lang.words.edit|title()}} {{lang.words.the}} {{ list }} {{lang.words.list}}">{{ list }}</a>
|
|
</span>
|
|
{% endfor %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div id="ajax"></div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.lists_howto}}
|
|
<a href="https://roxy-wi.org/howto/blacklist" title="How to create and manage blacklist" target="_blank">{{lang.words.article}}</a>
|
|
</div>
|
|
<div id="dialog-confirm-cert-edit" title="{{lang.words.view|title()}} {{lang.words.cert}} " style="display: none;">
|
|
<span><b>{{lang.words.note|title()}}:</b> {{lang.add_page.desc.lists_new_line}}</span>
|
|
<textarea id="edit_lists" style="width: 100%" rows=20></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="maps">
|
|
<table class="overview">
|
|
<tr class="overviewHead">
|
|
<th class="padding10 first-collumn">{{lang.words.new|title()}} {{lang.words.map}}</th>
|
|
<th>{{lang.words.server|title()}} {{lang.words.for}} {{lang.words.uploading}}</th>
|
|
<th>{{lang.words.existing|title()}} {{lang.words.maps}}</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding10 first-collumn" style="width: 25%;">
|
|
{{lang.words.name|title()}}: {{ input('new_map_name') }}
|
|
<button onclick="createMap()">{{lang.words.create|title()}}</button>
|
|
</td>
|
|
<td class="first-collumn">
|
|
{{ select('serv-map', values=g.user_params['servers'], is_servers='true') }}
|
|
</td>
|
|
<td style="width: 30%; padding: 10px 0 10px 0;">
|
|
{% for map in maps %}
|
|
<span class="list_of_lists list_maps">
|
|
<a onclick="editMap('{{ map }}')" title="{{lang.words.edit|title()}} {{lang.words.the}} {{ map }} {{lang.words.map}}">{{ map }}</a>
|
|
</span>
|
|
{% endfor %}
|
|
</td>
|
|
</tr>
|
|
{{ input('group', value=group, type='hidden') }}
|
|
</table>
|
|
<div id="ajax-maps"></div>
|
|
<div class="add-note alert addName alert-info" style="width: inherit; margin-right: 15px;">
|
|
{{lang.add_page.desc.lists_howto}}
|
|
<a href="https://www.haproxy.com/blog/introduction-to-haproxy-maps" title="Introduction to HAProxy Maps" target="_blank">{{lang.words.article}}</a>
|
|
</div>
|
|
<div id="dialog-confirm-map-edit" title="{{lang.words.view|title()}} {{lang.words.map}} " style="display: none;">
|
|
<span><b>{{lang.words.note|title()}}:</b> {{lang.add_page.desc.lists_new_line}}</span>
|
|
<textarea id="edit_map" style="width: 100%" rows=20></textarea>
|
|
</div>
|
|
</div>
|
|
{% include 'include/del_confirm.html' %}
|
|
<div id="dialog-confirm-cert" title="View certificate " style="display: none;">
|
|
<pre id="dialog-confirm-body"></pre>
|
|
</div>
|
|
<input type="hidden" id="group_id" value="{{ g.user_params['group_id']|string() }}">
|
|
</div>
|
|
</div>
|
|
<script>
|
|
$( function() {
|
|
$( ".force_close" ).selectmenu({
|
|
width: 180
|
|
});
|
|
if (window.matchMedia('(max-width: 1280px)').matches || window.matchMedia('(max-width: 1024px)').matches || window.matchMedia('(max-width: 667px)').matches) {
|
|
$( "select" ).selectmenu({
|
|
width: 150
|
|
});
|
|
}
|
|
});
|
|
var serv_ports = $('.send_proxy');
|
|
|
|
for (var i = 0; i <= serv_ports.length; i++) {
|
|
var uniqId = makeid(3);
|
|
$(serv_ports[i]).append('<label for="' + uniqId + '" class="send_proxy_label" title="Set send-proxy for this server" data-help="The Send-proxy parameter enforces the use of the PROXY protocol over any connection established to this server. The PROXY protocol informs the other end about the layer 3/4 addresses of the incoming connection so that it can know the client\'s address or the public address it accessed to, whatever the upper-layer protocol.">send-proxy</label><input type="checkbox" name="send_proxy" value="1" id="' + uniqId + '">');
|
|
var uniqId = makeid(3);
|
|
$(serv_ports[i]).append('<label for="' + uniqId + '" class="send_proxy_label" title="Set this server as backup server" data-help="When all servers in a farm are down, we want to redirect traffic to a backup server which delivers either sorry pages or a degraded mode of the application.\n' +
|
|
'This can be done easily in HAProxy by adding the keyword backup on the server line. If multiple backup servers are configured, only the first active one is used.">backup</label><input type="checkbox" name="backup" value="1" id="' + uniqId + '">');
|
|
}
|
|
</script>
|
|
<div id="le-add-table" style="display: none;">
|
|
<table class="overview" id="group-add-table-overview" title="{{lang.words.add|title()}} {{lang.words.w_a}} {{lang.words.new3}} {{lang.words.group2}}">
|
|
{% include 'include/tr_validate_tips.html' %}
|
|
<tr>
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.server|title() }}
|
|
</td>
|
|
<td>
|
|
{{ select('new-le-server_id', values=g.user_params['servers'], is_servers='true', by_id=1) }}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.type|title() }}
|
|
</td>
|
|
<td>
|
|
<select id="new-le-type">
|
|
<option value="standalone">Stand alone</option>
|
|
<option value="route53">Route 53</option>
|
|
<option value="cloudflare">CloudFlare</option>
|
|
<option value="digitalocean">DigitalOcean</option>
|
|
<option value="linode">Linode</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.domains|title() }}
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-domain') }}
|
|
<div class="tooltip tooltipTop">{{ lang.add_page.desc.comma_separated }}</div>
|
|
</td>
|
|
</tr>
|
|
<tr class="le-standalone">
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.email|title() }}
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-email') }}
|
|
</td>
|
|
</tr>
|
|
<tr class="le-dns" style="display: none;">
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.token|title() }}
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-token') }}
|
|
</td>
|
|
</tr>
|
|
<tr class="le-aws" style="display: none;">
|
|
<td class="padding20 first-collumn">
|
|
Access key ID
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-access_key_id') }}
|
|
</td>
|
|
</tr>
|
|
<tr class="le-aws" style="display: none;">
|
|
<td class="padding20 first-collumn">
|
|
Secret access key
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-secret_access_key') }}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="padding20 first-collumn">
|
|
{{ lang.words.desc|title() }}
|
|
</td>
|
|
<td>
|
|
{{ input('new-le-description') }}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
{% endblock %}
|