Add tokens
This commit is contained in:
parent
c05b1e8d06
commit
eacd690b18
20 changed files with 381 additions and 83 deletions
16
README.md
16
README.md
|
@ -94,6 +94,22 @@ location ~ \.php$ {
|
|||
* start server with `php -S localhost:8080 -t public public/index.php`
|
||||
* point browser to [localhost:8080](http://localhost:8080) to have a preview
|
||||
|
||||
### Helpers ###
|
||||
|
||||
Attributes can be defined when including `table`, `keyvalues` and `form` templates of twig. This helps to generate tables and forms without the need to specify all attributes.
|
||||
|
||||
```
|
||||
hiddenDependingOnAttribute // hides a row depending on a value in a table
|
||||
hiddenColumns // hides an entire column depending on a key in a table
|
||||
links // generates a link for a specific cell in a table or keyvalue
|
||||
additional_links // generates extra columns in a table
|
||||
filters // applies filters depending on a key in a table or key value view
|
||||
attributesEditable // define editable attributes in the key value view
|
||||
fields // define fields for a form
|
||||
```
|
||||
|
||||
See example usage in the folder `View/material`.
|
||||
|
||||
## Translations ##
|
||||
- This app uses Symfony Translator. It's bootstrapped in `Util\BootstrapHelper` and locales are placed under `data/locale/`. Adjust to your needs or help translating.
|
||||
- Form fields (name/id should be the same) are also translated. For a field named `content` or `ConT enT` translate `form_field_content`.
|
||||
|
|
|
@ -41,6 +41,10 @@ class ACL extends \Zend\Permissions\Acl\Acl
|
|||
'/servers/send/{sid}',
|
||||
'/servers/edit/{sid}',
|
||||
|
||||
'/tokens/{sid}',
|
||||
'/tokens/add/{sid}',
|
||||
'/tokens/delete/{sid}/{token}',
|
||||
|
||||
'/online/{sid}',
|
||||
'/online/{sid}/{clid}',
|
||||
'/online/poke/{sid}/{clid}',
|
||||
|
|
|
@ -263,3 +263,19 @@ $container[ChannelSendAction::class] = function ($container) {
|
|||
return new ChannelSendAction($container);
|
||||
};
|
||||
$app->post('/channels/send/{sid}/{cid}', ChannelSendAction::class);
|
||||
|
||||
// tokens
|
||||
$container[TokensAction::class] = function ($container) {
|
||||
return new TokensAction($container);
|
||||
};
|
||||
$app->get('/tokens/{sid}', TokensAction::class);
|
||||
|
||||
$container[TokenAddAction::class] = function ($container) {
|
||||
return new TokenAddAction($container);
|
||||
};
|
||||
$app->post('/tokens/add/{sid}', TokenAddAction::class);
|
||||
|
||||
$container[TokenDeleteAction::class] = function ($container) {
|
||||
return new TokenDeleteAction($container);
|
||||
};
|
||||
$app->get('/tokens/delete/{sid}/{token}', TokenDeleteAction::class);
|
||||
|
|
|
@ -63,6 +63,7 @@ menu.servers.clients: "Clients"
|
|||
menu.servers.groups: "Groups"
|
||||
menu.servers.bans: "Bans"
|
||||
menu.servers.complains: "Complains"
|
||||
menu.servers.tokens: "Tokens"
|
||||
menu.servers.logs: "Log"
|
||||
|
||||
# titles
|
||||
|
@ -81,6 +82,7 @@ complains.title: "Complains"
|
|||
groups.title: "Groups"
|
||||
group_info.title: "Group Info"
|
||||
profile.title: "Profile"
|
||||
tokens.title: "Tokens"
|
||||
|
||||
# dynamic render of key value pairs
|
||||
key: "Attribute"
|
||||
|
@ -202,4 +204,17 @@ online.send: "Send a message"
|
|||
online.send.message: "Message"
|
||||
online.poked.success: "Poked client %clid%."
|
||||
online.kicked.success: "Kicked client %clid%."
|
||||
online.banned.success: "Banned client %clid%."
|
||||
online.banned.success: "Banned client %clid%."
|
||||
|
||||
# tokens
|
||||
tokens.delete: "Delete"
|
||||
tokens.h.details: "Details"
|
||||
tokens.h.add: "Add"
|
||||
tokens.add: "Add a token"
|
||||
tokens.add.tokentype: "Type"
|
||||
tokens.add.serverGroup: "Servergroup (type SERVER has to be selected)"
|
||||
tokens.add.channelGroup: "Channelgroup (type CHANNEL has to be selected)"
|
||||
tokens.add.channel: "Channel (type CHANNEL has to be selected)"
|
||||
tokens.add.description: "Description"
|
||||
tokens.type.servergroup: "Server: "
|
||||
tokens.type.channelgroup: "Channel: "
|
|
@ -110,34 +110,15 @@ $container['view'] = function ($container) use ($app) {
|
|||
));
|
||||
$view->addExtension(new Twig_Extension_Debug());
|
||||
|
||||
// file size
|
||||
$fileSizeFilter = new Twig_SimpleFilter('file', function($bytes, $decimals = 2) {
|
||||
$sz = 'BKMGTP';
|
||||
$factor = floor((strlen($bytes) - 1) / 3);
|
||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
|
||||
});
|
||||
$view->getEnvironment()->addFilter($fileSizeFilter);
|
||||
|
||||
// time in seconds to human readable
|
||||
$timeInSecondsFilter = new Twig_SimpleFilter('timeInSeconds', function($seconds) use ($container) {
|
||||
return $container['ts']->getInstance()->convertSecondsToStrTime($seconds);
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timeInSecondsFilter);
|
||||
|
||||
$timeInMillisFilter = new Twig_SimpleFilter('timeInMillis', function($millis) use ($container) {
|
||||
return $container['ts']->getInstance()->convertSecondsToStrTime(floor($millis/1000));
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timeInMillisFilter);
|
||||
|
||||
// timestamp to carbon
|
||||
$timestampFilter = new Twig_SimpleFilter('timestamp', function($timestamp) {
|
||||
return Carbon::createFromTimestamp($timestamp);
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timestampFilter);
|
||||
|
||||
// dynamically apply filters
|
||||
$view->getEnvironment()->addExtension(new ApplyFilterExtension());
|
||||
|
||||
// encode url
|
||||
$encodeUrl = new Twig_SimpleFilter('escape_url', function($str) {
|
||||
return urlencode($str);
|
||||
});
|
||||
$view->getEnvironment()->addFilter($encodeUrl);
|
||||
|
||||
// translation
|
||||
$view->addExtension(new \Symfony\Bridge\Twig\Extension\TranslationExtension($container['translator']));
|
||||
$view->getEnvironment()->getExtension('Twig_Extension_Core')->setDateFormat(getenv('site_date_format'));
|
||||
|
@ -158,6 +139,55 @@ $container['view'] = function ($container) use ($app) {
|
|||
return $container['session']->get($key);
|
||||
}));
|
||||
|
||||
// ts specific: file size
|
||||
$fileSizeFilter = new Twig_SimpleFilter('file', function($bytes, $decimals = 2) {
|
||||
$sz = 'BKMGTP';
|
||||
$factor = floor((strlen($bytes) - 1) / 3);
|
||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
|
||||
});
|
||||
$view->getEnvironment()->addFilter($fileSizeFilter);
|
||||
|
||||
// ts specific: time in seconds to human readable
|
||||
$timeInSecondsFilter = new Twig_SimpleFilter('timeInSeconds', function($seconds) use ($container) {
|
||||
return $container['ts']->getInstance()->convertSecondsToStrTime($seconds);
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timeInSecondsFilter);
|
||||
|
||||
$timeInMillisFilter = new Twig_SimpleFilter('timeInMillis', function($millis) use ($container) {
|
||||
return $container['ts']->getInstance()->convertSecondsToStrTime(floor($millis/1000));
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timeInMillisFilter);
|
||||
|
||||
// ts specific: timestamp to carbon
|
||||
$timestampFilter = new Twig_SimpleFilter('timestamp', function($timestamp) {
|
||||
return Carbon::createFromTimestamp($timestamp);
|
||||
});
|
||||
$view->getEnvironment()->addFilter($timestampFilter);
|
||||
|
||||
// ts specific: token type
|
||||
$tokenTypeFilter = new Twig_SimpleFilter('tokentype', function($type) {
|
||||
$tokenTypes = TSInstance::getTokenTypes();
|
||||
|
||||
foreach ($tokenTypes as $name => $tokenType) {
|
||||
if ($type == $tokenType) return $name;
|
||||
}
|
||||
|
||||
return $type;
|
||||
});
|
||||
$view->getEnvironment()->addFilter($tokenTypeFilter);
|
||||
|
||||
// ts specific: group type
|
||||
$groupTypeFilter = new Twig_SimpleFilter('permgrouptype', function($type) {
|
||||
$groupTypes = TSInstance::getPermGroupTypes();
|
||||
|
||||
foreach ($groupTypes as $name => $groupType) {
|
||||
if ($type == $groupType) return $name;
|
||||
}
|
||||
|
||||
return $type;
|
||||
});
|
||||
$view->getEnvironment()->addFilter($groupTypeFilter);
|
||||
|
||||
// flash
|
||||
$view['flash'] = $container['flash'];
|
||||
|
||||
|
|
36
src/Control/Actions/TokenAddAction.php
Normal file
36
src/Control/Actions/TokenAddAction.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
final class TokenAddAction extends AbstractAction
|
||||
{
|
||||
public function __invoke(Request $request, Response $response, $args)
|
||||
{
|
||||
$sid = $args['sid'];
|
||||
|
||||
$body = $request->getParsedBody();
|
||||
$type = $body['tokentype'];
|
||||
$serverGroup = $body['serverGroup'];
|
||||
$channelGroup = $body['channelGroup'];
|
||||
$channel = $body['channel'];
|
||||
$description = $body['description'];
|
||||
|
||||
$this->logger->debug('Body', $body);
|
||||
|
||||
$this->ts->login($this->auth->getIdentity()['user'], $this->auth->getIdentity()['password']);
|
||||
$selectResult = $this->ts->getInstance()->selectServer($sid, 'serverId');
|
||||
|
||||
|
||||
$tokenAddResult = $this->ts->getInstance()->tokenAdd(
|
||||
$type,
|
||||
($type == ts3admin::TokenServerGroup ? $serverGroup : $channelGroup),
|
||||
$channel,
|
||||
$description
|
||||
);
|
||||
|
||||
$this->flash->addMessage('success', $this->translator->trans('added'));
|
||||
|
||||
return $response->withRedirect('/tokens/' . $sid);
|
||||
}
|
||||
}
|
22
src/Control/Actions/TokenDeleteAction.php
Normal file
22
src/Control/Actions/TokenDeleteAction.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
final class TokenDeleteAction extends AbstractAction
|
||||
{
|
||||
public function __invoke(Request $request, Response $response, $args)
|
||||
{
|
||||
$sid = $args['sid'];
|
||||
$token = rawurldecode($args['token']);
|
||||
|
||||
$this->ts->login($this->auth->getIdentity()['user'], $this->auth->getIdentity()['password']);
|
||||
$selectResult = $this->ts->getInstance()->selectServer($sid, 'serverId');
|
||||
|
||||
$tokenDeleteResult = $this->ts->getInstance()->tokenDelete($token);
|
||||
|
||||
$this->flash->addMessage('success', $this->translator->trans('done'));
|
||||
|
||||
return $response->withRedirect('/tokens/' . $sid);
|
||||
}
|
||||
}
|
56
src/Control/Actions/TokensAction.php
Normal file
56
src/Control/Actions/TokensAction.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
final class TokensAction extends AbstractAction
|
||||
{
|
||||
public function __invoke(Request $request, Response $response, $args)
|
||||
{
|
||||
$sid = $args['sid'];
|
||||
|
||||
$this->ts->login($this->auth->getIdentity()['user'], $this->auth->getIdentity()['password']);
|
||||
$selectResult = $this->ts->getInstance()->selectServer($sid, 'serverId');
|
||||
|
||||
$dataResult = $this->ts->getInstance()->tokenList();
|
||||
|
||||
// channels
|
||||
$channelsResult = $this->ts->getInstance()->channelList();
|
||||
$channelsResult = $this->ts->getInstance()->getElement('data', $channelsResult);
|
||||
$channels = [];
|
||||
foreach ($channelsResult as $channel) {
|
||||
$channels[$channel['channel_name']] = $channel['cid'];
|
||||
}
|
||||
|
||||
// groups
|
||||
$serverGroups = [];
|
||||
|
||||
$serverGroupsResult = $this->ts->getInstance()->serverGroupList();
|
||||
$serverGroupsResult = $this->ts->getInstance()->getElement('data', $serverGroupsResult);
|
||||
|
||||
foreach ($serverGroupsResult as $group) {
|
||||
$serverGroups[$group['name']] = $group['sgid'];
|
||||
}
|
||||
arsort($serverGroups);
|
||||
|
||||
$channelGroups = [];
|
||||
$channelGroupsResult = $this->ts->getInstance()->channelGroupList();
|
||||
$channelGroupsResult = $this->ts->getInstance()->getElement('data', $channelGroupsResult);
|
||||
|
||||
foreach ($channelGroupsResult as $group) {
|
||||
$channelGroups[$group['name']] = $group['cgid'];
|
||||
}
|
||||
arsort($channelGroups);
|
||||
|
||||
// render GET
|
||||
$this->view->render($response, 'tokens.twig', [
|
||||
'title' => $this->translator->trans('tokens.title'),
|
||||
'data' => $this->ts->getInstance()->getElement('data', $dataResult),
|
||||
'tokentypes' => TSInstance::getTokenTypes(),
|
||||
'channels' => $channels,
|
||||
'serverGroups' => $serverGroups,
|
||||
'channelGroups' => $channelGroups,
|
||||
'sid' => $sid
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -178,4 +178,31 @@ class TSInstance
|
|||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getTokenTypes()
|
||||
{
|
||||
$arr = [];
|
||||
$arr['TokenServerGroup'] = ts3admin::TokenServerGroup;
|
||||
$arr['TokenChannelGroup'] = ts3admin::TokenChannelGroup;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getPermGroupTypes()
|
||||
{
|
||||
$arr = [];
|
||||
$arr['PermGroupTypeServerGroup'] = ts3admin::PermGroupTypeServerGroup;
|
||||
$arr['PermGroupTypeGlobalClient'] = ts3admin::PermGroupTypeGlobalClient;
|
||||
$arr['PermGroupTypeChannel'] = ts3admin::PermGroupTypeChannel;
|
||||
$arr['PermGroupTypeChannelGroup'] = ts3admin::PermGroupTypeChannelGroup;
|
||||
$arr['PermGroupTypeChannelClient'] = ts3admin::PermGroupTypeChannelClient;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<h2 class="header">{% trans %}channel_info.h.actions{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'channel_info.send'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
@ -20,7 +20,7 @@
|
|||
{% if clients|length > 0 %}
|
||||
<h2 class="header">{% trans %}channel_info.h.clients{% endtrans %}</h2>
|
||||
{% include 'table.twig' with {'data': clients,
|
||||
'hide': [{'key': 'client_type', 'values': ['1']}],
|
||||
'hiddenDependingOnAttribute': [{'key': 'client_type', 'values': ['1']}],
|
||||
'links': [
|
||||
{'key': 'clid', 'uri': '/online/' ~ sid},
|
||||
{'key': 'client_database_id', 'uri': '/clients/' ~ sid, 'uri_param': 'client_database_id'}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<h1 class="header">{{ title }}</h1>
|
||||
<h2 class="header">{% trans %}client_info.h.actions{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'client_info.ban'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% for form in additional_forms %}
|
||||
{% for form in fields %}
|
||||
|
||||
<h3 class="header">{{ form.header_label }}</h3>
|
||||
{% set item = "#{form.uri}" %}
|
||||
|
@ -16,12 +16,23 @@
|
|||
{% for field in form.fields %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="{{ field.key }}">{{ field.label }}</label>
|
||||
|
||||
<div class="col-md-10">
|
||||
<input
|
||||
class="form-control"
|
||||
name="{{ field.key }}"
|
||||
id="{{ field.key }}"
|
||||
type="{{ field.type }}"/>
|
||||
{% if field.type == 'select' %}
|
||||
|
||||
<select class="form-control" name="{{ field.key }}" id="{{ field.key }}">
|
||||
{% for k,v in field.options %}
|
||||
<option class="form-control" value="{{ v }}">{{ k }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
{% else %}
|
||||
<input
|
||||
class="form-control"
|
||||
name="{{ field.key }}"
|
||||
id="{{ field.key }}"
|
||||
type="{{ field.type }}"/>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<h2 class="header">{% trans %}group_info.h.clients_add{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'group_info.add'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
<a href="/complains/{{ session_get('sid') }}">
|
||||
<li class="active withripple" data-target="#page">{% trans %}menu.servers.complains{% endtrans %}</li>
|
||||
</a>
|
||||
<a href="/tokens/{{ session_get('sid') }}">
|
||||
<li class="active withripple" data-target="#page">{% trans %}menu.servers.tokens{% endtrans %}</li>
|
||||
</a>
|
||||
<a href="/logs/{{ session_get('sid') }}">
|
||||
<li class="active withripple" data-target="#page">{% trans %}menu.servers.logs{% endtrans %}</li>
|
||||
</a>
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
<div class="col-md-8">
|
||||
{% if data|length >0 %}
|
||||
{% include 'table.twig' with {'data': data,
|
||||
'hide': [{'key': 'client_type', 'values': ['1']}],
|
||||
'hiddenDependingOnAttribute': [{'key': 'client_type', 'values': ['1']}],
|
||||
'hiddenColumns': ['client_type'],
|
||||
'filters': [
|
||||
{'key': 'client_idle_time', 'apply': 'timeInMillis'},
|
||||
{'key': 'connection_connected_time', 'apply': 'timeInSeconds'},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<h2 class="header">{% trans %}online_info.h.actions{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'online.poke'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<h2 class="header">{% trans %}server_info.h.actions{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'server_info.send'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
<h2 class="header">{% trans %}servers.h.create{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'additional_forms': [
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'server_create.label'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
{% endfor %}
|
||||
|
||||
{% for key in added %}
|
||||
<th>{{ key|replace({'_' : ' '})|title }}</th>
|
||||
{% if key not in hiddenColumns %}
|
||||
<th>{{ key|replace({'_' : ' '})|title }}</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for link in additional_links %}
|
||||
|
@ -19,62 +21,77 @@
|
|||
<tbody>
|
||||
|
||||
{% for arr in data %}
|
||||
{% set show = true %}
|
||||
|
||||
{% for hidden in hide %}
|
||||
{% if hidden.key in arr|keys and attribute(arr, hidden.key) in hidden.values %}
|
||||
{% set show = false %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set show = true %}
|
||||
|
||||
{% if show == true %}
|
||||
<tr>
|
||||
{% for key, value in arr %}
|
||||
{% set value = value %}
|
||||
{% for hidden in hiddenDependingOnAttribute %}
|
||||
{% if hidden.key in arr|keys and attribute(arr, hidden.key) in hidden.values %}
|
||||
{% set show = false %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for filter in filters %}
|
||||
{% if filter.key == key %}
|
||||
{% set value = value|apply_filter(filter.apply)|raw %}
|
||||
{% if show == true %}
|
||||
<tr>
|
||||
{% for key, value in arr %}
|
||||
{% set value = value %}
|
||||
|
||||
{% for filter in filters %}
|
||||
{% if filter.key == key %}
|
||||
{% set value = value|apply_filter(filter.apply)|raw %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% set showColumn = true %}
|
||||
|
||||
{% if key in hiddenColumns %}
|
||||
{% set showColumn = false %}
|
||||
{% endif %}
|
||||
|
||||
{% if showColumn %}
|
||||
{% set item = '<td>' ~ value ~ '</td>' %}
|
||||
|
||||
{% 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 = "<td><a href=\"#{link.uri}\/#{searchingValue}\">#{value}</a></td>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set item = "<td><a href=\"#{link.uri}\/#{value}\">#{value}</a></td>" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{{ item|raw }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% set item = '<td>' ~ value ~ '</td>' %}
|
||||
{% for link in additional_links %}
|
||||
|
||||
<td>
|
||||
{% set item = "<a href=\"#{link.uri}\">#{link.label}" %}
|
||||
|
||||
{% 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 = "<td><a href=\"#{link.uri}\/#{searchingValue}\">#{value}</a></td>" %}
|
||||
{% set shownValue = searchingValue %}
|
||||
|
||||
{% if link.apply is not empty %}
|
||||
{% set shownValue = shownValue|apply_filter(link.apply)|raw %}
|
||||
{% endif %}
|
||||
|
||||
{% set item = "<a href=\"#{link.uri}\/#{shownValue}\">#{link.label}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set item = "<td><a href=\"#{link.uri}\/#{value}\">#{value}</a></td>" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{{ item|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
{{ item|raw }}
|
||||
{% endfor %}
|
||||
|
||||
{% 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 item = "<a href=\"#{link.uri}\/#{searchingValue}\">#{link.label}</a>" %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{{ item|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
|
|
44
src/View/material/tokens.twig
Normal file
44
src/View/material/tokens.twig
Normal file
|
@ -0,0 +1,44 @@
|
|||
{% extends 'layout.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="header">{{ title }}</h1>
|
||||
|
||||
<h2 class="header">{% trans %}tokens.h.add{% endtrans %}</h2>
|
||||
{% include 'form.twig' with {
|
||||
'fields': [
|
||||
{
|
||||
'header_label': 'tokens.add'|trans,
|
||||
'label': '<i class="material-icons">check_circle</i>',
|
||||
'uri': '/tokens/add/' ~ sid,
|
||||
'uri_method': 'post',
|
||||
'fields': [
|
||||
{'type': 'select', 'key': 'tokentype', 'options': tokentypes, 'label': 'tokens.add.tokentype'|trans},
|
||||
{'type': 'select', 'key': 'serverGroup', 'options': serverGroups, 'label': 'tokens.add.serverGroup'|trans},
|
||||
{'type': 'select', 'key': 'channelGroup', 'options': channelGroups, 'label': 'tokens.add.channelGroup'|trans},
|
||||
{'type': 'select', 'key': 'channel', 'options': channels, 'label': 'tokens.add.channel'|trans},
|
||||
{'type': 'text', 'key': 'description', 'label': 'tokens.add.description'|trans},
|
||||
]
|
||||
}
|
||||
]
|
||||
} %}
|
||||
|
||||
{% if data|length >0 %}
|
||||
<h2 class="header">{% trans %}tokens.h.details{% endtrans %}</h2>
|
||||
{% include 'table.twig' with {'data': data,
|
||||
'filters': [
|
||||
{'key': 'token_created', 'apply': 'timestamp'},
|
||||
{'key': 'token_type', 'apply': 'tokentype'},
|
||||
],
|
||||
'hiddenColumns': ['token_id1','token_id2'],
|
||||
'additional_links': [
|
||||
{
|
||||
'header_label': 'tokens.delete'|trans,
|
||||
'label': '<i class="material-icons">delete</i>',
|
||||
'uri': '/tokens/delete/' ~ sid,
|
||||
'uri_param': 'token',
|
||||
'apply': 'escape_url'
|
||||
}
|
||||
],
|
||||
} %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
Reference in a new issue