From 5deba88a5c05b5fda8b2e61d4d3fea10e2a6effb Mon Sep 17 00:00:00 2001 From: Zacharie Date: Thu, 18 Jun 2020 11:16:14 +0200 Subject: [PATCH] Issue #1193 : Improvement of tag's manager * Hide Tag item when there are more than 5 * Change data format in Ajax calls * Remove useless code in tag.php * Remove pwg_token in pwg.tags.add * Minor design fixes --- admin/tags.php | 187 ------------------------- admin/themes/default/js/tags.js | 115 +++++++++++---- admin/themes/default/template/tags.tpl | 40 +++--- admin/themes/default/theme.css | 49 ++++++- include/ws_functions/pwg.tags.php | 14 +- ws.php | 3 +- 6 files changed, 163 insertions(+), 245 deletions(-) diff --git a/admin/tags.php b/admin/tags.php index 52fcd8270..db90f6bcd 100644 --- a/admin/tags.php +++ b/admin/tags.php @@ -27,193 +27,6 @@ $tabsheet->set_id('tags'); $tabsheet->select(''); $tabsheet->assign(); -// +-----------------------------------------------------------------------+ -// | dulicate tags | -// +-----------------------------------------------------------------------+ - -if (isset($_POST['duplic_submit'])) -{ - $query = ' -SELECT name - FROM '.TAGS_TABLE.' -;'; - $existing_names = array_from_query($query, 'name'); - - - $current_name_of = array(); - $query = ' -SELECT id, name - FROM '.TAGS_TABLE.' - WHERE id IN ('.$_POST['edit_list'].') -;'; - $result = pwg_query($query); - while ($row = pwg_db_fetch_assoc($result)) - { - $current_name_of[ $row['id'] ] = $row['name']; - } - - $updates = array(); - // we must not rename tag with an already existing name - foreach (explode(',', $_POST['edit_list']) as $tag_id) - { - $tag_name = stripslashes($_POST['tag_name-'.$tag_id]); - - if ($tag_name != $current_name_of[$tag_id]) - { - if (in_array($tag_name, $existing_names)) - { - $page['errors'][] = l10n('Tag "%s" already exists', $tag_name); - } - else if (!empty($tag_name)) - { - single_insert( - TAGS_TABLE, - array( - 'name' => $tag_name, - 'url_name' => trigger_change('render_tag_url', $tag_name), - ) - ); - $destination_tag_id = pwg_db_insert_id(TAGS_TABLE); - - pwg_activity('tag', $destination_tag_id, 'add', array('action'=>'duplicate', 'source_tag'=>$tag_id)); - - $query = ' - SELECT - image_id - FROM '.IMAGE_TAG_TABLE.' - WHERE tag_id = '.$tag_id.' - ;'; - $destination_tag_image_ids = array_from_query($query, 'image_id'); - - $inserts = array(); - foreach ($destination_tag_image_ids as $image_id) - { - $inserts[] = array( - 'tag_id' => $destination_tag_id, - 'image_id' => $image_id - ); - } - - if (count($inserts) > 0) - { - mass_inserts( - IMAGE_TAG_TABLE, - array_keys($inserts[0]), - $inserts - ); - } - - $page['infos'][] = l10n( - 'Tag "%s" is now a duplicate of "%s"', - stripslashes($tag_name), - $current_name_of[$tag_id] - ); - } - } - } - - mass_updates( - TAGS_TABLE, - array( - 'primary' => array('id'), - 'update' => array('name', 'url_name'), - ), - $updates - ); -} - -// +-----------------------------------------------------------------------+ -// | merge tags | -// +-----------------------------------------------------------------------+ - -if (isset($_POST['merge_submit'])) -{ - if (!isset($_POST['destination_tag'])) - { - $page['errors'][] = l10n('No destination tag selected'); - } - else - { - $destination_tag_id = $_POST['destination_tag']; - $tag_ids = explode(',', $_POST['merge_list']); - - if (is_array($tag_ids) and count($tag_ids) > 1) - { - $name_of_tag = array(); - $query = ' -SELECT - id, - name - FROM '.TAGS_TABLE.' - WHERE id IN ('.implode(',', $tag_ids).') -;'; - $result = pwg_query($query); - while ($row = pwg_db_fetch_assoc($result)) - { - $name_of_tag[ $row['id'] ] = trigger_change('render_tag_name', $row['name'], $row); - } - - $tag_ids_to_delete = array_diff( - $tag_ids, - array($destination_tag_id) - ); - - $query = ' -SELECT - DISTINCT(image_id) - FROM '.IMAGE_TAG_TABLE.' - WHERE tag_id IN ('.implode(',', $tag_ids_to_delete).') -;'; - $image_ids = array_from_query($query, 'image_id'); - - delete_tags($tag_ids_to_delete); - - $query = ' -SELECT - image_id - FROM '.IMAGE_TAG_TABLE.' - WHERE tag_id = '.$destination_tag_id.' -;'; - $destination_tag_image_ids = array_from_query($query, 'image_id'); - - $image_ids_to_link = array_diff( - $image_ids, - $destination_tag_image_ids - ); - - $inserts = array(); - foreach ($image_ids_to_link as $image_id) - { - $inserts[] = array( - 'tag_id' => $destination_tag_id, - 'image_id' => $image_id - ); - } - - if (count($inserts) > 0) - { - mass_inserts( - IMAGE_TAG_TABLE, - array_keys($inserts[0]), - $inserts - ); - } - - $tags_deleted = array(); - foreach ($tag_ids_to_delete as $tag_id) - { - $tags_deleted[] = $name_of_tag[$tag_id]; - } - - $page['infos'][] = l10n( - 'Tags %s merged into tag %s', - implode(', ', $tags_deleted), - $name_of_tag[$destination_tag_id] - ); - } - } -} - // +-----------------------------------------------------------------------+ // | delete orphan tags | // +-----------------------------------------------------------------------+ diff --git a/admin/themes/default/js/tags.js b/admin/themes/default/js/tags.js index 856ec352c..f1c03d7b3 100644 --- a/admin/themes/default/js/tags.js +++ b/admin/themes/default/js/tags.js @@ -78,7 +78,9 @@ function addTag(name) { jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.add", type: "POST", - data: "name=" + name + "&pwg_token=" + pwg_token, + data: { + name: name + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); if (data.stat === "ok") { @@ -108,7 +110,6 @@ function createTagBox(id, name) { if ($("#toggleSelectionMode").is(":checked")) { newTag.addClass('selection'); newTag.find(".in-selection-mode").show(); - newTag.find(".not-in-selection-mode").hide(); } return newTag; } @@ -158,6 +159,7 @@ function setupTagbox(tagBox) { tagBox.find('.tag-rename .icon-cancel').on('click', function() { tagBox.removeClass('edit-name'); + tagBox.find('.tag-name-editable').val(name); }) tagBox.find('.tag-rename .validate').on('click', function() { @@ -219,7 +221,10 @@ function removeTag(id, name) { return jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.delete", type: "POST", - data: "tag_id=" + id + "&pwg_token=" + pwg_token, + data: { + tag_id: id, + pwg_token: pwg_token + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); showMessage(str_tag_deleted.replace('%s', name)); @@ -238,12 +243,16 @@ function renameTag(id, new_name) { jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.rename", type: "POST", - data: "tag_id=" + id + "&new_name=" + new_name + "&pwg_token=" + pwg_token, + data: { + tag_id: id, + new_name: new_name, + pwg_token: pwg_token + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); if (data.stat === "ok") { $('.tag-box[data-id='+id+'] p').html(data.result.name); - $('.tag-box[data-id='+id+'] .tag-name-editable').attr('placeholder', data.result.name); + $('.tag-box[data-id='+id+'] .tag-name-editable').attr('value', data.result.name); resolve(data); } else { reject(str_already_exist.replace('%s', new_name)) @@ -278,7 +287,11 @@ function duplicateTag(id, name) { jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.duplicate", type: "POST", - data: "tag_id=" + id + "©_name=" + copy_name + "&pwg_token=" + pwg_token, + data: { + tag_id : id, + copy_name: copy_name, + pwg_token: pwg_token + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); if (data.stat === "ok") { @@ -302,21 +315,27 @@ function duplicateTag(id, name) { /*------- Selection mode -------*/ +numberItemDisplayed = 5; + $("#toggleSelectionMode").attr("checked", false) $("#toggleSelectionMode").click(function () { - if ($(this).is(":checked")) { + selectionMode($(this).is(":checked")) +}); + +function selectionMode(isSelection) { + if (isSelection) { $(".in-selection-mode").show(); - $(".not-in-selection-mode").removeAttr('style'); + $(".not-in-selection-mode").hide(); $(".tag-box").addClass("selection"); $(".tag-box").removeClass('edit-name'); } else { $(".in-selection-mode").removeAttr('style'); - $(".not-in-selection-mode").show(); + $(".not-in-selection-mode").removeAttr('style'); $(".tag-box").removeClass("selection"); $(".tag-box").attr("data-selected", '0'); updateListItem(); } -}); +} function updateListItem() { @@ -362,6 +381,15 @@ function updateListItem() { ) }) + if (selected.length > 5) { + $('.selection-other-tags').show(); + $('.selection-other-tags').html(str_and_others_tags.replace('%s', selected.length - 5)) + } else { + $('.selection-other-tags').hide(); + } + + + updateSelectionContent() } @@ -402,6 +430,27 @@ $('#CancelMerge').on('click', function() { updateSelectionContent() }); +$('#selectAll').on('click', function() { + $('.tag-box').attr('data-selected', '1'); + updateListItem(); +}); + +$('#selectNone').on('click', function() { + $('.tag-box').attr('data-selected', '0'); + updateListItem(); +}); + +$('#selectInvert').on('click', function() { + $('.tag-box').each(function() { + if ($(this).attr('data-selected') == 1) { + $(this).attr('data-selected', '0'); + } else { + $(this).attr('data-selected', '1'); + } + }); + updateListItem(); +}); + /*------- Actions in selection mode -------*/ @@ -415,7 +464,7 @@ $('#DeleteSelectionMode').on('click', function() { }) $.confirm({ - title: str_delete_tags.replace("%s",names.join(', ')), + title: str_delete_tags.replace("%s",tagListToString(names)), buttons: { confirm: { text: str_yes_delete_confirmation, @@ -433,7 +482,6 @@ $('#DeleteSelectionMode').on('click', function() { }) function removeSelectedTags() { - str_id = ""; names = []; ids = []; @@ -441,18 +489,18 @@ function removeSelectedTags() { id = $(this).data('id'); ids.push(id); names.push($(this).find('.tag-name').html()); - str_id += "tag_id[]=" + id + "&"; }) - console.log(names); - $.alert({ - title : str_tags_deleted.replace("%s",names.join(', ')), + title : str_tags_deleted.replace("%s",tagListToString(names)), content: function() { return jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.delete", type: "POST", - data: str_id + "pwg_token=" + pwg_token, + data: { + tag_id: ids, + pwg_token: pwg_token + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); if (data.stat === "ok") { @@ -460,7 +508,6 @@ function removeSelectedTags() { $('.tag-box[data-id='+id+']').remove(); }) updateListItem(); - showMessage(str_tags_deleted.replace('%s', names.join(', '))); } } }) @@ -489,7 +536,7 @@ function mergeGroups(destination_id, merge_ids) { }) str_message = str_merged_into - .replace('%s1', merge_name.join(', ')) + .replace('%s1', tagListToString(merge_name)) .replace('%s2', destination_name) $.alert({ @@ -498,13 +545,14 @@ function mergeGroups(destination_id, merge_ids) { return jQuery.ajax({ url: "ws.php?format=json&method=pwg.tags.merge", type: "POST", - data: "destination_tag_id=" + destination_id - + "&merge_tag_id[]=" + merge_ids.join('&merge_tag_id[]=') - + "&pwg_token=" + pwg_token, + data: { + destination_tag_id: destination_id, + merge_tag_id: merge_ids, + pwg_token: pwg_token + }, success: function (raw_data) { data = jQuery.parseJSON(raw_data); if (data.stat === "ok") { - console.log() data.result.deleted_tag.forEach((id) => { if (data.result.destination_tag != id) $('.tag-box[data-id='+id+']').remove(); @@ -513,7 +561,6 @@ function mergeGroups(destination_id, merge_ids) { tagBox = $('.tag-box[data-id='+data.result.destination_tag+']') tagBox.find('.tag-dropdown-action.view, .tag-dropdown-action.manage').show(); } - showMessage(str_message); $(".tag-box").attr("data-selected", '0'); updateListItem(); } @@ -524,6 +571,16 @@ function mergeGroups(destination_id, merge_ids) { }); } +function tagListToString(list) { + if (list.length > 5) { + return list.slice(0,5).join(', ') + + ' ' + + str_and_others_tags.replace('%s', list.length - 5); + } else { + return list.join(', '); + } +} + /*------- Filter research -------*/ @@ -533,22 +590,22 @@ $("#search-tag .search-input").on("input", function() { var searchNumber = 0; $('.tag-box').each(function () { if (text == "") { - $(this).fadeIn() + $(this).show() searchNumber++; } else { let name = $(this).find("p").text().toLowerCase(); if (name.search(text) != -1){ - $(this).delay(300).fadeIn() + $(this).delay(300).show() searchNumber++; } else { - $(this).fadeOut() + $(this).hide() } } }) if (searchNumber == 0) { - $('.emptyResearch').delay(300).fadeIn(); + $('.emptyResearch').show(); } else { - $('.emptyResearch').fadeOut(); + $('.emptyResearch').hide(); } }) diff --git a/admin/themes/default/template/tags.tpl b/admin/themes/default/template/tags.tpl index 81ca766bb..99672ac8a 100644 --- a/admin/themes/default/template/tags.tpl +++ b/admin/themes/default/template/tags.tpl @@ -1,21 +1,22 @@ {footer_script} var pwg_token = "{$PWG_TOKEN}"; -var str_delete = '{'Delete tag "%s"?'|@translate}' -var str_delete_tags = '{'Delete tags \{%s\}?'|@translate}' -var str_yes_delete_confirmation = "{'Yes, delete'|@translate}" -var str_no_delete_confirmation = "{"No, I have changed my mind"|@translate}" -var str_tag_deleted = '{'Tag "%s" succesfully deleted'|@translate}' -var str_tags_deleted = '{'Tags \{%s\} succesfully deleted'|@translate}' -var str_already_exist = '{'Tag "%s" already exists'|@translate}' -var str_tag_created = '{'Tag "%s" created'|@translate}' -var str_tag_renamed = '{'Tag "%s1" renamed in "%s2"'|@translate}' -var str_delete_orphan_tags = '{'Delete orphan tags ?'|@translate}' +var str_delete = '{'Delete tag "%s"?'|@translate}'; +var str_delete_tags = '{'Delete tags \{%s\}?'|@translate}'; +var str_yes_delete_confirmation = "{'Yes, delete'|@translate}"; +var str_no_delete_confirmation = "{"No, I have changed my mind"|@translate}"; +var str_tag_deleted = '{'Tag "%s" succesfully deleted'|@translate}'; +var str_tags_deleted = '{'Tags \{%s\} succesfully deleted'|@translate}'; +var str_already_exist = '{'Tag "%s" already exists'|@translate}'; +var str_tag_created = '{'Tag "%s" created'|@translate}'; +var str_tag_renamed = '{'Tag "%s1" renamed in "%s2"'|@translate}'; +var str_delete_orphan_tags = '{'Delete orphan tags ?'|@translate}'; var str_orphan_tags = '{'You have %s1 orphan : %s2'|@translate}'; var str_delete_them = '{'Delete them'|@translate}'; var str_keep_them = '{'Keep them'|@translate}'; -var str_copy = '{' (copy)'|@translate}' -var str_other_copy = '{' (copy %s)'|@translate}' -var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translate}' +var str_copy = '{' (copy)'|@translate}'; +var str_other_copy = '{' (copy %s)'|@translate}'; +var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translate}'; +var str_and_others_tags = '{'and %s others'|@translate}'; {/footer_script} {combine_script id='common' load='footer' path='admin/themes/default/js/common.js'} @@ -28,7 +29,7 @@ var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translat {function name=tagContent} {function tagContent}

