1
0
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:
Thomas Tanghus 2013-05-21 23:39:50 +02:00
parent 9b6a2fde01
commit e8c7047869
7 changed files with 232 additions and 120 deletions

View File

@ -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(

View File

@ -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);

View File

@ -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)];

View File

@ -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})
});
});
};

View File

@ -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
*

View File

@ -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

View File

@ -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}">