mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-06-02 04:15:05 +02:00
Issue #1167 : Add pwg.groups.duplicate to API methods, add the merge action in group manager (and small code fixes)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const DELAY_FEEDBACK = 3000;
|
||||
|
||||
/*-------
|
||||
Group Popup
|
||||
Group Popin
|
||||
-------*/
|
||||
|
||||
$(".group_details_popup_trigger").click(function () {
|
||||
@@ -84,31 +84,8 @@ jQuery(document).ready(function () {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
$(".addGroupFormLabelAndInput input").val('');
|
||||
id = data.result.groups[0].id;
|
||||
//Setup the group
|
||||
newgroup = $("#group-template").clone().attr("id", "group-" + id);
|
||||
newgroup.css("order", -id);
|
||||
newgroup.attr("data-id", id);
|
||||
newgroup.find("#group_name").html(name);
|
||||
newgroup.find(".group_name-editable").val(name);
|
||||
newgroup.find(".Group-checkbox label").attr("for", "Group-Checkbox-selection-" + id);
|
||||
newgroup.find(".Group-checkbox input").attr("id", "Group-Checkbox-selection-" + id);
|
||||
newgroup.find(".input-edit-group-name").attr("placeholder", name);
|
||||
newgroup.find(".group_number_users").html("0 " + str_member_default);
|
||||
newgroup.find(".group_name-editable").html(name);
|
||||
hideAddGroupForm();
|
||||
//Setup the icon color
|
||||
var colors = [["#ffa744", "#ffe9cf"],["#896af3", "#e0daf4"], ["#6ece5e","#d6ffcf"],["#2883c3","#cfebff"]];
|
||||
var colorId = Number(id)%4;
|
||||
newgroup.find(".icon-users-1").attr("style", "color:"+colors[colorId][0]+"; background-color:"+colors[colorId][1]);
|
||||
|
||||
setupGroupBox(newgroup);
|
||||
|
||||
//Place group in first Place
|
||||
newgroup.appendTo(".groups");
|
||||
newgroup.find(".groupMessage").html(str_group_created);
|
||||
newgroup.find(".groupMessage").fadeIn();
|
||||
newgroup.find(".groupMessage").delay(DELAY_FEEDBACK).fadeOut();
|
||||
group = data.result.groups[0];
|
||||
createGroup(group)
|
||||
} else {
|
||||
$("#addGroupForm .groupError").html(str_name_taken);
|
||||
$("#addGroupForm .groupError").fadeIn();
|
||||
@@ -122,6 +99,33 @@ jQuery(document).ready(function () {
|
||||
});
|
||||
});
|
||||
|
||||
var createGroup = function(group) {
|
||||
//Setup the group
|
||||
newgroup = $("#group-template").clone().attr("id", "group-" + group.id);
|
||||
newgroup.css("order", -group.id);
|
||||
newgroup.attr("data-id", group.id);
|
||||
newgroup.find("#group_name").html(group.name);
|
||||
newgroup.find(".group_name-editable").val(group.name);
|
||||
newgroup.find(".Group-checkbox label").attr("for", "Group-Checkbox-selection-" + group.id);
|
||||
newgroup.find(".Group-checkbox input").attr("id", "Group-Checkbox-selection-" + group.id);
|
||||
newgroup.find(".input-edit-group-name").attr("placeholder", group.name);
|
||||
newgroup.find(".group_number_users").html(group.nb_users+" " + ((group.nb_users > 1)? str_members_default:str_member_default));
|
||||
newgroup.find(".group_name-editable").html(group.name);
|
||||
hideAddGroupForm();
|
||||
//Setup the icon color
|
||||
var colors = [["#ffa744", "#ffe9cf"],["#896af3", "#e0daf4"], ["#6ece5e","#d6ffcf"],["#2883c3","#cfebff"]];
|
||||
var colorId = Number(group.id)%4;
|
||||
newgroup.find(".icon-users-1").attr("style", "color:"+colors[colorId][0]+"; background-color:"+colors[colorId][1]);
|
||||
|
||||
setupGroupBox(newgroup);
|
||||
|
||||
//Place group in first Place
|
||||
newgroup.appendTo(".groups");
|
||||
newgroup.find(".groupMessage").html(str_group_created);
|
||||
newgroup.find(".groupMessage").fadeIn();
|
||||
newgroup.find(".groupMessage").delay(DELAY_FEEDBACK).fadeOut();
|
||||
}
|
||||
|
||||
/*-------
|
||||
SETUP JS ON GROUP BOX
|
||||
-------*/
|
||||
@@ -215,8 +219,15 @@ var setupGroupBox = function (groupBox) {
|
||||
/* Hide group options and rename field on click on the screen */
|
||||
|
||||
$(document).mouseup(function (e) {
|
||||
if ($(e.target).closest("#group-"+id+" #GroupOptions").length === 0) {
|
||||
groupBox.find(".group-dropdown-options #GroupOptions").hide();
|
||||
e.stopPropagation();
|
||||
let option_is_clicked = false
|
||||
$("#GroupOptions div").each(function () {
|
||||
if (!($(this).has(e.target).length === 0)) {
|
||||
option_is_clicked = true;
|
||||
}
|
||||
})
|
||||
if (!option_is_clicked) {
|
||||
groupBox.find("#GroupOptions").hide();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -229,6 +240,7 @@ var setupGroupBox = function (groupBox) {
|
||||
|
||||
groupBox.find(".manage-users").on("click", function(){openUserManager(id)});
|
||||
|
||||
groupBox.find("#GroupDuplicate").on("click", function(){duplicateAction(id)})
|
||||
|
||||
};
|
||||
|
||||
@@ -289,6 +301,7 @@ var deleteGroup = function (id) {
|
||||
if (data.stat === "ok") {
|
||||
$("#group-" + id).remove();
|
||||
$(".DeleteGroupList div[data-id="+id+"]").remove()
|
||||
$("#MergeOptionsChoices option[value="+ id +"]").remove()
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
@@ -393,6 +406,47 @@ var setupDefaultActions = function(id, is_default) {
|
||||
}
|
||||
}
|
||||
|
||||
var duplicateAction = function(id) {
|
||||
let loadState = new TemporaryState();
|
||||
loadState.changeHTML($("#group-" + id + " #GroupDuplicate"), "<i class='icon-spin6 animate-spin'> </i>")
|
||||
loadState.removeClass($("#group-" + id + " #GroupDuplicate"), "icon-docs");
|
||||
loadState.changeAttribute($("#group-" + id + " #GroupDuplicate"), "style", "pointer-events: none; text-align: center;")
|
||||
copy_name = $("#group-" + id + " #group_name").html() + str_copy;
|
||||
|
||||
let name_exist = function(name) {
|
||||
exist = false;
|
||||
$(".Group-name-container p").each(function () {
|
||||
if ($(this).html() === name)
|
||||
exist = true
|
||||
})
|
||||
return exist;
|
||||
}
|
||||
|
||||
let i = 1;
|
||||
while (name_exist(copy_name))
|
||||
{
|
||||
copy_name = $("#group-" + id + " #group_name").html() + str_other_copy.replace("%s", i++)
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.groups.duplicate",
|
||||
type: "POST",
|
||||
data: "group_id=" + id + "&pwg_token=" + pwg_token + "©_name=" + copy_name,
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
console.log(data);
|
||||
loadState.reverse();
|
||||
if (data.stat === "ok") {
|
||||
group = data.result.groups[0];
|
||||
createGroup(group);
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*-------
|
||||
Selection mode toggle actions,
|
||||
@@ -512,12 +566,18 @@ $('.ConfirmMergeButton').on("click", function() {
|
||||
loadState.removeClass($('.ConfirmMergeButton'), "icon-ok");
|
||||
merge_group = [];
|
||||
str_merge_group = "";
|
||||
name_merge = [];
|
||||
name_dest = [];
|
||||
dest_grp = $("#MergeOptionsChoices").val();
|
||||
|
||||
$(".DeleteGroupList div").each(function () {
|
||||
if (dest_grp != $(this).attr("data-id")) {
|
||||
if (dest_grp != $(this).attr("data-id"))
|
||||
{
|
||||
str_merge_group += "&merge_group_id[]="+$(this).attr("data-id");
|
||||
merge_group.push($(this).attr("data-id"));
|
||||
name_merge.push($(this).find("p").html())
|
||||
} else {
|
||||
name_dest = $(this).find("p").html();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -540,6 +600,23 @@ $('.ConfirmMergeButton').on("click", function() {
|
||||
$(".DeleteGroupList").html("");
|
||||
$("#MergeOptionsChoices").html("");
|
||||
|
||||
$.alert({
|
||||
title: str_merged_into
|
||||
.replace("%s1",name_merge.toString())
|
||||
.replace("%s2",name_dest),
|
||||
icon: 'icon-ok',
|
||||
titleClass: "groupDeleteAlert",
|
||||
theme:"modern",
|
||||
closeIcon: true,
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false,
|
||||
backgroundDismiss: true,
|
||||
animateFromElement: false,
|
||||
typeAnimated: false,
|
||||
});
|
||||
|
||||
$("#group-"+dest_grp + " .group_number_users").html("<i class='icon-spin6 animate-spin'> </i>");
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.users.getList",
|
||||
@@ -564,11 +641,11 @@ $('.ConfirmMergeButton').on("click", function() {
|
||||
|
||||
$('.ConfirmDeleteButton').on("click", function() {
|
||||
let names = [];
|
||||
let promises = [];
|
||||
let ids = [];
|
||||
$('.DeleteGroupList div').each(function () {
|
||||
let id = $(this).data('id');
|
||||
names.push($("#group-"+id+" #group_name").html());
|
||||
promises.push(deleteGroup(id));
|
||||
ids.push(id);
|
||||
});
|
||||
|
||||
let loadState = new TemporaryState;
|
||||
@@ -576,25 +653,47 @@ $('.ConfirmDeleteButton').on("click", function() {
|
||||
loadState.changeHTML($('.ConfirmDeleteButton'), "<i class='icon-spin6 animate-spin'> </i>");
|
||||
loadState.removeClass($('.ConfirmDeleteButton'),"icon-ok");
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
loadState.reverse();
|
||||
updateSelectionPanel("NoSelection");
|
||||
$.alert({
|
||||
title: str_groups_deleted.replace("%s",names.toString()),
|
||||
titleClass: "groupDeleteAlert",
|
||||
theme: "modern",
|
||||
icon: 'icon-ok',
|
||||
closeIcon: true,
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false,
|
||||
backgroundDismiss: true,
|
||||
animateFromElement: false,
|
||||
typeAnimated: false,
|
||||
backgroundDismiss: true,
|
||||
});
|
||||
str_id = ""
|
||||
ids.forEach(function(id) {
|
||||
str_id += "group_id[]=" + id + "&"
|
||||
})
|
||||
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.groups.delete",
|
||||
type: "POST",
|
||||
data: str_id + "pwg_token=" + pwg_token,
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
$(".DeleteGroupList div").each(function() {
|
||||
$(this).remove();
|
||||
$("#group-" + $(this).attr("data-id")).remove();
|
||||
$("#MergeOptionsChoices option[value="+ $(this).attr("data-id") +"]").remove()
|
||||
})
|
||||
|
||||
loadState.reverse();
|
||||
updateSelectionPanel("NoSelection");
|
||||
$.alert({
|
||||
title: str_groups_deleted.replace("%s",names.toString()),
|
||||
titleClass: "groupDeleteAlert",
|
||||
theme: "modern",
|
||||
icon: 'icon-ok',
|
||||
closeIcon: true,
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false,
|
||||
backgroundDismiss: true,
|
||||
animateFromElement: false,
|
||||
typeAnimated: false,
|
||||
backgroundDismiss: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/*-------
|
||||
@@ -671,6 +770,7 @@ var openUserManager = function(grp_id) {
|
||||
loadState.reverse();
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
//Set the popin name
|
||||
$(".group-name-block p").html(
|
||||
$("#group-" + grp_id + " #group_name").html() + " / " + str_user_list
|
||||
)
|
||||
@@ -684,12 +784,12 @@ var openUserManager = function(grp_id) {
|
||||
// Sort in alphabetic order
|
||||
usersInGroup.sort(function( a, b ) {
|
||||
if ( a.username.toLowerCase() < b.username.toLowerCase() ){
|
||||
return 1;
|
||||
} else return -1
|
||||
return -1;
|
||||
} else return 1
|
||||
});
|
||||
let i = 0;
|
||||
while ($(".UsersInGroupList").outerHeight() <= maxOffsetUserCont && usersInGroup[i] != undefined){
|
||||
getUserDisplay(usersInGroup[i].username, usersInGroup[i].id, grp_id).prependTo(".UsersInGroupList");
|
||||
getUserDisplay(usersInGroup[i].username, usersInGroup[i].id, grp_id).appendTo(".UsersInGroupList");
|
||||
i++;
|
||||
};
|
||||
while ($(".UsersInGroupList").height() > maxOffsetUserCont) {
|
||||
@@ -806,7 +906,6 @@ $(".AddUserBlock button").on("click", function () {
|
||||
associateUserInfo.insertAfter(userBlock);
|
||||
associateUserInfo.find("p").html(str_user_associated);
|
||||
associateUserInfo.fadeIn()
|
||||
associateUserInfo.delay(DELAY_FEEDBACK).fadeOut()
|
||||
|
||||
updateUserSearch();
|
||||
|
||||
@@ -846,7 +945,7 @@ $(".input-user-name").on("input", function() {
|
||||
let i = 0;
|
||||
while ($(".UsersInGroupList").outerHeight() <= maxOffsetUserCont && usersInGroup[i] != undefined){
|
||||
getUserDisplay(usersInGroup[i].username, usersInGroup[i].id, grp_id)
|
||||
.prependTo(".UsersInGroupList");
|
||||
.appendTo(".UsersInGroupList");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,11 @@ var str_delete = '{'Delete group "%s"?'|@translate}'
|
||||
var str_yes_delete_confirmation = "{'Yes, delete'|@translate}"
|
||||
var str_no_delete_confirmation = "{"No, I have changed my mind"|@translate}"
|
||||
var str_user_associated = "{"User associated"|@translate}"
|
||||
var str_user_dissociated = '{'User "%s" Dissociated from this group'|@translate}'
|
||||
var str_user_dissociated = '{'User "%s" dissociated from this group'|@translate}'
|
||||
var str_user_list = "{"User List"|@translate}"
|
||||
var str_merged_into = '{'Group(s) \{%s1\} succesfully merged into "%s2"'|@translate}'
|
||||
var str_copy = '{' (copy)'|@translate}'
|
||||
var str_other_copy = '{' (copy %s)'|@translate}'
|
||||
|
||||
var serverKey = '{$CACHE_KEYS.users}'
|
||||
var serverId = '{$CACHE_KEYS._hash}'
|
||||
|
||||
@@ -2050,6 +2050,10 @@ input:checked + .slider:before {
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.groupDeleteAlert {
|
||||
margin-bottom: -2px !important;
|
||||
}
|
||||
|
||||
.groupDeleteConfirm ~ .jconfirm-content-pane, .groupDeleteAlert ~ .jconfirm-content-pane {
|
||||
height: 0px !important;
|
||||
margin: 0px !important;
|
||||
@@ -2070,7 +2074,7 @@ input:checked + .slider:before {
|
||||
}
|
||||
|
||||
.groupDeleteAlert .jconfirm-icon-c {
|
||||
margin-bottom: 20px !important;
|
||||
margin-bottom: 25px !important;
|
||||
}
|
||||
|
||||
/*Group checkbox*/
|
||||
|
||||
@@ -316,6 +316,97 @@ SELECT user_id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Create a copy of a group
|
||||
* @param mixed[] $params
|
||||
* @option int group_id
|
||||
* @option string copy_name
|
||||
*/
|
||||
function ws_groups_duplicate($params, &$service) {
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
WHERE name = \''.$params['copy_name'].'\'
|
||||
;';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($count != 0)
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already used by another group.');
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id = '.$params["group_id"].'
|
||||
;';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($count == 0)
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'This group does not exist.');
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT is_default
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id = '.$params['group_id'].'
|
||||
;';
|
||||
|
||||
$is_default = pwg_db_fetch_row(pwg_query($query))[0];
|
||||
|
||||
// creating the group
|
||||
single_insert(
|
||||
GROUPS_TABLE,
|
||||
array(
|
||||
'name' => $params['copy_name'],
|
||||
'is_default' => boolean_to_string($is_default),
|
||||
)
|
||||
);
|
||||
$inserted_id = pwg_db_insert_id();
|
||||
|
||||
pwg_activity('group', $inserted_id, 'add');
|
||||
|
||||
$query = '
|
||||
SELECT user_id
|
||||
FROM `'. USER_GROUP_TABLE .'`
|
||||
WHERE group_id = '.$params['group_id'].'
|
||||
;';
|
||||
|
||||
$users = query2array($query, null, 'user_id');
|
||||
|
||||
$inserts = array();
|
||||
foreach ($users as $user)
|
||||
{
|
||||
$inserts[] = array(
|
||||
'group_id' => $inserted_id,
|
||||
'user_id' => $user,
|
||||
);
|
||||
}
|
||||
|
||||
mass_inserts(
|
||||
USER_GROUP_TABLE,
|
||||
array('group_id', 'user_id'),
|
||||
$inserts,
|
||||
array('ignore'=>true)
|
||||
);
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
invalidate_user_cache();
|
||||
|
||||
foreach ($users as $user_id)
|
||||
{
|
||||
pwg_activity('user', $user_id, 'edit', array("associated" => $params['group_id']));
|
||||
}
|
||||
|
||||
return $service->invoke('pwg.groups.getList', array('group_id' => $inserted_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Removes user(s) from a group
|
||||
|
||||
@@ -915,7 +915,7 @@ function ws_addDefaultMethods( $arr )
|
||||
'ws_groups_merge',
|
||||
array(
|
||||
'destination_group_id' => array('type'=>WS_TYPE_ID,
|
||||
'info'=>'Destination group (is not necessarily part of groups to merge)'),
|
||||
'info'=>'Is not necessarily part of groups to merge'),
|
||||
'merge_group_id' => array('flags'=>WS_PARAM_FORCE_ARRAY,
|
||||
'type'=>WS_TYPE_ID),
|
||||
'pwg_token' => array(),
|
||||
@@ -925,6 +925,19 @@ function ws_addDefaultMethods( $arr )
|
||||
array('admin_only'=>true, 'post_only'=>true)
|
||||
);
|
||||
|
||||
$service->addMethod(
|
||||
'pwg.groups.duplicate',
|
||||
'ws_groups_duplicate',
|
||||
array(
|
||||
'group_id' => array('type'=>WS_TYPE_ID),
|
||||
'copy_name' => array(),
|
||||
'pwg_token' => array(),
|
||||
),
|
||||
'Create a copy of a group',
|
||||
$ws_functions_root . 'pwg.groups.php',
|
||||
array('admin_only'=>true, 'post_only'=>true)
|
||||
);
|
||||
|
||||
$service->addMethod(
|
||||
'pwg.users.getList',
|
||||
'ws_users_getList',
|
||||
|
||||
Reference in New Issue
Block a user