show note if no entries exist for a listing

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2022-02-27 18:54:36 +01:00
parent 1a6b899c67
commit f1e91af58a
6 changed files with 201 additions and 189 deletions

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace Froxlor\UI; namespace Froxlor\UI;
use Froxlor\UI\Panel\UI; use Froxlor\UI\Panel\UI;
@@ -20,142 +21,143 @@ use Froxlor\UI\Panel\UI;
*/ */
class Listing class Listing
{ {
public static function format(Collection $collection, array $tabellisting): array public static function format(Collection $collection, array $tabellisting): array
{ {
$collection = $collection->get(); $collection = $collection->get();
return [ return [
'title' => $tabellisting['title'], 'title' => $tabellisting['title'],
'icon' => $tabellisting['icon'], 'icon' => $tabellisting['icon'],
'table' => [ 'table' => [
'th' => self::generateTableHeadings($tabellisting), 'th' => self::generateTableHeadings($tabellisting),
'tr' => self::generateTableRows($collection['data']['list'], $tabellisting), 'tr' => self::generateTableRows($collection['data']['list'], $tabellisting),
], ],
'pagination' => $collection['pagination'], 'pagination' => $collection['pagination'],
]; 'empty_msg' => $tabellisting['empty_msg'] ?? null
} ];
}
private static function generateTableHeadings(array $tabellisting): array private static function generateTableHeadings(array $tabellisting): array
{ {
$heading = []; $heading = [];
// Table headings for columns // Table headings for columns
foreach ($tabellisting['visible_columns'] as $visible_column) { foreach ($tabellisting['visible_columns'] as $visible_column) {
if (isset($tabellisting['columns'][$visible_column]['visible']) && !$tabellisting['columns'][$visible_column]['visible']) { if (isset($tabellisting['columns'][$visible_column]['visible']) && !$tabellisting['columns'][$visible_column]['visible']) {
continue; continue;
} }
$heading[$visible_column] = [ $heading[$visible_column] = [
'text' => $tabellisting['columns'][$visible_column]['label'], 'text' => $tabellisting['columns'][$visible_column]['label'],
'class' => $tabellisting['columns'][$visible_column]['class'] ?? null, 'class' => $tabellisting['columns'][$visible_column]['class'] ?? null,
]; ];
} }
// Table headings for actions // Table headings for actions
if (isset($tabellisting['actions'])) { if (isset($tabellisting['actions'])) {
$heading['actions'] = [ $heading['actions'] = [
'text' => UI::getLng('panel.options'), 'text' => UI::getLng('panel.options'),
'class' => 'text-end', 'class' => 'text-end',
]; ];
} }
return $heading; return $heading;
} }
private static function generateTableRows(array $list, array $tabellisting): array private static function generateTableRows(array $list, array $tabellisting): array
{ {
$rows = []; $rows = [];
// Create new row from item // Create new row from item
foreach ($list as $row => $item) { foreach ($list as $row => $item) {
// Generate columns from item // Generate columns from item
foreach ($tabellisting['visible_columns'] as $col => $visible_column) { foreach ($tabellisting['visible_columns'] as $col => $visible_column) {
if (isset($tabellisting['columns'][$visible_column]['visible']) && !$tabellisting['columns'][$visible_column]['visible']) { if (isset($tabellisting['columns'][$visible_column]['visible']) && !$tabellisting['columns'][$visible_column]['visible']) {
continue; continue;
} }
$format_callback = $tabellisting['columns'][$visible_column]['format_callback'] ?? null; $format_callback = $tabellisting['columns'][$visible_column]['format_callback'] ?? null;
$column = $tabellisting['columns'][$visible_column]['field']; $column = $tabellisting['columns'][$visible_column]['field'];
$data = self::getMultiArrayFromString($item, $column); $data = self::getMultiArrayFromString($item, $column);
if ($format_callback) { if ($format_callback) {
$rows[$row]['td'][$col]['data'] = call_user_func($format_callback, ['data' => $data, 'fields' => $item]); $rows[$row]['td'][$col]['data'] = call_user_func($format_callback, ['data' => $data, 'fields' => $item]);
} else { } else {
$rows[$row]['td'][$col]['data'] = $data; $rows[$row]['td'][$col]['data'] = $data;
} }
$rows[$row]['td'][$col]['class'] = $tabellisting['columns'][$visible_column]['class'] ?? null; $rows[$row]['td'][$col]['class'] = $tabellisting['columns'][$visible_column]['class'] ?? null;
} }
// Set row classes from format_callback // Set row classes from format_callback
if (isset($tabellisting['format_callback'])) { if (isset($tabellisting['format_callback'])) {
$class = []; $class = [];
foreach ($tabellisting['format_callback'] as $format_callback) { foreach ($tabellisting['format_callback'] as $format_callback) {
$class[] = call_user_func($format_callback, ['fields' => $item]); $class[] = call_user_func($format_callback, ['fields' => $item]);
} }
$rows[$row]['class'] = implode(' ', $class); $rows[$row]['class'] = implode(' ', $class);
} }
// Set all actions for row // Set all actions for row
if (isset($tabellisting['actions'])) { if (isset($tabellisting['actions'])) {
$actions = self::setLinks($tabellisting['actions'], $item); $actions = self::setLinks($tabellisting['actions'], $item);
$rows[$row]['td'][] = [ $rows[$row]['td'][] = [
'class' => 'text-end', 'class' => 'text-end',
'data' => [ 'data' => [
'type' => 'actions', 'type' => 'actions',
'data' => $actions 'data' => $actions
] ]
]; ];
} }
} }
return $rows; return $rows;
} }
private static function setLinks(array $actions, array $item): array private static function setLinks(array $actions, array $item): array
{ {
$linker = UI::getLinker(); $linker = UI::getLinker();
// Check each action for a href // Check each action for a href
foreach ($actions as $key => $action) { foreach ($actions as $key => $action) {
// Set link if href is an array // Set link if href is an array
if (isset($action['href']) && is_array($action['href'])) { if (isset($action['href']) && is_array($action['href'])) {
// Search for "columns" in our href array // Search for "columns" in our href array
foreach ($action['href'] as $href_key => $href_value) { foreach ($action['href'] as $href_key => $href_value) {
$length = strlen(':'); $length = strlen(':');
if (substr($href_value, 0, $length) === ':') { if (substr($href_value, 0, $length) === ':') {
$column = ltrim($href_value, ':'); $column = ltrim($href_value, ':');
$action['href'][$href_key] = $item[$column]; $action['href'][$href_key] = $item[$column];
} }
} }
// Set actual link from linker // Set actual link from linker
$actions[$key]['href'] = $linker->getLink($action['href']); $actions[$key]['href'] = $linker->getLink($action['href']);
} }
} }
return $actions; return $actions;
} }
public static function getVisibleColumnsForListing(string $listing, array $default_columns): array public static function getVisibleColumnsForListing(string $listing, array $default_columns): array
{ {
// Hier käme dann die Logik, die das aus der DB zieht ... // Hier käme dann die Logik, die das aus der DB zieht ...
// alternativ nimmt er die $default_columns, wenn kein Eintrag // alternativ nimmt er die $default_columns, wenn kein Eintrag
// in der DB definiert ist // in der DB definiert ist
return $default_columns; return $default_columns;
} }
public static function getMultiArrayFromString(array $arr, string $str) public static function getMultiArrayFromString(array $arr, string $str)
{ {
foreach (explode('.', $str) as $key) { foreach (explode('.', $str) as $key) {
if (!array_key_exists($key, $arr)) { if (!array_key_exists($key, $arr)) {
return null; return null;
} }
$arr = $arr[$key]; $arr = $arr[$key];
} }
return $arr; return $arr;
} }
} }

