Use autofocus on username input field instead of the password field, Fill missing cells on incorrect cell count in table views
This commit is contained in:
parent
8612251448
commit
a0e712827d
5 changed files with 130 additions and 75 deletions
|
@ -1,5 +1,9 @@
|
|||
# CHANGELOG
|
||||
|
||||
## 2.1.4 - 2019/11/08
|
||||
* Use autofocus on username input field instead of the password field
|
||||
* Fill missing cells on incorrect cell count in table views when only partial data is available
|
||||
|
||||
## 2.1.3 - 2019/08/08
|
||||
* Fixed false rendering of forms
|
||||
* Fixed channel tree view showing the wrong virtual server after selection
|
||||
|
|
11
README.md
11
README.md
|
@ -3,8 +3,8 @@ ts3web is a free and open-source web interface for TeamSpeak 3 instances.
|
|||
|
||||
The minimalistic approach of this application is intentional.
|
||||
|
||||
* Docker images available on https://hub.docker.com/r/varakh/ts3web
|
||||
* Sources are hosted on https://gitlab.com/varakh/ts3web
|
||||
* Docker images available on [https://hub.docker.com/r/varakh/ts3web](https://hub.docker.com/r/varakh/ts3web)
|
||||
* Sources are hosted on [https://gitlab.com/varakh/ts3web](https://gitlab.com/varakh/ts3web)
|
||||
|
||||
## Limitations
|
||||
Features which are currently not supported:
|
||||
|
@ -52,7 +52,7 @@ IP for this example setup.
|
|||
the `env` file referenced in the example `docker-compose`.
|
||||
|
||||
```
|
||||
version: '2'
|
||||
version: '2.1'
|
||||
networks:
|
||||
teamspeak:
|
||||
external: false
|
||||
|
@ -86,6 +86,11 @@ services:
|
|||
restart: always
|
||||
networks:
|
||||
- teamspeak
|
||||
healthcheck:
|
||||
test: "nc -z localhost 80"
|
||||
interval: 1s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
```
|
||||
|
||||
Now execute `docker-compose up -d` to start those containers. If you like to update, do `docker-compose down`,
|
||||
|
|
|
@ -75,7 +75,6 @@ http {
|
|||
# Enable checking the existence of precompressed files.
|
||||
#gzip_static on;
|
||||
|
||||
|
||||
# Specifies the main log format.
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
<input type="text" id="username" name="username" class="form-control form-control-sm"
|
||||
placeholder="{{ getenv('teamspeak_user') }}"
|
||||
value="{{ getenv('teamspeak_user') }}"
|
||||
required>
|
||||
autofocus required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password" class="sr-only">{% trans %}login.form.password{% endtrans %}</label>
|
||||
<input type="password" id="password" name="password"
|
||||
class="form-control form-control-sm"
|
||||
placeholder="{% trans %}login.form.password.placeholder{% endtrans %}" autofocus required>
|
||||
placeholder="{% trans %}login.form.password.placeholder{% endtrans %}" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
|
@ -1,10 +1,50 @@
|
|||
<!-- determine if keys are missing and add empty values for them -->
|
||||
{% set allKeys = [] %}
|
||||
{% for arr in data %}
|
||||
{% for key in arr|keys %}
|
||||
{% if key not in allKeys %}
|
||||
{% set allKeys = allKeys|merge([key]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% set workData = [] %}
|
||||
{% for arr in data %}
|
||||
{% set missing = [] %}
|
||||
|
||||
{% for ix,key in allKeys %}
|
||||
{% if key not in arr|keys %}
|
||||
{% set missing = missing|merge({(key) : null}) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if missing is not null %}
|
||||
{% set manipulatedArr = arr %}
|
||||
{% set manipulatedArr = manipulatedArr|merge(missing) %}
|
||||
|
||||
{% set correctOrdered = [] %}
|
||||
{% for key in allKeys %}
|
||||
{% for k,v in manipulatedArr %}
|
||||
{% if k == key %}
|
||||
{% set correctOrdered = correctOrdered|merge({(k):v}) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% set workData = workData|merge([correctOrdered]) %}
|
||||
|
||||
{% else %}
|
||||
{% set workData = workData|merge([arr]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm small sortable-bootstrap table-striped table-bordered" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- determine if to hide entire column header -->
|
||||
{% set added = [] %}
|
||||
{% for arr in data %}
|
||||
{% for arr in workData %}
|
||||
{% set added = arr|keys %}
|
||||
{% endfor %}
|
||||
|
||||
|
@ -22,95 +62,102 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for arr in data %}
|
||||
{% for arr in workData %}
|
||||
|
||||
<!-- determine if row should be hidden -->
|
||||
{% set show = true %}
|
||||
{% for hidden in hiddenDependingOnAttribute %}
|
||||
{% if hidden.key in arr|keys and attribute(arr, hidden.key) in hidden.values %}
|
||||
{% set show = false %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- determine if row should be hidden -->
|
||||
{% set show = true %}
|
||||
{% for hidden in hiddenDependingOnAttribute %}
|
||||
{% if hidden.key in arr|keys and attribute(arr, hidden.key) in hidden.values %}
|
||||
{% set show = false %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if show == true %}
|
||||
<tr>
|
||||
{% for key, value in arr %}
|
||||
{% set value = value %}
|
||||
{% if show == true %}
|
||||
<tr>
|
||||
{% for key, value in arr %}
|
||||
{% set value = value %}
|
||||
|
||||
<!-- apply filters to item -->
|
||||
{% for filter in filters %}
|
||||
{% if filter.key == key %}
|
||||
<!-- apply filters to item -->
|
||||
{% for filter in filters %}
|
||||
{% if filter.key == key %}
|
||||
{% if value is not empty %}
|
||||
{% set value = value|apply_filter(filter.apply)|raw %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- determine if to hide entire column cell -->
|
||||
{% set showColumn = true %}
|
||||
{% if key in hiddenColumns %}
|
||||
{% set showColumn = false %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if showColumn %}
|
||||
<td>
|
||||
{% set item = value %}
|
||||
<!-- determine if to hide entire column cell -->
|
||||
{% set showColumn = true %}
|
||||
{% if key in hiddenColumns %}
|
||||
{% set showColumn = false %}
|
||||
{% endif %}
|
||||
|
||||
<!-- determine if cell should -->
|
||||
{% set editable = null %}
|
||||
{% for attr in attributesEditable %}
|
||||
{% if attr.key == key %}
|
||||
{% set editable = attr %}
|
||||
{% if showColumn %}
|
||||
<td>
|
||||
{% set item = value %}
|
||||
|
||||
<!-- determine if cell should -->
|
||||
{% set editable = null %}
|
||||
{% for attr in attributesEditable %}
|
||||
{% if attr.key == key %}
|
||||
{% set editable = attr %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- cell is editable, generate a form -->
|
||||
{% if editable is not empty %}
|
||||
{% include 'form_inline.twig' with {'editable': editable} %}
|
||||
<!-- cell is static or a link-->
|
||||
{% else %}
|
||||
{% for link in links %}
|
||||
{% if link.key == key %}
|
||||
{% if link.uri_param is not empty %}
|
||||
{% for searchingKey, searchingValue in arr %}
|
||||
{% if searchingKey == link.uri_param %}
|
||||
{% set item = "<a href=\"#{link.uri}\/#{searchingValue}\">#{value}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set item = "<a href=\"#{link.uri}\/#{value}\">#{value}</a>" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- cell is editable, generate a form -->
|
||||
{% if editable is not empty %}
|
||||
{% include 'form_inline.twig' with {'editable': editable} %}
|
||||
<!-- cell is static or a link-->
|
||||
{% if item is empty %}
|
||||
{% else %}
|
||||
{% for link in links %}
|
||||
{% if link.key == key %}
|
||||
{% if link.uri_param is not empty %}
|
||||
{% for searchingKey, searchingValue in arr %}
|
||||
{% if searchingKey == link.uri_param %}
|
||||
{% set item = "<a href=\"#{link.uri}\/#{searchingValue}\">#{value}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set item = "<a href=\"#{link.uri}\/#{value}\">#{value}</a>" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{{ item|raw }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- generate additional columns as links, maybe apply filters -->
|
||||
{% for link in additional_links %}
|
||||
<td>
|
||||
{% set item = "<a href=\"#{link.uri}\">#{link.label}" %}
|
||||
<!-- generate additional columns as links, maybe apply filters -->
|
||||
{% for link in additional_links %}
|
||||
<td>
|
||||
{% set item = "<a href=\"#{link.uri}\">#{link.label}" %}
|
||||
|
||||
{% if link.uri_param is not empty %}
|
||||
{% for searchingKey, searchingValue in arr %}
|
||||
{% if searchingKey == link.uri_param %}
|
||||
{% set shownValue = searchingValue %}
|
||||
{% if link.uri_param is not empty %}
|
||||
{% for searchingKey, searchingValue in arr %}
|
||||
{% if searchingKey == link.uri_param %}
|
||||
{% set shownValue = searchingValue %}
|
||||
|
||||
{% if link.apply is not empty %}
|
||||
{% if link.apply is not empty %}
|
||||
{% if shownValue is not empty %}
|
||||
{% set shownValue = shownValue|apply_filter(link.apply)|raw %}
|
||||
{% endif %}
|
||||
|
||||
{% set item = "<a href=\"#{link.uri}\/#{shownValue}\">#{link.label}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{{ item|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% set item = "<a href=\"#{link.uri}\/#{shownValue}\">#{link.label}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{{ item|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
|
|
Reference in a new issue