Skip to content

Commit

Permalink
Issue #1193 : Tag Manager redesign
Browse files Browse the repository at this point in the history
 * Create the new design of tag manager
 * Replace all actions by ajax actions
 * Add delete, rename, duplicate and merge tag's functions in the Piwigo API
 * Modification of group manager to match both designs
  • Loading branch information
Zacharieg committed Jun 16, 2020
1 parent 2e70ebf commit 7c733a8
Show file tree
Hide file tree
Showing 12 changed files with 1,529 additions and 632 deletions.
171 changes: 18 additions & 153 deletions admin/tags.php
Expand Up @@ -14,16 +14,6 @@
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
check_status(ACCESS_ADMINISTRATOR);

if (!empty($_POST))
{
check_pwg_token();
check_input_parameter('tags', $_POST, true, PATTERN_ID);
check_input_parameter('selectAction', $_POST, false, '/^[a-zA-Z0-9_-]+$/');
check_input_parameter('edit_list', $_POST, false, '/^\d+(,\d+)*$/');
check_input_parameter('merge_list', $_POST, false, '/^\d+(,\d+)*$/');
check_input_parameter('destination_tag', $_POST, false, PATTERN_ID);
}

// +-----------------------------------------------------------------------+
// | tabs |
// +-----------------------------------------------------------------------+
Expand All @@ -37,64 +27,6 @@
$tabsheet->select('');
$tabsheet->assign();

// +-----------------------------------------------------------------------+
// | edit tags |
// +-----------------------------------------------------------------------+

if (isset($_POST['edit_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))
{
$updates[] = array(
'id' => $tag_id,
'name' => addslashes($tag_name),
'url_name' => trigger_change('render_tag_url', $tag_name),
);
}
}
}
mass_updates(
TAGS_TABLE,
array(
'primary' => array('id'),
'update' => array('name', 'url_name'),
),
$updates
);

pwg_activity('tag', explode(',', $_POST['edit_list']), 'edit');
}
// +-----------------------------------------------------------------------+
// | dulicate tags |
// +-----------------------------------------------------------------------+
Expand Down Expand Up @@ -282,67 +214,21 @@
}
}


// +-----------------------------------------------------------------------+
// | delete tags |
// +-----------------------------------------------------------------------+

if (isset($_POST['delete']) and isset($_POST['tags']))
{
if (!isset($_POST['confirm_deletion']))
{
$page['errors'][] = l10n('You need to confirm deletion');
}
else
{
$query = '
SELECT name
FROM '.TAGS_TABLE.'
WHERE id IN ('.implode(',', $_POST['tags']).')
;';
$tag_names = array_from_query($query, 'name');

delete_tags($_POST['tags']);

$page['infos'][] = l10n_dec(
'The following tag was deleted', 'The %d following tags were deleted',
count($tag_names)
)
.' : '.implode(', ', $tag_names);
}
}

// +-----------------------------------------------------------------------+
// | delete orphan tags |
// +-----------------------------------------------------------------------+

$message_tags = "";

if (isset($_GET['action']) and 'delete_orphans' == $_GET['action'])
{
check_pwg_token();

delete_orphan_tags();
$_SESSION['page_infos'] = array(l10n('Orphan tags deleted'));
$message_tags = array(l10n('Orphan tags deleted'));
redirect(get_root_url().'admin.php?page=tags');
}

// +-----------------------------------------------------------------------+
// | add a tag |
// +-----------------------------------------------------------------------+

if (isset($_POST['add']) and !empty($_POST['add_tag']))
{
$ret = create_tag($_POST['add_tag']);

if (isset($ret['error']))
{
$page['errors'][] = $ret['error'];
}
else
{
$page['infos'][] = $ret['info'];
}
}

// +-----------------------------------------------------------------------+
// | template init |
// +-----------------------------------------------------------------------+
Expand All @@ -360,6 +246,8 @@
// | orphan tags |
// +-----------------------------------------------------------------------+

$warning_tags = "";

$orphan_tags = get_orphan_tags();

$orphan_tag_names = array();
Expand All @@ -370,14 +258,23 @@

if (count($orphan_tag_names) > 0)
{
$page['warnings'][] = sprintf(
l10n('You have %d orphan tags: %s.').' <a href="%s" class="icon-trash">'.l10n('Delete orphan tags').'</a>',
$warning_tags = sprintf(
l10n('You have %d orphan tags: %s.'),
count($orphan_tag_names),
implode(', ', $orphan_tag_names),
get_root_url().'admin.php?page=tags&amp;action=delete_orphans&amp;pwg_token='.get_pwg_token()
'<a
data-tags=\'["'.implode('" ,"', $orphan_tag_names).'"]\'
data-url="'.get_root_url().'admin.php?page=tags&amp;action=delete_orphans&amp;pwg_token='.get_pwg_token().'">'
.l10n('See details').'</a>'
);
}

$template->assign(
array(
'warning_tags' => $warning_tags,
'message_tags' => $message_tags
)
);

// +-----------------------------------------------------------------------+
// | form creation |
// +-----------------------------------------------------------------------+
Expand Down Expand Up @@ -423,38 +320,6 @@
)
);

