mirror of
https://github.com/owncloudarchive/contacts.git
synced 2025-01-18 07:52:21 +01:00
Implement rename group. Refs #97
This commit is contained in:
parent
9b6a2fde01
commit
e8c7047869
@ -215,6 +215,15 @@ $this->create('contacts_categories_delete', 'groups/delete')
|
||||
}
|
||||
);
|
||||
|
||||
$this->create('contacts_categories_rename', 'groups/rename')
|
||||
->post()
|
||||
->action(
|
||||
function($params) {
|
||||
session_write_close();
|
||||
Main::main('GroupController', 'renameGroup', $params, new DIContainer());
|
||||
}
|
||||
);
|
||||
|
||||
$this->create('contacts_categories_addto', 'groups/addto/{categoryid}')
|
||||
->post()
|
||||
->action(
|
||||
|
12
js/app.js
12
js/app.js
@ -577,6 +577,18 @@ OC.Contacts = OC.Contacts || {
|
||||
});
|
||||
});
|
||||
|
||||
$(document).bind('status.group.grouprenamed', function(e, result) {
|
||||
console.log('status.group.grouprenamed', result);
|
||||
$.each(result.contacts, function(idx, contactid) {
|
||||
var contact = self.contacts.findById(contactid);
|
||||
if(!contact) {
|
||||
console.log('Couldn\'t find contact', contactid)
|
||||
return true; // continue
|
||||
}
|
||||
contact.renameGroup(result.from, result.to);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).bind('status.group.contactadded', function(e, result) {
|
||||
console.log('status.group.contactadded', result);
|
||||
var contact = self.contacts.findById(result.contactid);
|
||||
|
@ -165,6 +165,29 @@ OC.Contacts = OC.Contacts || {};
|
||||
}*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Update group name internally. No saving as this is done by groups backend.
|
||||
*/
|
||||
Contact.prototype.renameGroup = function(from, to) {
|
||||
if(!this.data.CATEGORIES.length) {
|
||||
console.warn(this.getDisplayName(), 'had no groups!?!');
|
||||
return;
|
||||
}
|
||||
var groups = this.data.CATEGORIES[0].value;
|
||||
var self = this;
|
||||
$.each(groups, function(idx, group) {
|
||||
if(from.toLowerCase() === group.toLowerCase()) {
|
||||
console.log('Updating group name for', self.getDisplayName(), group, to);
|
||||
self.data.CATEGORIES[0].value[idx] = to;
|
||||
return false; // break
|
||||
}
|
||||
});
|
||||
$(document).trigger('status.contact.updated', {
|
||||
property: 'CATEGORIES',
|
||||
contact: this
|
||||
});
|
||||
};
|
||||
|
||||
Contact.prototype.pushToUndo = function(params) {
|
||||
// Check if the same property has been changed before
|
||||
// and update it's checksum if so.
|
||||
@ -1926,7 +1949,7 @@ OC.Contacts = OC.Contacts || {};
|
||||
id = String(id);
|
||||
if(typeof this.contacts[id] === 'undefined') {
|
||||
console.warn('Could not find contact with id', id);
|
||||
console.trace();
|
||||
//console.trace();
|
||||
return null;
|
||||
}
|
||||
return this.contacts[String(id)];
|
||||
|
219
js/groups.js
219
js/groups.js
@ -21,34 +21,36 @@ OC.Contacts = OC.Contacts || {};
|
||||
this.$groupList = groupList;
|
||||
var self = this;
|
||||
var numtypes = ['category', 'fav', 'all'];
|
||||
this.$groupList.on('click', 'li', function(event) {
|
||||
this.$groupList.on('click', 'li.group', function(event) {
|
||||
$('.tipsy').remove();
|
||||
if(wrongKey(event)) {
|
||||
return;
|
||||
}
|
||||
console.log($(event.target));
|
||||
console.log('group click', $(this));
|
||||
if($(event.target).is('.action.delete')) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
var id = $(event.target).parents('li').first().data('id');
|
||||
self.deleteGroup(id, function(response) {
|
||||
if(response.error) {
|
||||
OC.notify({message:response.data.message});
|
||||
}
|
||||
});
|
||||
} else if($(event.target).is('.add-group')) {
|
||||
//self.editGroup();
|
||||
} else if($(event.target).is('.add-contact')) {
|
||||
$.noop(); // handled elsewhere in app.js
|
||||
} else if($(event.target).is('.action.edit')) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
self.editGroup($(this));
|
||||
} else {
|
||||
self.selectGroup({element:$(this)});
|
||||
if($(this).is(':not(.editing)')) {
|
||||
self.selectGroup({element:$(this)});
|
||||
}
|
||||
}
|
||||
});
|
||||
var $addInput = this.$groupList.find('.add-group');
|
||||
$addInput.addnew({
|
||||
ok: function(event, name) {
|
||||
console.log('add-address-book ok', name);
|
||||
$addInput.addClass('loading');
|
||||
self.addGroup({name:name}, function(response) {
|
||||
console.log('response', response);
|
||||
if(response.error) {
|
||||
$(document).trigger('status.contact.error', {
|
||||
message: response.message
|
||||
@ -117,6 +119,16 @@ OC.Contacts = OC.Contacts || {};
|
||||
this.selectGroup({id:this.lastgroup});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a group with this name exists (case-insensitive)
|
||||
*
|
||||
* @param string name
|
||||
* @return bool
|
||||
*/
|
||||
GroupList.prototype.hasGroup = function(name) {
|
||||
return (this.findByName(name) !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group name by id.
|
||||
*
|
||||
@ -131,6 +143,22 @@ OC.Contacts = OC.Contacts || {};
|
||||
//return $.trim(this.findById(id).clone().find("*").remove().end().text()); //.contents().filter(function(){ return(this.nodeType == 3); }).text().trim();
|
||||
};
|
||||
|
||||
/** Get the group element by name.
|
||||
*
|
||||
* @param string name. The name of the group to search for (case-insensitive).
|
||||
* @returns object|null The jQuery object.
|
||||
*/
|
||||
GroupList.prototype.findByName = function(name) {
|
||||
var $elem = null;
|
||||
self.$groupList.find('li[data-type="category"]').each(function() {
|
||||
if ($(this).data('rawname').toLowerCase() === name.toLowerCase()) {
|
||||
$elem = $(this);
|
||||
return false; //break out of loop
|
||||
}
|
||||
});
|
||||
return $elem;
|
||||
};
|
||||
|
||||
/** Get the group element by id.
|
||||
*
|
||||
* @param integer id. The numeric group or addressbook id.
|
||||
@ -460,94 +488,78 @@ OC.Contacts = OC.Contacts || {};
|
||||
|
||||
/**
|
||||
* Edit a groups name.
|
||||
* Currently only used for adding, as renaming a group also
|
||||
* requires updating all contacts in that group.
|
||||
*
|
||||
* @param integer id. Group id NOTE: Not used yet.
|
||||
* FIXME: This works fine for adding, but will need refactoring
|
||||
* if used for renaming.
|
||||
* @param object $element jQuery element
|
||||
*/
|
||||
/*GroupList.prototype.editGroup = function(id) {
|
||||
GroupList.prototype.editGroup = function($element) {
|
||||
console.log('editGroup', $element);
|
||||
var self = this;
|
||||
if(this.$editelem) {
|
||||
console.log('Already editing, returning');
|
||||
return;
|
||||
}
|
||||
// NOTE: Currently this only works for adding, not renaming
|
||||
var saveChanges = function($elem, $input) {
|
||||
console.log('saveChanges', $input.val());
|
||||
var name = $.trim($input.val());
|
||||
if(name.length === 0) {
|
||||
return false;
|
||||
var oldname = $element.data('rawname');
|
||||
var id = $element.data('id');
|
||||
|
||||
var $editInput = $('<input type="text" />').val(oldname);
|
||||
$element.hide();
|
||||
$editInput.insertBefore($element).wrap('<li class="group editing" />');
|
||||
var $tmpelem = $editInput.parent('li');
|
||||
console.log('tmpelem', $tmpelem);
|
||||
|
||||
$editInput.addnew({
|
||||
autoOpen: true,
|
||||
addText: t('contacts', 'Save'),
|
||||
ok: function(event, newname) {
|
||||
console.log('New name', newname);
|
||||
$editInput.addClass('loading');
|
||||
self.renameGroup(oldname, newname, function(response) {
|
||||
if(response.error) {
|
||||
$(document).trigger('status.contact.error', {
|
||||
message: response.message
|
||||
});
|
||||
} else {
|
||||
$editInput.addnew('close');
|
||||
$(document).trigger('status.group.grouprenamed', {
|
||||
groupid: id,
|
||||
from: oldname,
|
||||
to: newname,
|
||||
contacts: $element.data('contacts')
|
||||
});
|
||||
$element.data('rawname', newname);
|
||||
$element.find('.name').text(escapeHTML(newname));
|
||||
}
|
||||
$editInput.removeClass('loading');
|
||||
});
|
||||
},
|
||||
cancel: function(event) {
|
||||
console.log('cancel');
|
||||
$editInput.removeClass('loading');
|
||||
},
|
||||
close: function() {
|
||||
console.log('close');
|
||||
$tmpelem.remove();
|
||||
$element.show();
|
||||
}
|
||||
$input.prop('disabled', true);
|
||||
$elem.data('rawname', '');
|
||||
self.addGroup({name:name}, function(response) {
|
||||
if(!response.error) {
|
||||
$elem.remove();
|
||||
self.$editelem = null;
|
||||
} else {
|
||||
$input.prop('disabled', false);
|
||||
OC.notify({message:response.message});
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
if(typeof id === 'undefined') {
|
||||
// Add new group
|
||||
var tmpl = this.$groupListItemTemplate;
|
||||
self.$editelem = (tmpl).octemplate({
|
||||
id: 'new',
|
||||
type: 'category',
|
||||
num: 0,
|
||||
name: ''
|
||||
});
|
||||
var $input = $('<input type="text" class="active" /><a class="action checked disabled" />');
|
||||
self.$editelem.prepend($input).addClass('editing');
|
||||
self.$editelem.data('contacts', []);
|
||||
self.$editelem.data('rawname', '');
|
||||
this.$groupList.find('li.group[data-type="category"]').first().before(self.$editelem);
|
||||
this.selectGroup({element:self.$editelem});
|
||||
$input.on('input', function(event) {
|
||||
if($(this).val().length > 0) {
|
||||
$(this).next('.checked').removeClass('disabled');
|
||||
} else {
|
||||
$(this).next('.checked').addClass('disabled');
|
||||
}
|
||||
});
|
||||
$input.on('keyup', function(event) {
|
||||
var keyCode = Math.max(event.keyCode, event.which);
|
||||
if(keyCode === 13) {
|
||||
saveChanges(self.$editelem, $(this));
|
||||
} else if(keyCode === 27) {
|
||||
self.$editelem.remove();
|
||||
self.$editelem = null;
|
||||
}
|
||||
});
|
||||
$input.next('.checked').on('click keydown', function(event) {
|
||||
console.log('clicked', event);
|
||||
if(wrongKey(event)) {
|
||||
return;
|
||||
}
|
||||
saveChanges(self.$editelem, $input);
|
||||
});
|
||||
$input.focus();
|
||||
} else if(utils.isUInt(id)) {
|
||||
alert('Renaming groups is not implemented!');
|
||||
return;
|
||||
var $elem = this.findById(id);
|
||||
var $text = $elem.contents().filter(function(){ return(this.nodeType == 3); });
|
||||
var name = $text.text();
|
||||
console.log('Group name', $text, name);
|
||||
$text.remove();
|
||||
var $input = $('<input type="text" class="active" value="' + name + '" /><a class="action checked disabled />');
|
||||
$elem.prepend($input).addClass('editing');
|
||||
$input.focus();
|
||||
};
|
||||
|
||||
} else {
|
||||
throw { name: 'WrongParameterType', message: 'GroupList.editGroup only accept integers.'};
|
||||
}
|
||||
};*/
|
||||
/**
|
||||
* Rename a group.
|
||||
*
|
||||
* @param string from
|
||||
* @param string to
|
||||
* @param function cb
|
||||
*/
|
||||
GroupList.prototype.renameGroup = function(from, to, cb) {
|
||||
$.when(this.storage.renameGroup(from, to)).then(function(response) {
|
||||
cb({error:false});
|
||||
})
|
||||
.fail(function(response) {
|
||||
console.log( "Request Failed: " + response);
|
||||
cb({error:true});
|
||||
$(document).trigger('status.contact.error', {
|
||||
message: t('contacts', 'Failed renaming group: {error}', {error:response.message})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a new group.
|
||||
@ -572,14 +584,8 @@ OC.Contacts = OC.Contacts || {};
|
||||
//console.log('GroupList.addGroup', params);
|
||||
var name = params.name;
|
||||
var contacts = []; // $.map(contacts, function(c) {return parseInt(c)});
|
||||
var self = this, exists = false;
|
||||
self.$groupList.find('li[data-type="category"]').each(function() {
|
||||
if ($(this).data('rawname').toLowerCase() === name.toLowerCase()) {
|
||||
exists = true;
|
||||
return false; //break out of loop
|
||||
}
|
||||
});
|
||||
if(exists) {
|
||||
var self = this;
|
||||
if(this.hasGroup(name)) {
|
||||
if(typeof cb === 'function') {
|
||||
cb({error:true, message:t('contacts', 'A group named {group} already exists', {group: escapeHTML(name)})});
|
||||
}
|
||||
@ -627,11 +633,10 @@ OC.Contacts = OC.Contacts || {};
|
||||
}
|
||||
}
|
||||
})
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
var err = textStatus + ', ' + error;
|
||||
console.log( "Request Failed: " + err);
|
||||
.fail(function(response) {
|
||||
console.log( "Request Failed: " + response);
|
||||
$(document).trigger('status.contact.error', {
|
||||
message: t('contacts', 'Failed adding group: {error}', {error:err})
|
||||
message: t('contacts', 'Failed adding group: {error}', {error:response.message})
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -761,9 +766,11 @@ OC.Contacts = OC.Contacts || {};
|
||||
cb();
|
||||
}
|
||||
})
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
var err = textStatus + ', ' + error;
|
||||
console.log( "Request Failed: " + err);
|
||||
.fail(function(response) {
|
||||
console.log( "Request Failed: " + response);
|
||||
$(document).trigger('status.contact.error', {
|
||||
message: t('contacts', 'Failed loading groups: {error}', {error:response.message})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -11,9 +11,10 @@ OC.Contacts = OC.Contacts || {};
|
||||
this.getAllResponseHeaders = jqXHR.getAllResponseHeaders;
|
||||
this.getResponseHeader = jqXHR.getResponseHeader;
|
||||
this.status = jqXHR.status;
|
||||
if(!response || !response.status || response.status === 'error') {
|
||||
if(!response) {
|
||||
console.log('jqXHR', jqXHR);
|
||||
this.error = true;
|
||||
this.message = response.data.message || 'Unknown error.';
|
||||
this.message = jqXHR.statusText;
|
||||
} else {
|
||||
this.error = false;
|
||||
if(response.data) {
|
||||
@ -392,6 +393,21 @@ OC.Contacts = OC.Contacts || {};
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a group
|
||||
*
|
||||
* @param string from
|
||||
* @param string to
|
||||
*/
|
||||
Storage.prototype.renameGroup = function(from, to) {
|
||||
return this.requestRoute(
|
||||
'contacts_categories_rename',
|
||||
'POST',
|
||||
{},
|
||||
{from: from, to: to}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add contacts to a group
|
||||
*
|
||||
|
@ -80,8 +80,9 @@ class GroupController extends BaseController {
|
||||
$name = $this->request->post['name'];
|
||||
|
||||
$response = new JSONResponse();
|
||||
if(is_null($name) || $name === "") {
|
||||
if(is_null($name) || $name === '') {
|
||||
$response->bailOut(App::$l10n->t('No group name given.'));
|
||||
return $response;
|
||||
}
|
||||
|
||||
$catman = new \OC_VCategories('contact', $this->api->getUserId());
|
||||
@ -89,6 +90,49 @@ class GroupController extends BaseController {
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @Ajax
|
||||
*/
|
||||
public function renameGroup() {
|
||||
$from = $this->request->post['from'];
|
||||
$to = $this->request->post['to'];
|
||||
|
||||
$response = new JSONResponse();
|
||||
if(is_null($from) || $from === '') {
|
||||
$response->bailOut(App::$l10n->t('No group name to rename from given.'));
|
||||
return $response;
|
||||
}
|
||||
if(is_null($to) || $to === '') {
|
||||
$response->bailOut(App::$l10n->t('No group name to rename to given.'));
|
||||
return $response;
|
||||
}
|
||||
|
||||
$catman = new \OC_VCategories('contact', $this->api->getUserId());
|
||||
if(!$catman->rename($from, $to)) {
|
||||
$response->bailOut(App::$l10n->t('Error renaming group.'));
|
||||
return $response;
|
||||
}
|
||||
$ids = $catman->idsForCategory($to);
|
||||
$app = new App($this->api->getUserId());
|
||||
$backend = $app->getBackend('local');
|
||||
foreach($ids as $id) {
|
||||
$contact = $backend->getContact(null, $id, true);
|
||||
$obj = \Sabre\VObject\Reader::read(
|
||||
$contact['carddata'],
|
||||
\Sabre\VObject\Reader::OPTION_IGNORE_INVALID_LINES
|
||||
);
|
||||
if($obj) {
|
||||
if(!isset($obj->CATEGORIES)) {
|
||||
continue;
|
||||
}
|
||||
$obj->CATEGORIES->renameGroup($from, $to);
|
||||
$backend->updateContact(null, $id, $obj, true);
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
|
@ -137,6 +137,17 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="groupListItemTemplate" type="text/template">
|
||||
<li class="group" data-type="{type}" data-id="{id}">
|
||||
<a class="name" role="button">{name}</a>
|
||||
<span class="utils">
|
||||
<a class="action delete tooltipped rightwards" title="<?php p($l->t('Delete group')); ?>"></a>
|
||||
<a class="action edit tooltipped rightwards" title="<?php p($l->t('Rename group')); ?>"></a>
|
||||
<span class="action numcontacts">{num}</span>
|
||||
</span>
|
||||
</li>
|
||||
</script>
|
||||
|
||||
<script id="mergeContactsTemplate" type="text/template">
|
||||
<div id="dialog-merge-contacts" title="<?php p($l->t('Merge contacts')); ?>">
|
||||
<p><?php p($l->t('Which contact should the data be merged into?')); ?></p>
|
||||
@ -173,16 +184,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="groupListItemTemplate" type="text/template">
|
||||
<li class="group" data-type="{type}" data-id="{id}">
|
||||
<a role="button">{name}</a>
|
||||
<span class="utils">
|
||||
<a class="action delete tooltipped rightwards" title="<?php p($l->t('Delete group')); ?>"></a>
|
||||
<span class="action numcontacts">{num}</span>
|
||||
</span>
|
||||
</li>
|
||||
</script>
|
||||
|
||||
<script id="contactFullTemplate" type="text/template">
|
||||
<form action="<?php print_unescaped(OCP\Util::linkTo('contacts', 'index.php')); ?>" method="post" enctype="multipart/form-data">
|
||||
<section id="contact" data-id="{id}">
|
||||
|
Loading…
x
Reference in New Issue
Block a user