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:
Zacharie
2020-05-15 12:37:01 +02:00
committed by plegall
parent c4b38d1a41
commit 9a293dc1c5
5 changed files with 267 additions and 57 deletions
+153 -54
View File
@@ -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 + "&copy_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++;
}
}
+4 -1
View File
@@ -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}'
+5 -1
View File
@@ -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*/
+91
View File
@@ -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
+14 -1
View File
@@ -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',