View File

@@ -24,6 +24,7 @@ return [
'domain_list' => [ 'domain_list' => [
'title' => $lng['admin']['domains'], 'title' => $lng['admin']['domains'],
'icon' => 'fa-solid fa-user', 'icon' => 'fa-solid fa-user',
'empty_msg' => $lng['admin']['domain_nocustomeraddingavailable'],
'columns' => [ 'columns' => [
'd.domain_ace' => [ 'd.domain_ace' => [
'label' => $lng['domains']['domainname'], 'label' => $lng['domains']['domainname'],

View File

@@ -24,22 +24,22 @@ return [
'title' => $lng['admin']['plans']['plans'], 'title' => $lng['admin']['plans']['plans'],
'icon' => 'fa-solid fa-user', 'icon' => 'fa-solid fa-user',
'columns' => [ 'columns' => [
'p.name' => [ 'p.name' => [
'label' => $lng['admin']['plans']['name'], 'label' => $lng['admin']['plans']['name'],
'field' => 'name', 'field' => 'name',
], ],
'p.description' => [ 'p.description' => [
'label' => $lng['admin']['plans']['description'], 'label' => $lng['admin']['plans']['description'],
'field' => 'description', 'field' => 'description',
], ],
'p.adminname' => [ 'p.adminname' => [
'label' => $lng['admin']['admin'], 'label' => $lng['admin']['admin'],
'field' => 'adminname', 'field' => 'adminname',
], ],
'p.ts' => [ 'p.ts' => [
'label' => $lng['admin']['plans']['last_update'], 'label' => $lng['admin']['plans']['last_update'],
'field' => 'ts', 'field' => 'ts',
], ],
], ],
'visible_columns' => Listing::getVisibleColumnsForListing('sslcertificates_list', [ 'visible_columns' => Listing::getVisibleColumnsForListing('sslcertificates_list', [
'p.name', 'p.name',
@@ -47,26 +47,26 @@ return [
'p.adminname', 'p.adminname',
'p.ts', 'p.ts',
]), ]),
'actions' => [ 'actions' => [
'edit' => [ 'edit' => [
'icon' => 'fa fa-edit', 'icon' => 'fa fa-edit',
'href' => [ 'href' => [
'section' => 'plans', 'section' => 'plans',
'page' => 'overview', 'page' => 'overview',
'action' => 'edit', 'action' => 'edit',
'id' => ':id' 'id' => ':id'
], ],
], ],
'delete' => [ 'delete' => [
'icon' => 'fa fa-trash', 'icon' => 'fa fa-trash',
'class' => 'text-danger', 'class' => 'text-danger',
'href' => [ 'href' => [
'section' => 'plans', 'section' => 'plans',
'page' => 'overview', 'page' => 'overview',
'action' => 'delete', 'action' => 'delete',
'id' => ':id' 'id' => ':id'
], ],
], ],
] ]
] ]
]; ];

View File

@@ -2146,3 +2146,4 @@ $lng['ssl_certificates']['certificate_for'] = 'Certificate for';
$lng['ssl_certificates']['valid_from'] = 'Valid from'; $lng['ssl_certificates']['valid_from'] = 'Valid from';
$lng['ssl_certificates']['valid_until'] = 'Valid until'; $lng['ssl_certificates']['valid_until'] = 'Valid until';
$lng['ssl_certificates']['issuer'] = 'Issuer'; $lng['ssl_certificates']['issuer'] = 'Issuer';
$lng['panel']['listing_empty'] = 'No entries found';

View File

@@ -1788,3 +1788,4 @@ $lng['serversettings']['acmeshpath']['description'] = 'Installationspfad zu acme
$lng['panel']['usage_statistics'] = 'Resourcen-Verbrauch'; $lng['panel']['usage_statistics'] = 'Resourcen-Verbrauch';
$lng['panel']['security_question'] = 'Sicherheitsabfrage'; $lng['panel']['security_question'] = 'Sicherheitsabfrage';
$lng['panel']['listing_empty'] = 'Keine Einträge gefunden';

View File

@@ -13,49 +13,56 @@
</h3> </h3>
{% endif %} {% endif %}
<div class="card table-responsive"> {% if listing.table.tr|length == 0 %}
<table class="table table-borderless table-striped table-sm mb-0 px-3"> <div class="alert alert-info" role="alert">
<thead> <h4 class="alert-heading">{{ lng('admin.note') }}</h4>
<tr> <p>{{ listing.empty_msg|default(lng('panel.listing_empty'))|raw }}</p>
{% for key,th in listing.table.th %} </div>
{{ pagination.titlesorting(listing.pagination, key, th) }} {% else %}
{% endfor %} <div class="card table-responsive">
</tr> <table class="table table-borderless table-striped table-sm mb-0 px-3">
</thead> <thead>
<tbody> <tr>
{% for tr in listing.table.tr %} {% for key,th in listing.table.th %}
<tr {% if tr.class is defined %}class="{{ tr.class }}"{% endif %}> {{ pagination.titlesorting(listing.pagination, key, th) }}
{% for td in tr.td %}
<td class="px-3{% if td.class is defined %} {{ td.class }}{% endif %}">
{% if td.data is iterable %}
{% if td.data.type == 'progressbar' %}
{{ callbacks.progressbar(td.data.data) }}
{% elseif td.data.type == 'boolean' %}
{{ callbacks.boolean(td.data.data) }}
{% elseif td.data.type == 'booleanWithInfo' %}
{{ callbacks.booleanWithInfo(td.data.data) }}
{% elseif td.data.type == 'link' %}
{{ callbacks.link(td.data.data) }}
{% elseif td.data.type == 'domainWithSan' %}
{{ callbacks.domainWithSan(td.data.data) }}
{% elseif td.data.type == 'actions' %}
{{ callbacks.actions(td.data.data) }}
{% else %}
Callback '{{ td|json_encode }}' is not implemented!
{% endif %}
{% else %}
{{ td.data|raw }}
{% endif %}
</td>
{% endfor %} {% endfor %}
</tr> </tr>
{% endfor %} </thead>
</tbody> <tbody>
</table> {% for tr in listing.table.tr %}
{% if listing.pagination is not empty %} <tr {% if tr.class is defined %} class="{{ tr.class }}" {% endif %}>
{{ pagination.paging(listing.pagination) }} {% for td in tr.td %}
{% endif %} <td class="px-3{% if td.class is defined %} {{ td.class }}{% endif %}">
</div> {% if td.data is iterable %}
{% if td.data.type == 'progressbar' %}
{{ callbacks.progressbar(td.data.data) }}
{% elseif td.data.type == 'boolean' %}
{{ callbacks.boolean(td.data.data) }}
{% elseif td.data.type == 'booleanWithInfo' %}
{{ callbacks.booleanWithInfo(td.data.data) }}
{% elseif td.data.type == 'link' %}
{{ callbacks.link(td.data.data) }}
{% elseif td.data.type == 'domainWithSan' %}
{{ callbacks.domainWithSan(td.data.data) }}
{% elseif td.data.type == 'actions' %}
{{ callbacks.actions(td.data.data) }}
{% else %}
Callback '{{ td|json_encode }}' is not implemented!
{% endif %}
{% else %}
{{ td.data|raw }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% if listing.pagination is not empty %}
{{ pagination.paging(listing.pagination) }}
{% endif %}
</div>
{% endif %}
</form> </form>
{% endmacro %} {% endmacro %}