Issue #1854 adding a new tab in maintenance page

This commit is contained in:
Willy "Linty 2023-12-04 17:34:52 +01:00
parent cba04ce5c6
commit 0ac1131e8c
9 changed files with 794 additions and 21 deletions

View file

@ -77,11 +77,11 @@ function add_core_tabs($sheets, $tab_id)
case 'configuration':
global $conf_link;
$sheets['main'] = array('caption' => l10n('General'), 'url' => $conf_link.'main');
$sheets['sizes'] = array('caption' => l10n('Photo sizes'), 'url' => $conf_link.'sizes');
$sheets['watermark'] = array('caption' => l10n('Watermark'), 'url' => $conf_link.'watermark');
$sheets['display'] = array('caption' => l10n('Display'), 'url' => $conf_link.'display');
$sheets['comments'] = array('caption' => l10n('Comments'), 'url' => $conf_link.'comments');
$sheets['main'] = array('caption' => '<span class="icon-cog"></span>'.l10n('General'), 'url' => $conf_link.'main');
$sheets['sizes'] = array('caption' => '<span class="icon-zoom-square"></span>'.l10n('Photo sizes'), 'url' => $conf_link.'sizes');
$sheets['watermark'] = array('caption' => '<span class="icon-file-image"></span>'.l10n('Watermark'), 'url' => $conf_link.'watermark');
$sheets['display'] = array('caption' => '<span class="icon-television"></span>'.l10n('Display'), 'url' => $conf_link.'display');
$sheets['comments'] = array('caption' => '<span class="icon-chat"></span>'.l10n('Comments'), 'url' => $conf_link.'comments');
// $sheets['default'] = array('caption' => l10n('Guest Settings'), 'url' => $conf_link.'default');
break;
@ -186,6 +186,7 @@ function add_core_tabs($sheets, $tab_id)
global $my_base_url;
$sheets['actions'] = array('caption' => '<span class="icon-tools"></span>'.l10n('Actions'), 'url' => $my_base_url.'maintenance&tab=actions');
$sheets['env'] = array('caption' => '<span class="icon-television"></span>'.l10n('Environment'), 'url' => $my_base_url.'maintenance&tab=env');
$sheets['sys'] = array('caption' => '<span class="icon-pulse"></span>'.l10n('System Activities'), 'url' => $my_base_url.'maintenance&tab=sys');
break;
}

View file

@ -24,6 +24,72 @@ if (isset($_GET['action']))
{
check_pwg_token();
}
// +-----------------------------------------------------------------------+
// | Commons parameters |
// +-----------------------------------------------------------------------+
$maint_actions = array(
'derivatives' => array(
'icon' => 'icon-trash-1',
'label' => l10n('Delete multiple size images'),
),
'lock_gallery' => array(
'icon' => 'icon-lock',
'label' => l10n('Lock gallery'),
),
'unlock_gallery' => array(
'icon' => 'icon-lock',
'label' => l10n('Unlock gallery'),
),
'categories' => array(
'icon' => 'icon-folder-open',
'label' => l10n('Update albums informations'),
),
'images' => array(
'icon' => 'icon-info-circled-1',
'label' => l10n('Update photos information'),
),
'delete_orphan_tags' => array(
'icon' => 'icon-tags',
'label' => l10n('Delete orphan tags'),
),
'user_cache' => array(
'icon' => 'icon-user-1',
'label' => l10n('Purge user cache'),
),
'history_detail' => array(
'icon' => 'icon-back-in-time',
'label' => l10n('Purge history detail'),
),
'history_summary' => array(
'icon' => 'icon-back-in-time',
'label' => l10n('Purge history summary'),
),
'sessions' => array(
'icon' => 'icon-th-list',
'label' => l10n('Purge sessions'),
),
'feeds' => array(
'icon' => 'icon-bell',
'label' => l10n('Purge never used notification feeds'),
),
'database' => array(
'icon' => 'icon-database',
'label' => l10n('Repair and optimize database'),
),
'c13y' => array(
'icon' => 'icon-ok',
'label' => l10n('Reinitialize check integrity'),
),
'search' => array(
'icon' => 'icon-search',
'label' => l10n('Purge search history'),
),
'compiled-templates' => array(
'icon' => 'icon-file-code',
'label' => l10n('Purge compiled templates'),
),
);
// +-----------------------------------------------------------------------+
// | tabs |
@ -34,7 +100,7 @@ $my_base_url = get_root_url().'admin.php?page=';
if (isset($_GET['tab']))
{
check_input_parameter('tab', $_GET, false, '/^(actions|env)$/');
check_input_parameter('tab', $_GET, false, '/^(actions|env|sys)$/');
$page['tab'] = $_GET['tab'];
}
else

