Merge branch 'feature-5726-gab-autocomplete'

This commit is contained in:
smizrahi committed 2023-11-27 11:19:17 +01:00
commit fb542e6e26
6 files changed
+164 -20

No files matched your search

@@ -271,6 +271,9 @@ static NSArray *folderListingFields = nil;
if ([data length]) if ([data length])
[contactRecord setObject: data forKey: @"id"]; [contactRecord setObject: data forKey: @"id"];
// Container name
[contactRecord setObject: [self displayName] forKey: @"containerName"];
// c_cn // c_cn
data = [contactRecord objectForKey: @"c_cn"]; data = [contactRecord objectForKey: @"c_cn"];
if (![data length]) if (![data length])
@@ -242,6 +242,10 @@
//source id //source id
[newRecord setObject: [source sourceID] forKey: @"sourceID"]; [newRecord setObject: [source sourceID] forKey: @"sourceID"];
//source display name
[newRecord setObject: [self displayName]
forKey: @"containerName"];
// c_name => id // c_name => id
[newRecord setObject: [oldRecord objectForKey: @"c_name"] [newRecord setObject: [oldRecord objectForKey: @"c_name"]
forKey: @"c_name"]; forKey: @"c_name"];
+75 -5
View File
@@ -42,6 +42,7 @@
#import <SoObjects/Contacts/SOGoContactGCSEntry.h> #import <SoObjects/Contacts/SOGoContactGCSEntry.h>
#import <SoObjects/Contacts/SOGoContactGCSFolder.h> #import <SoObjects/Contacts/SOGoContactGCSFolder.h>
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
#import "UIxContactsListActions.h" #import "UIxContactsListActions.h"
@@ -140,17 +141,18 @@
{ {
id <SOGoContactFolder> folder; id <SOGoContactFolder> folder;
NSString *ascending, *valueText; NSString *ascending, *valueText;
NSArray *results, *searchFields, *fields; NSArray *searchFields, *fields, *folders, *tmpGlobalAddressBookResults;
NSMutableArray *filteredContacts, *headers; NSMutableArray *filteredContacts, *headers, *results, *globalAddressBookResults;
NSDictionary *data, *contact; NSDictionary *data, *contact;
BOOL excludeLists; BOOL excludeLists;
NSComparisonResult ordering; NSComparisonResult ordering;
NSUInteger max, count; NSUInteger max, count;
unsigned int i; unsigned int i;
NSSortDescriptor *descriptor;
NSMutableDictionary *tmpDict;
if (!contactInfos) if (!contactInfos)
{ {
folder = [self clientObject];
data = [self requestData]; data = [self requestData];
ascending = [data objectForKey: @"asc"]; ascending = [data objectForKey: @"asc"];
@@ -167,11 +169,78 @@
excludeLists = [[data objectForKey: @"excludeLists"] boolValue]; excludeLists = [[data objectForKey: @"excludeLists"] boolValue];
[contactInfos release]; [contactInfos release];
results = [folder lookupContactsWithFilter: valueText
onCriteria: searchFields folders = [[[self clientObject] container] subFolders];
globalAddressBookResults = nil;
for (folder in folders) {
// Global AB
if ([folder isKindOfClass: [SOGoContactSourceFolder class]] && (![folder isEqual: [self clientObject]])) {
tmpGlobalAddressBookResults = [folder lookupContactsWithFilter: valueText
onCriteria: nil
sortBy: [self sortKey] sortBy: [self sortKey]
ordering: ordering ordering: ordering
inDomain: [[context activeUser] domain]]; inDomain: [[context activeUser] domain]];
if (globalAddressBookResults) {
globalAddressBookResults = [globalAddressBookResults arrayByAddingObjectsFromArray: tmpGlobalAddressBookResults];
} else {
globalAddressBookResults = [NSMutableArray arrayWithArray: tmpGlobalAddressBookResults];
}
}
}
// Process for global address book instead of array
if (globalAddressBookResults) {
for (i = 0 ; i < [globalAddressBookResults count] ; i++) {
tmpDict = [NSMutableDictionary dictionaryWithDictionary: [globalAddressBookResults objectAtIndex: i]];
// Flatten emails
if ([tmpDict objectForKey: @"c_mail"] && [[tmpDict objectForKey: @"c_mail"] isKindOfClass:[NSArray class]] && [[tmpDict objectForKey: @"c_mail"] count] > 0) {
[tmpDict setObject:[[tmpDict objectForKey: @"c_mail"] componentsJoinedByString: @","] forKey:@"c_mail"];
}
if ((![tmpDict objectForKey:@"c_cn"] || [tmpDict objectForKey:@"c_cn"] == [NSNull null]) && [tmpDict objectForKey:@"c_name"]) {
// Replace c_cn if not filled
[tmpDict setObject:[tmpDict objectForKey:@"c_name"] forKey:@"c_cn"];
}
if ((![tmpDict objectForKey:@"c_uid"] || [tmpDict objectForKey:@"c_uid"] == [NSNull null]) && [tmpDict objectForKey:@"c_id"]) {
// Replace c_uid if not filled
[tmpDict setObject:[tmpDict objectForKey:@"c_uid"] forKey:@"c_id"];
}
[globalAddressBookResults replaceObjectAtIndex:i withObject: tmpDict];
}
}
// Current AB
folder = [self clientObject];
results = [NSMutableArray arrayWithArray: [folder lookupContactsWithFilter: valueText
onCriteria: searchFields
sortBy: [self sortKey]
ordering: ordering
inDomain: [[context activeUser] domain]]];
// Add sourceid for current AB
for (i = 0 ; i < [results count] ; i++) {
tmpDict = [NSMutableDictionary dictionaryWithDictionary: [results objectAtIndex: i]];
// Add sourceid
[tmpDict setObject:[folder nameInContainer] forKey:@"sourceid"];
[results replaceObjectAtIndex:i withObject: tmpDict];
}
if (globalAddressBookResults && results) { // Both results, merge arrays
// Results in personal folder will appear first
results = [results arrayByAddingObjectsFromArray: globalAddressBookResults];
} else if (globalAddressBookResults) { // No results in personal AB
results = globalAddressBookResults;
}
// Sort the results
descriptor = [[NSSortDescriptor alloc] initWithKey: [self sortKey]
ascending: ordering];
results = [results sortedArrayUsingDescriptors: [NSArray arrayWithObjects: descriptor, nil]];
[descriptor release];
if (excludeLists) if (excludeLists)
{ {
filteredContacts = [NSMutableArray array]; filteredContacts = [NSMutableArray array];
@@ -198,6 +267,7 @@
count = 0; count = 0;
fields = [[contactInfos objectAtIndex: 0] allKeys]; fields = [[contactInfos objectAtIndex: 0] allKeys];
[headers addObject: fields]; [headers addObject: fields];
while (count < max) while (count < max)
{ {
[headers addObject: [[contactInfos objectAtIndex: count] objectsForKeys: fields [headers addObject: [[contactInfos objectAtIndex: count] objectsForKeys: fields
+32 -3
View File
@@ -35,6 +35,8 @@
#import <SOGo/NSDictionary+Utilities.h> #import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
#import <Contacts/SOGoContactGCSEntry.h> #import <Contacts/SOGoContactGCSEntry.h>
#import <Contacts/SOGoContactGCSFolder.h> #import <Contacts/SOGoContactGCSFolder.h>
@@ -173,12 +175,14 @@
{ {
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
NSDictionary *values; NSDictionary *values;
NSArray *initialReferences, *refs, *emails; NSArray *initialReferences, *refs, *emails, *folders;
NSDictionary *currentReference; NSDictionary *currentReference;
NSString *uid, *workMail, *fn, *newUID; NSString *uid, *workMail, *fn, *newUID;
int i, count; int i, count;
NGVCardReference *cardReference; NGVCardReference *cardReference;
SOGoContactGCSFolder *folder; SOGoContactGCSFolder *folder;
NSMutableArray *publicSourceIDs;
id f;
folder = [co container]; folder = [co container];
@@ -200,12 +204,25 @@
count = [references count]; count = [references count];
pool = [[NSAutoreleasePool alloc] init]; pool = [[NSAutoreleasePool alloc] init];
// List container name of global AB
folders = [[[co lookupUserFolder] privateContacts: @"Contacts" inContext: nil] subFolders];
publicSourceIDs = [[NSMutableArray alloc] init];
for (f in folders) {
if ([f isKindOfClass:[SOGoContactSourceFolder class]]) {
[publicSourceIDs addObject: [f nameInContainer]];
}
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if ([[references objectAtIndex: i] isKindOfClass: [NSDictionary class]]) if ([[references objectAtIndex: i] isKindOfClass: [NSDictionary class]])
{ {
currentReference = [references objectAtIndex: i]; currentReference = [references objectAtIndex: i];
uid = [currentReference objectForKey: @"id"]; uid = [currentReference objectForKey: @"id"];
if (![self cardReferences: [list cardReferences] if (![self cardReferences: [list cardReferences]
contain: uid]) contain: uid])
{ {
@@ -222,8 +239,18 @@
[list addCardReference: cardReference]; [list addCardReference: cardReference];
} }
else else if ([currentReference objectForKey:@"sourceid"] && [publicSourceIDs containsObject:[currentReference objectForKey:@"sourceid"]]) {
{ // Create reference for shared AB (public)
uid = [currentReference objectForKey: @"id"];
emails = [[currentReference objectForKey: @"c_mail"] componentsSeparatedByString: @","];
cardReference = [NGVCardReference elementWithTag: @"card"];
[cardReference setFn: [currentReference objectForKey: @"c_cn"]];
if ([emails count])
[cardReference setEmail: [emails objectAtIndex: 0]];
[cardReference setReference: uid];
[list addCardReference: cardReference];
} else {
// Invalid UID or no UID // Invalid UID or no UID
NGVCard *newCard; NGVCard *newCard;
CardElement *newWorkMail; CardElement *newWorkMail;
@@ -264,6 +291,8 @@
pool = [[NSAutoreleasePool alloc] init]; pool = [[NSAutoreleasePool alloc] init];
} }
} }
[publicSourceIDs release];
} }
- (BOOL) cardReferences: (NSArray *) references - (BOOL) cardReferences: (NSArray *) references
+19 -1
View File
@@ -26,6 +26,8 @@
#import <SOGo/NSArray+Utilities.h> #import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h> #import <SOGo/NSDictionary+Utilities.h>
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
#import "UIxListView.h" #import "UIxListView.h"
@implementation UIxListView @implementation UIxListView
@@ -36,6 +38,7 @@
NGVCardReference *card, *cardCopy; NGVCardReference *card, *cardCopy;
int i, count; int i, count;
id test; id test;
NSArray *folders;
invalid = [NSMutableArray array]; invalid = [NSMutableArray array];
@@ -46,7 +49,22 @@
test = [[co container] lookupName: [card reference] test = [[co container] lookupName: [card reference]
inContext: context inContext: context
acquire: NO]; acquire: NO];
if ([test isKindOfClass: [NSException class]]) if ([test isKindOfClass: [NSException class]]) {
folders = [[[co lookupUserFolder] privateContacts: @"Contacts" inContext: nil] subFolders];
id <SOGoContactFolder> folder;
for (folder in folders) {
// Global AB
if ([folder isKindOfClass: [SOGoContactSourceFolder class]]) {
test = [folder lookupName: [card reference]
inContext: context
acquire: NO];
if (test && ![test isKindOfClass: [NSException class]]) break;
}
}
}
if (test && [test isKindOfClass: [NSException class]])
{ {
//NSLog (@"%@ not found", [card reference]); //NSLog (@"%@ not found", [card reference]);
cardCopy = [card copy]; cardCopy = [card copy];
@@ -468,17 +468,37 @@
<label class="pseudo-input-label"> <label class="pseudo-input-label">
<var:string label:value="Members"/> <var:string label:value="Members"/>
</label> </label>
<md-contact-chips <md-chips ng-model="editor.card.refs"
class="sg-chips-autocomplete" md-separator-keys="editor.recipientSeparatorKeys"
ng-model="editor.card.refs" md-add-on-blur="true"
ng-change="contactForm.$setDirty()" md-autocomplete-snap="width">
md-contacts="editor.userFilter($query, editor.card.refs)" <md-autocomplete
md-contact-name="$$fullname" class="md-flex"
md-contact-image="$$image" ng-model="editor.card.refs"
md-contact-email="$$email" sg-enter="contactForm.$setDirty()"
md-require-match="true" md-menu-class="md-2-line"
filter-selected="false" md-search-text="editor.searchText"
label:placeholder="Add Member"><!-- members --></md-contact-chips> md-items="card in editor.userFilter(editor.searchText, editor.card.refs)"
md-item-text="card.empty"
md-autoselect="true"
var:md-min-length="2"
md-delay="150"
md-no-cache="true">
<md-item-template>
<div class="sg-tile-content">
<div class="sg-tile-content">
<div class="sg-md-subhead md-block" md-highlight-text="editor.searchText" md-highlight-flags="gi">{{ card.$shortFormat(editor.searchText) }}</div>
<div class="sg-md-body" md-colors="::{color: 'default-background-500'}">{{ card.containername }}</div>
</div>
</div>
</md-item-template>
</md-autocomplete>
<md-chip-template>
<div class="sg-tile-content">
{{$chip.c_cn}}
</div>
</md-chip-template>
</md-chips>
</div> </div>
</div> </div>
</form> </form>