{$tag_name}

- +
@@ -41,7 +42,7 @@ var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translat
- +
@@ -72,6 +73,7 @@ var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translat
+
@@ -95,7 +97,7 @@ var str_merged_into = '{'Tag(s) \{%s1\} succesfully merged into "%s2"'|@translat
-
+
+
+

{'Select:'|@translate}

+ {'All'|@translate} + {'None'|@translate} + {'Invert'|@translate} +
{if $warning_tags != ""}

{$warning_tags}

{/if} diff --git a/admin/themes/default/theme.css b/admin/themes/default/theme.css index 21a370626..979f67789 100644 --- a/admin/themes/default/theme.css +++ b/admin/themes/default/theme.css @@ -3244,6 +3244,7 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; background-color: #fafafa; padding-left: 30px; width: 300px; + margin: 4px; } .tag-header #search-tag span { @@ -3348,6 +3349,32 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; opacity: 1; } +.tag-header .selection-controller { + display: none; + margin: 0px 7px; +} + +.tag-header .selection-controller p { + position: absolute; + transform: translateY(-40px); +} + +.tag-header .selection-controller a { + margin: 0; + background-color: #fafafa; + padding: 10px; + box-shadow: 0px 2px #00000024; + color: #777; + font-weight: bold; +} + +.tag-header .selection-controller a:hover { + background-color: #f0f0f0; + color: #3A3A3A; + text-decoration: none; +} + + .tag-info { height: 35px; overflow: hidden; @@ -3360,6 +3387,10 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; .tag-info p { margin: auto; white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + max-width: 300px; + text-align: initial; } .tag-info::before { @@ -3431,10 +3462,19 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; display: none; } +.tag-container .tag-box .showOptions { + color: #777; +} + .tag-container .tag-box.edit-name .showOptions { display: none; } + +.tag-container .tag-box.selection .showOptions { + display: none; +} + .tag-container .tag-box .tag-dropdown-block { display:none; position:absolute; @@ -3453,6 +3493,7 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; text-align: initial; padding: 5px 10px; font-size: 13px; + padding-right: 15px; } .tag-container .tag-box .tag-dropdown-block .tag-dropdown-action:hover { @@ -3502,7 +3543,6 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; } } - .tag-container .tag-box .tag-rename { display: none; } @@ -3548,6 +3588,8 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; text-align: start; font-weight: 700; font-size: 15px; + overflow: hidden; + max-height: 160px; } .selection-mode-tag .tag-list p { @@ -3563,4 +3605,9 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; display: flex; margin: 10px; text-align: start; +} + +.selection-mode-tag .selection-other-tags { + color: #ffa646; + font-weight: bold; } \ No newline at end of file diff --git a/include/ws_functions/pwg.tags.php b/include/ws_functions/pwg.tags.php index 46328150a..b91531a43 100644 --- a/include/ws_functions/pwg.tags.php +++ b/include/ws_functions/pwg.tags.php @@ -220,11 +220,6 @@ function ws_tags_add($params, &$service) { include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); - if (get_pwg_token() != $params['pwg_token']) - { - return new PwgError(403, 'Invalid security token'); - } - $creation_output = create_tag($params['name']); if (isset($creation_output['error'])) @@ -264,9 +259,6 @@ SELECT COUNT(*) { delete_tags($params['tag_id']); return array('id' => $tag_ids); - foreach ($tag_ids as $ids) { - pwg_activity('tag', $creation_output['id'], 'delete'); - } } else { return array('id' => array()); } @@ -334,7 +326,8 @@ SELECT name } -function ws_tags_duplicate($params, &$service) { +function ws_tags_duplicate($params, &$service) +{ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); @@ -415,7 +408,8 @@ SELECT image_id ); } -function ws_tags_merge($params, &$service) { +function ws_tags_merge($params, &$service) +{ if (get_pwg_token() != $params['pwg_token']) { diff --git a/ws.php b/ws.php index 1e35c0d23..627e0cd98 100644 --- a/ws.php +++ b/ws.php @@ -641,8 +641,7 @@ function ws_addDefaultMethods( $arr ) 'pwg.tags.add', 'ws_tags_add', array( - 'name' => array(), - 'pwg_token' => array(), + 'name' => array() ), 'Adds a new tag.', $ws_functions_root . 'pwg.tags.php',