View file

@ -282,6 +282,7 @@ list($db_current_date) = pwg_db_fetch_row(pwg_query('SELECT now();'));
$template->assign(
array(
'maint_actions' => $maint_actions,
'U_MAINT_CATEGORIES' => sprintf($url_format, 'categories'),
'U_MAINT_IMAGES' => sprintf($url_format, 'images'),
'U_MAINT_ORPHAN_TAGS' => sprintf($url_format, 'delete_orphan_tags'),

374
admin/maintenance_sys.php Normal file
View file

@ -0,0 +1,374 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
if (!defined('PHPWG_ROOT_PATH'))
{
die ("Hacking attempt!");
}
// +-----------------------------------------------------------------------+
// | Only Webmaster can see this tab |
// +-----------------------------------------------------------------------+
if (is_webmaster())
{
// Get system activities data
if (isset($_GET['method']) && 'pwg.activity_sys.getList' == $_GET['method'])
{
$response = array();
$data = array();
$query = '
SELECT
activity_id,
object,
object_id,
action,
performed_by,
occured_on,
details,
IF(performed_by = 0, \'System\', '.$conf['user_fields']['username'].') AS username
FROM '.ACTIVITY_TABLE.'
LEFT JOIN '.USERS_TABLE.' ON performed_by = '.$conf['user_fields']['id'].'
WHERE object = \'system\'
ORDER BY occured_on DESC';
// Format our data for frontend
$result = pwg_query($query);
while ($rows = pwg_db_fetch_assoc($result))
{
$major_infos = false;
$object = '';
$object_icon = '';
$action_icon = '';
$action_color = '';
$action = $rows['action'];
$date = '';
$hour = '';
$details = unserialize($rows['details']);
$detail = array(
'type' => 'empty',
);
// For each categories (Core, Plugin and Theme) we need to format theirs actions
switch ($rows['object_id'])
{
case ACTIVITY_SYSTEM_CORE:
$object_icon = 'icon-heart';
$object = l10n('Core');
switch ($rows['action'])
{
case 'install':
$action_icon = 'icon-download';
$action_color = 'icon-green';
$action = l10n('Install');
break;
case 'config':
$action_icon = 'icon-cog-alt';
$action_color = 'icon-yellow';
$action = l10n('Configuration');
// for config we need to specific format details
if (isset($details['config_section']))
{
$c_icon = '';
$c_text = '';
switch ($details['config_section'])
{
case 'main':
$c_icon = 'icon-cog';
$c_text = l10n('General');
break;
case 'watermark':
$c_icon = 'icon-file-image';
$c_text = l10n('Watermark');
break;
case 'sizes':
$c_icon = 'icon-zoom-square';
$c_text = l10n('Photo sizes');
// sizes have 2 params always Photo sizes and sometimes config_action
if (isset($details['config_action']) && 'restore_settings' == $details['config_action'])
{
$detail[] = array(
'icon' => 'icon-back-in-time',
'text' => l10n('Set as default')
);
}
break;
case 'comments':
$c_icon = 'icon-chat';
$c_text = l10n('Comments');
break;
case 'display':
$c_icon = 'icon-television';
$c_text = l10n('Display');
break;
default:
$c_icon = 'icon-cog-alt';
$c_text = $details['config_section'];
break;
}
$detail['type'] = 'config_section';
$detail[] = array(
'icon' => $c_icon,
'text' => $c_text
);
}
break;
case 'maintenance':
$action_icon = 'icon-cone';
$action_color = 'icon-yellow';
$action = l10n('Maintenance');
// for maintenance we need to specific format details
if (isset($details['maintenance_action']))
{
$action_detail = $details['maintenance_action'];
$detail = array(
'type' => 'maintenance_action',
'icon' => $maint_actions[$action_detail]['icon'] ?? 'icon-cone',
'text' => $maint_actions[$action_detail]['label'] ?? $action_detail,
);
}
break;
case 'update':
$action_icon = 'icon-arrows-cw';
$action_color = 'icon-blue';
$action = l10n('Update');
$major_infos = true;
break;
case 'autoupdate':
$action_icon = 'icon-arrows-cw';
$action_color = 'icon-blue';
$action = l10n('Auto-update');
$major_infos = true;
break;
default:
$action_icon = 'icon-download';
$action_color = 'icon-yellow';
break;
}
break;
case ACTIVITY_SYSTEM_PLUGIN:
$object_icon = 'icon-puzzle';
$object = str_replace(['_', '-'], ' ', $details['plugin_id']);
switch ($rows['action'])
{
case 'install':
$action_icon = 'icon-download';
$action_color = 'icon-green';
$action = l10n('Install');
break;
case 'update':
$action_icon = 'icon-arrows-cw';
$action_color = 'icon-blue';
$action = l10n('Update');
break;
case 'activate':
$action_icon = 'icon-check';
$action_color = 'icon-green';
$action = l10n('Activate');
break;
case 'deactivate':
$action_icon = 'icon-block';
$action_color = 'icon-purple';
$action = l10n('Deactivate');
break;
case 'uninstall':
$action_icon = 'icon-trash-1';
$action_color = 'icon-red';
$action = l10n('Uninstall');
break;
case 'restore':
$action_icon = 'icon-back-in-time';
$action_color = 'icon-blue';
$action = l10n('Restore');
break;
case 'delete':
$action_icon = 'icon-trash-1';
$action_color = 'icon-red';
$action = l10n('Delete');
// for delete we need to specific format details
if (isset($details['db_version']))
{
$detail['type'] = 'db_fs_version';
$detail[] = array(
'icon' => 'icon-flow-branch',
'text' => 'database : ' . $details['db_version']
);
}
if (isset($details['fs_version']))
{
$detail['type'] = 'db_fs_version';
$detail[] = array(
'icon' => 'icon-flow-branch',
'text' => 'filesystem : ' . $details['fs_version']
);
}
break;
case 'autoupdate':
$action_icon = 'icon-arrows-cw';
$action_color = 'icon-blue';
$action = l10n('Auto-update');
break;
default:
$action_icon = 'icon-puzzle';
$action_color = 'icon-yellow';
break;
}
break;
case ACTIVITY_SYSTEM_THEME:
$object_icon = 'icon-brush';
$object = str_replace(['_', '-'], ' ', $details['theme_id']);
switch ($rows['action'])
{
case 'install':
$action_icon = 'icon-download';
$action_color = 'icon-green';
$action = l10n('Install');
break;
case 'activate':
$action_icon = 'icon-check';
$action_color = 'icon-green';
$action = l10n('Activate');
break;
case 'deactivate':
$action_icon = 'icon-block';
$action_color = 'icon-purple';
$action = l10n('Deactivate');
break;
case 'delete':
$action_icon = 'icon-trash-1';
$action_color = 'icon-red';
$action = l10n('Delete');
break;
case 'set_default':
$action_icon = 'icon-star';
$action_color = 'icon-yellow';
$action = l10n('Set as default');
break;
case 'update':
$action_icon = 'icon-arrows-cw';
$action_color = 'icon-blue';
$action = l10n('Update');
break;
default:
$action_icon = 'icon-brush';
$action_color = 'icon-yellow';
break;
}
break;
default:
break;
}
// For each lines we need to format theirs details (general details)
if (isset($details['from_version']))
{
$detail = array(
'type' => 'from_to',
array(
'icon' => 'icon-flow-branch',
'text' => $details['from_version'],
),
array(
'icon' => isset($details['to_version']) ? 'icon-flow-branch' : 'icon-block',
'text' => isset($details['to_version']) ? $details['to_version'] : ($details['result'] ?? ''),
),
);
}
else if (isset($details['version']))
{
$detail = array(
'type' => 'version',
'icon' => 'icon-flow-branch',
'text' => $details['version']
);
}
else if (isset($details['result']))
{
$detail = array(
'type' => 'error',
'icon' => 'icon-block',
'text' => $details['result']
);
}
// Format our data before send
// This data will be manipulate by maintenance_sys.js
list($date, $hour) = explode(' ', $rows['occured_on']);
$data[] = array(
'major_infos' => $major_infos,
'id' => $rows['activity_id'],
'object_icon' => $object_icon,
'object' => ucwords($object),
'action_icon' => $action_icon,
'action_color' => $action_color,
'action' => $action,
'user_id' => $rows['performed_by'],
'username' => $rows['username'],
'date' => format_date($date),
'hour' => $hour,
'detail' => $detail
);
}
// Now we good to send our response data
$response = array(
'data' => $data,
);
echo json_encode($response);
exit;
}
}
else
{
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
}
// +-----------------------------------------------------------------------+
// | template init |
// +-----------------------------------------------------------------------+
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
$template->set_filenames(array('maintenance'=>'maintenance_sys.tpl'));
// +-----------------------------------------------------------------------+
// | sending html code |
// +-----------------------------------------------------------------------+
$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
?>

View file

@ -0,0 +1,116 @@
const color_icons = ["icon-red", "icon-blue", "icon-yellow", "icon-purple", "icon-green"];
function line_constructor(line){
let new_line = $('#body_example').clone();
const line_details_example = $('#line_details_example').clone();
const initial_user = line.username.charAt(0).toUpperCase();
// id
new_line.attr('id', line.id);
// Display major information
if (line.major_infos) {
new_line.addClass('major-infos');
}
// Display object
new_line.find('.icon_object').addClass(line.object_icon);
new_line.find('.text_object').text(line.object).attr('title', line.object);
// Display action
new_line.find('.color_action').addClass(line.action_color);
new_line.find('.icon_action').addClass(line.action_icon);
new_line.find('.text_action').text(line.action).attr('title', line.action);
// Display Username
'System' == line.username
? new_line.find('.icon_user').addClass('icon-wrench')
: new_line.find('.icon_user').addClass(color_icons[line.user_id % 5]).html(initial_user);
new_line.find('.text_username').text(line.username).attr('title', line.username);
// Display date & hour
new_line.find('.text_date').text(line.date).attr('title', line.date + ' ' + line.hour);
new_line.find('.text_hour').text(line.hour);
// Display Details
switch(line.detail.type){
case 'empty':
default:
// For empty CSS do it for us but he exist
break;
// Here is when we want to display only one element in details (and default)
case 'error':
case 'version':
case 'maintenance_action':
let new_line_detail = line_details_example.clone();
new_line_detail.removeAttr('id');
new_line_detail.find('.icon_details').addClass(line.detail.icon);
new_line_detail.find('.text_details').text(line.detail.text).attr('title', line.detail.text);
new_line.find('.tab-body-details').append(new_line_detail);
break;
// Here is when we want to display multiple elements one by one (Work if details can have one or multiple elements)
case 'db_fs_version':
case 'config_section':
Object.keys(line.detail)
.filter((key) => 'type' !== key)
.forEach((key) => {
let detail = line.detail[key];
let new_line_details = line_details_example.clone();
new_line_details.removeAttr('id');
new_line_details.find('.icon_details').addClass(detail.icon);
new_line_details.find('.text_details').text(detail.text).attr('title', detail.text);
new_line.find('.tab-body-details').append(new_line_details);
});
break;
// Here is when we need to specific the format for somes types
// from_to
case 'from_to':
let from = line_details_example.clone();
from.removeAttr('id');
from.find('.icon_details').addClass(line.detail[0].icon);
from.find('.text_details').text(line.detail[0].text).attr('title', line.detail[0].text);
new_line.find('.tab-body-details').append(from);
new_line.find('.tab-body-details').append('<span class="icon-right"> </span>');
let to = line_details_example.clone();
to.removeAttr('id');
to.find('.icon_details').addClass(line.detail[1].icon);
to.find('.text_details').text(line.detail[1].text).attr('title', line.detail[1].text);
new_line.find('.tab-body-details').append(to);
break;
}
$('#tab-body-content').append(new_line);
}
function get_system_activities(){
$.ajax({
url: window.location.href,
type: 'GET',
data: {
method: 'pwg.activity_sys.getList'
},
dataType: 'json',
success: (response) => {
const lines = response.data;
// help to debug
// console.log(lines);
$('.loading').hide();
lines.forEach((line) => line_constructor(line));
},
error: (e) => {
console.log(e);
}
});
}
$(document).ready(function() {
get_system_activities();
});

View file

@ -124,26 +124,26 @@ $(".delete-size-check").click( function () {
<legend><span class="icon-globe icon-blue"></span>{'Global Gallery Actions'|translate}</legend>
<div style="display:flex;flex-wrap: wrap;">
{if (isset($U_MAINT_LOCK_GALLERY))}
<a href="{$U_MAINT_LOCK_GALLERY}" class="lock-gallery-button icon-lock maintenance-action">{'Lock gallery'|@translate}</a>
<a href="{$U_MAINT_LOCK_GALLERY}" class="lock-gallery-button {$maint_actions['lock_gallery']['icon']} maintenance-action">{$maint_actions['lock_gallery']['label']}</a>
{else}
<a href="{$U_MAINT_UNLOCK_GALLERY}" class="lock-gallery-button icon-lock maintenance-action">{'Unlock gallery'|@translate}</a>
<a href="{$U_MAINT_UNLOCK_GALLERY}" class="lock-gallery-button {$maint_actions['unlock_gallery']['icon']} maintenance-action">{$maint_actions['unlock_gallery']['label']}</a>
{/if}
<a href="{$U_MAINT_CATEGORIES}" class="icon-folder-open maintenance-action">{'Update albums informations'|@translate}</a>
<a href="{$U_MAINT_IMAGES}" class="icon-info-circled-1 maintenance-action">{'Update photos information'|@translate}</a>
<a href="{$U_MAINT_DATABASE}" class="icon-database maintenance-action">{'Repair and optimize database'|@translate}</a>
<a href="{$U_MAINT_C13Y}" class="icon-ok maintenance-action">{'Reinitialize check integrity'|@translate}</a>
<a href="{$U_MAINT_CATEGORIES}" class="{$maint_actions['categories']['icon']} maintenance-action">{$maint_actions['categories']['label']}</a>
<a href="{$U_MAINT_IMAGES}" class="{$maint_actions['images']['icon']} maintenance-action">{$maint_actions['images']['label']}</a>
<a href="{$U_MAINT_DATABASE}" class="{$maint_actions['database']['icon']} maintenance-action">{$maint_actions['database']['label']}</a>
<a href="{$U_MAINT_C13Y}" class="{$maint_actions['c13y']['icon']} maintenance-action">{$maint_actions['c13y']['label']}</a>
</div>
</fieldset>
<fieldset class="">
<legend><span class="icon-trash-1 icon-green"></span>{'Purge Actions'|@translate}</legend>
<div style="display:flex;flex-wrap: wrap;">
<a href="{$U_MAINT_USER_CACHE}" class="icon-user-1 maintenance-action">{'Purge user cache'|@translate}</a>
<a href="{$U_MAINT_ORPHAN_TAGS}" class="icon-tags maintenance-action">{'Delete orphan tags'|@translate}</a>
<a href="{$U_MAINT_HISTORY_DETAIL}" class="icon-back-in-time maintenance-action purge-history-detail-button">{'Purge history detail'|@translate}</a>
<a href="{$U_MAINT_HISTORY_SUMMARY}" class="icon-back-in-time maintenance-action purge-history-summary-button">{'Purge history summary'|@translate}</a>
<a href="{$U_MAINT_SESSIONS}" class="icon-th-list maintenance-action">{'Purge sessions'|@translate}</a>
<a href="{$U_MAINT_FEEDS}" class="icon-bell maintenance-action">{'Purge never used notification feeds'|@translate}</a>
<a href="{$U_MAINT_SEARCH}" class="icon-search maintenance-action purge-search-history-button">{'Purge search history'|@translate}</a>
<a href="{$U_MAINT_USER_CACHE}" class="{$maint_actions['user_cache']['icon']} maintenance-action">{$maint_actions['user_cache']['label']}</a>
<a href="{$U_MAINT_ORPHAN_TAGS}" class="{$maint_actions['delete_orphan_tags']['icon']} maintenance-action">{$maint_actions['delete_orphan_tags']['label']}</a>
<a href="{$U_MAINT_HISTORY_DETAIL}" class="{$maint_actions['history_detail']['icon']} maintenance-action purge-history-detail-button">{$maint_actions['history_detail']['label']}</a>
<a href="{$U_MAINT_HISTORY_SUMMARY}" class="{$maint_actions['history_summary']['icon']} maintenance-action purge-history-summary-button">{$maint_actions['history_summary']['label']}</a>
<a href="{$U_MAINT_SESSIONS}" class="{$maint_actions['sessions']['icon']} maintenance-action">{$maint_actions['sessions']['label']}</a>
<a href="{$U_MAINT_FEEDS}" class="{$maint_actions['feeds']['icon']} maintenance-action">{$maint_actions['feeds']['label']}</a>
<a href="{$U_MAINT_SEARCH}" class="{$maint_actions['search']['icon']} maintenance-action purge-search-history-button">{$maint_actions['search']['label']}</a>
</div>
</fieldset>
@ -175,7 +175,7 @@ $(".delete-size-check").click( function () {
<span class="cache-lastCalculated-value">{if $time_elapsed_since_last_calc} {$time_elapsed_since_last_calc} {else} &ThickSpace;{"never calculated"|@translate} {/if}</span>
<a class="refresh-cache-size"><span class="refresh-icon icon-arrows-cw"></span>{'Refresh'|@translate}</a>
</div>
<a href="{$U_MAINT_COMPILED_TEMPLATES}" class="icon-file-code maintenance-action">{'Purge compiled templates'|@translate}
<a href="{$U_MAINT_COMPILED_TEMPLATES}" class="{$maint_actions['compiled-templates']['icon']} maintenance-action">{$maint_actions['compiled-templates']['label']}
<span class="multiple-compiledTemplate-sizes">
{if isset($cache_sizes)}
{"%s MB"|@translate:{round($cache_sizes[2]['value']/1024/1024, 2)}}
@ -187,7 +187,7 @@ $(".delete-size-check").click( function () {
</div>
<div class="delete-size-checks">
<span id="label-delete-size-checkbox">{'Delete multiple size images'|@translate}
<span id="label-delete-size-checkbox">{$maint_actions['derivatives']['label']}
<span class="multiple-pictures-sizes">
{if isset($cache_sizes)}
{"%s MB"|@translate:{round($cache_sizes[1]['value']['all']/1024/1024, 2)}}

View file

@ -0,0 +1,209 @@
{if $isWebmaster == 1}
{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *}
{combine_script id='sys' load='footer' path='admin/themes/default/js/maintenance_sys.js'}
<fieldset id="activities-system">
<div class="tab-header">
<div class="tab-object">
<p>{'Object'|translate}</p>
</div>
<div class="tab-action">
<p>{'Action'|translate}</p>
</div>
<div class="tab-users">
<p>{'Users'|translate}</p>
</div>
<div class="tab-date">
<p>{'Date'|translate}</p>
</div>
<div class="tab-details">
<p>{'Details'|translate}</p>
</div>
</div>
<div class="loading">
<span class="icon-spin6 animate-spin"></span>
</div>
<div class="tab-body line" id="body_example">
<div class="tab-body-object">
<p>
<span class="icon_object"> </span>
<span class="text_object">Object</span>
</p>
</div>
<div class="tab-body-action">
<p class="color_action">
<span class="icon_action"> </span>
<span class="text_action">Action</span>
</p>
</div>
<div class="tab-body-users">
<p>
<span class="icon_user"></span>
<span class="text_username">Username</span>
</p>
</div>
<div class="tab-body-date">
<p>
<span class="icon icon-clock"></span>
<span class="text_date">Date</span>
<span class="text_hour">Hour</span>
</p>
</div>
<div class="tab-body-details">
<p class="detail-item" id="line_details_example">
<span class="icon_details"></span>
<span class="text_details">Details</span>
</p>
</div>
</div>
<div id="tab-body-content"></div>
</fieldset>
<style>
#body_example {
display: none;
}
#line_details_example {
display: none;
}
.icon-th-list {
padding: 0;
font-size: unset;
}
.loading {
font-size: 40px;
}
.major-infos {
position: relative;
}
.major-infos::before {
content: '';
display: block;
width: 8px;
height: 100%;
background-color: #F4AB4F;
position: absolute;
left: -8px;
}
.tab-header,
.tab-body {
display: grid;
grid-template-columns: 1fr 1.2fr 1fr 1.2fr 2fr;
text-align: start;
}
.tab-body-object,
.tab-body-users,
.tab-body-date {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 5px;
}
.tab-body-object p,
.tab-body-users p,
.tab-body-date p {
display: inline;
}
.tab-body-action,
.tab-body-details {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 5px;
padding: 10px;
}
.tab-header p {
color: #9e9e9e;
font-size: 1.1em;
font-weight: bold;
}
.tab-body {
min-height: 40px;
align-content: center;
align-items: center;
margin-bottom: 10px;
}
.tab-body p {
font-weight: bold;
margin: 0;
}
.tab-body-object .icon_object {
margin-left: 10px;
margin-right: 0.4em;
}
.tab-body-action .color_action {
display: inline;
border-radius: 23px;
padding: 5px 15px 5px 7px;
}
.tab-body-action .icon_action {
margin-right: 0.3em;
}
.tab-body-users p {
display: flex;
align-items: center;
}
.tab-body-users .icon_user {
width: 30px;
height: 30px;
min-width: 30px;
border-radius: 50%;
margin-right: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: 600;
font-size: 17px;
}
.tab-body-date .icon {
font-weight: bold;
}
.tab-body-date .text_hour {
font-weight: normal;
}
.tab-body-details p {
display: inline;
align-items: center;
border-radius: 3px !important;
padding: 4px !important;
padding-right: 8px !important;
margin-right: 5px !important;
font-weight: normal;
}
@media (min-width: 1350px) {
.tab-header,
.tab-body {
grid-template-columns: 1fr 1fr 1fr 1.7fr 2fr;
}
}
@media (min-width: 1650px) {
.tab-header,
.tab-body {
grid-template-columns: 1fr 1.2fr 1fr 1.6fr 3fr;
}
}
</style>
{/if}

View file

@ -1351,4 +1351,7 @@ $lang['Activate button "%s"'] = 'Activate button "%s"';
$lang['Detect and avoid duplicates during upload'] = 'Detect and avoid duplicates during upload';
$lang['During upload, if Piwigo detects the photo already exists, associate the existing photo to the destination album, without duplicating file'] = 'During upload, if Piwigo detects the photo already exists, associate the existing photo to the destination album, without duplicating file';
$lang['%d files'] = "%d files";
$lang['Auto-update'] = 'Auto-update';
$lang['Core'] = 'Core';
$lang['System Activities'] = 'System Activities';
// Leave this line empty

View file

@ -1351,4 +1351,7 @@ $lang['Activate button "%s"'] = 'Afficher le bouton "%s"';
$lang['Detect and avoid duplicates during upload'] = 'Détecter et éviter les doublons à l\'import';
$lang['During upload, if Piwigo detects the photo already exists, associate the existing photo to the destination album, without duplicating file'] = 'Pendant l\'ajout de photo, si Piwigo détecte que la photo existe déjà, associer la photo existante à l\'album de destination, sans dupliquer le fichier.';
$lang['%d files'] = "%d fichiers";
$lang['Auto-update'] = 'Mise à jour auto';
$lang['Core'] = 'Noyau';
$lang['System Activities'] = 'Activités système';
// Leave this line empty