From 10a8db21023bfa64b111d1d46e3b16ed2e95f270 Mon Sep 17 00:00:00 2001 From: HWFord <54360213+HWFord@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:20:16 +0200 Subject: [PATCH] fixes #2164 batch manager unit mode redesign (#2179) * Interface Update Update front end according to web design Completed the implementation of album manager * Added image delete mechanism * Update Validation * Added filters according to global mode Page is now fully translated from EN_uk to FR_fr Harmonized global and unit mode by creating a template for the filters TODO : Uncomment updateBlock calls in metaSync and implement tags update Uncomment pluginSave method and test it with an updated plugin --------- Co-authored-by: marsooooo --- admin/batch_manager_unit.php | 289 ++++++++- admin/themes/default/js/album_selector.js | 17 +- admin/themes/default/js/batchManagerFilter.js | 69 +++ admin/themes/default/js/batchManagerGlobal.js | 70 --- admin/themes/default/js/batchManagerUnit.js | 556 ++++++++++++++++++ .../default/template/batch_manager_global.tpl | 247 +------- .../default/template/batch_manager_unit.tpl | 403 ++++++++++--- .../include/batch_manager_filter.inc.tpl | 239 ++++++++ admin/themes/default/theme.css | 332 ++++++++++- language/en_UK/admin.lang.php | 11 + language/fr_FR/admin.lang.php | 11 + 11 files changed, 1832 insertions(+), 412 deletions(-) create mode 100644 admin/themes/default/js/batchManagerFilter.js create mode 100644 admin/themes/default/js/batchManagerUnit.js create mode 100644 admin/themes/default/template/include/batch_manager_filter.inc.tpl diff --git a/admin/batch_manager_unit.php b/admin/batch_manager_unit.php index 352f8d2f0..d69577d01 100644 --- a/admin/batch_manager_unit.php +++ b/admin/batch_manager_unit.php @@ -96,6 +96,40 @@ SELECT id, date_creation invalidate_user_cache(); } +//collection +$collection = array(); +if (isset($_POST['nb_photos_deleted'])) +{ + check_input_parameter('nb_photos_deleted', $_POST, false, '/^\d+$/'); + + // let's fake a collection (we don't know the image_ids so we use "null", we only + // care about the number of items here) + $collection = array_fill(0, $_POST['nb_photos_deleted'], null); +} +else if (isset($_POST['setSelected'])) +{ + // Here we don't use check_input_parameter because preg_match has a limit in + // the repetitive pattern. Found a limit to 3276 but may depend on memory. + // + // check_input_parameter('whole_set', $_POST, false, '/^\d+(,\d+)*$/'); + // + // Instead, let's break the input parameter into pieces and check pieces one by one. + $collection = explode(',', $_POST['whole_set']); + + foreach ($collection as $id) + { + if (!preg_match('/^\d+$/', $id)) + { + fatal_error('[Hacking attempt] the input parameter "whole_set" is not valid'); + } + } +} +else if (isset($_POST['selection'])) +{ + $collection = $_POST['selection']; +} + + // +-----------------------------------------------------------------------+ // | template init | // +-----------------------------------------------------------------------+ @@ -105,15 +139,132 @@ $template->set_filenames( $base_url = PHPWG_ROOT_PATH.'admin.php'; + $template->assign( array( + 'U_ELEMENTS_PAGE' => $base_url.get_query_string_diff(array('display','start')), - 'F_ACTION' => $base_url.get_query_string_diff(array()), 'level_options' => get_privacy_level_options(), 'ADMIN_PAGE_TITLE' => l10n('Batch Manager'), 'PWG_TOKEN' => get_pwg_token(), ) ); + //prefilter + $prefilters = array( + array('ID' => 'caddie', 'NAME' => l10n('Caddie')), + array('ID' => 'favorites', 'NAME' => l10n('Your favorites')), + array('ID' => 'last_import', 'NAME' => l10n('Last import')), + array('ID' => 'no_album', 'NAME' => l10n('With no album').' ('.l10n('Orphans').')'), + array('ID' => 'no_tag', 'NAME' => l10n('With no tag')), + array('ID' => 'duplicates', 'NAME' => l10n('Duplicates')), + array('ID' => 'all_photos', 'NAME' => l10n('All')) + ); + + if ($conf['enable_synchronization']) + { + $prefilters[] = array('ID' => 'no_virtual_album', 'NAME' => l10n('With no virtual album')); + $prefilters[] = array('ID' => 'no_sync_md5sum', 'NAME' => l10n('With no checksum')); + } + + function UC_name_compare($a, $b) + { + return strcmp(strtolower($a['NAME']), strtolower($b['NAME'])); + } + + $prefilters = trigger_change('get_batch_manager_prefilters', $prefilters); + + // Sort prefilters by localized name. + usort($prefilters, function ($a, $b) { + return strcmp(strtolower($a['NAME']), strtolower($b['NAME'])); + }); + + $template->assign( + array( + 'conf_checksum_compute_blocksize' => $conf['checksum_compute_blocksize'], + 'prefilters' => $prefilters, + 'filter' => $_SESSION['bulk_manager_filter'], + 'selection' => $collection, + 'all_elements' => $page['cat_elements_id'], + 'START' => $page['start'], + 'U_DISPLAY'=>$base_url.get_query_string_diff(array('display')), + 'F_ACTION'=>$base_url.get_query_string_diff(array('cat','start','tag','filter')), + ) + ); + + if (isset($page['no_md5sum_number'])) + { + $template->assign( + array( + 'NB_NO_MD5SUM' => $page['no_md5sum_number'], + ) + ); + } else { + $template->assign('NB_NO_MD5SUM', ''); + } + + + // privacy level + foreach ($conf['available_permission_levels'] as $level) + { + $level_options[$level] = l10n(sprintf('Level %d', $level)); + + if (0 == $level) + { + $level_options[$level] = l10n('Everybody'); + } + } + $template->assign( + array( + 'filter_level_options'=> $level_options, + 'filter_level_options_selected' => isset($_SESSION['bulk_manager_filter']['level']) + ? $_SESSION['bulk_manager_filter']['level'] + : 0, + ) + ); + + // tags + $filter_tags = array(); + + if (!empty($_SESSION['bulk_manager_filter']['tags'])) + { + $query = ' + SELECT + id, + name + FROM '.TAGS_TABLE.' + WHERE id IN ('.implode(',', $_SESSION['bulk_manager_filter']['tags']).') + ;'; + + $filter_tags = get_taglist($query); + } + + $template->assign('filter_tags', $filter_tags); + + // in the filter box, which category to select by default + $selected_category = array(); + + if (isset($_SESSION['bulk_manager_filter']['category'])) + { + $selected_category = array($_SESSION['bulk_manager_filter']['category']); + } + else + { + // we need to know the category in which the last photo was added + $query = ' + SELECT category_id + FROM '.IMAGE_CATEGORY_TABLE.' + ORDER BY image_id DESC + LIMIT 1 + ;'; + $result = pwg_query($query); + if (pwg_db_num_rows($result) > 0) + { + $row = pwg_db_fetch_assoc($result); + $selected_category[] = $row['category_id']; + } + } + + $template->assign('filter_category_selected', $selected_category); // +-----------------------------------------------------------------------+ // | global mode thumbnails | @@ -122,6 +273,8 @@ $template->assign( // how many items to display on this page if (!empty($_GET['display'])) { + // conf_update_param('batch_manager_images_per_page_unit' , intval($_GET['display'])); + // $page['nb_images'] = $conf['batch_manager_images_per_page_unit']; $page['nb_images'] = intval($_GET['display']); } elseif (in_array($conf['batch_manager_images_per_page_unit'], array(5, 10, 50))) @@ -132,7 +285,7 @@ else { $page['nb_images'] = 5; } - +$template->assign('per_page', $conf['batch_manager_images_per_page_unit']); if (count($page['cat_elements_id']) > 0) @@ -193,6 +346,20 @@ SELECT * LIMIT '.$page['nb_images'].' OFFSET '.$page['start'].' ;'; $result = pwg_query($query); + + $storage_category_id = null; + if (!empty($row['storage_category_id'])) + { + $storage_category_id = $row['storage_category_id']; + } + + $level_convert = [ + "0" => "4", + "1" => "3", + "2" => "2", + "4" => "1", + "8" => "0", +]; while ($row = pwg_db_fetch_assoc($result)) { @@ -200,6 +367,10 @@ SELECT * $src_image = new SrcImage($row); + $image_file = $row['file']; + + + $query = ' SELECT id, @@ -208,6 +379,7 @@ SELECT JOIN '.TAGS_TABLE.' AS t ON t.id = it.tag_id WHERE image_id = '.$row['id'].' ;'; + $tag_selection = get_taglist($query); $legend = render_element_name($row); @@ -216,12 +388,95 @@ SELECT $legend.= ' ('.$row['file'].')'; } $extTab = explode('.',$row['path']); + + + +// represent + + // categories + + $query = ' + SELECT category_id, uppercats, dir + FROM '.IMAGE_CATEGORY_TABLE.' AS ic + INNER JOIN '.CATEGORIES_TABLE.' AS c + ON c.id = ic.category_id + WHERE image_id = '.$row['id'].' + ;'; + + $sub_result = pwg_query($query); + $related_categories = array(); + $related_category_ids = array(); + $media['image'] = get_image_infos($row['id'], true); + while ($item = pwg_db_fetch_assoc($sub_result)) + { + $name = + get_cat_display_name_cache( + $item['uppercats'], + get_root_url().'admin.php?page=album-' + ); + + if ($item['category_id'] == $storage_category_id) + { + $template->assign('STORAGE_CATEGORY', $name); + } + + $related_categories[$item['category_id']] = array('name' => $name, 'unlinkable' => $item['category_id'] != $storage_category_id); + $related_category_ids[] = $item['category_id']; + } + + // jump to link + $image_file = $row['file']; + + $query = ' + SELECT category_id + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE image_id = '.$row['id'].' + ;'; + $authorizeds = array_diff( + array_from_query($query, 'category_id'), + explode( + ',', + calculate_permissions($user['id'], $user['status']) + ) + ); + + if (isset($row['cat_id']) + and in_array($row['cat_id'], $authorizeds)) + { + $url_img = make_picture_url( + array( + 'image_id' => $row['id'], + 'image_file' => $image_file, + 'category' => $cache['cat_names'][ $row['cat_id'] ], + ) + ); + } + else + { + foreach ($authorizeds as $category) + { + $url_img = make_picture_url( + array( + 'image_id' => $row['id'], //utile ? + 'image_file' => $image_file, + 'category' => $cache['cat_names'][ $category ], + ) + ); + break; + } + } + $admin_photo_base_url = get_root_url().'admin.php?page=photo-'.$row['id']; + $admin_url_start = $admin_photo_base_url.'-properties'; + $admin_url_start.= isset($row['cat_id']) ? '&cat_id='.$row['cat_id'] : ''; + $selected_level = isset($row['level']) ? $row['level'] : $row['level']; + + $template->append( 'elements', array_merge($row, array( 'ID' => $row['id'], - 'TN_SRC' => DerivativeImage::url(IMG_THUMB, $src_image), + 'TN_SRC' => DerivativeImage::url(IMG_MEDIUM, $src_image), 'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image), 'LEGEND' => $legend, 'U_EDIT' => get_root_url().'admin.php?page=photo-'.$row['id'], @@ -232,14 +487,42 @@ SELECT 'DATE_CREATION' => $row['date_creation'], 'TAGS' => $tag_selection, 'is_svg' => (strtoupper(end($extTab)) == 'SVG'), + 'TITLE' => render_element_name($row), + 'DIMENSIONS' => @$row['width'].'x'.@$row['height'].' px', + 'FORMAT' => ($row['width'] >= $row['height'])? 1:0,//0:horizontal, 1:vertical + 'FILESIZE' => l10n('%.2f MB',$row['filesize']/1024), + 'REGISTRATION_DATE' => format_date($row['date_available']), + 'EXT' => l10n('%s file type',end($extTab)), + 'POST_DATE' => l10n('Posted the %s', format_date($row['date_available'], array('day', 'month', 'year'))), + 'AGE' => l10n(ucfirst(time_since($row['date_available'], 'year'))), + 'ADDED_BY' => l10n('Added by %s', $row['added_by']), + 'STATS' => l10n('Visited %d times', $row['hit']), + 'FILE' => l10n('%s', $row['file']), + 'related_categories' => $related_categories, + 'related_category_ids' => json_encode($related_category_ids,JSON_NUMERIC_CHECK), + 'U_JUMPTO' => (isset($url_img) and $user['level'] >= $media['image']['level']) ? $url_img : null, + 'tag_selection' => $tag_selection, + 'U_DOWNLOAD' => 'action.php?id='.$row['id'].'&part=e&pwg_token='.get_pwg_token().'&download', + 'U_HISTORY' => get_root_url().'admin.php?page=history&filter_image_id='.$row['id'], + 'U_DELETE' => $admin_url_start.'&delete=1&pwg_token='.get_pwg_token(), + 'U_SYNC' => $admin_url_start.'&sync_metadata=1', + 'PATH'=>$row['path'], + 'LEVEL_CONVERT' => $level_convert[!empty($row['level'])?$row['level']:'0'], + 'level_options_selected' => array($selected_level) + + ) )); } + + $template->assign('ACTIVE_PLUGINS', array_keys($pwg_loaded_plugins)); $template->assign(array( 'ELEMENT_IDS' => implode(',', $element_ids), 'CACHE_KEYS' => get_admin_client_cache_keys(array('tags')), + )); + } trigger_notify('loc_end_element_set_unit'); diff --git a/admin/themes/default/js/album_selector.js b/admin/themes/default/js/album_selector.js index 16cf5d308..1d2fbb01c 100644 --- a/admin/themes/default/js/album_selector.js +++ b/admin/themes/default/js/album_selector.js @@ -8,15 +8,20 @@ function linked_albums_close() { $("#addLinkedAlbum").fadeOut(); } -function linked_albums_open() { +function linked_albums_open(pictureId) { $("#addLinkedAlbum").fadeIn(); + if(null != pictureId) + { + console.log(pictureId); + $("#addLinkedAlbum .linkedAlbumPopInContainer").attr("id",pictureId); + } $(".search-input").val(""); $(".search-input").focus(); $("#searchResult").empty(); $(".limitReached").html(str_no_search_in_progress); } -function linked_albums_search(searchText) { +function linked_albums_search(searchText, pictureId) { if (api_method == 'pwg.categories.getList') { api_params = { @@ -32,8 +37,6 @@ function linked_albums_search(searchText) { } } - // console.log(api_method); - $(".linkedAlbumPopInContainer .searching").show(); $.ajax({ url: "ws.php?format=json&method=" + api_method, @@ -47,7 +50,11 @@ function linked_albums_search(searchText) { $(".linkedAlbumPopInContainer .searching").hide(); categories = raw_data.result.categories; - fill_results(categories); + if (typeof pictureId !== 'undefined') { + fill_results(categories, pictureId); + } else { + fill_results(categories); + } if (raw_data.result.limit_reached) { $(".limitReached").html(str_result_limit.replace("%d", categories.length)); diff --git a/admin/themes/default/js/batchManagerFilter.js b/admin/themes/default/js/batchManagerFilter.js new file mode 100644 index 000000000..bcef0ed99 --- /dev/null +++ b/admin/themes/default/js/batchManagerFilter.js @@ -0,0 +1,69 @@ +/* ********** Filters*/ +function filter_enable(filter) { + /* show the filter*/ + $("#"+filter).show(); + + /* check the checkbox to declare we use this filter */ + $("input[type=checkbox][name="+filter+"_use]").prop("checked", true); + + /* forbid to select this filter in the addFilter list */ + $("#addFilter").find("a[data-value="+filter+"]").addClass("disabled", "disabled"); + + /* hide the no filter message */ + $('.noFilter').hide(); + $('.addFilter-button').removeClass('highlight'); +} + +function filter_disable(filter) { + /* hide the filter line */ + $("#"+filter).hide(); + + /* uncheck the checkbox to declare we do not use this filter */ + $("input[name="+filter+"_use]").prop("checked", false); + + /* give the possibility to show it again */ + $("#addFilter").find("a[data-value="+filter+"]").removeClass("disabled"); + + /* show the no filter message if no filter selected */ + if ($('#filterList li:visible').length == 0) { + $('.noFilter').show(); + $('.addFilter-button').addClass('highlight'); + } + +} +$(document).ready(function () { + + $(".removeFilter").addClass("icon-cancel-circled"); + + $(".removeFilter").click(function () { + var filter = $(this).parent('li').attr("id"); + filter_disable(filter); + + return false; + }); + + $("#addFilter a").on('click', function () { + var filter = $(this).attr("data-value"); + filter_enable(filter); + }); + + $("#removeFilters").click(function() { + $("#filterList li").each(function() { + var filter = $(this).attr("id"); + filter_disable(filter); + }); + return false; + }); + + $('[data-slider=widths]').pwgDoubleSlider(sliders.widths); + $('[data-slider=heights]').pwgDoubleSlider(sliders.heights); + $('[data-slider=ratios]').pwgDoubleSlider(sliders.ratios); + $('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes); + + $(document).mouseup(function (e) { + e.stopPropagation(); + if (!$(event.target).hasClass('addFilter-button')) { + $('.addFilter-dropdown').slideUp(); + } + }); +}) \ No newline at end of file diff --git a/admin/themes/default/js/batchManagerGlobal.js b/admin/themes/default/js/batchManagerGlobal.js index c1ef1ae98..302a8e800 100644 --- a/admin/themes/default/js/batchManagerGlobal.js +++ b/admin/themes/default/js/batchManagerGlobal.js @@ -1,73 +1,3 @@ - -/* ********** Filters*/ -function filter_enable(filter) { - /* show the filter*/ - $("#"+filter).show(); - - /* check the checkbox to declare we use this filter */ - $("input[type=checkbox][name="+filter+"_use]").prop("checked", true); - - /* forbid to select this filter in the addFilter list */ - $("#addFilter").find("a[data-value="+filter+"]").addClass("disabled", "disabled"); - - /* hide the no filter message */ - $('.noFilter').hide(); - $('.addFilter-button').removeClass('highlight'); -} - -function filter_disable(filter) { - /* hide the filter line */ - $("#"+filter).hide(); - - /* uncheck the checkbox to declare we do not use this filter */ - $("input[name="+filter+"_use]").prop("checked", false); - - /* give the possibility to show it again */ - $("#addFilter").find("a[data-value="+filter+"]").removeClass("disabled"); - - /* show the no filter message if no filter selected */ - if ($('#filterList li:visible').length == 0) { - $('.noFilter').show(); - $('.addFilter-button').addClass('highlight'); - } - -} - -$(".removeFilter").addClass("icon-cancel-circled"); - -$(".removeFilter").click(function () { - var filter = $(this).parent('li').attr("id"); - filter_disable(filter); - - return false; -}); - -$("#addFilter a").on('click', function () { - var filter = $(this).attr("data-value"); - filter_enable(filter); -}); - -$("#removeFilters").click(function() { - $("#filterList li").each(function() { - var filter = $(this).attr("id"); - filter_disable(filter); - }); - return false; -}); - -$('[data-slider=widths]').pwgDoubleSlider(sliders.widths); -$('[data-slider=heights]').pwgDoubleSlider(sliders.heights); -$('[data-slider=ratios]').pwgDoubleSlider(sliders.ratios); -$('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes); - - -$(document).mouseup(function (e) { - e.stopPropagation(); - if (!$(event.target).hasClass('addFilter-button')) { - $('.addFilter-dropdown').slideUp(); - } -}); - /* ********** Thumbs */ /* Shift-click: select all photos between the click and the shift+click */ diff --git a/admin/themes/default/js/batchManagerUnit.js b/admin/themes/default/js/batchManagerUnit.js new file mode 100644 index 000000000..2ab2bec7c --- /dev/null +++ b/admin/themes/default/js/batchManagerUnit.js @@ -0,0 +1,556 @@ +$(document).ready(function() { + // Detect unsaved changes on any inputs + var user_interacted = false; + + $('input, textarea, select').on('focus', function() { + user_interacted = true; + }); + + $('input, textarea').on('input', function() { + var pictureId = $(this).parents("fieldset").data("image_id"); + if (user_interacted == true) { + showUnsavedLocalBadge(pictureId); + } + }); + + // Specific handler for datepicker inputs + $('input[data-datepicker]').on('change', function() { + var pictureId = $(this).parents("fieldset").data("image_id"); + if (user_interacted == true) { + showUnsavedLocalBadge(pictureId); + } + }); + + $('select').on('change', function() { + var pictureId = $(this).parents("fieldset").data("image_id"); + if (user_interacted == true) { + showUnsavedLocalBadge(pictureId); + } + }); + + $('.related-categories-container .remove-item, .datepickerDelete').on('click', function() { + user_interacted = true; + var pictureId = $(this).parents("fieldset").data("image_id"); + showUnsavedLocalBadge(pictureId); + }); + + // METADATA SYNC + $('.action-sync-metadata').on('click', function(event) { + var pictureId = $(this).parents("fieldset").data("image_id"); + $.confirm({ + title: str_meta_warning, + draggable: false, + titleClass: "metadataSyncConfirm", + theme: "modern", + content: "", + animation: "zoom", + boxWidth: '30%', + useBootstrap: false, + type: 'red', + animateFromElement: false, + backgroundDismiss: true, + typeAnimated: false, + buttons: { + confirm: { + text: str_meta_yes, + btnClass: 'btn-red', + action: function() { + disableLocalButton(pictureId); + $.ajax({ + type: 'POST', + url: 'ws.php?format=json', + data: { + method: "pwg.images.syncMetadata", + pwg_token: jQuery("input[name=pwg_token]").val(), + image_id: pictureId + }, + dataType: 'json', + success: function(data) { + var isOk = data.stat && data.stat === "ok"; + if (isOk) { + updateBlock(pictureId); + } else { + showErrorLocalBadge(pictureId); + enableLocalButton(pictureId); + } + }, + error: function(data) { + console.error("Error occurred"); + enableLocalButton(pictureId); + } + }); + } + }, + cancel: { + text: str_meta_no + } + } + }); + }); + // DELETE + $('.action-delete-picture').on('click', function(event) { + var $fieldset = $(this).parents("fieldset"); + var pictureId = $fieldset.data("image_id"); + $.confirm({ + title: str_are_you_sure, + draggable: false, + titleClass: "groupDeleteConfirm", + theme: "modern", + content: "", + animation: "zoom", + boxWidth: '30%', + useBootstrap: false, + type: 'red', + animateFromElement: false, + backgroundDismiss: true, + typeAnimated: false, + buttons: { + confirm: { + text: str_yes, + btnClass: 'btn-red', + action: function() { + var image_ids = [pictureId]; + (function(ids) { + $.ajax({ + type: 'POST', + url: 'ws.php?format=json', + data: { + method: "pwg.images.delete", + pwg_token: jQuery("input[name=pwg_token]").val(), + image_id: ids.join(',') + }, + dataType: 'json', + success: function(data) { + var isOk = data.stat && data.stat === "ok"; + if (isOk) { + $fieldset.remove(); + $('.pagination-container').css({ + 'pointer-events': 'none', + 'opacity': '0.5' + }); + $('.button-reload').css('display', 'block'); + $('div[data-image_id="' + pictureId + '"]').css('display', 'flex'); + } else { + showErrorLocalBadge(pictureId); + } + }, + error: function(data) { + console.error("Error occurred"); + } + }); + })(image_ids); + image_ids = []; + } + }, + cancel: { + text: str_no + } + } + }); + }); + // VALIDATION + //Unit Save + $('.action-save-picture').on('click', function(event) { + var $fieldset = $(this).parents("fieldset"); + var pictureId = $fieldset.data("image_id"); + saveChanges(pictureId); + }); + //Global Save + $('.action-save-global').on('click', function(event) { + saveAllChanges(); + }); + //Categories + $(".linked-albums.add-item").on("click", function() { + var pictureId = $(this).parents("fieldset").data("image_id") + linked_albums_open(pictureId); + set_up_popin(); + }); + $(".limitReached").html(str_no_search_in_progress); + $(".search-cancel-linked-album").hide(); + $(".linkedAlbumPopInContainer .searching").hide(); + $("#linkedAlbumSearch .search-input").on('input', function() { + var pictureId = $("#linkedAlbumSearch .search-input").parents(".linkedAlbumPopInContainer").attr("id"); + if ($(this).val() != 0) { + $("#linkedAlbumSearch .search-cancel-linked-album").show() + } else { + $("#linkedAlbumSearch .search-cancel-linked-album").hide(); + } + // Search input value length required to start searching + if ($(this).val().length > 0) { + linked_albums_search($(this).val(), pictureId); + } else { + $(".limitReached").html(str_no_search_in_progress); + $("#searchResult").empty(); + } + }) + $(".search-cancel-linked-album").on("click", function() { + $("#linkedAlbumSearch .search-input").val(""); + $("#linkedAlbumSearch .search-input").trigger("input"); + }) + $(".related-categories-container .breadcrumb-item .remove-item").on("click", function() { + var pictureId = $(this).parents("fieldset").data("image_id") + remove_related_category($(this).attr("id"), pictureId); + }) + pluginFunctionMapInit(activePlugins); +}) + +function fill_results(cats, pictureId) { + $("#searchResult").empty(); + cats.forEach(cat => { + $("#searchResult").append( + "
" + + "" + cat.fullname + "" + + "
" + ); + var this_related_category_ids = window["related_category_ids_" + pictureId]; + var catId = parseInt(cat.id); + if (this_related_category_ids.includes(catId)) { + $(".search-result-item#" + catId + " .item-add").addClass("notClickable").attr("title", str_already_in_related_cats).on("click", function(event) { + event.preventDefault(); + }); + $(".search-result-item").addClass("notClickable").attr("title", str_already_in_related_cats).on("click", function(event) { + event.preventDefault(); + }); + } else { + $(".search-result-item#" + catId + " .item-add").on("click", function() { + add_related_category(catId, cat.full_name_with_admin_links, pictureId); + }); + } + }); +} + +function remove_related_category(cat_id, pictureId) { + var catId = parseInt(cat_id); + var this_related_category_ids = window["related_category_ids_" + pictureId]; + $("#" + pictureId + " .invisible-related-categories-select option[value=" + catId + "]").remove(); + $("#" + pictureId + " .invisible-related-categories-select").trigger('change'); + $("#" + pictureId + " #" + catId).parent().remove(); + cat_to_remove_index = this_related_category_ids.indexOf(catId); + if (cat_to_remove_index > -1) { + this_related_category_ids.splice(cat_to_remove_index, 1); + } + check_related_categories(pictureId); +} + +function add_related_category(cat_id, cat_link_path, pictureId) { + var catId = parseInt(cat_id); + var this_related_category_ids = window["related_category_ids_" + pictureId]; + if (!this_related_category_ids.includes(catId)) { + $("#" + pictureId + " .related-categories-container").append( + "" + ); + $(".search-result-item#" + catId).addClass("notClickable"); + this_related_category_ids.push(catId); + $(".invisible-related-categories-select").append("").trigger('change'); + $("#" + catId).on("click", function() { + remove_related_category(catId, pictureId); + }) + linked_albums_close(); + } + check_related_categories(pictureId); +} + +function check_related_categories(pictureId) { + var this_related_category_ids = window["related_category_ids_" + pictureId]; + $("#picture-" + pictureId + " .linked-albums-badge").html(this_related_category_ids.length); + if (this_related_category_ids.length == 0) { + $("#" + pictureId + " .linked-albums-badge").addClass("badge-red"); + $("#" + pictureId + " .add-item").addClass("highlight"); + $("#" + pictureId + " .orphan-photo").html(str_orphan).show(); + } else { + $("#" + pictureId + " .linked-albums-badge.badge-red").removeClass("badge-red"); + $("#" + pictureId + " .add-item.highlight").removeClass("highlight"); + $("#" + pictureId + " .orphan-photo").hide(); + } +} + +function updateUnsavedGlobalBadge() { + var visibleLocalUnsavedCount = $(".local-unsaved-badge").filter(function() { + return $(this).css('display') === 'block'; + }).length; + if (visibleLocalUnsavedCount > 0) { + $(".global-unsaved-badge").css('display', 'block'); + $("#unsaved-count").text(visibleLocalUnsavedCount); + } else { + $(".global-unsaved-badge").css('display', 'none'); + $("#unsaved-count").text(''); + } +} + +function showUnsavedLocalBadge(pictureId) { + hideSuccesLocalBadge(pictureId); + hideErrorLocalBadge(pictureId); + $("#picture-" + pictureId + " .local-unsaved-badge").css('display', 'block'); + updateUnsavedGlobalBadge(); +} + +function hideUnsavedLocalBadge(pictureId) { + $("#picture-" + pictureId + " .local-unsaved-badge").css('display', 'none'); + updateUnsavedGlobalBadge(); +} +$(window).on('beforeunload', function() { + if (user_interacted) { + return "You have unsaved changes, are you sure you want to leave this page?"; + } +}); +//Error badge +function showErrorLocalBadge(pictureId) { + $("#picture-" + pictureId + " .local-error-badge").css('display', 'block'); +} + +function hideErrorLocalBadge(pictureId) { + $("#picture-" + pictureId + " .local-error-badge").css('display', 'none'); +} +//Succes badge +function updateSuccessGlobalBadge() { + var visibleLocalSuccesCount = $(".local-success-badge").filter(function() { + return $(this).css('display') === 'block'; + }).length; + if (visibleLocalSuccesCount > 0) { + showSuccesGlobalBadge() + } else { + hideSuccesGlobalBadge() + } +} + +function showSuccessLocalBadge(pictureId) { + var badge = $("#picture-" + pictureId + " .local-success-badge"); + badge.css({ + 'display': 'block', + 'opacity': 1 + }); + setTimeout(() => { + badge.fadeOut(1000, function() { + badge.css('display', 'none'); + }); + }, 3000); +} + +function hideSuccesLocalBadge(pictureId) { + $("#picture-" + pictureId + " .local-success-badge").css('display', 'none'); +} + +function showSuccesGlobalBadge() { + var badge = $(".global-succes-badge"); + badge.css({ + 'display': 'block', + 'opacity': 1 + }); + setTimeout(() => { + badge.fadeOut(1000, function() { + badge.css('display', 'none'); + }); + }, 3000); +} + +function hideSuccesGlobalBadge() { + $("global-succes-badge").css('display', 'none'); +} + +function showMetasyncSuccesBadge(pictureId) { + var badge = $("#picture-" + pictureId + " .metasync-success"); + badge.css({ + 'display': 'block', + 'opacity': 1 + }); + setTimeout(() => { + badge.fadeOut(1000, function() { + badge.css('display', 'none'); + }); + }, 3000); +} + +function disableLocalButton(pictureId) { + $("#picture-" + pictureId + " .action-save-picture").addClass("disabled"); + $("#picture-" + pictureId + " .action-save-picture i").removeClass("icon-floppy").addClass("icon-spin6 animate-spin"); + disableGlobalButton(); +} + +function enableLocalButton(pictureId) { + $("#picture-" + pictureId + " .action-save-picture").removeClass("disabled"); + $("#picture-" + pictureId + " .action-save-picture i").removeClass("icon-spin6 animate-spin").addClass("icon-floppy"); +} + +function disableGlobalButton() { + $(".action-save-global").addClass("disabled"); + $(".action-save-global i").removeClass("icon-floppy").addClass("icon-spin6 animate-spin"); +} + +function enableGlobalButton() { + $(".action-save-global").removeClass("disabled"); + $(".action-save-global i").removeClass("icon-spin6 animate-spin").addClass("icon-floppy"); +} + +function saveChanges(pictureId) { + if ($("#picture-" + pictureId + " .local-unsaved-badge").css('display') === 'block') { + disableLocalButton(pictureId); + // Retrieve Infos + var name = $("#name-" + pictureId).val(); + var author = $("#author-" + pictureId).val(); + var date_creation = $("#date_creation-" + pictureId).val(); + var comment = $("#description-" + pictureId).val(); + var level = $("#level-" + pictureId + " option:selected").val(); + // Get Categories + var categories = []; + $("#picture-" + pictureId + " .remove-item").each(function() { + categories.push($(this).attr("id")); + }); + var categoriesStr = categories.join(';'); + // Get Tags + var tags = []; + $("#tags-" + pictureId + " option").each(function() { + var tagId = $(this).val().replace(/~~/g, ''); + tags.push(tagId); + }); + var tagsStr = tags.join(','); + $.ajax({ + url: 'ws.php?format=json', + method: 'POST', + data: { + method: 'pwg.images.setInfo', + image_id: pictureId, + name: name, + author: author, + date_creation: date_creation, + comment: comment, + categories: categoriesStr, + tag_ids: tagsStr, + level: level, + single_value_mode: "replace", + multiple_value_mode: "replace", + pwg_token: jQuery("input[name=pwg_token]").val() + }, + success: function(response) { + enableLocalButton(pictureId); + enableGlobalButton(); + hideUnsavedLocalBadge(pictureId); + showSuccessLocalBadge(pictureId); + updateSuccessGlobalBadge(); + // pluginSaveLoop(activePlugins); //call for plugin save + }, + error: function(xhr, status, error) { + enableLocalButton(pictureId); + enableGlobalButton(); + hideUnsavedLocalBadge(pictureId); + showErrorLocalBadge(pictureId); + updateSuccessGlobalBadge(); + console.error('Error:', error); + } + }); + } else {} +} + +function saveAllChanges() { + $("fieldset").each(function() { + var pictureId = $(this).data("image_id"); + saveChanges(pictureId); + }); +} +//PLUGINS SAVE METHOD +var pluginFunctionMap = {}; + +function pluginFunctionMapInit(activePlugins) { + activePlugins.forEach(function(pluginId) { + var functionName = pluginId + '_batchManagerSave'; + if (typeof window[functionName] === 'function') { + pluginFunctionMap[pluginId] = window[functionName]; + } else { + console.log('Function not found during initialization: ' + functionName); + } + }); +} + +function pluginSaveLoop(activePlugins) { + if (activePlugins.length === 0) { + console.log("No plugins to process in pluginSaveLoop."); + return; + } + activePlugins.forEach(function(pluginId) { + var saveFunction = pluginFunctionMap[pluginId]; + if (typeof saveFunction === 'function') { + saveFunction(); + console.log('Executed function for plugin: ' + pluginId); + } else { + console.log('Function not found for plugin: ' + pluginId); + } + }); +} +//UPDATE BLOCKS (Yet to be implemented) +function updateBlock(pictureId) { + $.ajax({ + url: 'ws.php?format=json', + type: 'GET', + dataType: 'json', + data: { + method: 'pwg.images.getInfo', + image_id: pictureId, + format: 'json' + }, + success: function(response) { + if (response.stat === 'ok') { + $("#picture-" + pictureId + " #name-" + pictureId).val(response.result.name); + $("#picture-" + pictureId + " #author-" + pictureId).val(response.result.author); + $("#picture-" + pictureId + " #date_creation-" + pictureId).val(response.result.date_creation); + $("#picture-" + pictureId + " #description-" + pictureId).val(response.result.comment); + $("#picture-" + pictureId + " #level-" + pictureId).val(response.result.level); + $("#picture-" + pictureId + " #filename-" + pictureId).text(response.result.file); + $("#picture-" + pictureId + " #filesize-" + pictureId).text(response.result.filesize); + $("#picture-" + pictureId + " #dimensions-" + pictureId).text(response.result.width + "x" + response.result.height); + // updateTags(response.result.tags, pictureId); //Yet to be implemented + showMetasyncSuccesBadge(pictureId); + enableLocalButton(pictureId); + enableGlobalButton(); + } else { + console.error("Error:", response.message); + showErrorLocalBadge(pictureId); + enableLocalButton(pictureId); + enableGlobalButton(); + } + }, + error: function(xhr, status, error) { + console.error("Error:", status, error); + showErrorLocalBadge(pictureId); + enableLocalButton(pictureId); + } + }); +} +//TAGS UPDATE Yet to be implemented +// function updateTags(tagsData, pictureId) { +// var $tagsUpdate = $('#tags-'+pictureId).selectize({ +// create: true, +// persist: false +// }); +// var selectizeTags = $tagsUpdate[0].selectize; +// var transformedData = tagsData.map(function(item) { +// return { +// value: item.id, +// text: item.name +// }; +// }) +// console.log(transformedData); +// selectizeTags.clearOptions(); +// selectizeTags.addOption(transformedData); +// selectizeTags.refreshOptions(true); +// }; + +//UNRELEASED LEVEL SLIDER +// $(function () { +// $('.privacy-filter-slider').each(function() { +// var id = $(this).attr('id'); +// $(this).slider({ +// range: 'min', +// value: $(this).attr('value'), +// min: 0, +// max: 4, +// slide: function (event, ui) { +// updateCertificationFilterLabel(ui.value, id); +// } +// }); +// }); +// }); +// function updateCertificationFilterLabel(value, id) { +// let label = strs_privacy[value]; +// $('#' + id + ' .privacy').html(label); +// } \ No newline at end of file diff --git a/admin/themes/default/template/batch_manager_global.tpl b/admin/themes/default/template/batch_manager_global.tpl index 9d5424b3f..c1feda680 100644 --- a/admin/themes/default/template/batch_manager_global.tpl +++ b/admin/themes/default/template/batch_manager_global.tpl @@ -6,7 +6,7 @@ {combine_script id='jquery.ui.slider' require='jquery.ui' load='async' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'} {combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"} -{combine_script id='doubleSlider' load='async' require='jquery.ui.slider' path='admin/themes/default/js/doubleSlider.js'} +{combine_script id='doubleSlider' load='footer' require='jquery.ui.slider' path='admin/themes/default/js/doubleSlider.js'} {combine_script id='LocalStorageCache' load='footer' path='admin/themes/default/js/LocalStorageCache.js'} @@ -311,46 +311,6 @@ $(document).ready(function() { jQuery("#sync_md5sum").toggle(jQuery(this).val() == "no_sync_md5sum"); }); }); - -{**} -var sliders = { - widths: { - values: [{$dimensions.widths}], - selected: { - min: {$dimensions.selected.min_width}, - max: {$dimensions.selected.max_width}, - }, - text: '{'between %d and %d pixels'|translate|escape:'javascript'}' - }, - - heights: { - values: [{$dimensions.heights}], - selected: { - min: {$dimensions.selected.min_height}, - max: {$dimensions.selected.max_height}, - }, - text: '{'between %d and %d pixels'|translate|escape:'javascript'}' - }, - - ratios: { - values: [{$dimensions.ratios}], - selected: { - min: {$dimensions.selected.min_ratio}, - max: {$dimensions.selected.max_ratio}, - }, - text: '{'between %.2f and %.2f'|translate|escape:'javascript'}' - }, - - filesizes: { - values: [{$filesize.list}], - selected: { - min: {$filesize.selected.min}, - max: {$filesize.selected.max}, - }, - text: '{'between %s and %s MB'|translate|escape:'javascript'}' - } -}; - {/footer_script} {combine_script id='jquery.confirm' load='footer' require='jquery' path='themes/default/js/plugins/jquery-confirm.min.js'} @@ -361,207 +321,10 @@ var sliders = {
- -
- {'Filter'|@translate} - -
-
    -
  • - -

    {'Predefined filter'|@translate}

    - [x] - - {'Empty caddie'|translate} - {if $NB_ORPHANS > 0} - {'Delete %d orphan photos'|translate:$NB_ORPHANS} - {/if} - {if $NB_NO_MD5SUM > 0} - {'Compute %d missing checksums'|translate:{$NB_NO_MD5SUM}} - {/if} - - - - - - - - - - - {'based on'|translate} - - - - - -
  • - -
  • - -

    {'Album'|@translate}

    - [x] - - -
  • - -
  • - -

    {'Tags'|@translate}

    - [x] - - - -
  • - -
  • - -

    {'Privacy level'|@translate}

    - [x] - - -
  • - -
  • - -

    {'Dimensions'|translate}

    - [x] -
    -
    -
    -
    - {'Width'|translate} {'between %d and %d pixels'|translate:$dimensions.selected.min_width:$dimensions.selected.max_width} -
    - {'Reset'|translate} -
    -
    - - - -
    - -
    -
    -
    - {'Height'|translate} {'between %d and %d pixels'|translate:$dimensions.selected.min_height:$dimensions.selected.max_height} -
    - {'Reset'|translate} -
    -
    - - - -
    - -
    -
    - {'Ratio'|translate} ({'Width'|@translate}/{'Height'|@translate}) - {'between %.2f and %.2f'|translate:$dimensions.selected.min_ratio:$dimensions.selected.max_ratio} -
    -
    -
    - {if isset($dimensions.ratio_portrait)} {'Portrait'|translate}{/if} - {if isset($dimensions.ratio_square)} {'square'|translate}{/if} - {if isset($dimensions.ratio_landscape)} {'Landscape'|translate}{/if} - {if isset($dimensions.ratio_panorama)} {'Panorama'|translate}{/if} -
    - -
    -
    - - - -
    -
    -
  • - - - -
  • - -

    {'Filesize'|translate}

    - [x] -
    -
    - {'between %s and %s MB'|translate:$filesize.selected.min:$filesize.selected.max} - {'Reset'|translate} -
    - - - -
    -
    -
  • -
