Fix handling of contact organizations

Fixes #4028
pull/234/head
Francis Lachapelle 2017-03-03 10:35:23 -05:00
parent 79a0d5e133
commit 25430a8128
8 changed files with 121 additions and 103 deletions

1
NEWS
View File

@ -16,6 +16,7 @@ Bug fixes
- [web] SOGoCalendarWeekdays must now be defined before saving preferences
- [web] fixed CAS session timeout handling during XHR requests (#1456)
- [web] exposed default value of SOGoMailAutoSave (#4053)
- [web] fixed handling of contact organizations (#4028)
3.2.7 (2017-02-14)
------------------

View File

@ -1,6 +1,6 @@
/* NGVCard+SOGo.h - this file is part of SOGo
*
* Copyright (C) 2009-2016 Inverse inc.
* Copyright (C) 2009-2017 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -43,6 +43,9 @@
- (NSArray *) emails;
- (NSArray *) secondaryEmails;
- (void) setOrganizations: (NSArray *) newOrganizations;
- (NSArray *) organizations;
- (NSString *) workPhone;
- (NSString *) homePhone;
- (NSString *) fax;

View File

@ -261,9 +261,9 @@ convention:
NSInteger year, yearOfToday, month, day;
CardElement *element;
NSCalendarDate *now;
NSArray *units;
NSString *fn, *ou;
id o;
NSMutableArray *units;
NSString *fn;
id o, ou;
[self setNWithFamily: [ldifRecord objectForKey: @"sn"]
given: [ldifRecord objectForKey: @"givenname"]
@ -306,13 +306,17 @@ convention:
ou = [ldifRecord objectForKey: @"ou"];
if ([ou isKindOfClass: [NSArray class]])
units = [NSArray arrayWithArray: (NSArray *)ou];
units = [NSMutableArray arrayWithArray: (NSArray *)ou];
else if (ou)
units = [NSArray arrayWithObject: ou];
units = [NSMutableArray arrayWithObject: ou];
else
units = nil;
[self setOrg: [ldifRecord objectForKey: @"o"]
units: units];
units = [NSMutableArray array];
o = [ldifRecord objectForKey: @"o"];
if ([o isKindOfClass: [NSArray class]])
[units addObjectsFromArray: (NSArray *)o];
else if (ou)
[units addObject: o];
[self setOrganizations: units];
[self _setPhoneValues: ldifRecord];
[self _setEmails: ldifRecord];
@ -712,6 +716,53 @@ convention:
return company;
}
- (void) setOrganizations: (NSArray *) newOrganizations
{
CardElement *org;
NSArray *elements;
NSUInteger count, max;
// First remove all current org properties
elements = [self childrenWithTag: @"org"];
[self removeChildren: elements];
org = [self uniqueChildWithTag: @"org"];
max = [newOrganizations count];
for (count = 0; count < max; count++)
{
[org setSingleValue: [newOrganizations objectAtIndex: count]
atIndex: count forKey: @""];
}
}
- (NSArray *) organizations
{
CardElement *org;
NSArray *organizations;
NSEnumerator *orgs;
NSMutableArray *flattenedOrganizations;
NSString *value;
NSUInteger count, max;
// Get all org properties
orgs = [[self childrenWithTag: @"org"] objectEnumerator];
flattenedOrganizations = [NSMutableArray array];
while ((org = [orgs nextObject]))
{
// Get all values of each org property
organizations = [org valuesForKey: @""];
max = [organizations count];
for (count = 0; count < max; count++)
{
value = [[organizations objectAtIndex: count] lastObject];
if ([value length])
[flattenedOrganizations addObject: value];
}
}
return flattenedOrganizations;
}
- (NSString *) fullName
{
CardElement *n;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2005-2015 Inverse inc.
Copyright (C) 2005-2017 Inverse inc.
This file is part of SOGo
@ -339,7 +339,7 @@ static Class SOGoContactGCSEntryK = Nil;
{
CardElement *element;
NSArray *elements, *values;
NSMutableArray *units, *categories;
NSMutableArray *orgs, *categories;
NSCalendarDate *date;
id o;
unsigned int i, year, month, day;
@ -398,27 +398,13 @@ static Class SOGoContactGCSEntryK = Nil;
}
}
if ([[attributes objectForKey: @"orgUnits"] isKindOfClass: [NSArray class]])
{
elements = [card childrenWithTag: @"org"];
[card removeChildren: elements];
values = [attributes objectForKey: @"orgUnits"];
units = [NSMutableArray arrayWithCapacity: [values count]];
for (i = 0; i < [values count]; i++)
{
o = [values objectAtIndex: i];
if ([o isKindOfClass: [NSDictionary class]])
{
[units addObject: [o objectForKey: @"value"]];
}
}
}
if ([[attributes objectForKey: @"orgs"] isKindOfClass: [NSArray class]])
orgs = [NSMutableArray arrayWithArray: [attributes objectForKey: @"orgs"]];
else
{
units = nil;
}
[card setOrg: [attributes objectForKey: @"c_org"]
units: units];
orgs = [NSMutableArray array];
if ([[attributes objectForKey: @"org"] length])
[orgs insertObject: [attributes objectForKey: @"org"] atIndex: 0];
[card setOrganizations: orgs];
elements = [card childrenWithTag: @"tel"];
[card removeChildren: elements];
@ -520,7 +506,9 @@ static Class SOGoContactGCSEntryK = Nil;
* @apiParam {String} c_cn Fullname
* @apiParam {String} c_screenname Screen Name (X-AIM for now)
* @apiParam {String} tz Timezone
* @apiParam {String} note Note
* @apiParam {String} org Main organization
* @apiParam {String[]} orgs Additional organizations
* @apiParam {String[]} notes Notes
* @apiParam {String[]} allCategories All available categories
* @apiParam {Object[]} categories Categories assigned to the card
* @apiParam {String} categories.value Category name

View File

@ -1,18 +1,18 @@
/*
Copyright (C) 2005-2016 Inverse inc.
Copyright (C) 2005-2017 Inverse inc.
This file is part of SOGo.
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
@ -69,7 +69,7 @@
categoryLabels = [[self labelForKey: @"contacts_category_labels"] componentsSeparatedByString: @","];
if (!categoryLabels)
categoryLabels = [NSArray array];
return [categoryLabels trimmedComponents];
}
@ -101,33 +101,6 @@
return cats;
}
- (NSArray *) orgUnits
{
NSMutableArray *orgUnits;
NSArray *values;
CardElement *org;
NSString *service;
NSUInteger count, max;
org = [card org];
values = [org valuesForKey: @""];
max = [values count];
if (max > 1)
{
orgUnits = [NSMutableArray arrayWithCapacity: max];
for (count = 1; count < max; count++)
{
service = [org flattenedValueAtIndex: count forKey: @""];
if ([service length] > 0)
[orgUnits addObject: [NSDictionary dictionaryWithObject: service forKey: @"value"]];
}
}
else
orgUnits = nil;
return orgUnits;
}
- (NSArray *) categories
{
NSMutableArray *categories;
@ -267,9 +240,13 @@
* @apiSuccess (Success 200) {String} [nickname] Nickname
* @apiSuccess (Success 200) {String} [c_sn] Lastname
* @apiSuccess (Success 200) {String} [c_fn] Fullname
* @apiSuccess (Success 200) {String} [title] Title
* @apiSuccess (Success 200) {String} [role] Role
* @apiSuccess (Success 200) {String} [c_screenname] Screen Name (X-AIM for now)
* @apiSuccess (Success 200) {String} [tz] Timezone
* @apiSuccess (Success 200) {String} [notes] Notes
* @apiSuccess (Success 200) {String} [org] Main organization
* @apiSuccess (Success 200) {String[]} [orgs] Additional organizations
* @apiSuccess (Success 200) {String[]} [notes] Notes
* @apiSuccess (Success 200) {String[]} allCategories All available categories
* @apiSuccess (Success 200) {Object[]} [categories] Categories assigned to the card
* @apiSuccess (Success 200) {String} categories.value Category name
@ -297,6 +274,7 @@
id <WOActionResults> result;
id o;
SOGoObject <SOGoContactObject> *contact;
NSArray *values;
NSMutableDictionary *data;
contact = [self clientObject];
@ -341,12 +319,13 @@
o = [card role];
if ([o length] > 0)
[data setObject: o forKey: @"role"];
o = [self orgUnits];
if ([o count] > 0)
[data setObject: o forKey: @"orgUnits"];
o = [card workCompany];
if ([o length] > 0)
[data setObject: o forKey: @"c_org"];
values = [card organizations];
if ([values count])
{
[data setObject: [values objectAtIndex: 0] forKey: @"org"];
if ([values count] > 1)
[data setObject: [values subarrayWithRange: NSMakeRange(1, [values count] - 1)] forKey: @"orgs"];
}
o = [card birthday];
if (o)
@ -376,7 +355,7 @@
result = [self responseWithStatus: 200
andString: [data jsonRepresentation]];
return result;
}

View File

@ -78,7 +78,7 @@
<label>
<var:string label:value="Organization"/>
</label>
<input type="text" ng-model="editor.card.c_org"/>
<input type="text" ng-model="editor.card.org"/>
</md-input-container>
<md-input-container flex="40" flex-xs="100">
<label>
@ -94,23 +94,23 @@
</md-input-container>
</div>
<!-- org units -->
<div class="attr" ng-repeat="unit in editor.card.orgUnits">
<!-- other orgs -->
<div class="attr" ng-repeat="org in editor.card.orgs">
<div layout="row" layout-align="start center">
<md-button class="md-icon-button" type="button" ng-click="editor.card.$delete('orgUnits', $index)">
<md-button class="md-icon-button" type="button" ng-click="editor.card.$delete('orgs', $index)">
<md-icon>remove_circle</md-icon>
</md-button>
<md-input-container class="md-flex">
<label>
<var:string label:value="Organization Unit"/>
</label>
<input type="text" ng-model="unit.value"
sg-focus-on="orgUnit_{{$index}}"/>
<input type="text" ng-model="org.value"
sg-focus-on="org_{{$index}}"/>
</md-input-container>
</div>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center">
<md-button class="md-icon-button" type="button" ng-click="editor.addOrgUnit($event)">
<md-button class="md-icon-button" type="button" ng-click="editor.addOrg($event)">
<md-icon>add_circle</md-icon>
</md-button>
<label class="button-label">

View File

@ -157,6 +157,8 @@
if (this.isgroup)
this.c_component = 'vlist';
this.$avatarIcon = this.$isList()? 'group' : 'person';
if (data.orgs && data.orgs.length)
this.orgs = _.map(data.orgs, function(org) { return { 'value': org }; });
if (data.notes && data.notes.length)
this.notes = _.map(data.notes, function(note) { return { 'value': note }; });
else if (!this.notes || !this.notes.length)
@ -300,8 +302,8 @@
names.push(this.c_sn);
if (names.length > 0)
fn = names.join(' ');
else if (this.c_org && this.c_org.length > 0) {
fn = this.c_org;
else if (this.org && this.org.length > 0) {
fn = this.org;
}
else if (this.emails && this.emails.length > 0) {
email = _.find(this.emails, function(i) { return i.value !== ''; });
@ -317,12 +319,8 @@
var description = [];
if (this.title) description.push(this.title);
if (this.role) description.push(this.role);
if (this.orgUnits && this.orgUnits.length > 0)
_.forEach(this.orgUnits, function(unit) {
if (unit.value !== '')
description.push(unit.value);
});
if (this.c_org) description.push(this.c_org);
if (this.org) description.push(this.org);
if (this.orgs) description = _.concat(description, _.map(this.orgs, 'value'));
if (this.description) description.push(this.description);
return description.join(', ');
@ -391,20 +389,14 @@
return this.c_component == 'vlist' && condition;
};
Card.prototype.$addOrgUnit = function(orgUnit) {
if (angular.isUndefined(this.orgUnits)) {
this.orgUnits = [{value: orgUnit}];
Card.prototype.$addOrg = function(org) {
if (angular.isUndefined(this.orgs)) {
this.orgs = [org];
}
else {
for (var i = 0; i < this.orgUnits.length; i++) {
if (this.orgUnits[i].value == orgUnit) {
break;
}
}
if (i == this.orgUnits.length)
this.orgUnits.push({value: orgUnit});
else if (org != this.org && !_.includes(this.orgs, org)) {
this.orgs.push(org);
}
return this.orgUnits.length - 1;
return this.orgs.length - 1;
};
// Card.prototype.$addCategory = function(category) {
@ -615,6 +607,10 @@
card.birthday = '';
}
// We flatten the organizations to an array of strings
if (this.orgs)
card.orgs = _.map(this.orgs, 'value');
// We flatten the notes to an array of strings
if (this.notes)
card.notes = _.map(this.notes, 'value');

View File

@ -21,7 +21,7 @@
vm.categories = {};
vm.userFilterResults = [];
vm.transformCategory = transformCategory;
vm.addOrgUnit = addOrgUnit;
vm.addOrg = addOrg;
vm.addBirthday = addBirthday;
vm.addScreenName = addScreenName;
vm.addEmail = addEmail;
@ -71,9 +71,9 @@
else
return input;
}
function addOrgUnit() {
var i = vm.card.$addOrgUnit('');
focus('orgUnit_' + i);
function addOrg() {
var i = vm.card.$addOrg({ value: '' });
focus('org_' + i);
}
function addBirthday() {
vm.card.birthday = new Date();