if ((isset($_POST['edit']) or isset($_POST['duplicate']) or isset($_POST['merge'])) and isset($_POST['tags']))
{
$list_name = 'EDIT_TAGS_LIST';
if (isset($_POST['duplicate']))
{
$list_name = 'DUPLIC_TAGS_LIST';
}
elseif (isset($_POST['merge']))
{
$list_name = 'MERGE_TAGS_LIST';
}

$template->assign($list_name, implode(',', $_POST['tags']));

$query = '
SELECT id, name
FROM '.TAGS_TABLE.'
WHERE id IN ('.implode(',', $_POST['tags']).')
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
$template->append(
'tags',
array(
'ID' => $row['id'],
'NAME' => $row['name'],
)
);
}
}

// +-----------------------------------------------------------------------+
// | sending html code |
// +-----------------------------------------------------------------------+
Expand Down
4 changes: 2 additions & 2 deletions admin/themes/clear/theme.css
Expand Up @@ -513,12 +513,12 @@ input:focus + .slider {
color:#a0a0a0;
}

.SelectionModeGroup button{
#selection-mode-block button{
border: 1px solid #e7e7e7;
}


.SelectionModeGroup button:hover{
#selection-mode-block button:hover{
background-color: #ffa744;
border: 1px solid #ffa744;
}
Expand Down
133 changes: 133 additions & 0 deletions admin/themes/default/js/common.js
Expand Up @@ -125,4 +125,137 @@ function sprintf() {
}

return o.join('');
}

// Class to implement a temporary state and reverse it
class TemporaryState {
//Arrays to reverse changes
attrChanges = []; //Attribute changes : {object(s), attribute, value}
classChanges = []; //Class changes : {object(s), state(add:true/remove:false), class}
htmlChanges = []; //Html changes : {object(s), html}

/**
* Change temporaly an attribute of an object
* @param {Jquery Object(s)} obj HTML Object(s)
* @param {String} attr Attribute
* @param {String} tempVal Temporary value of the attribute
*/
changeAttribute(obj, attr, tempVal) {
for (let i = 0; i < obj.length; i++) {
this.attrChanges.push({
object: $(obj[i]),
attribute: attr,
value: $(obj[i]).attr(attr)
})
}
obj.attr(attr, tempVal)
}

/**
* Add/remove a class temporarily
* @param {Jquery Object(s)} obj HTML Object
* @param {Boolean} st Add (true) or Remove (false) the class
* @param {String} loadclass Class Name
*/
changeClass(obj, st, tempclass) {
for (let i = 0; i < obj.length; i++) {
if (!($(obj[i]).hasClass(tempclass) && st)) {
this.classChanges.push({
object: $(obj[i]),
state: !st,
class: tempclass
})
if (st)
$(obj[i]).addClass(tempclass)
else
$(obj[i]).removeClass(tempclass)
}
}
}

/**
* Add temporarily a class to the object
* @param {Jquery Object(s)} obj
* @param {string} tempclass
*/
addClass(obj, tempclass) {
this.changeClass(obj, true, tempclass);
}

/**
* Remove temporarily a class to the object
* @param {Jquery Object(s)} obj
* @param {string} tempclass
*/
removeClass(obj, tempclass) {
this.changeClass(obj, false, tempclass);
}

/**
* Change temporaly the html of objects (remove event handlers on the actual content)
* @param {Jquery Object(s)} obj
* @param {string} temphtml
*/
changeHTML(obj, temphtml) {
for (let i = 0; i < obj.length; i++) {
this.htmlChanges.push({
object:$(obj[i]),
html:$(obj[i]).html()
})
}
obj.html(temphtml);
}

/**
* Reverse all the changes and clear the history
*/
reverse() {
this.attrChanges.forEach(function(change) {
if (change.value == undefined) {
change.object.removeAttr(change.attribute);
} else {
change.object.attr(change.attribute, change.value)
}
})
this.classChanges.forEach(function(change) {
if (change.state)
change.object.addClass(change.class)
else
change.object.removeClass(change.class)
})
this.htmlChanges.forEach(function(change) {
change.object.html(change.html);
})
this.attrChanges = [];
this.classChanges = [];
this.htmlChanges = [];
}
}

const jConfirm_alert_options = {
icon: 'icon-ok',
titleClass: "jconfirmAlert",
theme:"modern",
closeIcon: true,
draggable: false,
animation: "zoom",
boxWidth: '20%',
useBootstrap: false,
backgroundDismiss: true,
animateFromElement: false,
typeAnimated: false,
}

const jConfirm_confirm_options = {
draggable: false,
titleClass: "jconfirmDeleteConfirm",
theme: "modern",
content: "",
animation: "zoom",
boxWidth: '30%',
useBootstrap: false,
type: 'red',
animateFromElement: false,
backgroundDismiss: true,
typeAnimated: false,
}

0 comments on commit 7c733a8

Please sign in to comment.