related to #1614 replacing selectize in photo editor for related categories

This commit is contained in:
Matthieu Leproux 2022-03-08 16:56:31 +01:00 committed by Matthieu Leproux
parent 34fe0fc36f
commit 66bd06176c
9 changed files with 454 additions and 17 deletions

View file

@ -357,6 +357,9 @@ SELECT category_id, uppercats
;';
$result = pwg_query($query);
$related_categories = array();
$related_categories_ids = array();
while ($row = pwg_db_fetch_assoc($result))
{
$name =
@ -371,10 +374,14 @@ while ($row = pwg_db_fetch_assoc($result))
}
else
{
$template->append('related_categories', $name);
$related_categories[$row['category_id']] = $name;
$related_categories_ids[] = $row['category_id'];
}
}
$template->assign('related_categories', $related_categories);
$template->assign('related_categories_ids', $related_categories_ids);
// jump to link
//
// 1. find all linked categories that are reachable for the current user.

View file

@ -0,0 +1,151 @@
$(document).ready(function () {
$(".linked-albums.add-item").on("click", function () {
linked_albums_open();
set_up_popin();
});
$(".limitReached").html(str_no_search_in_progress);
$(".search-cancel-linked-album").hide();
$(".linkedAlbumPopInContainer .searching").hide();
$("#linkedAlbumSearch .search-input").on('input', function () {
if ($(this).val() != 0) {
$("#linkedAlbumSearch .search-cancel-linked-album").show()
} else {
$("#linkedAlbumSearch .search-cancel-linked-album").hide();
}
if ($(this).val().length > 2) {
linked_albums_search($(this).val());
} 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 () {
remove_related_category($(this).attr("id"));
})
})
function set_up_popin() {
$(".ClosePopIn").on('click', function () {
linked_albums_close();
});
}
function linked_albums_close() {
$("#addLinkedAlbum").fadeOut();
}
function linked_albums_open() {
$("#addLinkedAlbum").fadeIn();
$(".search-input").val("");
$(".search-input").focus();
$("#searchResult").empty();
}
function linked_albums_search(searchText) {
$(".linkedAlbumPopInContainer .searching").show();
$.ajax({
url: "ws.php?format=json&method=pwg.categories.getAdminList",
type: "POST",
dataType: "json",
data : {
search: searchText,
additional_output: "full_name_with_admin_links",
},
before: function () {
},
success: function (raw_data) {
$(".linkedAlbumPopInContainer .searching").hide();
categories = raw_data.result.categories;
fill_results(categories);
if (raw_data.result.limit_reached) {
$(".limitReached").html(str_result_limit.replace("%d", categories.length));
} else {
if (categories.length == 1) {
$(".limitReached").html(str_album_found);
} else {
$(".limitReached").html(str_albums_found.replace("%d", categories.length));
}
}
},
error: function (e) {
$(".linkedAlbumPopInContainer .searching").hide();
console.log(e.message);
}
})
}
function fill_results(cats) {
$("#searchResult").empty();
cats.forEach(cat => {
$("#searchResult").append(
"<div class='search-result-item'>" +
"<span class='search-result-path'>" + cat.fullname +"</span><span id="+ cat.id + " class='icon-plus-circled item-add'></span>" +
"</div>"
);
if (related_categories_ids.includes(cat.id)) {
$(".search-result-item #"+ cat.id +".item-add").addClass("notClickable").attr("title", str_already_in_related_cats).on("click", function (event) {
event.preventDefault();
});
} else {
$(".search-result-item #"+ cat.id +".item-add").on("click", function () {
add_related_category(cat.id, cat.full_name_with_admin_links);
});
}
});
}
function remove_related_category(cat_id) {
$(".invisible-related-categories-select option[value="+ cat_id +"]").remove();
$("#" + cat_id).parent().remove();
related_categories_ids.pop(cat_id);
check_related_categories();
}
function add_related_category(cat_id, cat_link_path) {
if (!related_categories_ids.includes(cat_id)) {
$(".related-categories-container").append(
"<div class='breadcrumb-item'>" +
"<span class='link-path'>" + cat_link_path + "</span><span id="+ cat_id + " class='icon-cancel-circled remove-item'></span>" +
"</div>"
);
$(".search-result-item #" + cat_id).addClass("notClickable");
related_categories_ids.push(cat_id);
$(".invisible-related-categories-select").append("<option selected value="+ cat_id +"></option>");
$("#"+ cat_id).on("click", function () {
remove_related_category($(this).attr("id"))
})
linked_albums_close();
}
check_related_categories();
}
function check_related_categories() {
$(".linked-albums-badge").html(related_categories_ids.length);
if (related_categories_ids.length == 0) {
$(".linked-albums-badge").addClass("badge-red");
$(".add-item").addClass("highlight");
$(".orphan-photo").html(str_orphan).show();
} else {
$(".linked-albums-badge.badge-red").removeClass("badge-red");
$(".add-item.highlight").removeClass("highlight");
$(".orphan-photo").hide();
}
}

View file

@ -49,6 +49,14 @@ str_are_you_sure = '{'Are you sure?'|translate}';
str_yes = '{'Yes, delete'|translate}';
str_no = '{'No, I have changed my mind'|translate|@escape:'javascript'}';
url_delete = '{$U_DELETE}';
str_albums_found = '{"<b>%d</b> albums found"|translate}';
str_album_found = '{"<b>1</b> album found"|translate}';
str_result_limit = '{"<b>%d+</b> albums found, try to refine the search"|translate|escape:javascript}';
str_orphan = '{'This photo is an orphan'|@translate}';
str_no_search_in_progress = '{'No search in progress'|@translate}';
related_categories_ids = {$related_categories_ids|@json_encode};
str_already_in_related_cats = '{'This albums is already in related categories list'|translate}';
{literal}
$('#action-delete-picture').on('click', function() {
@ -84,6 +92,9 @@ $('#action-delete-picture').on('click', function() {
}());
{/footer_script}
{combine_script id='picture_modify' load='footer' path='admin/themes/default/js/picture_modify.js'}
{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *}
<form action="{$F_ACTION}" method="post" id="pictureModify">
<div id='picture-preview'>
<div class='picture-preview-actions'>
@ -154,11 +165,24 @@ $('#action-delete-picture').on('click', function() {
</p>
<p>
<strong>{'Linked albums'|@translate}</strong>
<strong>{'Linked albums'|@translate} <span class="linked-albums-badge {if $related_categories|@count < 1 } badge-red {/if}"> {$related_categories|@count} </span></strong>
{if $related_categories|@count < 1}
<span class="orphan-photo">{'This photo is an orphan'|@translate}</span>
{else}
<span class="orphan-photo"></span>
{/if}
<br>
<select data-selectize="categories" data-value="{$associated_albums|@json_encode|escape:html}"
placeholder="{'Type in a search term'|translate}"
data-default="{$STORAGE_ALBUM}" name="associate[]" multiple style="width:calc(100% + 2px);"></select>
<select class="invisible-related-categories-select" name="associate[]" multiple>
{foreach from=$related_categories item=$cat_path key=$key}
<option selected value="{$key}"></option>
{/foreach}
</select>
<div class="related-categories-container">
{foreach from=$related_categories item=$cat_path key=$key}
<div class="breadcrumb-item"><span class="link-path">{$cat_path}</span><span id={$key} class="icon-cancel-circled remove-item"></span></div>
{/foreach}
</div>
<div class="breadcrumb-item linked-albums add-item {if $related_categories|@count < 1 } highlight {/if}"><span class="icon-plus-circled"></span>{'Add'|translate}</div>
</p>
<p>
@ -200,6 +224,31 @@ $('#action-delete-picture').on('click', function() {
</form>
<div id="addLinkedAlbum" class="linkedAlbumPopIn">
<div class="linkedAlbumPopInContainer">
<a class="icon-cancel ClosePopIn"></a>
<div class="AddIconContainer">
<span class="AddIcon icon-blue icon-plus-circled"></span>
</div>
<div class="AddIconTitle">
<span>{'Associate to album'|@translate}</span>
</div>
<div id="linkedAlbumSearch">
<span class='icon-search search-icon'> </span>
<span class="icon-cancel search-cancel-linked-album"></span>
<input class='search-input' type='text' placeholder='{'Search'|@translate}'>
</div>
<div class="limitReached"></div>
<div class="noSearch"></div>
<div class="searching icon-spin6 animate-spin"> </div>
<div id="searchResult">
</div>
</div>
</div>
<style>
.selectize-input .item,
.selectize-input .item.active {

View file

@ -6258,6 +6258,191 @@ color:#FF7B00;
margin-top: -10px;
}
.linked-albums-badge {
padding: 2px 6px;
background: #F1F1F1;
border-radius: 50px;
font-size: 10px;
transition: 0.3s;
}
.linked-albums-badge.badge-red {
background: red;
color: white;
}
.breadcrumb-item {
margin: 0 10px 10px 12px;
padding: 7px 10px;
background-color: #fafafa;
box-shadow: 0px 2px #00000024;
border-radius: 5px;
font-weight: bold;
color: #777 !important;
display: flex;
align-items: center;
position: relative;
}
.breadcrumb-item a {
padding: 0 5px;
font-weight: 400;
}
.breadcrumb-item .icon-cancel-circled {
margin-left: auto !important;
cursor: pointer;
position: absolute;
right: 10px;
}
.breadcrumb-item .icon-cancel-circled:hover {
color: #ff7700;
}
.breadcrumb-item.add-item {
width: min-content;
cursor: pointer;
color: #111111;
transition: 0.3s;
}
.breadcrumb-item.add-item.highlight {
background: #ffa646;
box-shadow: 0 2px #af7200;
color: white !important;
}
#addLinkedAlbum {
display:none;
}
.linkedAlbumPopIn {
position: fixed;
z-index: 100;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.7);
}
.linkedAlbumPopInContainer {
display:flex;
position:absolute;
left:50%;
top: 50%;
transform:translate(-50%, -48%);
text-align:left;
padding:20px;
flex-direction:column;
border-radius:15px;
align-items:center;
width: 400px;
background-color: white;
}
.linkedAlbumPopInContainer .AddIconContainer {
margin-top: 20px;
}
.ClosePopIn {
position: absolute;
right: -40px;
top: -40px;
font-size: 30px;
color: white;
}
.linkedAlbumPopInContainer .AddIcon {
border-radius: 9999px;
padding: 10px;
font-size: 2em;
}
.AddIconTitle {
font-size: 1.4em;
font-weight: bold;
text-align: center;
color: #000;
margin-bottom: 10px;
margin-top: 15px;
}
#linkedAlbumSearch .search-icon {
position: absolute;
transform: translate(7px, 8px);
font-size: 18px;
top: auto;
}
.linkedAlbumPopInContainer #searchResult {
width: 100%;
overflow-y: scroll;
max-height: 400px;
margin: 10px 0 0 0;
}
.search-cancel-linked-album {
opacity: 0.4;
cursor: pointer;
position: absolute;
font-size: 18px;
transform: translate(215px, 8px);
}
.search-cancel-linked-album:hover {
opacity: 1;
}
.search-result-item {
margin: 10px 0px;
padding: 5px 10px;
height: 25px;
background-color: #fafafa;
box-shadow: 0px 2px #00000024;
border-radius: 5px;
font-weight: bold;
color: #777;
display: flex;
align-items: center;
}
.search-result-path {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 80%;
direction: rtl;
text-align: left;
}
.search-result-item .icon-plus-circled{
margin-left: auto;
cursor: pointer;
color: black;
}
.search-result-item .icon-plus-circled:hover{
color: black;
}
.search-result-item .notClickable {
opacity: 0.3;
}
.linkedAlbumPopInContainer .searching {
margin-top: 10px;
}
.invisible-related-categories-select {
display: none;
}
.orphan-photo {
margin-left: 4px;
font-style: italic;
}
.search-line {
background: #fafafa;
}

View file

@ -274,6 +274,9 @@ $conf['album_description_on_all_pages'] = false;
// Number of years displayed in the history compare mode (for the years chart)
$conf['stat_compare_year_displayed'] = 5;
// Limit for linked albums search
$conf['linked_album_search_limit'] = 100;
// +-----------------------------------------------------------------------+
// | email |
// +-----------------------------------------------------------------------+

View file

@ -474,6 +474,11 @@ SELECT id, path, representative_ext
*/
function ws_categories_getAdminList($params, &$service)
{
global $conf;
$params['additional_output'] = array_map('trim', explode(',', $params['additional_output']));
$query = '
SELECT category_id, COUNT(*) AS counter
FROM '. IMAGE_CATEGORY_TABLE .'
@ -481,18 +486,36 @@ SELECT category_id, COUNT(*) AS counter
;';
$nb_images_of = query2array($query, 'category_id', 'counter');
// pwg_db_real_escape_string
$query = '
SELECT id, name, comment, uppercats, global_rank, dir, status
FROM '. CATEGORIES_TABLE .'
SELECT SQL_CALC_FOUND_ROWS id, name, comment, uppercats, global_rank, dir, status
FROM '. CATEGORIES_TABLE;
if (isset($params["search"]) and $params['search'] != "")
{
$query .= '
WHERE name LIKE \'%'.pwg_db_real_escape_string($params["search"]).'%\'
LIMIT '.$conf["linked_album_search_limit"];
}
$query .= '
;';
$result = pwg_query($query);
list($counter) = pwg_db_fetch_row(pwg_query('SELECT FOUND_ROWS()'));
$cats = array();
while ($row = pwg_db_fetch_assoc($result))
{
$id = $row['id'];
$row['nb_images'] = isset($nb_images_of[$id]) ? $nb_images_of[$id] : 0;
$cat_display_name = get_cat_display_name_cache(
$row['uppercats'],
get_root_url().'admin.php?page=album-'
);
$row['name'] = strip_tags(
trigger_change(
'render_category_name',
@ -500,12 +523,7 @@ SELECT id, name, comment, uppercats, global_rank, dir, status
'ws_categories_getAdminList'
)
);
$row['fullname'] = strip_tags(
get_cat_display_name_cache(
$row['uppercats'],
null
)
);
$row['fullname'] = strip_tags($cat_display_name);
$row['comment'] = strip_tags(
trigger_change(
'render_category_description',
@ -514,16 +532,28 @@ SELECT id, name, comment, uppercats, global_rank, dir, status
)
);
if (in_array('full_name_with_admin_links', $params['additional_output']))
{
$row["full_name_with_admin_links"] = $cat_display_name;
}
$cats[] = $row;
}
$limit_reached = false;
if ($counter > $conf["linked_album_search_limit"]) {
$limit_reached = true;
}
usort($cats, 'global_rank_compare');
return array(
'categories' => new PwgNamedArray(
$cats,
'category',
array('id', 'nb_images', 'name', 'uppercats', 'global_rank', 'status')
)
array('id', 'nb_images', 'name', 'uppercats', 'global_rank', 'status', 'test')
),
'limit' => $conf["linked_album_search_limit"],
'limit_reached' => $limit_reached,
);
}

View file

@ -1273,6 +1273,9 @@ $lang['Yes, rename'] = 'Yes, rename';
$lang['Tag name'] = 'Tag name';
$lang['Current Version'] = 'Current Version';
$lang['More information'] = 'More information';
$lang['This photo is an orphan'] = 'This photo is an orphan';
$lang['This albums is already in related categories list'] = 'This albums is already in related albums list';
$lang['No search in progress'] = 'No search in progress';
$lang['Visited'] = 'Visited';
$lang['Downloaded'] = 'Downloaded';

View file

@ -1281,3 +1281,6 @@ $lang['Memories'] = 'Souvenirs';
$lang['Current Version'] = 'Version actuelle';
$lang['More information'] = 'Plus d\'information';
$lang['Add as filter'] = 'Ajouter en tant que filtre';
$lang['This photo is an orphan'] = 'Cette photo est orpheline';
$lang['This albums is already in related categories list'] = 'Cet album est déjà dans la liste des albums associés';
$lang['No search in progress'] = 'Pas de recherche en cours';

10
ws.php
View file

@ -556,8 +556,14 @@ function ws_addDefaultMethods( $arr )
$service->addMethod(
'pwg.categories.getAdminList',
'ws_categories_getAdminList',
null,
'Get albums list as displayed on admin page.',
array(
'search' => array('default' => null),
'additional_output' => array('default'=>null,
'info'=>'Comma saparated list (see method description)'),
),
'Get albums list as displayed on admin page. <br>
<b>additional_output</b> controls which data are returned, possible values are:<br>
null, full_name_with_admin_links<br>',
$ws_functions_root . 'pwg.categories.php',
array('admin_only'=>true)
);