(feat) added custom fields support from Thunderbird's address book

This commit is contained in:
Ludovic Marcotte
2017-05-30 09:12:13 -04:00
parent 43141a48cf
commit 2b90ff70fa
6 changed files with 134 additions and 5 deletions

1
NEWS
View File

@@ -9,6 +9,7 @@ Enhancements
- [web] AngularJS optimizations in Mail module
- [web] AngularJS optimization of color picker
- [web] improve display of tasks status
- [web] added custom fields support from Thunderbird's address book
Bug fixes
- [web] respect SOGoLanguage and SOGoSupportedLanguages (#4169)

View File

@@ -337,11 +337,13 @@ static Class SOGoContactGCSEntryK = Nil;
- (void) setAttributes: (NSDictionary *) attributes
{
CardElement *element;
NSArray *elements, *values;
NSMutableArray *orgs, *categories;
NSDictionary *customFields;
NSArray *elements, *values;
NSCalendarDate *date;
CardElement *element;
id o;
unsigned int i, year, month, day;
[card setNWithFamily: [attributes objectForKey: @"c_sn"]
@@ -485,6 +487,38 @@ static Class SOGoContactGCSEntryK = Nil;
[card setCategories: categories];
}
customFields = [attributes objectForKey: @"customFields"];
if (customFields && [customFields isKindOfClass: [NSDictionary class]])
{
if ((o = [customFields objectForKey: @"1"]))
{
elements = [card childrenWithTag: @"custom1"];
[card removeChildren: elements];
[card addElementWithTag: @"custom1" ofType: nil withValue: o];
}
if ((o = [customFields objectForKey: @"2"]))
{
elements = [card childrenWithTag: @"custom2"];
[card removeChildren: elements];
[card addElementWithTag: @"custom2" ofType: nil withValue: o];
}
if ((o = [customFields objectForKey: @"3"]))
{
elements = [card childrenWithTag: @"custom3"];
[card removeChildren: elements];
[card addElementWithTag: @"custom1" ofType: nil withValue: o];
}
if ((o = [customFields objectForKey: @"4"]))
{
elements = [card childrenWithTag: @"custom4"];
[card removeChildren: elements];
[card addElementWithTag: @"custom1" ofType: nil withValue: o];
}
}
[card cleanupEmptyChildren];
}

View File

@@ -270,14 +270,15 @@
* @apiSuccess (Success 200) {Object[]} [urls] URLs
* @apiSuccess (Success 200) {String} urls.type Type (e.g., personal or work)
* @apiSuccess (Success 200) {String} urls.value URL
* @apiSuccess (Success 200) {Object[]} customFields Custom fields from Thunderbird
*/
- (id <WOActionResults>) dataAction
{
id <WOActionResults> result;
id o;
NSMutableDictionary *customFields, *data;
SOGoObject <SOGoContactObject> *contact;
id <WOActionResults> result;
NSArray *values;
NSMutableDictionary *data;
id o;
contact = [self clientObject];
card = [contact vCard];
@@ -355,6 +356,23 @@
if ([contact hasPhoto])
[data setObject: [self photoURL] forKey: @"photoURL"];
// Custom fields from Thunderbird
customFields = [NSMutableDictionary dictionary];
if ((o = [[card uniqueChildWithTag: @"custom1"] flattenedValuesForKey: @""]) && [o length])
[customFields setObject: o forKey: @"1"];
if ((o = [[card uniqueChildWithTag: @"custom2"] flattenedValuesForKey: @""]) && [o length])
[customFields setObject: o forKey: @"2"];
if ((o = [[card uniqueChildWithTag: @"custom3"] flattenedValuesForKey: @""]) && [o length])
[customFields setObject: o forKey: @"3"];
if ((o = [[card uniqueChildWithTag: @"custom4"] flattenedValuesForKey: @""]) && [o length])
[customFields setObject: o forKey: @"4"];
if ([customFields count])
[data setObject: customFields forKey: @"customFields"];
result = [self responseWithStatus: 200
andString: [data jsonRepresentation]];

View File

@@ -348,6 +348,38 @@
</div>
</div>
<!-- custom fields -->
<div class="section">
<div class="attr" ng-repeat="(key, value) in editor.card.customFields">
<div layout="row" layout-align="start center">
<md-button class="md-icon-button" type="button" ng-click="editor.deleteCustomField(key)">
<md-icon>remove_circle</md-icon>
</md-button>
<md-input-container flex="20">
<label>
<var:string label:value="Type"/>
</label>
<input type="text" readonly="readonly" ng-value="key"/>
</md-input-container>
<md-input-container class="md-flex">
<label>
<var:string label:value="Custom Value"/>
</label>
<input type="text" ng-model="editor.card.customFields[key]"/>
</md-input-container>
</div>
</div>
<div class="md-layout-margin" layout="row"
layout-align="start center" ng-show="editor.canAddCustomField()">
<md-button class="md-icon-button" type="button" ng-click="editor.addCustomField()">
<md-icon>add_circle</md-icon>
</md-button>
<label class="button-label">
<var:string label:value="New Custom Value"/>
</label>
</div>
</div>
<!-- note -->
<md-input-container class="md-block md-flex"
ng-repeat="note in editor.card.notes">

View File

@@ -146,6 +146,33 @@
</div>
</div>
<div class="section" ng-show="editor.card.customFields">
<div class="pseudo-input-container" ng-show="editor.card.customFields['1']">
<label class="pseudo-input-label"><var:string label:value="Custom 1"/></label>
<div class="pseudo-input-field">
<span>{{editor.card.customFields['1']}}</span>
</div>
</div>
<div class="pseudo-input-container" ng-show="editor.card.customFields['2']">
<label class="pseudo-input-label"><var:string label:value="Custom 2"/></label>
<div class="pseudo-input-field">
<span>{{editor.card.customFields['2']}}</span>
</div>
</div>
<div class="pseudo-input-container" ng-show="editor.card.customFields['3']">
<label class="pseudo-input-label"><var:string label:value="Custom 3"/></label>
<div class="pseudo-input-field">
<span>{{editor.card.customFields['3']}}</span>
</div>
</div>
<div class="pseudo-input-container" ng-show="editor.card.customFields['4']">
<label class="pseudo-input-label"><var:string label:value="Custom 4"/></label>
<div class="pseudo-input-field">
<span>{{editor.card.customFields['4']}}</span>
</div>
</div>
</div>
<div class="section" ng-show="editor.card.notes[0].value.length">
<div class="pseudo-input-container" ng-repeat="note in editor.card.notes">
<label class="pseudo-input-label"><var:string label:value="Note"/></label>

View File

@@ -29,6 +29,9 @@
vm.addPhone = addPhone;
vm.addUrl = addUrl;
vm.addAddress = addAddress;
vm.canAddCustomField = canAddCustomField;
vm.addCustomField = addCustomField;
vm.deleteCustomField = deleteCustomField;
vm.userFilter = userFilter;
vm.save = save;
vm.close = close;
@@ -98,6 +101,20 @@
var i = vm.card.$addUrl('', '');
focus('url_' + i);
}
function canAddCustomField() {
return _.keys(stateCard.customFields).length < 4;
}
function addCustomField() {
if (!angular.isDefined(vm.card.customFields))
vm.card.customFields = {};
// Find the first 'available' custom field
var availableKeys = _.pullAll(['1', '2', '3', '4'], _.keys(stateCard.customFields));
vm.card.customFields[availableKeys[0]] = "";
}
function deleteCustomField(key) {
delete vm.card.customFields[key];
}
function addAddress() {
var i = vm.card.$addAddress('', '', '', '', '', '', '', '');
focus('address_' + i);