- -
{'No filter, add one'|@translate}
- - -
- -
- + {include file='include/batch_manager_filter.inc.tpl' + title={'Batch Manager Filter'|@translate} + searchPlaceholder={'Filters'|@translate} + }
{'Selection'|@translate} diff --git a/admin/themes/default/template/batch_manager_unit.tpl b/admin/themes/default/template/batch_manager_unit.tpl index 0edc7df86..1253c413e 100644 --- a/admin/themes/default/template/batch_manager_unit.tpl +++ b/admin/themes/default/template/batch_manager_unit.tpl @@ -2,12 +2,27 @@ {include file='include/datepicker.inc.tpl'} {include file='include/colorbox.inc.tpl'} +{combine_script id='jquery.sort' load='footer' path='themes/default/js/plugins/jquery.sort.js'} + {combine_script id='LocalStorageCache' load='footer' path='admin/themes/default/js/LocalStorageCache.js'} -{combine_script id='jquery.selectize' load='footer' path='themes/default/js/plugins/selectize.min.js'} +{combine_script id='jquery.selectize' load='header' path='themes/default/js/plugins/selectize.min.js'} {combine_css id='jquery.selectize' path="themes/default/js/plugins/selectize.{$themeconf.colorscheme}.css"} +{combine_script id='doubleSlider' load='footer' require='jquery.ui.slider' path='admin/themes/default/js/doubleSlider.js'} + +{combine_script id='jquery.ui.slider' require='jquery.ui' load='header' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'} +{combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"} + +{combine_script id='jquery.selectize' load='footer' path='themes/default/js/plugins/selectize.min.js'} + +{combine_script id='jquery.confirm' load='footer' require='jquery' path='themes/default/js/plugins/jquery-confirm.min.js'} +{combine_css path="themes/default/js/plugins/jquery-confirm.min.css"} + +{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {footer_script} +{* *} +var activePlugins = {$ACTIVE_PLUGINS|json_encode}; (function(){ {* *} var tagsCache = new TagsCache({ @@ -32,99 +47,291 @@ jQuery(function(){ {* *} jQuery("a.preview-box").colorbox( { photo: true }); + +str_are_you_sure = '{'Are you sure?'|translate|escape:javascript}'; +str_yes = '{'Yes, delete'|translate|escape:javascript}'; +str_no = '{'No, I have changed my mind'|translate|@escape:'javascript'}'; +str_albums_found = '{"%d albums found"|translate|escape:javascript}'; +str_album_found = '{"1 album found"|translate|escape:javascript}'; +str_result_limit = '{"%d+ albums found, try to refine the search"|translate|escape:javascript}'; +str_orphan = '{'This photo is an orphan'|@translate|escape:javascript}'; +str_no_search_in_progress = '{'No search in progress'|@translate|escape:javascript}'; +str_already_in_related_cats = '{'This albums is already in related categories list'|translate|escape:javascript}'; +str_meta_warning = '{'Warning ! Unsaved changes will be lost'|translate|escape:javascript}'; +str_meta_yes = '{'I want to continue'|translate|escape:javascript}' +str_meta_no = '{'No, I have changed my mind'|translate|escape:javascript}' + }()); +const strs_privacy = { + "0" : "{$level_options[8]}", + "1" : "{$level_options[4]}", + "2" : "{$level_options[2]}", + "3" : "{$level_options[1]}", + "4" : "{$level_options[0]}", +}; {/footer_script} - -
-
- {if !empty($navbar) }{include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if} -
-
- {'photos per page'|@translate} : - 5 - 10 - 50 -
-
-
-{if !empty($elements) } -
-{foreach from=$elements item=element} -
- {$element.LEGEND} +{combine_script id='batchManagerUnit' load='footer' require='jquery.ui.effect-blind,jquery.sort' path='admin/themes/default/js/batchManagerUnit.js'} - - - {'Edit'|@translate} - +
+
+ {debug}{if isset($ELEMENT_IDS)} +
+ +
+ {/if} + {*Filters*} + + {include file='include/batch_manager_filter.inc.tpl' title={'Batch Manager Filter'|@translate} searchPlaceholder={'Filters'|@translate}} + + + + Liste + {count($all_elements)} + + {if !empty($elements) } +
+
+ {'photos per page'|@translate} : + 5 + 10 + 50 +
+
+
+ {if !empty($navbar) } + + {include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if} +
+
+
+ {foreach from=$elements item=element} + {footer_script} + var related_category_ids_{$element.ID} = {$element.related_category_ids}; + url_delete_{$element.id} = '{$element.U_DELETE}'; + {/footer_script} + +
+ +
+ #{$element.ID} +
+
+ imagename +
+
+ + + + + {if !url_is_remote($element.PATH)} + {* *} + + {/if} +
+ {if isset($element.U_JUMPTO)} + +

+ + {'Open in gallery'|@translate} +

+ {else} +
+

+ + {'Open in gallery'|translate} +

+ {/if} +
+
+
+
+
+
+ +
+ {$element.FILE} + {$element.DIMENSIONS} + {$element.FILESIZE} + {$element.EXT} +
+
+
+ +
+ {$element.POST_DATE} + {$element.AGE} + {$element.ADDED_BY} + {$element.STATS} +
+
+
+
+ {'Title'|@translate} + +
+
+ {'Creation date'|@translate} + + +
+
+ {'Author'|@translate} + +
+
+
+ {'Who can see ?'|@translate} + {'level of confidentiality'|@translate} +
+ + {* +
+
+ {'Who can see this photo?'|@translate} + +
+
+
+
+
+
+
+
+ *} +
+
+ {'Tags'|@translate} + +
+
+ {'Linked albums'|@translate} {$element.related_categories|@count} + {if $element.related_categories|@count + < 1} + {'This photo is an orphan'|@translate} + {else} + + {/if} + + +
+
+ {'Description'|@translate} + +
+
+
+
+ + {'Save'|@translate} +
+
+ + + +
+
+
+ {/foreach} +
+
+ {'Display'|@translate} + 5 + 10 + 50 +
+
+
+ {if !empty($navbar) } + + {include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if} +
+
+
+ {/if} +
+ + + + +
+ + Save all photos +
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{'Title'|@translate}
{'Author'|@translate}
{'Creation date'|@translate} - - - {'unset'|translate} -
{'Who can see this photo?'|@translate}
({'Privacy level'|translate})
- -
{'Tags'|@translate} - -
{'Description'|@translate}
- -
-{/foreach} - -{if !empty($navbar)}{include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if} - -

- - - - - {* {'Submit'|@translate} *} - {* *} -

-{/if} - - +{include file='include/album_selector.inc.tpl' + title={'Associate to album'|@translate} + searchPlaceholder={'Search'|@translate} +} \ No newline at end of file + +.breadcrumb-item.add-item.highlight{ + color: #3C3C3C !important; +} + +.breadcrumb-item{ + margin: 5px 0 5px 0 !important; +} + +.album-listed{ + background-color: #FFFFFF !important; +} + diff --git a/admin/themes/default/template/include/batch_manager_filter.inc.tpl b/admin/themes/default/template/include/batch_manager_filter.inc.tpl new file mode 100644 index 000000000..7798908a4 --- /dev/null +++ b/admin/themes/default/template/include/batch_manager_filter.inc.tpl @@ -0,0 +1,239 @@ +{footer_script} + +var sliders = { + widths: { + values: [{$dimensions.widths}], + selected: { + min: {$dimensions.selected.min_width}, + max: {$dimensions.selected.max_width}, + }, + text: '{'between %d and %d pixels'|translate|escape:'javascript'}' + }, + + heights: { + values: [{$dimensions.heights}], + selected: { + min: {$dimensions.selected.min_height}, + max: {$dimensions.selected.max_height}, + }, + text: '{'between %d and %d pixels'|translate|escape:'javascript'}' + }, + + ratios: { + values: [{$dimensions.ratios}], + selected: { + min: {$dimensions.selected.min_ratio}, + max: {$dimensions.selected.max_ratio}, + }, + text: '{'between %.2f and %.2f'|translate|escape:'javascript'}' + }, + + filesizes: { + values: [{$filesize.list}], + selected: { + min: {$filesize.selected.min}, + max: {$filesize.selected.max}, + }, + text: '{'between %s and %s MB'|translate|escape:'javascript'}' + } +}; +{/footer_script} + +{combine_script id='batchManagerFilter' load='footer' path='admin/themes/default/js/batchManagerFilter.js'} +
+{'Filter'|@translate} +
+
    +
  • + +

    {'Predefined filter'|@translate}

    + [x] + + {'Empty caddie'|translate} +{if $NB_ORPHANS > 0} + {'Delete %d orphan photos'|translate:$NB_ORPHANS} +{/if} +{if $NB_NO_MD5SUM > 0} +{'Compute %d missing checksums'|translate:{$NB_NO_MD5SUM}} +{/if} + + + + + + + + + + + {'based on'|translate} + + + + + +
  • + +
  • + +

    {'Album'|@translate}

    + [x] + + +
  • + +
  • + +

    {'Tags'|@translate}

    + [x] + + + +
  • + +
  • + +

    {'Privacy level'|@translate}

    + [x] + + +
  • + +
  • + +

    {'Dimensions'|translate}

    + [x] +
    +
    +
    +
    + {'Width'|translate} {'between %d and %d pixels'|translate:$dimensions.selected.min_width:$dimensions.selected.max_width} +
    + {'Reset'|translate} +
    +
    + + + +
    + +
    +
    +
    + {'Height'|translate} {'between %d and %d pixels'|translate:$dimensions.selected.min_height:$dimensions.selected.max_height} +
    + {'Reset'|translate} +
    +
    + + + +
    + +
    +
    + {'Ratio'|translate} ({'Width'|@translate}/{'Height'|@translate}) + {'between %.2f and %.2f'|translate:$dimensions.selected.min_ratio:$dimensions.selected.max_ratio} +
    +
    +
    + {if isset($dimensions.ratio_portrait)} {'Portrait'|translate}{/if} + {if isset($dimensions.ratio_square)} {'square'|translate}{/if} + {if isset($dimensions.ratio_landscape)} {'Landscape'|translate}{/if} + {if isset($dimensions.ratio_panorama)} {'Panorama'|translate}{/if} +
    + +
    +
    + + + +
    +
    +
  • + + + +
  • + +

    {'Filesize'|translate}

    + [x] +
    +
    + {'between %s and %s MB'|translate:$filesize.selected.min:$filesize.selected.max} + {'Reset'|translate} +
    + + + +
    +
    +
  • +
+ +
{'No filter, add one'|@translate}
+ + +
+
diff --git a/admin/themes/default/theme.css b/admin/themes/default/theme.css index 902503522..902657bdb 100644 --- a/admin/themes/default/theme.css +++ b/admin/themes/default/theme.css @@ -2281,6 +2281,19 @@ h2:lang(en) { text-transform:capitalize; } border-left:4px solid #00529b; } +.success { + color: #6DCE5E; + background-color:#D6FFCF; + border-left:4px solid #6DCE5E; +} + +.metasync-success { + position: absolute; + top: -15px; + left: 50%; + transform: translateX(-50%); +} + .badge { background-color:#0a0; color:white; @@ -2291,6 +2304,10 @@ h2:lang(en) { text-transform:capitalize; } margin-left:5px; } +.buttonSubmitLocal { + margin-left: 9px !important; +} + .infos li, .errors li, .warnings li, .messages li { list-style-type:none; } .infos .submit {margin-left:30px;} @@ -3379,6 +3396,317 @@ LEGEND SPAN { margin-right: 6px; font-size: 16px; } +/* Batch Manager, unit mode */ +.elementEdit{ + position: relative; + display:flex; + flex-direction:row; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2); + background-color:#FAFAFA; + padding:0px; + margin: 1.5em !important; + border-radius: 4px; +} + +.pictureIdLabel{ + position: absolute; + bottom: 20px; + right: 0px; + align-items: right; + color:#7a7a7a89; + font-size: 14px; + padding: 14px 20px 14px 0px; +} + + +.media-box{ + display: flex; + background-color: #3C3C3C; + width:33%; + justify-content: center; + position: relative; + border-radius: 4px 0 0 4px; +} + +.media-box-embed{ + height: 100%; + object-fit: contain; + position: absolute; +} + +.media-hover{ + opacity:0%; + position: relative; + height: 100%; + width: 100%; +} + +.media-hover:hover{ + opacity: 100%; + transition: ease-in-out 0.3s; +} + +.main-info-container{ + display:flex; + flex-direction:column; + text-align:center; + padding:20px; + row-gap:15px; + width:200px; +} + +.main-info-block{ + display:flex; + flex-direction:column; + border: 1px solid #D3D3D3; + background: #FFF; + border-radius: 2px; + flex:1; + align-items: center; + justify-content: center; +} + +.main-info-icon{ + width:40px; + height:40px; + margin-bottom:5px; + fill: #3C3C3C; +} + +.main-info-title{ + color: #000; + text-align: center; + font-size: 12px; + font-weight: 700; + line-height: normal; + width:100px; + overflow-wrap: break-word; +} + +.main-info-desc{ + color: #777; + text-align: center; + font-family: "Open Sans"; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: normal; + width:100px; +} + +.info-container{ + flex:1; + display:flex; + flex-direction:row; + flex-wrap:wrap; + align-content: flex-start; + padding: 20px 10px 20px 0px; + gap: 10px 0px; + color:#7A7A7A; + text-align: left; +} + +.half-line-info-box{ + flex: 0 0 calc(50% - 20px); + margin: 0px 10px; + display:flex; + flex-direction:column; + text-align:left; + height: 50px; +} + +.full-line-info-box{ + flex: 0 0 calc(100% - 20px); + margin: 0px 10px; + display:flex; + flex-direction:column; +} + +.full-line-tag-box{ + flex: 0 0 calc(100% - 20px); + margin: 0px 10px; + display:flex; + flex-direction:column; +} + +.calendar-box{ + flex: 0 0 calc(50% - 20px); + height: 50px; + margin: 0px 10px; + display:flex; + flex-direction:column; +} + +.full-line-info-box input, +.half-line-info-box input, +.half-line-info-box select{ + display: flex; + border-radius: 2px; + padding: 0 7px; + border: 1px solid #D3D3D3; + background-color: #FFFFFF !important; + flex: 1; +} + +.full-line-tag-box select{ + display: flex; + border-radius: 2px; + padding: 0 7px; + border: 1px solid #D3D3D3; + background: #FFF; +} + +.calendar-input{ + display: flex; + border-radius: 2px; + padding-left: 7px; + border: 1px solid #D3D3D3; + background: #FFF; + align-items: center; + justify-content: space-between; + flex: 1; +} + +.calendar-box input{ + border:none; + outline: none; + height: 90%; + width: 90%; +} + +.full-line-description-box{ + flex: 0 0 calc(100% - 20px); + min-height: 50px; + margin: 0px 10px; + display:flex; + flex-direction:column; +} + +.description-box{ + resize: none; + border-radius: 2px; + border: 1px solid #D3D3D3; + background: #FFF; +} +.full-line-info-box input, +.half-line-info-box input, +.description-box{ + outline: none !important; +} + + + +.privacy-label-container{ + display: flex; + flex-direction: row; + gap: 5px; +} + +.privacy-label-container span{ + color: #ffa646; + font-weight: bold; +} +.bottom-save-bar{ + display:flex; + flex-direction: row; + position: fixed; + bottom: 0; + right: 0; + width: calc(100% - 205px); + background-color: #ffffff; + justify-content: flex-end; + align-items: center; + z-index: 101; + border-top: 1px solid #CCCCCC; +} + +.action-save-global{ + margin: 10px 0; + margin-right: 2%; +} + +.badge-container { + text-align: right; + margin-right: 2%; +} +.badge-unsaved{ + padding: 5px 10px; + border-radius: 100px; + font-weight: bold; + background-color: #FADDA2; + color: #E18C32; +} + +.badge-succes{ + padding: 5px 10px; + border-radius: 100px; + font-weight: bold; + background-color: #D6FFCF; + color: #6DCE5E; +} + +.badge-error{ + padding: 5px 10px; + border-radius: 100px; + font-weight: bold; + background-color: #F8D7DC; + color: #EB3D33; +} + +.badge-count{ + padding: 10px 10px; + border-radius: 100px; + background-color: #3C3C3C; + color: #FFFFFF; +} + +.pagination-reload{ + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.deleted-badge{ + display:flex; + flex-direction: row; + justify-content: left; + align-items: center; + padding:0px; + margin: 1.5em !important; + border-radius: 4px; +} + +.validation-container{ + margin: 20px 0 0 2px; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + flex: 1; + gap: 10px; +} + +.save-button-container{ + display: flex; + justify-content: center; + align-items: center; +} + +.disabled { + pointer-events: none; + opacity: 0.5; +} + +.count-badge { + display: inline-block; + text-align: center; + border-radius: 100px !important; + padding: 3px 9px !important; + background-color: #686868 !important; + color: #FFFFFF !important; + margin-left: 5px; +} /* Batch Manager, global mode */ #batchManagerGlobal #action p {text-align:left;} @@ -3423,7 +3751,7 @@ LEGEND SPAN { #batchManagerGlobal #selectedMessage {padding:5px; border-radius:5px; float: right;} #batchManagerGlobal #applyOnDetails {text-align: center; margin-top: 8px; color: #FFA646; font-weight: bold;} #batchManagerGlobal .actionButtons {text-align:left; display: flex; flex-direction: column;} -#batchManagerGlobal #filterList {padding-left:0px; display: flex; flex-wrap: wrap; align-items: start; margin-top: 0px;} +#batchManagerGlobal #filterList {padding-left:0px; display: flex; flex-wrap: wrap; align-items: start; margin-top: 0px; margin-bottom: 10px !important;} #batchManagerGlobal #filterList li { list-style-type:none; background-color: #fafafa; @@ -6844,7 +7172,7 @@ color:#FF7B00; .linkedAlbumPopIn { position: fixed; - z-index: 100; + z-index: 102; left: 0; top: 0; width: 100%; diff --git a/language/en_UK/admin.lang.php b/language/en_UK/admin.lang.php index ce374e520..17a1d36ea 100644 --- a/language/en_UK/admin.lang.php +++ b/language/en_UK/admin.lang.php @@ -1356,4 +1356,15 @@ $lang['Core'] = 'Core'; $lang['System Activities'] = 'System Activities'; $lang['Shrink'] = 'Shrink'; $lang['Expand'] = 'Expand'; +$lang['Image'] = 'Image'; +$lang['was succesfully deleted'] = 'was succesfully deleted'; +$lang['Who can see ?'] = 'Who can see ?'; +$lang['level of confidentiality'] = 'level of confidentiality'; +$lang['You have unsaved changes'] = 'You have unsaved changes'; +$lang['Changes saved'] = 'Changes saved'; +$lang['An error has occured'] = 'An error has occured'; +$lang['image(s) contains unsaved changes'] = 'image(s) contains unsaved changes'; +$lang['Pagination has changed and needs to be reloaded !'] = 'Pagination has changed and needs to be reloaded !'; +$lang['Metadata sync complete'] = 'Metadata sync complete'; +$lang['Save'] = 'Save'; // Leave this line empty diff --git a/language/fr_FR/admin.lang.php b/language/fr_FR/admin.lang.php index c951a0e62..9e15bef63 100644 --- a/language/fr_FR/admin.lang.php +++ b/language/fr_FR/admin.lang.php @@ -1356,4 +1356,15 @@ $lang['Core'] = 'Noyau'; $lang['System Activities'] = 'Activités système'; $lang['Shrink'] = 'Réduire'; $lang['Expand'] = 'Agrandir'; +$lang['Image'] = "L'image"; +$lang['was succesfully deleted'] = 'a été supprimée avec succès'; +$lang['Who can see ?'] = 'Qui peut voir ?'; +$lang['level of confidentiality'] = 'niveau de confidentialité'; +$lang['You have unsaved changes'] = 'Changements non sauvegardés'; +$lang['Changes saved'] = 'Changements enregistrés'; +$lang['An error has occured'] = 'Une erreur est survenue'; +$lang['image(s) contains unsaved changes'] = 'image(s) ne sont pas sauvegardées'; +$lang['Pagination has changed and needs to be reloaded !'] = "La pagination a changée et nécessite d'être rechargée !"; +$lang['Metadata sync complete'] = 'Méta-données synchronisées'; +$lang['Save'] = 'Enregistrer'; // Leave this line empty