Compare commits

...
Author SHA1 Message Date
Ludovic Marcotte f1037e7d48 Updates for the 3.0b1 release. 2015-08-31 11:27:40 -04:00
Ludovic Marcotte 233b9c0613 (js/css) updates for the new packages 2015-08-31 11:08:41 -04:00
Francis Lachapelle 89206f3705 (css) Fix for latest md changes 2015-08-31 09:51:08 -04:00
Ludovic Marcotte a87daf282c (fix) workaround for Firefox with menus which include md-checkbox
See https://github.com/angular/material/issues/4212 for details
on the Angular Material bug.
2015-08-29 16:30:07 -04:00
Ludovic Marcotte fb4889a15e (fix) small code refactoring 2015-08-28 20:11:21 -04:00
Ludovic Marcotte 3fdabf8671 (fix) properly update flags when message was answered/forwarded 2015-08-28 15:50:46 -04:00
Ludovic Marcotte 66c52f22dd (fix) added timepicker directive 2015-08-28 15:26:21 -04:00
Francis Lachapelle 8f7334f11d (js) Simplify Account and Message services 2015-08-28 15:17:04 -04:00
Ludovic Marcotte 624833eca9 (fix) updates for new packages 2015-08-28 14:09:20 -04:00
Ludovic Marcotte 431c53b84d (feat) new time picker component + enabled it in the calendar module 2015-08-28 13:59:41 -04:00
Francis Lachapelle c9d9f7b47a (js) Add caching of cards 2015-08-27 15:55:56 -04:00
Francis Lachapelle 1667f8879d (js) New progress indicator in AddressBook module 2015-08-27 14:09:43 -04:00
Francis Lachapelle 3611c4021d Improve view detail (messages, cards) 2015-08-27 13:37:47 -04:00
Luc Charland bba0d6f44d make the tests more robust when data is invalid in DB/Webdav 2015-08-27 11:51:58 -04:00
Luc Charland bf390f17dd fixed when strings not initialized in prefs 2015-08-27 11:51:58 -04:00
Ludovic Marcotte 834aba85a6 (fix) cleanups 2015-08-27 11:47:51 -04:00
Ludovic Marcotte d878c69c15 (feat) can now create mails from address book module 2015-08-27 11:01:23 -04:00
Francis Lachapelle d9d59c6b52 (fix) Force a single mail composer dialog 2015-08-26 21:22:39 -04:00
Francis Lachapelle 69000a0929 Review animations of view detail (messages, cards) 2015-08-26 17:28:03 -04:00
Ludovic Marcotte 876d9cfa21 (fix) make messages loading very fast
Avoid calling angular.extend() loading when unwrapping the mailbox
and never call again Message.id directly, but rather use Message.$absolutePath()
which does initialization and caching
2015-08-26 11:56:47 -04:00
Luc Charland 117e6b6bc1 added the multiple phone test 2015-08-26 11:28:54 -04:00
Francis Lachapelle 01e2256483 (css) Improve autocompletion menu 2015-08-26 09:48:47 -04:00
Francis Lachapelle 49e7cf0994 (css) Adapt fullscreen dialogs to new md layout 2015-08-26 09:41:49 -04:00
Ludovic Marcotte b3d6973fb1 (fix) small optimization 2015-08-26 09:31:08 -04:00
Ludovic Marcotte aae522259f (fix) expose the json accounts call 2015-08-26 08:28:19 -04:00
Ludovic Marcotte 68ef8784a0 (fix) added json call to get all mail accounts 2015-08-26 08:27:45 -04:00
Francis Lachapelle da821ea6c7 (js) Improve recipient auto-completion 2015-08-25 22:17:57 -04:00
Ludovic Marcotte 4dee99e0ba (fix) improved padding usage to better align icons 2015-08-25 20:47:12 -04:00
Francis Lachapelle eea08d083d (html) Improve contacts list 2015-08-25 14:56:30 -04:00
Francis Lachapelle 8055acfd4a (fix) Restore previous sort in Contacts module 2015-08-25 14:20:20 -04:00
Francis Lachapelle 1fc947d8c8 (fix) Define CSS styles for ALL calendars 2015-08-25 13:46:33 -04:00
Francis Lachapelle 7b3a238fb9 (js) New progress indicator in Mail module 2015-08-25 12:20:46 -04:00
Ludovic Marcotte 99d121fd3e (fix) updates for new packages 2015-08-25 11:46:14 -04:00
Ludovic Marcotte eab3ee111a (feat) now use md-on-demand for (hopefully) faster mailbox loading 2015-08-25 11:45:17 -04:00
Francis Lachapelle eeb6be1f08 (css) Match new ng-material files names 2015-08-25 11:01:28 -04:00
Francis Lachapelle 29108bbb62 (html) Localization 2015-08-25 06:34:34 -04:00
Ludovic Marcotte 9c6884bd7d (feat) add single export/save as actions 2015-08-24 20:04:56 -04:00
Francis Lachapelle 0aac4897fa (fix) Set virtual item size in contacts list 2015-08-24 17:28:01 -04:00
Ludovic Marcotte 2a99d1fd80 (fix) reset search filter when switching address books 2015-08-24 16:17:44 -04:00
Francis Lachapelle ba148eec5b (js) Fix error in Component.prototype.$reset 2015-08-24 14:54:25 -04:00
Francis Lachapelle 49c4884cc9 (html) Improve grids layout in recurrence editor 2015-08-24 14:40:20 -04:00
Francis Lachapelle e5d6ee93c3 Update Angular to version 1.4.x 2015-08-24 11:32:40 -04:00
Ludovic Marcotte 40eff05d4e (feat) added toolbar to account editing dialog 2015-08-24 11:26:00 -04:00
Francis Lachapelle be031fe2c9 (html) Restore animation when opening a card 2015-08-24 11:24:51 -04:00
Francis Lachapelle 0fe1419289 (html) Enlarge folder links dialog width 2015-08-24 11:23:34 -04:00
Francis Lachapelle 9db633cada (html) Replace md-layout-fill by layout-fill 2015-08-24 11:21:17 -04:00
Ludovic Marcotte 8a2d7d56e0 (feat) added toolbar to filter editor dialog 2015-08-24 11:20:23 -04:00
Francis Lachapelle 0c17e745f1 (html) Localization 2015-08-24 11:11:23 -04:00
Ludovic Marcotte 18bc75e50b (fix) adjust import path due to md changes 2015-08-24 08:49:31 -04:00
Ludovic Marcotte 68ad3c1045 (fix) localize 'me' 2015-08-22 07:51:13 -04:00
Ludovic Marcotte 85c8aebbd4 (feat) initial support for contact import in the address book module 2015-08-21 20:56:21 -04:00
Ludovic Marcotte 0a8834193f (fix) updates for new packages 2015-08-21 13:40:07 -04:00
Ludovic Marcotte 91e4c2cefc (feat) improved the mailviewer with regards to sender + recipients 2015-08-21 13:37:18 -04:00
Ludovic Marcotte b80d8dbb06 (fix) Session fix when SOGoEnableDomainBasedUID is enabled but logins are domain-less 2015-08-21 10:51:45 -04:00
Ludovic Marcotte 525d1ad80f (fix) also return all calendars in findAll 2015-08-20 22:38:01 -04:00
Ludovic Marcotte 332dd0d96d (fix) small optimization 2015-08-20 22:37:27 -04:00
Ludovic Marcotte a45000d15d (fix) show delete option only where objectEraser is on 2015-08-20 19:42:24 -04:00
Ludovic Marcotte 3301bdb055 (fix) return the complete list of addressbooks
This fixes many bugs / side effects, especially with ACLs
2015-08-20 19:37:30 -04:00
Francis Lachapelle 2f82b5cfd3 (js) Localization of toast message 2015-08-20 16:39:34 -04:00
Francis Lachapelle e3b64e035d (css) New md-fab-overlap-bottom class 2015-08-20 16:28:11 -04:00
Francis Lachapelle 1470258b5c (js) Simplify Account.prototype.$newMailbox 2015-08-20 16:28:11 -04:00
Francis Lachapelle 83fee27ca8 (js) Simplify Mailbox.prototype.$emptyTrash 2015-08-20 16:28:10 -04:00
Ludovic Marcotte e5b0596bc9 (fix) don't convert back the birthday date object on non-deep omits 2015-08-20 15:47:41 -04:00
Ludovic Marcotte 26e8276b08 (feat) improved ACLs handling for address book 2015-08-20 15:47:11 -04:00
Ludovic Marcotte 078ba95f8e (feat) show small toast when preferences are saved to give user's feedback 2015-08-20 14:53:43 -04:00
Ludovic Marcotte 65525dd33b (feat) added date picker in contact editor + now handle correctly birthday 2015-08-20 10:29:47 -04:00
Ludovic Marcotte da81f7bc58 (fix) set background to transparent by default 2015-08-19 20:45:07 -04:00
Ludovic Marcotte 8fcd594be6 (fix) removed unused code 2015-08-19 19:38:42 -04:00
Ludovic Marcotte 548f056b9c (fix) small formatting nit 2015-08-19 11:23:03 -04:00
Ludovic Marcotte dffdbf318c (feat) new 'viewable' property on events/tasks for full viewers 2015-08-19 11:22:17 -04:00
Ludovic Marcotte 161bcfac87 (fix) proper loading of transalations 2015-08-19 10:39:10 -04:00
Ludovic Marcotte c6f17cd45c (feat) make use of the sieve capabilities 2015-08-19 08:47:33 -04:00
Ludovic Marcotte 38713a6c67 (feat) handle multiple home/work phones, emails and urls 2015-08-18 16:21:47 -04:00
Ludovic Marcotte 8cef98eba1 (fix) add flex/flex-sm attributes 2015-08-18 15:32:44 -04:00
Ludovic Marcotte 2144d3122a (feat) added support back for SOGoForwardConstraints 2015-08-18 15:25:51 -04:00
Ludovic Marcotte 9d272ae063 (feat) added the 'add default email addresses' feature in vacation module 2015-08-18 14:57:29 -04:00
Ludovic Marcotte fcd0140ffd Revert "(fix) by default, open links in new tab/window from html mails"
This reverts commit 869b3c4cd1.
2015-08-18 14:52:47 -04:00
Ludovic Marcotte d783782af7 (fix) adding basic flags 2015-08-18 11:31:42 -04:00
Ludovic Marcotte 869b3c4cd1 (fix) by default, open links in new tab/window from html mails 2015-08-18 11:13:27 -04:00
Ludovic Marcotte 2da2937391 (fix) formatting improvements 2015-08-18 11:01:59 -04:00
Ludovic Marcotte 5034d6655a (fix) correctly refresh the mailboxes list when empty'ing the trash that contains subfolders 2015-08-18 10:10:37 -04:00
Ludovic Marcotte d1446f7dc1 (fix) broken top level mailbox creation 2015-08-18 09:57:07 -04:00
Ludovic Marcotte c5a219add8 (fix) wrong check for web calendars 2015-08-18 09:27:33 -04:00
Ludovic Marcotte bc2c839fbc Update for the new packaging 2015-08-18 08:39:20 -04:00
Ludovic Marcotte 2e736490d5 Merge branch 'master' of https://github.com/inverse-inc/sogo 2015-08-17 16:22:41 -04:00
Ludovic Marcotte 20bf66d931 (feat) handle links to addressbooks like we do for calendars
also included missing template commit for calendar
2015-08-17 16:21:10 -04:00
Francis Lachapelle 864a7f8028 (html) Improve Preferences module 2015-08-17 16:14:47 -04:00
Ludovic Marcotte 7b5541b5d1 (fix) reuse the calendar urls from the model 2015-08-17 13:44:21 -04:00
Ludovic Marcotte 744cba4422 (feat) integrated md-datepicker and enabled it in the Preferences module (Vacation)
The date picker suffers from this bug: https://github.com/angular/material/issues/4192

Which makes it not that usable right now.
2015-08-17 10:10:57 -04:00
Ludovic Marcotte ded467e0a2 (fix) add empty settings hashes to prever JS exceptions 2015-08-17 09:55:14 -04:00
Ludovic Marcotte a718b87d91 (fix) minor gui improvement to links templates 2015-08-16 21:42:53 -04:00
Ludovic Marcotte 6e2e71b202 (fix) correctly set flex attribut on sm devices 2015-08-15 17:25:04 -04:00
Ludovic Marcotte 04e63e5edf (fix) add minimal constraints when creating events or tasks 2015-08-15 17:08:15 -04:00
Ludovic Marcotte f1a50bcb74 (feat) added refresh support to calendar 2015-08-14 16:31:29 -04:00
Ludovic Marcotte 0672b96b8b (fix) show the alarm name as a floating label for now
This might change as the text is so tiny!
2015-08-14 15:51:17 -04:00
Ludovic Marcotte 93fa74d279 (feat) save/restore sorting state for address books
The initial loading doesn't work yet. Will work on this later.
2015-08-14 15:22:59 -04:00
Ludovic Marcotte ffa4079fa8 (fix) b0rk3n sort saving regarding the asc/desc state 2015-08-14 15:11:07 -04:00
Luc Charland 8f75bdce2d Use Json for testing webcalendar 2015-08-14 12:46:37 -04:00
Luc Charland 4f53ea70e1 Commented out testing two phones same type until fixed 2015-08-14 12:46:03 -04:00
Ludovic Marcotte b72a9383a4 (feat) major rework of the sidenav and top toolbars 2015-08-14 12:14:15 -04:00
extrafu d3d9a720dc Merge pull request #99 from inverse-inc/feature/saveSortContacts
Added sort saving to Contacts
2015-08-13 15:29:59 -04:00
Ludovic Marcotte 02daebe36b (fix) also handle tasks deletion correctly 2015-08-12 18:31:06 -04:00
Ludovic Marcotte 336e4c93e9 (fix) added temporary fix for file inputs on firefox 2015-08-12 18:25:15 -04:00
Ludovic Marcotte 47252affba (feat) initial selection + ops in calendar module 2015-08-12 16:11:38 -04:00
151 changed files with 36449 additions and 12913 deletions

No files matched your search

+13104 -402
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -7,6 +7,7 @@ Bug fixes
- Fixed several sync issues on environments with multiple users (Zentyal)
- Folders from other users will no longer appear on your Outlook (Zentyal)
- Use right auth in multidomain environments in contacts and calendar from Outlook (Zentyal)
- Session fix when SOGoEnableDomainBasedUID is enabled but logins are domain-less
2.3.1 (2015-07-23)
------------------
+5 -1
View File
@@ -1,6 +1,6 @@
/* NGVCard+SOGo.h - this file is part of SOGo
*
* Copyright (C) 2009-2014 Inverse inc.
* Copyright (C) 2009-2015 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
@@ -31,6 +31,10 @@
- (CardElement *) elementWithTag: (NSString *) elementTag
ofType: (NSString *) type;
- (void) addElementWithTag: (NSString *) elementTag
ofType: (NSString *) type
withValue: (id) value;
- (void) updateFromLDIFRecord: (NSDictionary *) ldifRecord;
- (NSMutableDictionary *) asLDIFRecord;
+2 -2
View File
@@ -188,8 +188,8 @@ convention:
}
- (void) addElementWithTag: (NSString *) elementTag
ofType: (NSString *) type
withValue: (id) value
ofType: (NSString *) type
withValue: (id) value
{
NSArray *allValues;
NSEnumerator *list;
+6 -3
View File
@@ -1,6 +1,5 @@
/*
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2006-2015 Inverse inc.
This file is part of SOGo.
@@ -32,9 +31,13 @@
@class NSString;
@interface SOGoContactGCSFolder : SOGoGCSFolder <SOGoContactFolder>
{
NSString *baseCardDAVURL, *basePublicCardDAVURL;
}
- (void) fixupContactRecord: (NSMutableDictionary *) contactRecord;
- (NSDictionary *) lookupContactWithName: (NSString *) aName;
- (NSString *) cardDavURL;
- (NSString *) publicCardDavURL;
@end
+63 -2
View File
@@ -1,6 +1,5 @@
/*
Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2006-2013-2015 Inverse inc.
This file is part of SOGo.
@@ -67,6 +66,24 @@ static NSArray *folderListingFields = nil;
@"c_component", nil];
}
- (id) init
{
if ((self = [super init]))
{
baseCardDAVURL = nil;
basePublicCardDAVURL = nil;
}
return self;
}
- (void) dealloc
{
[baseCardDAVURL release];
[basePublicCardDAVURL release];
[super dealloc];
}
- (Class) objectClassForContent: (NSString *) content
{
CardGroup *cardEntry;
@@ -436,4 +453,48 @@ static NSArray *folderListingFields = nil;
return [NSString stringWithFormat: @"%@:%@", nsRep, nodeName];
}
- (NSString *) _baseCardDAVURL
{
NSString *davURL;
if (!baseCardDAVURL)
{
davURL = [[self realDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
baseCardDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
baseCardDAVURL = davURL;
[baseCardDAVURL retain];
}
return baseCardDAVURL;
}
- (NSString *) cardDavURL
{
return [NSString stringWithFormat: @"%@/", [self _baseCardDAVURL]];
}
- (NSString *) _basePublicCardDAVURL
{
NSString *davURL;
if (!basePublicCardDAVURL)
{
davURL = [[self publicDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
basePublicCardDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
basePublicCardDAVURL = davURL;
[basePublicCardDAVURL retain];
}
return basePublicCardDAVURL;
}
- (NSString *) publicCardDavURL
{
return [NSString stringWithFormat: @"%@/", [self _basePublicCardDAVURL]];
}
@end /* SOGoContactGCSFolder */
+1 -3
View File
@@ -1,8 +1,6 @@
/* NSArray+Utilities.h - this file is part of SOGo
*
* Copyright (C) 2006 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2015 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
+1 -3
View File
@@ -1,8 +1,6 @@
/* NSArray+Utilities.m - this file is part of SOGo
*
* Copyright (C) 2006-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2015 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
+1 -3
View File
@@ -1,8 +1,6 @@
/* NSObject+Utilities.h - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2015 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
+1 -3
View File
@@ -1,8 +1,6 @@
/* NSObject+Utilities.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2015 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
+4 -1
View File
@@ -778,7 +778,10 @@ static Class NSNullK;
NSRange r;
r = [theUID rangeOfString: [NSString stringWithFormat: @"@%@", theDomain]];
theUID = [theUID substringToIndex: r.location];
// We check if the range is ok here since we could be using DomainLessLogin
if (r.location != NSNotFound)
theUID = [theUID substringToIndex: r.location];
}
sogoSources = [[self authenticationSourceIDsInDomain: theDomain] objectEnumerator];
+5 -1
View File
@@ -70,7 +70,11 @@ class Carddav:
if not self.cards:
url = "/SOGo/so/%s/Contacts/personal/view" % (self.login)
content = self._get(url)
self.cards = content['cards']
#print "\nCONTENT:", content
if 'cards' in content:
self.cards = content['cards']
else:
self.cards = []
return self.cards
def get_cards(self, pattern):
+4 -4
View File
@@ -89,9 +89,9 @@ class preferences:
get = HTTPPreferencesGET(url)
get.cookie = self.cookie
self.client.execute(get)
if DEBUG: print "LUC (url):", url
if DEBUG: print "LUC (status):", get.response["status"]
if DEBUG: print "LUC (body):", get.response['body']
if DEBUG: print "DEBUG (url):", url
if DEBUG: print "DEBUG (status):", get.response["status"]
if DEBUG: print "DEBUG (body):", get.response['body']
content = simplejson.loads(get.response['body'])
result = None
try:
@@ -117,7 +117,7 @@ class preferences:
# Get the right sub-dict and change the key/value
subdict = self.find_key(self.preferences, preference)
if not subdict:
print "LUC(nosubdict):", preference, self.preferences
raise AttributeError("ERROR(nosubdict): looking for %s in: %s" %(preference, str(self.preferences)))
subdict[preference] = value
def set(self, preference, value=None):
+24
View File
@@ -85,6 +85,13 @@ class JsonDavPhoneTests(unittest.TestCase):
self.allphones = list(self.newphone)
self.allphones.extend(self.newphones_difftype)
self.allphones.extend(self.newphones_sametype)
#- In case there are no cards for this user
try:
self._get_card()
except IndexError:
path = 'Contacts/personal'
(card, path, gid) = self._create_new_card(path)
self._save_card(card)
def tearDown(self):
self._connect_as_user()
@@ -102,6 +109,23 @@ class JsonDavPhoneTests(unittest.TestCase):
def _connect_as_user(self, newuser=username, newpassword=password):
self.dv = carddav.Carddav(newuser, newpassword)
def _create_new_card(self, path):
gid = self.dv.newguid(path)
card = {'c_categories': None,
'c_cn': 'John Doe',
'c_component': 'vcard',
'c_givenname': 'John Doe',
'c_mail': 'johndoe@nothere.com',
'c_name': gid,
'c_o': '',
'c_screenname': '',
'c_sn': '',
'c_telephonenumber': '123.456.7890',
'emails': [{'type': 'pref', 'value': 'johndoe@nothere.com'}],
'phones': [{'type': 'home', 'value': '111.222.3333'}],
'id': gid}
return (card, path, gid)
def _get_card(self, name="John Doe"):
tmp_card = self.dv.get_cards(name)[0]
self.card = self.dv.get_card(tmp_card['c_name'])
@@ -28,12 +28,14 @@ class preventInvitationsTest(unittest.TestCase):
self.caldav = CalDAVSchedulingTest(self)
cal = self.prefs.get("Calendar")
if "PreventInvitationsWhitelist" not in cal:
#print "LUC (cal):", cal
cal["PreventInvitationsWhitelist"] = None
self.prefs.set("PreventInvitationsWhitelist", None)
if "PreventInvitations" not in cal:
cal["PreventInvitations"] = 0
self.prefs.set("PreventInvitations", 0)
def tearDown(self):
self.prefs.set("autoReplyText", "")
#self.prefs.set("autoReplyText", "")
self.prefs.set('PreventInvitations', 0)
self.prefs.set("PreventInvitationsWhitelist", None)
#- Manual Cleanup, not called because classs is not derived from unittest
+4 -6
View File
@@ -21,8 +21,8 @@ class UIPostsTests(unittest.TestCase):
self.cookie = sogoLogin.getAuthCookie(hostname, port, username, password)
def _urlPostData(self, client, url, data, exp_status=200):
post = webdavlib.HTTPPOST(url, data)
post.content_type = "application/x-www-form-urlencoded"
post = webdavlib.HTTPPOST(url, simplejson.dumps(data))
post.content_type = "application/json"
post.cookie = self.cookie
client.execute(post)
@@ -43,16 +43,14 @@ class UIPostsTests(unittest.TestCase):
""" Add Web Calendar """
ret=True
data = "url=%s" % webCalendarURL
data = {"url":"%s" % webCalendarURL}
calendarBaseURL="/SOGo/so/%s/Calendar" % username
addWebCalendarURL = "%s/addWebCalendar" % calendarBaseURL
response = self._urlPostData(self.client, addWebCalendarURL, data)
respJSON = simplejson.loads(response['body'])
folderID = respJSON['folderID']
calID = respJSON['id']
#sogo1:Calendar/C07-5006F300-1-370E2480
(_, calID) = folderID.split('/', 1)
self.assertNotEqual(calID, None)
# reload the cal
+6 -34
View File
@@ -440,40 +440,6 @@
return ([[self productCSSURL] length] > 0);
}
- (BOOL) _moduleIs: (NSString *) moduleName
{
NSString *frameworkName;
frameworkName = [[context page] frameworkName];
return [frameworkName isEqualToString: moduleName];
}
- (BOOL) isCalendar
{
return [self _moduleIs: @"SchedulerUI"];
}
- (BOOL) isContacts
{
return [self _moduleIs: @"ContactsUI"];
}
- (BOOL) isMail
{
return [self _moduleIs: @"MailerUI"];
}
- (BOOL) isPreferences
{
return [self _moduleIs: @"PreferencesUI"];
}
- (BOOL) isAdministration
{
return [self _moduleIs: @"AdministrationUI"];
}
- (void) setToolbar: (NSString *) newToolbar
{
ASSIGN (toolbar, newToolbar);
@@ -509,6 +475,12 @@
return [[context activeUser] cn];
}
- (NSString *) userEmail
{
return [[context activeUser] systemEmail];
}
- (BOOL) canLogoff
{
BOOL canLogoff;
@@ -43,6 +43,12 @@
"Copy To" = "Copy To";
"Add to:" = "Add to:";
/* Number of selected contacts in list */
"selected" = "selected";
/* Empty right pane */
"No contact selected" = "No contact selected";
/* Tooltips */
"Create a new address book card" = "Create a new address book card";
+11 -6
View File
@@ -367,6 +367,8 @@ static Class SOGoContactGCSEntryK = Nil;
day = [date dayOfMonth];
[card setBday: [NSString stringWithFormat: @"%.4d%.2d%.2d", year, month, day]];
}
else
[card setBday: nil];
if ([[attributes objectForKey: @"addresses"] isKindOfClass: [NSArray class]])
{
@@ -430,8 +432,9 @@ static Class SOGoContactGCSEntryK = Nil;
{
if ([attrs isKindOfClass: [NSDictionary class]])
{
element = [card elementWithTag: @"tel" ofType: [attrs objectForKey: @"type"]];
[element setSingleValue: [attrs objectForKey: @"value"] forKey: @""];
[card addElementWithTag: @"tel"
ofType: [attrs objectForKey: @"type"]
withValue: [attrs objectForKey: @"value"]];
}
}
}
@@ -448,8 +451,9 @@ static Class SOGoContactGCSEntryK = Nil;
{
if ([o isKindOfClass: [NSDictionary class]])
{
element = [card elementWithTag: @"email" ofType: [o objectForKey: @"type"]];
[element setSingleValue: [o objectForKey: @"value"] forKey: @""];
[card addElementWithTag: @"email"
ofType: [o objectForKey: @"type"]
withValue: [o objectForKey: @"value"]];
}
}
}
@@ -466,8 +470,9 @@ static Class SOGoContactGCSEntryK = Nil;
{
if ([attrs isKindOfClass: [NSDictionary class]])
{
element = [card elementWithTag: @"url" ofType: [attrs objectForKey: @"type"]];
[element setSingleValue: [attrs objectForKey: @"value"] forKey: @""];
[card addElementWithTag: @"url"
ofType: [attrs objectForKey: @"type"]
withValue: [attrs objectForKey: @"value"]];
}
}
}
+7 -13
View File
@@ -112,15 +112,11 @@
request = [context request];
rc = [NSMutableDictionary dictionary];
data = [request formValueForKey: @"contactsFile"];
if ([data respondsToSelector: @selector(isEqualToString:)])
fileContent = (NSString *) data;
else
{
fileContent = [[NSString alloc] initWithData: (NSData *) data
encoding: NSUTF8StringEncoding];
[fileContent autorelease];
}
data = [[[[[request httpRequest] body] parts] lastObject] body];
fileContent = [[NSString alloc] initWithData: (NSData *) data
encoding: NSUTF8StringEncoding];
[fileContent autorelease];
if (fileContent && [fileContent length])
{
@@ -132,12 +128,10 @@
imported = 0;
}
[rc setObject: [NSNumber numberWithInt: imported]
forKey: @"imported"];
[rc setObject: [NSNumber numberWithInt: imported] forKey: @"imported"];
response = [self responseWithStatus: 200];
[response setHeader: @"text/html"
forKey: @"content-type"];
[response setHeader: @"text/html" forKey: @"content-type"];
[(WOResponse*)response appendContentString: [rc jsonRepresentation]];
return response;
@@ -20,14 +20,6 @@
#import <SOGoUI/UIxComponent.h>
@class NSString;
@class SOGoContactGCSFolder;
@interface UIxContactFolderLinksTemplate : UIxComponent
{
SOGoContactGCSFolder *addressBook;
NSString *baseCardDAVURL, *basePublicCardDAVURL;
}
@end
@@ -24,69 +24,6 @@
@implementation UIxContactFolderLinksTemplate
- (id) init
{
if ((self = [super init]))
{
addressBook = [self clientObject];
baseCardDAVURL = nil;
basePublicCardDAVURL = nil;
}
return self;
}
- (void) dealloc
{
[baseCardDAVURL release];
[basePublicCardDAVURL release];
[super dealloc];
}
- (NSString *) _baseCardDAVURL
{
NSString *davURL;
if (!baseCardDAVURL)
{
davURL = [[addressBook realDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
baseCardDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
baseCardDAVURL = davURL;
[baseCardDAVURL retain];
}
return baseCardDAVURL;
}
- (NSString *) cardDavURL
{
return [NSString stringWithFormat: @"%@/", [self _baseCardDAVURL]];
}
- (NSString *) _basePublicCardDAVURL
{
NSString *davURL;
if (!basePublicCardDAVURL)
{
davURL = [[addressBook publicDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
basePublicCardDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
basePublicCardDAVURL = davURL;
[basePublicCardDAVURL retain];
}
return basePublicCardDAVURL;
}
- (NSString *) publicCardDavURL
{
return [NSString stringWithFormat: @"%@/", [self _basePublicCardDAVURL]];
}
- (BOOL) isPublicAccessEnabled
{
// NOTE: This method is the same found in Common/UIxAclEditor.m
+43 -11
View File
@@ -275,32 +275,70 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
return [[self queryParameterForKey: @"popup"] boolValue];
}
- (BOOL) isPublicAccessEnabled
{
// NOTE: This method is the same found in Common/UIxAclEditor.m
return [[SOGoSystemDefaults sharedSystemDefaults] enablePublicAccess];
}
- (NSString *) contactFolders
{
SOGoContactFolders *folderContainer;
NSArray *folders;
NSMutableDictionary *urls, *acls;
NSMutableArray *foldersAttrs;
NSString *userLogin, *owner;
NSArray *folders, *allACLs;
NSDictionary *folderAttrs;
id currentFolder;
BOOL objectCreator, objectEditor, objectEraser;
int max, i;
userLogin = [[context activeUser] login];
folderContainer = [self clientObject];
// return [folderContainer subFolders];
folders = [folderContainer subFolders];
max = [folders count];
foldersAttrs = [NSMutableArray arrayWithCapacity: max];
urls = nil;
for (i = 0; i < max; i++)
{
currentFolder = [folders objectAtIndex: i];
owner = [currentFolder ownerInContext: context];
// We extract URLs for this address book
if ([currentFolder respondsToSelector: @selector(cardDavURL)])
{
urls = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[currentFolder cardDavURL], @"cardDavURL",
nil];
if ([self isPublicAccessEnabled])
{
[urls setObject: [currentFolder publicCardDavURL] forKey: @"publicCardDavURL"];
}
}
// We extract ACLs for this address book
allACLs = ([owner isEqualToString: userLogin] ? nil : [currentFolder aclsForUser: userLogin]);
objectCreator = ([owner isEqualToString: userLogin] || [allACLs containsObject: SOGoRole_ObjectCreator]);
objectEditor = ([owner isEqualToString: userLogin] || [allACLs containsObject: SOGoRole_ObjectEditor]);
objectEraser = ([owner isEqualToString: userLogin] || [allACLs containsObject: SOGoRole_ObjectEraser]);
acls = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: objectCreator], @"objectCreator",
[NSNumber numberWithBool: objectEditor], @"objectEditor",
[NSNumber numberWithBool: objectEraser], @"objectEraser", nil];
// NOTE: keep urls as the last key/value here, to avoid chopping the dictionary
// if it is not a GCS folder
folderAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat: @"%@", [currentFolder nameInContainer]], @"id",
[currentFolder displayName], @"name",
[currentFolder ownerInContext: context], @"owner",
owner, @"owner",
[NSNumber numberWithBool: [currentFolder isKindOfClass: SOGoGCSFolderK]], @"isEditable",
[NSNumber numberWithBool: [currentFolder isKindOfClass: SOGoContactSourceFolderK]
&& ![currentFolder isPersonalSource]], @"isRemote",
acls, @"acls",
urls, @"urls",
nil];
[foldersAttrs addObject: folderAttrs];
}
@@ -419,12 +457,6 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
return [super defaultAction];
}
- (BOOL) isPublicAccessEnabled
{
// NOTE: This method is the same found in Common/UIxAclEditor.m
return [[SOGoSystemDefaults sharedSystemDefaults] enablePublicAccess];
}
@end
@interface UIxContactViewTemplate : UIxComponent
+3 -4
View File
@@ -838,11 +838,10 @@
o = [card birthday];
if (o)
{
NSNumber *time = [NSNumber numberWithInt: [o timeIntervalSince1970]];
[data setObject: time forKey: @"birthday"];
[data setObject: [NSNumber numberWithInt: [o timeIntervalSince1970]]
forKey: @"birthday"];
}
// o = [card source];
// if (o) [data setObject: o forKey: @"source"];
o = [card tz];
if (o) [data setObject: o forKey: @"tz"];
+22 -18
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2006-2015 Inverse inc.
This file is part of SOGo.
@@ -39,6 +39,7 @@
#import <Contacts/SOGoContactFolder.h>
#import <Contacts/SOGoContactFolders.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserSettings.h>
#import <NGCards/NGVCard.h>
@@ -83,32 +84,33 @@
s = [rq formValueForKey: @"sort"];
if (![s length])
s = [self defaultSortKey];
else
[self saveSortValue: s];
return s;
}
- (void) saveSortValue: (NSString *) sort
{
NSString *ascending;
SOGoUserSettings *us;
- (void) saveSortValue
{
NSMutableDictionary *contactSettings;
NSString *ascending, *sort;
SOGoUserSettings *us;
sort = [[context request] formValueForKey: @"sort"];
ascending = [[context request] formValueForKey: @"asc"];
if ([sort length])
{
us = [[context activeUser] userSettings];
contactSettings = [us objectForKey: @"Contact"];
// Must create if it doesn't exist
if (!contactSettings)
{
contactSettings = [NSMutableDictionary dictionary];
[us setObject: contactSettings forKey: @"Contact"];
us = [[context activeUser] userSettings];
contactSettings = [us objectForKey: @"Contact"];
// Must create if it doesn't exist
if (!contactSettings)
{
contactSettings = [NSMutableDictionary dictionary];
[us setObject: contactSettings forKey: @"Contact"];
}
[contactSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", [ascending intValue]], nil]
forKey: @"SortingState"];
[us synchronize];
}
[contactSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", (ascending?1:0)], nil] forKey: @"SortingState"];
[us synchronize];
}
}
- (NSArray *) contactInfos
@@ -123,6 +125,8 @@
WORequest *rq;
unsigned int i;
[self saveSortValue];
if (!contactInfos)
{
folder = [self clientObject];
+1 -3
View File
@@ -1,8 +1,6 @@
/* UIxMailPartTextViewer.h - this file is part of $PROJECT_NAME_HERE$
*
* Copyright (C) 2006 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2015 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
+19 -20
View File
@@ -1,23 +1,22 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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.
OGo 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
02111-1307, USA.
*/
/* UIxMailPartTextViewer.m - this file is part of $PROJECT_NAME_HERE$
*
* Copyright (C) 2006-2015 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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
UIxMailPartTextViewer
@@ -65,6 +65,9 @@
"Account: " = "Account: ";
"Shared Account: " = "Shared Account: ";
/* Empty right pane */
"No message selected" = "No message selected";
/* acls */
"Access rights to" = "Access rights to";
"For user" = "For user";
+7 -7
View File
@@ -92,7 +92,7 @@
}
else
{
errorFormat = [self labelForKey: @"The folder with name \"%@\" could not be created."];
errorFormat = [self labelForKey: @"The folder with name \"%@\" could not be created." inContext: context];
jsonResponse = [NSDictionary dictionaryWithObject: [NSString stringWithFormat: errorFormat, folderName]
forKey: @"error"];
response = [self responseWithStatus: 500
@@ -101,7 +101,7 @@
}
else
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing 'name' parameter."]
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing 'name' parameter." inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500
andJSONRepresentation: jsonResponse];
@@ -149,7 +149,7 @@
if (!newFolderName || [newFolderName length] == 0)
{
message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing name parameter"]
message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing name parameter" inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500
andString: [message jsonRepresentation]];
@@ -160,7 +160,7 @@
error = [co renameTo: newFolderName];
if (error)
{
message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to rename folder."]
message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to rename folder." inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500
andString: [message jsonRepresentation]];
@@ -251,7 +251,7 @@
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
if (error)
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move folder."]
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move folder." inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500
andString: [jsonResponse jsonRepresentation]];
@@ -283,7 +283,7 @@
}
else
{
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move folder."]
jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"Unable to move folder." inContext: context]
forKey: @"error"];
response = [self responseWithStatus: 500
andString: [jsonResponse jsonRepresentation]];
@@ -374,7 +374,7 @@
{
uids = [value componentsSeparatedByString: @","];
response = [co archiveUIDs: uids
inArchiveNamed: [self labelForKey: @"Saved Messages.zip"]
inArchiveNamed: [self labelForKey: @"Saved Messages.zip" inContext: context]
inContext: context];
if (!response)
response = [self responseWith204];
+18 -13
View File
@@ -55,6 +55,7 @@
#import <Mailer/SOGoSentFolder.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSObject+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDateFormatter.h>
#import <SOGo/SOGoUser.h>
@@ -131,7 +132,7 @@
else if ([now dayOfCommonEra] - [messageDate dayOfCommonEra] == 1)
{
// Yesterday
return [self labelForKey: @"Yesterday"];
return [self labelForKey: @"Yesterday" inContext: context];
}
else if ([now dayOfCommonEra] - [messageDate dayOfCommonEra] < 7)
{
@@ -190,10 +191,10 @@
s = [[s substringFromIndex: r.location+1]
stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([s hasPrefix: @"1"]) result = [self labelForKey: @"highest"];
else if ([s hasPrefix: @"2"]) result = [self labelForKey: @"high"];
else if ([s hasPrefix: @"4"]) result = [self labelForKey: @"low"];
else if ([s hasPrefix: @"5"]) result = [self labelForKey: @"lowest"];
if ([s hasPrefix: @"1"]) result = [self labelForKey: @"highest" inContext: context];
else if ([s hasPrefix: @"2"]) result = [self labelForKey: @"high" inContext: context];
else if ([s hasPrefix: @"4"]) result = [self labelForKey: @"low" inContext: context];
else if ([s hasPrefix: @"5"]) result = [self labelForKey: @"lowest" inContext: context];
}
}
}
@@ -242,7 +243,7 @@
{
NSString *s;
s = [self labelForKey:@"View Mail Folder"];
s = [self labelForKey:@"View Mail Folder" inContext: context];
s = [s stringByAppendingString:@": "];
s = [s stringByAppendingString:[self objectTitle]];
return s;
@@ -622,11 +623,12 @@
- (NSDictionary *) getUIDsInFolder: (SOGoMailFolder *) folder
withHeaders: (BOOL) includeHeaders
{
NSMutableDictionary *data;
NSArray *uids, *threadedUids, *headers;
NSRange r;
NSMutableDictionary *data;
SOGoMailAccount *account;
id quota;
NSRange r;
int count;
data = [NSMutableDictionary dictionary];
@@ -644,10 +646,14 @@
if (includeHeaders)
{
// Also retrieve the first headers, up to 'headersPrefetchMaxSize'
count = [[uids flattenedArray] count];
if (count > headersPrefetchMaxSize) count = headersPrefetchMaxSize;
NSArray *a;
a = [uids flattenedArray];
count = [a count];
if (count > headersPrefetchMaxSize)
count = headersPrefetchMaxSize;
r = NSMakeRange(0, count);
headers = [self getHeadersForUIDs: [[uids flattenedArray] subarrayWithRange: r]
headers = [self getHeadersForUIDs: [a subarrayWithRange: r]
inFolder: folder];
[data setObject: headers forKey: @"headers"];
@@ -744,7 +750,6 @@
noHeaders = [[[requestContent objectForKey: @"sortingAttributes"] objectForKey:@"noHeaders"] boolValue];
data = [self getUIDsInFolder: folder
withHeaders: !noHeaders];
[response appendContentString: [data jsonRepresentation]];
return response;
@@ -878,7 +883,7 @@
data = [NSDictionary dictionaryWithObjectsAndKeys:
@"No UID specified", @"error", nil];
return [self responseWithStatus: 404 /* Not Found */
andString: [data jsonRepresentation]];
andString: [data jsonRepresentation]];
}
uids = [data objectForKey: @"uids"];
+12
View File
@@ -118,6 +118,18 @@
return [accounts jsonRepresentation];
}
- (WOResponse *) mailAccountsAction
{
WOResponse *response;
NSString *s;
s = [self mailAccounts];
response = [self responseWithStatus: 200
andString: s];
return response;
}
- (NSString *) userNames
{
NSArray *accounts, *userNames;
+5
View File
@@ -342,6 +342,11 @@
actionClass = "UIxMailMainFrame";
actionName = "unseenCount";
};
mailAccounts = {
protectedBy = "View";
actionClass = "UIxMailMainFrame";
actionName = "mailAccounts";
};
// viewerTemplate = {
// protectedBy = "View";
// pageName = "UIxMailViewTemplate";
+7 -6
View File
@@ -183,7 +183,6 @@
SOGoWebAuthenticator *auth;
SOGoAppointmentFolders *calendars;
SOGoUserDefaults *ud;
SOGoSystemDefaults *sd;
SOGoUser *loggedInUser;
NSDictionary *params;
NSString *username, *password, *language, *domain, *remoteHost;
@@ -226,13 +225,15 @@
response = [self responseWithStatus: 200
andJSONRepresentation: json];
// We get the proper username for cookie creation. If we are using a multidomain
// environment with SOGoEnableDomainBasedUID, we could have to append the domain
// to the username. Also when SOGoEnableDomainBasedUID is enabled, we could be in
// the DomainLessLogin situation, so we would NOT add the domain. -getUIDForEmail
// has all the logic for this, so lets use it.
if ([domain isNotNull])
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
if ([sd enableDomainBasedUID] &&
[username rangeOfString: @"@"].location == NSNotFound)
username = [NSString stringWithFormat: @"%@@%@", username, domain];
username = [[SOGoUserManager sharedUserManager] getUIDForEmail: username];
}
authCookie = [auth cookieWithUsername: username
@@ -1,6 +1,7 @@
/* toolbar */
"Save and Close" = "Save and Close";
"Close" = "Close";
"Preferences saved" = "Preferences saved";
/* tabs */
"General" = "General";
+10
View File
@@ -255,6 +255,16 @@ static SoProduct *preferencesProduct = nil;
forKey: @"PreventInvitationsWhitelist"];
}
// Initialize some default values
if (![settings objectForKey: @"Calendar"])
[settings setObject: [NSMutableDictionary dictionary] forKey: @"Calendar"];
if (![settings objectForKey: @"Contact"])
[settings setObject: [NSMutableDictionary dictionary] forKey: @"Contact"];
if (![settings objectForKey: @"Mail"])
[settings setObject: [NSMutableDictionary dictionary] forKey: @"Mail"];
return [self _makeResponse: [[settings source] values]];
}
+1 -1
View File
@@ -1064,7 +1064,7 @@ static NSArray *reminderValues = nil;
if (!capabilities)
{
if ([self _sieveClient])
if ([self isSieveScriptsEnabled] && [self _sieveClient])
capabilities = [[self _sieveClient] capabilities];
else
capabilities = [NSArray array];
+33 -15
View File
@@ -94,7 +94,7 @@ static NSArray *tasksFields = nil;
@"c_classification", @"c_category",
@"c_partmails", @"c_partstates", @"c_owner",
@"c_iscycle", @"c_nextalarm",
@"c_recurrence_id", @"isException", @"editable",
@"c_recurrence_id", @"isException", @"viewable", @"editable",
@"erasable", @"ownerIsOrganizer", @"c_description", nil];
[eventsFields retain];
}
@@ -104,7 +104,7 @@ static NSArray *tasksFields = nil;
@"calendarName",
@"c_status", @"c_title", @"c_enddate",
@"c_classification", @"c_location", @"c_category",
@"editable", @"erasable",
@"viewable", @"editable", @"erasable",
@"c_priority", @"c_owner",
@"c_iscycle", @"c_nextalarm",
@"c_recurrence_id", @"isException", @"c_description", nil];
@@ -258,7 +258,7 @@ static NSArray *tasksFields = nil;
labelKey = [NSString stringWithFormat: @"%@_class%@",
type, [component objectForKey: @"c_classification"]];
[component setObject: [self labelForKey: labelKey]
[component setObject: [self labelForKey: labelKey inContext: context]
forKey: @"c_title"];
}
@@ -441,21 +441,35 @@ static NSArray *tasksFields = nil;
}
else
{
id foo;
foo = [currentFolder fetchCoreInfosFrom: startDate
currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
to: endDate
title: value
component: component];
currentInfos = [foo objectEnumerator];
component: component]
objectEnumerator];
}
owner = [currentFolder ownerInContext: context];
ownerUser = [SOGoUser userWithLogin: owner];
isErasable = ([owner isEqualToString: userLogin] || [[currentFolder aclsForUser: userLogin] containsObject: SOGoRole_ObjectEraser]);
while ((newInfo = [currentInfos nextObject]))
{
if ([fields containsObject: @"viewable"])
{
if ([owner isEqualToString: userLogin])
[newInfo setObject: [NSNumber numberWithInt: 1] forKey: @"viewable"];
else
{
role = [currentFolder roleForComponentsWithAccessClass: [[newInfo objectForKey: @"c_classification"] intValue]
forUser : userLogin];
if ([role isEqualToString: @"ComponentViewer"])
[newInfo setObject: [NSNumber numberWithInt: 1] forKey: @"viewable"];
else
[newInfo setObject: [NSNumber numberWithInt: 0] forKey: @"viewable"];
}
}
if ([fields containsObject: @"editable"])
{
if (folderIsRemote)
@@ -548,19 +562,19 @@ static NSArray *tasksFields = nil;
{
// Same day
if (forAllDay)
return [self labelForKey: @"Today"];
return [self labelForKey: @"Today" inContext: context];
else
return [dateFormatter formattedTime: date];
}
else if ([now dayOfCommonEra] - [date dayOfCommonEra] == 1)
{
// Yesterday
return [self labelForKey: @"Yesterday"];
return [self labelForKey: @"Yesterday" inContext: context];
}
else if ([date dayOfCommonEra] - [now dayOfCommonEra] == 1)
{
// Tomorrow
return [self labelForKey: @"Tomorrow"];
return [self labelForKey: @"Tomorrow" inContext: context];
}
else if (abs(delta = [date dayOfCommonEra] - [now dayOfCommonEra]) < 7)
{
@@ -573,7 +587,7 @@ static NSArray *tasksFields = nil;
return dayOfWeek;
else
// With the past 7 days
return [NSString stringWithFormat: [self labelForKey: @"last %@"], dayOfWeek];
return [NSString stringWithFormat: [self labelForKey: @"last %@" inContext: context], dayOfWeek];
}
else
{
@@ -695,7 +709,8 @@ static NSArray *tasksFields = nil;
calendarSettings = [NSMutableDictionary dictionary];
[us setObject: calendarSettings forKey: @"Calendar"];
}
[calendarSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", (ascending?1:0)], nil] forKey: submodule];
[calendarSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", [ascending intValue]], nil]
forKey: submodule];
[us synchronize];
}
}
@@ -731,10 +746,11 @@ static NSArray *tasksFields = nil;
* @apiSuccess (Success 200) {String[]} events.c_partmails Participants email addresses
* @apiSuccess (Success 200) {String[]} events.c_partstates Participants states
* @apiSuccess (Success 200) {String} events.c_owner Event's owner
* @apiSuccess (Success 200) {Number} events.c_iscycle 1 if the event is cyclic
* @apiSuccess (Success 200) {Number} events.c_iscycle 1 if the event is cyclic/recurring
* @apiSuccess (Success 200) {Number} events.c_nextalarm Epoch time of next alarm
* @apiSuccess (Success 200) {String} [events.c_recurrence_id] Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {Number} events.isException 1 if recurrence is an exception
* @apiSuccess (Success 200) {Number} events.viewable 1 if active user can view the event
* @apiSuccess (Success 200) {Number} events.editable 1 if active user can edit the event
* @apiSuccess (Success 200) {Number} events.erasable 1 if active user can erase the event
* @apiSuccess (Success 200) {Number} events.ownerIsOrganizer 1 if owner is also the organizer
@@ -1253,6 +1269,7 @@ _computeBlocksPosition (NSArray *blocks)
* @apiSuccess (Success 200) {Number} events.c_nextalarm Epoch time of next alarm
* @apiSuccess (Success 200) {String} [events.c_recurrence_id] Recurrence ID if event is cyclic
* @apiSuccess (Success 200) {Number} events.isException 1 if recurrence is an exception
* @apiSuccess (Success 200) {Number} events.viewable 1 if active user can view the event
* @apiSuccess (Success 200) {Number} events.editable 1 if active user can edit the event
* @apiSuccess (Success 200) {Number} events.erasable 1 if active user can erase the event
* @apiSuccess (Success 200) {Number} events.ownerIsOrganizer 1 if owner is also the organizer
@@ -1417,6 +1434,7 @@ _computeBlocksPosition (NSArray *blocks)
* @apiSuccess (Success 200) {Number} tasks.c_classification 0: Public, 1: Private, 2: Confidential
* @apiSuccess (Success 200) {String} tasks.c_location Location
* @apiSuccess (Success 200) {String} tasks.c_category Category
* @apiSuccess (Success 200) {Number} tasks.viewable 1 if task is viewable by the active user
* @apiSuccess (Success 200) {Number} tasks.editable 1 if task is editable by the active user
* @apiSuccess (Success 200) {Number} tasks.erasable 1 if task is erasable by the active user
* @apiSuccess (Success 200) {String} tasks.c_priority Priority (0-9)
@@ -20,14 +20,6 @@
#import <SOGoUI/UIxComponent.h>
@class NSString;
@class SOGoAppointmentFolder;
@interface UIxCalendarFolderLinksTemplate : UIxComponent
{
SOGoAppointmentFolder *calendar;
NSString *baseCalDAVURL, *basePublicCalDAVURL;
}
@end
@@ -28,89 +28,6 @@
@implementation UIxCalendarFolderLinksTemplate
- (id) init
{
if ((self = [super init]))
{
calendar = [self clientObject];
baseCalDAVURL = nil;
basePublicCalDAVURL = nil;
}
return self;
}
- (void) dealloc
{
[baseCalDAVURL release];
[basePublicCalDAVURL release];
[super dealloc];
}
- (NSString *) _baseCalDAVURL
{
NSString *davURL;
if (!baseCalDAVURL)
{
davURL = [[calendar realDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
baseCalDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
baseCalDAVURL = davURL;
[baseCalDAVURL retain];
}
return baseCalDAVURL;
}
- (NSString *) calDavURL
{
return [NSString stringWithFormat: @"%@/", [self _baseCalDAVURL]];
}
- (NSString *) webDavICSURL
{
return [calendar webDavICSURL];
}
- (NSString *) webDavXMLURL
{
return [calendar webDavXMLURL];
}
- (NSString *) _basePublicCalDAVURL
{
NSString *davURL;
if (!basePublicCalDAVURL)
{
davURL = [[calendar publicDavURL] absoluteString];
if ([davURL hasSuffix: @"/"])
basePublicCalDAVURL = [davURL substringToIndex: [davURL length] - 1];
else
basePublicCalDAVURL = davURL;
[basePublicCalDAVURL retain];
}
return basePublicCalDAVURL;
}
- (NSString *) publicCalDavURL
{
return [NSString stringWithFormat: @"%@/", [self _basePublicCalDAVURL]];
}
- (NSString *) publicWebDavICSURL
{
return [calendar publicWebDavICSURL];
}
- (NSString *) publicWebDavXMLURL
{
return [calendar publicWebDavXMLURL];
}
- (BOOL) isPublicAccessEnabled
{
// NOTE: This method is the same found in Common/UIxAclEditor.m
@@ -118,14 +35,4 @@
enablePublicAccess];
}
- (BOOL) isWebCalendar
{
return ([calendar isKindOfClass: [SOGoWebAppointmentFolder class]]);
}
- (NSString *) webCalendarURL
{
return [calendar folderPropertyValueInCategory: @"WebCalendars"];
}
@end
+1 -1
View File
@@ -842,7 +842,7 @@ static NSArray *reminderValues = nil;
clientObject = [self clientObject];
ownerUser = [SOGoUser userWithLogin: [clientObject ownerInContext: context]];
if ([clientObject isKindOfClass: [SOGoWebAppointmentFolder class]])
if ([[clientObject container] isKindOfClass: [SOGoWebAppointmentFolder class]])
rc = componentReadableOnly;
else
{
+1 -1
View File
@@ -193,7 +193,7 @@
actionName = "saveUserRights";
};
links = {
protectedBy = "View";
protectedBy = "Access Contents Information";
pageName = "UIxCalendarFolderLinksTemplate";
};
};
@@ -115,7 +115,6 @@
<md-icon>remove_circle</md-icon>
</md-button>
</div>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center">
<md-button class="sg-icon-button" type="button" ng-click="editor.addEmail()">
@@ -128,12 +127,25 @@
</div>
<!-- birthday -->
<md-input-container>
<label>
<var:string label:value="Birthday"/>
</label>
<input type="date" ng-model="editor.card.birthday"/>
</md-input-container>
<div class="section">
<div layout="row" layout-align="space-between end" ng-show="editor.card.birthday">
<label>
<var:string label:value="Birthday"/>
</label>
<md-datepicker ng-model="editor.card.birthday"><!-- birthday --></md-datepicker>
<md-button class="sg-icon-button" type="button" ng-click="editor.card.$delete('birthday', -1)">
<md-icon>remove_circle</md-icon>
</md-button>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center" ng-hide="editor.card.birthday">
<md-button class="sg-icon-button" type="button" ng-click="editor.addBirthday()">
<md-icon>add_circle</md-icon>
</md-button>
<label class="button-label">
<var:string label:value="Add Birthday"/>
</label>
</div>
</div>
<!-- phones -->
<div class="section">
@@ -6,14 +6,15 @@
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<md-dialog flex="40">
<md-dialog flex="60" flex-sm="100">
<md-toolbar class="sg-padded">
<md-icon class="material-icons sg-icon-toolbar-bg">link</md-icon>
<div class="md-toolbar-tools">
<div class="pseudo-input-container md-flex">
<label class="pseudo-input-label"><var:string label:value="Links to this Address Book"/></label>
<div class="pseudo-input-field sg-md-title"><var:string value="addressBook.displayName"/></div>
<div class="pseudo-input-field sg-md-title">{{links.addressbook.name}}</div>
</div>
<md-button class="md-icon-button" ng-click="close()">
<md-button class="md-icon-button" ng-click="links.close()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
@@ -24,7 +25,7 @@
<div class="sg-md-title"><var:string label:value="Authenticated User Access"/></div>
<md-input-container>
<label><var:string label:value="CardDAV URL"/></label>
<input var:value="cardDavURL" ng-readonly="true"/>
<input type="text" ng-model="links.addressbook.urls.cardDavURL" ng-readonly="true"/>
</md-input-container>
</div>
<var:if condition="isPublicAccessEnabled">
@@ -32,7 +33,7 @@
<div class="sg-md-title"><var:string label:value="Public Access"/></div>
<md-input-container>
<label><var:string label:value="CardDAV URL"/></label>
<input var:value="publicCardDavURL" ng-readonly="true"/>
<input type="text" ng-model="links.addressbook.urls.publicCardDavURL" ng-readonly="true"/>
</md-input-container>
</div>
</var:if>
@@ -9,65 +9,12 @@
className="UIxPageFrame"
title="title"
const:userDefaultsKeys="SOGoContactsCategories"
const:jsFiles="Common.js, Preferences.services.js, Contacts.js, Contacts.services.js">
const:jsFiles="vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, Common.js, Preferences.services.js, Mailer.services.js, Contacts.js, Contacts.services.js, vendor/angular-file-upload.min.js">
<script type="text/javascript">
var contactFolders = <var:string value="contactFolders" const:escapeHTML="NO" />;
</script>
<!--
<div id="uploadDialog" style="display: none" class="dialog left">
<div>
<h3><var:string label:value="Import Cards"/></h3>
<p class="prompt"><var:string label:value="Select a vCard or LDIF file."/></p>
<form const:href="" name="uploadForm" id="uploadForm" method="post"
enctype="multipart/form-data"
onsubmit="return AIM.submit(this, {'onStart' : validateUploadForm,
'onComplete' : uploadCompleted})">
<p class="prompt"><input type="file" name="contactsFile" id="contactsFile" class="textField" required="required" />
<a href="#" class="button actionButton" id="uploadSubmit"
onclick="if($('uploadForm').onsubmit()) $('uploadForm').submit()">
<span><var:string label:value="Upload" /></span></a>
<a href="#" class="button" const:id="uploadCancel">
<span><var:string label:value="Cancel" /></span></a></p>
</form>
<hr/>
</div>
</div>
<div id="uploadResults" dropdown-content="dropdown-content" class="f-dropdown">
<div>
<h3><var:string label:value="Import Cards"/></h3>
<p id="uploadResultsContent">!- empty -</p>
<p><a href="#" class="button" const:id="uploadOK">
<span><var:string label:value="Done" /></span></a></p>
<hr/>
</div>
</div>
<ul class="f-dropdown" dropdown-content="dropdown-content" id="contactMenu">
<li><var:string label:value="Properties" /></li>
<li><var:string label:value="Categories" /></li>
<li>!- separator -</li>
<li><var:string label:value="Write" /></li>
<li><var:string label:value="Instant Message" /></li>
<li>!- separator -</li>
<li><var:string label:value="Delete" /></li>
<li>!- separator -</li>
<li><var:string label:value="Move To" /></li>
<li><var:string label:value="Copy To" /></li>
<li><var:string label:value="Export" /></li>
<li><var:string label:value="View Raw Source" /></li>
</ul>
-->
<!--
MAIN CONTENT ROW
Content of the application view injected injected in the element bellow
MUST be the first html element after body
SHOULD be a main tag (with role="main")
Templates script tag wrappers goes next
-->
<main class="view md-layout-fill" ui-view="addressbooks" layout="row" ng-controller="navController"><!-- addressbooks list --></main>
<main class="view layout-fill" ui-view="addressbooks" layout="row" ng-controller="navController"><!-- addressbooks list --></main>
<!-- TEMPLATE SCRIPT WRAPPER -->
<script type="text/ng-template" id="UIxContactFoldersView">
@@ -125,6 +72,12 @@
<var:string label:value="Delete"/>
</md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item>
<md-button type="button" ng-click="app.importCards($event, folder)">
<var:string label:value="Import"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="app.exportCards()">
<var:string label:value="Export"/>
@@ -219,17 +172,16 @@
<!-- </div> -->
</md-sidenav>
<section layout="column" class="sg-app-content md-layout-fill" ui-view="addressbook"><!-- contacts list --></section>
<section layout="column" class="sg-app-content layout-fill" ui-view="addressbook"><!-- contacts list --></section>
</script>
<script type="text/ng-template" id="addressbook">
<md-toolbar layout="column" layout-align="space-between start" class="md-tall toolbar-main">
<div class="md-toolbar-tools md-toolbar-tools-top sg-padded" layout="row" layout-align="space-between start">
<div class="md-toolbar-tools md-toolbar-tools-top" layout="row" layout-align="space-between start">
<var:component className="UIxTopnavToolbarTemplate" />
</div>
<div class="md-toolbar-tools" layout="row" layout-align="space-between center"
ng-show="addressbook.selectedFolder.$selectedCount() == 0">
<div class="view-list" layout="row" layout-align="space-between center"
ng-hide="addressbook.mode.search">
<div class="sg-toolbar-group">
@@ -280,9 +232,10 @@
</md-menu-item>
<md-menu-divider> <!-- divider --></md-menu-divider>
<md-menu-item >
<md-button ng-click="addressbook.sort()">
<md-button ng-href="#">
<md-checkbox
ng-model="addressbook.selectedFolder.$query.asc"
ng-change="addressbook.sort(addressbook.selectedFolder.constructor.$query.sort)"
ng-model="addressbook.selectedFolder.constructor.$query.asc"
ng-true-value="0"
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
</md-button>
@@ -315,17 +268,24 @@
</md-input-container>
</div>
</div>
<div layout="row" layout-align="start center" ng-show="addressbook.selectedFolder.$selectedCount() > 0">
<md-button class="sg-icon-button" ng-click="addressbook.unselectCards()">
<md-icon>arrow_back</md-icon>
</md-button>
<label>{{addressbook.selectedFolder.$selectedCount()}} selected</label>
<!-- multiple selection mode -->
<div class="md-toolbar-tools" layout="row" layout-align="space-between center"
ng-show="addressbook.selectedFolder.$selectedCount() > 0">
<div class="view-list" layout="row" layout-align="space-between center">
<div class="sg-toolbar-group">
<md-button class="sg-icon-button" ng-click="addressbook.unselectCards()">
<md-icon>arrow_back</md-icon>
</md-button>
<label>{{addressbook.selectedFolder.$selectedCount()}} <var:string label:value="selected"/></label>
</div>
<div class="sg-toolbar-group-last">
<md-button class="sg-icon-button" ng-click="addressbook.selectAll()">
<md-tooltip md-direction="left"><var:string label:value="Select All"/></md-tooltip>
<md-icon>select_all</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="addressbook.confirmDeleteSelectedCards()">
<md-button class="sg-icon-button"
ng-show="addressbook.selectedFolder.acls.objectEraser"
ng-click="addressbook.confirmDeleteSelectedCards()">
<md-icon>delete</md-icon>
</md-button>
<md-menu>
@@ -352,7 +312,7 @@
</md-button>
<md-menu-content width="2">
<md-menu-item>
<md-button>
<md-button ng-click="addressbook.newMessageWithSelectedCards($event)">
<var:string label:value="Write"/>
</md-button>
</md-menu-item>
@@ -363,9 +323,11 @@
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
</div>
</div>
</md-toolbar>
<div layout="row" class="md-flex" layout-align="space-between">
<div layout="row" class="md-flex">
<div class="view-list" layout="column">
<md-content id="contactsList" layout="column" class="md-flex">
<header class="sg-md-subheader sg-md-subheader--fixed">
@@ -376,46 +338,57 @@
</header>
<md-virtual-repeat-container class="md-flex">
<md-list class="sg-section-list">
<div md-virtual-repeat="currentCard in addressbook.selectedFolder.cards">
<div md-virtual-repeat="currentCard in addressbook.selectedFolder.cards" md-item-size="72">
<md-list-item
ng-class="{'sg-active': currentCard.id == addressbook.selectedFolder.selectedCard}"
ng-click="addressbook.selectCard(currentCard)"
ui-sref="app.addressbook.card.view({addressbookId: addressbook.selectedFolder.id, cardId: currentCard.id})">
<!-- ui-sref-active="sg-active" -->
<div class="sg-selected-avatar" ng-show="currentCard.selected"
ng-click="currentCard.selected = !currentCard.selected">
<!-- selected avatar -->
</div>
<sg-avatar-image class="md-tile-left"
ng-show="addressbook.notSelectedComponent(currentCard, 'vcard')"
ng-click="currentCard.selected = !currentCard.selected"
sg-email="currentCard.$preferredEmail(addressbook.selectedFolder.$query)"
size="48">
<!-- contact avatar -->
</sg-avatar-image>
<div class="sg-list-avatar"
ng-show="addressbook.notSelectedComponent(currentCard, 'vlist')"
ng-click="currentCard.selected = !currentCard.selected">
<!-- list avatar -->
</div>
<div class="sg-selected-avatar" ng-show="currentCard.selected"
ng-click="currentCard.selected = !currentCard.selected">
<!-- selected avatar -->
</div>
<sg-avatar-image class="md-tile-left"
ng-show="addressbook.notSelectedComponent(currentCard, 'vcard')"
ng-click="currentCard.selected = !currentCard.selected"
sg-email="currentCard.$preferredEmail(addressbook.selectedFolder.constructor.$query)"
size="40">
<!-- contact avatar -->
</sg-avatar-image>
<div class="sg-list-avatar"
ng-show="addressbook.notSelectedComponent(currentCard, 'vlist')"
ng-click="currentCard.selected = !currentCard.selected">
<!-- list avatar -->
</div>
<div class="sg-tile-content">
<div class="sg-md-subhead-multi" ng-bind-html="currentCard.$fullname()"><!-- cn --></div>
<div class="sg-md-body-multi">{{currentCard.$preferredEmail(addressbook.selectedFolder.$query)}}</div>
<div class="sg-md-body-multi">{{currentCard.$preferredEmail(addressbook.selectedFolder.constructor.$query)}}</div>
</div>
</md-list-item>
</div>
</md-list>
</md-virtual-repeat-container>
<div class="sg-progress-circular-floating"
ng-show="addressbook.selectedFolder.$isLoading">
<md-progress-circular class="md-accent"
md-mode="indeterminate"
md-diameter="32"><!-- progress --></md-progress-circular>
</div>
<md-button class="md-fab md-fab-bottom-right md-accent"
label:aria-label="New Contact"
ng-show="addressbook.selectedFolder.acls.objectCreator"
ng-click="addressbook.newComponent($event)">
<md-icon>add</md-icon>
</md-button>
</md-content>
</div>
<div id="detailView" class="view-detail ng-cloak" layout="column" ui-view="card"
ng-show="addressbook.selectedFolder.selectedCard"><!-- card view --></div>
<md-content id="detailView" class="view-detail md-hue-1" layout="column" layout-align="center center"
ng-class="{ 'sg-close': !addressbook.selectedFolder.selectedCard }"
ui-view="card">
<md-input-container class="hide-sm md-hue-1" style="flex-grow: 0">
<label class="sg-md-title"><var:string label:value="No contact selected"/></label>
</md-input-container>
</md-content>
</div>
</script>
@@ -5,7 +5,7 @@
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<md-card class="viewer md-flex">
<md-card class="viewer flex-sm">
<md-card-content>
<header class="msg-header">
<div ng-show="editor.card.tag == 'vcard'">
@@ -30,18 +30,19 @@
<div class="sg-icon-bar--vertical">
<md-button class="sg-icon-button show-sm"
label:aria-label="Close"
ng-click="toggleDetailView()">
ng-click="editor.close()">
<md-icon>close</md-icon>
</md-button>
<md-button class="sg-icon-button"
label:aria-label="Edit"
ng-show="editor.currentFolder.isEditable"
ng-show="editor.currentFolder.acls.objectEditor"
ui-sref="app.addressbook.card.editor({addressbookId: editor.currentFolder.id, cardId: editor.card.id})">
<md-tooltip md-direction="left"><var:string label:value="Edit"/></md-tooltip>
<md-icon>mode_edit</md-icon>
</md-button>
<md-button class="sg-icon-button"
label:aria-label="Delete"
ng-show="editor.currentFolder.acls.objectEraser"
ng-click="editor.confirmDelete(editor.card)">
<md-tooltip md-direction="left"><var:string label:value="Delete"/></md-tooltip>
<md-icon>delete</md-icon>
@@ -53,7 +54,13 @@
</md-button>
<md-menu-content>
<md-menu-item>
<md-button aria-label="View Raw Source"
<md-button label:aria-label="Export"
ng-click="editor.exportCard()">
<var:string label:value="Export"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button label:aria-label="View Raw Source"
ng-click="editor.viewRawSource($event)">
<var:string label:value="View Raw Source"/>
</md-button>
@@ -65,14 +72,14 @@
</header>
<section class="msg-body">
<div class="pseudo-input-container" ng-show="editor.card.birthday">
<div class="pseudo-input-container" ng-show="editor.card.$birthday().length">
<div class="key">
<label class="pseudo-input-label">
<var:string label:value="Birthday"/>
</label>
</div>
<div class="pseudo-input-field">
<span>{{editor.card.$birthday() | date}}</span>
<span>{{editor.card.$birthday()}}</span>
</div>
</div>
@@ -111,7 +118,8 @@
</div>
<div class="pseudo-input-field">
<a href="mailto:{{email.value}}">{{email.value}}</a>
<a href="#" ng-bind="email.value"
ng-click="addressbook.newMessageWithRecipient($event, email.value, editor.card.$fullname())"><!-- recipient --></a>
</div>
</div>
@@ -165,5 +173,4 @@
</section>
</md-card-content>
</md-card>
</container>
@@ -7,6 +7,7 @@
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<var:string value="cssContent" const:escapeHTML="NO" />
<div class="SOGoHTMLMail-CSS-Delimiter mailer_htmlcontent"
><var:string value="flatContentAsString" const:escapeHTML="NO" /></div>
<div class="SOGoHTMLMail-CSS-Delimiter mailer_htmlcontent">
<var:string value="flatContentAsString" const:escapeHTML="NO" />
</div>
</container>
+71 -33
View File
@@ -6,15 +6,17 @@
xmlns:label="OGo:label">
<md-dialog flex="80" flex-sm="100">
<md-toolbar class="md-padding">
<md-toolbar class="sg-padded--right">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">edit</md-icon>
<!-- FROM -->
<sg-avatar-image class="md-tile-left" hide-sm="hide-sm" sg-email="editor.message.editable.from" size="32"><!-- avatar --></sg-avatar-image>
<!-- from -->
<sg-avatar-image class="md-tile-left" hide-sm="hide-sm"
sg-email="editor.message.editable.from"
size="32"><!-- avatar --></sg-avatar-image>
<md-input-container flex="flex">
<label><var:string label:value="From"/></label>
<md-select name="from"
ng-model="editor.message.editable.from">
ng-model="editor.message.editable.from">
<md-option ng-value="identity" ng-repeat="identity in editor.identities">{{identity}}</md-option>
</md-select>
</md-input-container>
@@ -22,71 +24,107 @@
<md-button class="sg-icon-button" ng-click="editor.send()">
<md-icon>send</md-icon>
</md-button>
<md-button class="sg-icon-button " ng-click="editor.message.$save()">
<md-button class="sg-icon-button" ng-click="editor.message.$save()">
<md-icon>save</md-icon>
</md-button>
<md-button class="sg-icon-button " ng-click="editor.cancel()">
<md-button class="sg-icon-button" ng-click="editor.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</div>
</md-toolbar>
<md-dialog-content>
<header>
<!-- TO / CC/ BCC / SUBJECT / ATTACHMENTS -->
<div class="msg-header-content">
<!-- to -->
<div class="pseudo-input-container">
<label class="pseudo-input-label">
<var:string label:value="To"/>
</label>
<md-chips ng-model="editor.message.editable.to">
<md-chips ng-model="editor.message.editable.to"
md-on-append="editor.addRecipient($chip)">
<md-autocomplete
md-selected-item="editor.autocomplete.to.selected"
class="sg-chips-autocomplete"
md-search-text="editor.autocomplete.to.searchText"
md-selected-item="editor.autocomplete.to.selected"
md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)"
md-min-length="3"
md-delay="300"
md-no-cache="true"
label:placeholder="Add a recipient">
<span md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user}}</span>
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- cc -->
<div class="pseudo-input-container" ng-hide="editor.hideCc">
<label class="pseudo-input-label">
<var:string label:value="Cc"/>
</label>
<md-chips ng-model="editor.message.editable.cc">
<md-chips ng-model="editor.message.editable.cc"
md-on-append="editor.addRecipient($chip)">
<md-autocomplete
md-selected-item="editor.autocomplete.cc.selected"
class="sg-chips-autocomplete"
md-search-text="editor.autocomplete.cc.searchText"
md-selected-item="editor.autocomplete.cc.selected"
md-items="user in editor.contactFilter(editor.autocomplete.cc.searchText)"
label:placeholder="Add a recipient">
<span md-highlight-text="editor.autocomplete.cc.searchText"
md-highlight-flags="^i">{{user}}</span>
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- bcc -->
<div class="pseudo-input-container" ng-hide="editor.hideBcc">
<label class="pseudo-input-label">
<var:string label:value="Bcc"/>
</label>
<md-chips ng-model="editor.message.editable.bcc">
<md-chips ng-model="editor.message.editable.bcc"
md-on-append="editor.addRecipient($chip)">
<md-autocomplete
class="sg-chips-autocomplete"
md-selected-item="editor.autocomplete.bcc.selected"
md-search-text="editor.autocomplete.bcc.searchText"
md-items="user in editor.contactFilter(editor.autocomplete.bcc.searchText)"
label:placeholder="Add a recipient">
<span md-highlight-text="editor.autocomplete.bcc.searchText"
md-highlight-flags="^i">{{user}}</span>
<md-item-template>
<span class="md-contact-suggestion">
<span class="md-contact-name"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$fullname}}</span>
<span class="md-contact-email"
md-highlight-text="editor.autocomplete.to.searchText"
md-highlight-flags="^i">{{user.$$email}}</span>
</span>
</md-item-template>
</md-autocomplete>
<md-chip-template>{{$chip}}</md-chip-template>
</md-chips>
</div>
<!-- subject -->
<md-input-container>
<label>
<var:string label:value="Subject"/>
@@ -95,7 +133,7 @@
</md-input-container>
</div>
<!-- TOOLBAR TO SHOW CC/BCC/ATTACHMENT FIELDS -->
<!-- toolbar to show cc/bcc/attachment fields -->
<div layout="column" layout-align="start end">
<md-button class="sg-icon-button " ng-show="editor.hideCc" ng-click="editor.hideCc = false">Cc</md-button>
<md-button class="sg-icon-button " ng-show="editor.hideBcc" ng-click="editor.hideBcc = false">Bcc</md-button>
@@ -105,7 +143,7 @@
</md-button>
<md-menu-content width="4">
<md-menu-item>
<md-button>
<md-button ng-href="#">
<md-checkbox ng-model="editor.message.editable.receipt">
<var:string label:value="Return Receipt"/>
</md-checkbox>
@@ -161,19 +199,19 @@
<!-- TOOLBAR BUTTONS -->
<div class="md-actions">
<div layout="row" layout-align="space-between center" layout-fill="layout-fill">
<div>
<md-button>
<md-icon>attach_file</md-icon>
<label for="file-input">
Attach
<div>
<!-- md-icon does not play well with Firefox - makes the
file input never appear. This should eventually be
fixed in Angular Material -->
<label class="md-button" for="file-input">
<span><var:string label:value="Attach"/></span>
</label>
</md-button>
<input id="file-input" type="file"
nv-file-select="nv-file-select"
multiple="multiple"
uploader="editor.uploader"
ng-show="false"/>
</div>
<input id="file-input" type="file"
nv-file-select="nv-file-select"
multiple="multiple"
uploader="editor.uploader"
ng-show="false"/>
</div>
<div>
<!-- FILES ALREADY UPLOADED, FOR EXAMPLE WHEN WE FORWARD A
MAIL WITH ATTACHMENTS -->
+42 -34
View File
@@ -5,7 +5,6 @@
xmlns:label="OGo:label">
<div class="view-list" layout="column">
<md-content id="messagesList" layout="column" class="md-flex">
<md-progress-linear ng-show="mailbox.selectedFolder.$isLoading" md-mode="indeterminate"><!-- progress --></md-progress-linear>
<header class="sg-md-subheader sg-md-subheader--fixed">
<h2 class="md-default-theme sg-md-subhead-solo fg-sogoBlue-700">
<span ng-show="mailbox.selectedFolder.$messages.length > 0">{{mailbox.selectedFolder.$messages.length}} <var:string label:value="messages"/></span>
@@ -14,39 +13,43 @@
</header>
<md-virtual-repeat-container class="md-flex">
<md-list class="sg-section-list">
<div md-virtual-repeat="currentMessage in mailbox.selectedFolder.$messages">
<md-list-item
ng-class="{'sg-active': currentMessage.uid == mailbox.selectedFolder.selectedMessage, unread: !currentMessage.isread}"
ng-click="mailbox.selectMessage(currentMessage)"
ui-sref="mail.account.mailbox.message({accountId: mailbox.account.id, mailboxId: (mailbox.selectedFolder.path | encodeUri), messageId: currentMessage.uid})">
<!-- ui-sref-active="sg-active"> -->
<div class="sg-selected-avatar"
ng-show="currentMessage.selected"
ng-click="currentMessage.selected = !currentMessage.selected"><!-- selected avatar --></div>
<sg-avatar-image class="md-tile-left"
ng-show="!currentMessage.selected"
ng-click="currentMessage.selected = !currentMessage.selected"
sg-email="currentMessage['from'][0].email"
size="48"><!-- avatar --></sg-avatar-image>
<div class="sg-tile-content">
<span class="msg-date"
ng-bind-html="currentMessage.relativedate"><!-- date --></span>
<div class="sg-md-subhead-multi">{{currentMessage.$shortAddress('from')}}</div>
<div class="sg-md-body-multi">{{currentMessage.subject}}</div>
<i class="icon-ion-refresh"
ng-hide="mailbox.selectedFolder.$loadMessage(currentMessage.uid)"><!-- loading --></i>
</div>
<div class="sg-tile-icons">
<md-icon ng-show="currentMessage.priority == 'highest' || currentMessage.priority == 'high'">warning</md-icon>
<md-icon ng-show="currentMessage.isflagged">star</md-icon>
<md-icon ng-show="currentMessage.isanswered">reply</md-icon>
<md-icon ng-show="currentMessage.isforwarded">forward</md-icon>
<md-icon ng-show="currentMessage.hasattachment">attach_file</md-icon>
</div>
</md-list-item>
</div>
<md-list-item
md-virtual-repeat="currentMessage in mailbox.selectedFolder"
md-on-demand="md-on-demand"
ng-class="{'sg-active': currentMessage.uid == mailbox.selectedFolder.selectedMessage, unread: !currentMessage.isread}"
ng-click="mailbox.selectMessage(currentMessage)"
ui-sref="mail.account.mailbox.message({accountId: mailbox.account.id, mailboxId: (mailbox.selectedFolder.path | encodeUri), messageId: currentMessage.uid})">
<!-- ui-sref-active="sg-active"> -->
<div class="sg-selected-avatar"
ng-show="currentMessage.selected"
ng-click="currentMessage.selected = !currentMessage.selected"><!-- selected avatar --></div>
<sg-avatar-image class="md-tile-left"
ng-show="!currentMessage.selected"
ng-click="currentMessage.selected = !currentMessage.selected"
sg-email="::currentMessage.from[0].email"
size="48"><!-- avatar --></sg-avatar-image>
<div class="sg-tile-content">
<span class="msg-date"
ng-bind-html="currentMessage.relativedate"><!-- date --></span>
<div class="sg-md-subhead-multi">{{currentMessage.$shortAddress('from')}}</div>
<div class="sg-md-body-multi">{{currentMessage.subject}}</div>
</div>
<div class="sg-tile-icons">
<md-icon ng-show="currentMessage.priority == 'highest' || currentMessage.priority == 'high'">warning</md-icon>
<md-icon ng-show="currentMessage.isflagged">star</md-icon>
<md-icon ng-show="currentMessage.isanswered">reply</md-icon>
<md-icon ng-show="currentMessage.isforwarded">forward</md-icon>
<md-icon ng-show="currentMessage.hasattachment">attach_file</md-icon>
</div>
</md-list-item>
</md-list>
</md-virtual-repeat-container>
<div class="sg-progress-circular-floating"
ng-show="mailbox.selectedFolder.$isLoading">
<md-progress-circular class="md-accent"
md-mode="indeterminate"
md-diameter="32"><!-- progress --></md-progress-circular>
</div>
<md-button class="md-fab md-fab-bottom-right md-accent"
label:aria-label="Write a new message"
ng-click="mailbox.newMessage($event)">
@@ -55,7 +58,12 @@
</md-content>
</div>
<div id="detailView" class="view-detail ng-cloak" layout="column" ui-view="message"
ng-show="mailbox.selectedFolder.selectedMessage"><!-- message view --></div>
<md-content id="detailView" class="view-detail md-hue-1" layout="column" layout-align="center center"
ng-class="{ 'sg-close': !mailbox.selectedFolder.selectedMessage }"
ui-view="message">
<md-input-container class="hide-sm md-hue-1" style="flex-grow: 0">
<label class="sg-md-title"><var:string label:value="No message selected"/></label>
</md-input-container>
</md-content>
</container>
+20 -23
View File
@@ -221,13 +221,13 @@
Templates script tag wrappers go next
-->
<main class="view md-layout-fill" ui-view="mailboxes" layout="row" ng-controller="navController"><!-- mailboxes list --></main>
<main class="view layout-fill" ui-view="mailboxes" layout="row" ng-controller="navController"><!-- mailboxes list --></main>
<!-- TEMPLATE SCRIPT WRAPPER -->
<script type="text/ng-template" id="UIxMailMainFrame">
<!-- Sidenav -->
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1 md-layout-fill" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1 layout-fill" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
<var:component className="UIxSidenavToolbarTemplate" />
<md-content md-scroll-y="md-scroll-y" class="md-flex">
<section ng-repeat="account in app.accounts track by account.id">
@@ -235,17 +235,17 @@
<div layout="row" layout-align="space-between center">
<span>{{account.name}}</span>
<div>
<md-button class="sg-icon-button"
label:aria-label="New Folder..."
ng-click="app.newFolder(account)">
<md-icon>add_circle_outline</md-icon>
</md-button>
<md-button class="sg-icon-button"
ng-show="account.id == 0"
label:aria-label="Delegation..."
ng-click="app.delegate(account)">
<md-icon>people</md-icon>
</md-button>
<md-button class="sg-icon-button"
label:aria-label="New Folder..."
ng-click="app.newFolder(account)">
<md-icon>add_circle_outline</md-icon>
</md-button>
<md-button class="sg-icon-button"
ng-show="account.id == 0"
label:aria-label="Delegation..."
ng-click="app.delegate(account)">
<md-icon>people</md-icon>
</md-button>
</div>
</div>
</md-subheader>
@@ -342,18 +342,14 @@
</md-content>
</md-sidenav>
<section layout="column" class="sg-app-content md-layout-fill" ui-view="mailbox"><!-- messages list --></section>
<section layout="column" class="sg-app-content layout-fill" ui-view="mailbox"><!-- messages list --></section>
</script>
<script type="text/ng-template" id="UIxMailFolderTemplate">
<md-toolbar layout="column" layout-align="space-between start" class="md-tall toolbar-main">
<div class="md-toolbar-tools md-toolbar-tools-top sg-padded" layout="row" layout-align="space-between start">
<md-toolbar layout="column" layout-align="space-between start" class="md-tall toolbar-main" >
<div class="md-toolbar-tools md-toolbar-tools-top"
layout="row" layout-align="space-between start">
<var:component className="UIxTopnavToolbarTemplate" />
<div class="sg-toolbar-group-last">
<md-button class="sg-icon-button" label:aria-label="More">
<md-icon>more_vert</md-icon>
</md-button>
</div>
</div>
<div class="md-toolbar-tools" layout="row" layout-align="space-between center"
ng-show="mailbox.selectedFolder.$selectedCount() == 0">
@@ -398,9 +394,10 @@
</md-button>
</md-menu-item>
<md-menu-divider> <!-- divider --></md-menu-divider>
<md-menu-item >
<md-button ng-click="mailbox.selectedFolder.$filter()">
<md-menu-item>
<md-button ng-href="#">
<md-checkbox
ng-change="mailbox.selectedFolder.$filter()"
ng-model="mailbox.service.$query.asc"
ng-true-value="0"
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
+38 -8
View File
@@ -20,10 +20,18 @@
<label class="pseudo-input-label">
<var:string label:value="From"/>
</label>
<div class="pseudo-input-field">
<a href="#"
ng-bind="viewer.message.from[0].full"
ng-click="viewer.newMessage($event, viewer.message.from[0])"><!-- from --></a>
<div layout="row" layout-align="start center">
<sg-avatar-image class="md-tile-left"
sg-email="viewer.message.from[0].email"
size="48">
<!-- contact avatar -->
</sg-avatar-image>
<div class="md-list-item-text">
<span>{{ viewer.message.from[0].name }}</span><br/>
<a class="md-caption" href="#"
ng-bind="viewer.message.from[0].email"
ng-click="viewer.newMessage($event, viewer.message.from[0])"><!-- from --></a>
</div>
</div>
</div>
@@ -31,10 +39,26 @@
<label class="pseudo-input-label">
<var:string label:value="To"/>
</label>
<div class="pseudo-input-field" ng-hide="viewer.message.$showDetailedRecipients">
<a href="#" ng-click="viewer.message.showDetailedRecipients()">{{viewer.message.$shortRecipients()}}</a>
</div>
<div class="pseudo-input-field" ng-show="viewer.message.$showDetailedRecipients">
<span ng-repeat="recipient in viewer.message.to">
<a href="#" ng-bind="recipient.full"
ng-click="viewer.newMessage($event, recipient)"><!-- recipient --></a>
</span>
</div>
</div>
<div class="pseudo-input-container--compact" ng-show="viewer.message.$showDetailedRecipients">
<label class="pseudo-input-label" ng-show="viewer.message.cc.length > 0">
<var:string label:value="Cc"/>
</label>
<div class="pseudo-input-field">
<a href="#"
ng-bind="viewer.message.to[0].full"
ng-click="viewer.newMessage($event, viewer.message.to[0])"><!-- to --></a>
<span ng-repeat="recipient in viewer.message.cc">
<a href="#" ng-bind="recipient.full"
ng-click="viewer.newMessage($event, recipient)"><!-- recipient --></a>
</span>
</div>
</div>
@@ -61,7 +85,7 @@
<div class="sg-icon-bar--vertical">
<md-button class="sg-icon-button show-sm"
label:aria-label="Close"
ng-click="toggleDetailView()">
ng-click="viewer.close()">
<md-icon>close</md-icon>
</md-button>
<!-- todo: Replace md-tooltip values by localizable string variable -->
@@ -106,6 +130,12 @@
<var:string label:value="Load Images"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button label:aria-label="Save As..."
ng-click="viewer.saveMessage()">
<var:string label:value="Save As..."/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button label:aria-label="View Message Source"
ng-click="viewer.viewRawSource($event)">
+1 -1
View File
@@ -15,7 +15,7 @@
MUST be the first html element after body
SHOULD be a main tag (with role="main")
-->
<main class="view md-layout-fill md-layout-padding" ui-view="login" layout="row" layout-align="center start">
<main class="view layout-fill layout-padding" ui-view="login" layout="row" layout-align="center start">
<md-content class="md-padding" md-scroll-y="true">
<div class="sg-login" ng-controller="LoginController as app">
@@ -9,17 +9,24 @@
xmlns:label="OGo:label"
className="UIxPageFrame"
>
<md-dialog>
<md-dialog-content>
<form id="mainForm" name="accountForm" var:href="ownPath">
<md-dialog flex="50" flex-sm="100">
<md-toolbar class="md-padding">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">account_box</md-icon>
<md-input-container>
<label><var:string label:value="Account Name"/></label>
<input type="text" required="required"
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.name"/>
</md-input-container>
<md-button type="button" class="sg-icon-button " ng-click="$AccountDialogController.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<form id="mainForm" name="accountForm" var:href="ownPath">
<md-input-container>
<label><var:string label:value="Server Name"/></label>
@@ -130,7 +137,6 @@
</form>
</md-dialog-content>
<div class="md-actions">
<md-button type="button" ng-click="$AccountDialogController.cancel()"><var:string label:value="Cancel"/></md-button>
<md-button ng-disabled="$AccountDialogController.accountForm.$invalid" ng-click="$AccountDialogController.save()"><var:string label:value="Save"/></md-button>
</div>
</md-dialog>
+102 -66
View File
@@ -7,23 +7,31 @@
xmlns:label="OGo:label"
xmlns:rsrc="OGo:url"
xmlns:uix="OGo:uix"><var:string var:value="doctype" const:escapeHTML="NO" />
<md-dialog flex="50">
<md-dialog flex="50" flex-sm="100">
<form id="mainForm" var:href="ownPath">
<md-toolbar class="md-padding">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">filter_list</md-icon>
<md-input-container>
<label><var:string label:value="Filter name:"/></label>
<input class="md-title" type="text" ng-model="filter.name" required="required"/>
</md-input-container>
<md-button type="button" class="sg-icon-button " ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<script type="text/javascript">
var filterId = '<var:string value="filterId"/>';
var sieveFolderEncoding = '<var:string value="sieveFolderEncoding"/>';
var mailTags = <var:string value="labels" const:escapeHTML="NO"/>;
</script>
<form id="mainForm" var:href="ownPath">
<div id="filterNameContainer" class="container">
<md-input-container>
<label><var:string label:value="Filter name:"/></label>
<input const:name="filterName" type="text" ng-model="filter.name"/>
</md-input-container>
</div>
<div id="filterMatchContainer" class="container">
<var:string label:value="For incoming messages that"/>
<md-select const:name="matchType" const:id="matchType" ng-model="filter.match">
<div layout="row" layout-align="start center">
<div><var:string label:value="For incoming messages that"/></div>
<md-input-container class="md-flex">
<md-select ng-model="filter.match" required="required">
<md-option const:value="all">
<var:string label:value="match all of the following rules:"/>
</md-option>
@@ -34,107 +42,135 @@
<var:string label:value="match all messages"/>
</md-option>
</md-select>
</div>
</md-input-container>
</div>
<!-- CONDITIONS -->
<div id="filterRulesContainer" class="container">
<div id="filterRules"><!-- empty -->
<md-list>
<md-list-item ng-repeat="rule in filter.rules">
<!-- CONDITIONS -->
<div layout="column">
<div id="filterRules"><!-- empty -->
<md-list>
<md-list-item ng-repeat="rule in filter.rules">
<md-input-container flex="25">
<md-select ng-model="rule.field">
<md-option ng-value="key" ng-repeat="(key, value) in fieldLabels">{{ value }}</md-option>
</md-select>
</md-input-container>
<input type="text" ng-show="rule.field ==
'header'" ng-model="rule.custom_header"/>
<md-input-container flex="25" ng-show="rule.field == 'header'">
<input type="text" ng-model="rule.custom_header"/>
</md-input-container>
<md-select ng-show="rule.field =='size'" ng-model="rule.operator">
<md-input-container flex="25" ng-show="rule.field == 'size'">
<md-select ng-model="rule.operator">
<md-option ng-value="key" ng-repeat="(key, value) in numberOperatorLabels">
{{ value }}
</md-option>
</md-select>
</md-input-container>
<md-select ng-show="rule.field !='size'" ng-model="rule.operator">
<md-input-container flex="25" ng-show="rule.field != 'size'">
<md-select ng-model="rule.operator">
<md-option ng-value="key" ng-repeat="(key, value) in textOperatorLabels">
{{ value }}
</md-option>
</md-select>
</md-input-container>
<md-input-container class="md-flex">
<input type="text" ng-model="rule.value"/>
</md-input-container>
<md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterRule($index)">
<md-icon>remove</md-icon>
</md-button>
<md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterRule($index)">
<md-icon>remove_circle</md-icon>
</md-button>
</md-list-item>
</md-list>
</div>
<md-button class="sg-icon-button" type="button"
ng-click="addMailFilterRule($event)">
<md-icon>add</md-icon>
</md-button>
</md-list-item>
</md-list>
</div>
<!-- ACTIONS -->
<div id="filterActionsContainer" class="container">
<var:string label:value="Perform these actions:"/><br/>
<div id="filterActions"><!-- empty --></div>
<div layout="row" layout-align="end center">
<md-button class="sg-icon-button" type="button"
ng-click="addMailFilterRule($event)">
<md-icon>add_circle</md-icon>
</md-button>
</div>
</div>
<md-list>
<md-list-item ng-repeat="action in filter.actions">
<!-- ACTIONS -->
<div layout="column">
<var:string label:value="Perform these actions:"/>
<div id="filterActions"><!-- empty --></div>
<md-list>
<md-list-item layout="row" layout-align="space-between center"
ng-repeat="action in filter.actions">
<md-input-container>
<md-select ng-model="action.method">
<md-option ng-value="key" ng-repeat="(key, value) in methodLabels">{{ value }}</md-option>
</md-select>
</md-input-container>
<!-- FORWARD MESSAGE TO -->
<input type="text" ng-show="action.method == 'redirect'" ng-model="action.argument"/>
<!-- FORWARD MESSAGE TO -->
<md-input-container ng-show="action.method == 'redirect'" >
<input type="text" ng-model="action.argument"/>
</md-input-container>
<!-- DISCARD -->
<!-- nada -->
<!-- DISCARD -->
<!-- nada -->
<!-- KEEP -->
<!-- nada -->
<!-- KEEP -->
<!-- nada -->
<!-- SEND REJECT MESSAGE -->
<input type="text" ng-show="action.method == 'reject'" ng-model="action.argument"/>
<!-- SEND REJECT MESSAGE -->
<md-input-container ng-show="action.method == 'reject'">
<input type="text" ng-model="action.argument"/>
</md-input-container>
<!-- FILE INTO -->
<md-select ng-show="action.method == 'fileinto'" ng-model="action.argument">
<!-- FILE INTO -->
<md-input-container ng-show="action.method == 'fileinto'" >
<md-select ng-model="action.argument">
<md-option ng-value="item.path" ng-repeat="item in mailboxes">
{{ item.name }}
</md-option>
</md-select>
</md-input-container>
<!-- FLAG WITH -->
<md-select ng-show="action.method == 'addflag'" ng-model="action.argument" >
<!-- FLAG WITH -->
<md-input-container ng-show="action.method == 'addflag'" >
<md-select ng-model="action.argument" >
<md-option value="seen"><var:string label:value="Seen"/></md-option>
<md-option value="deleted"><var:string label:value="Deleted"/></md-option>
<md-option value="answered"><var:string label:value="Answered"/></md-option>
<md-option value="flagged"><var:string label:value="Flagged"/></md-option>
<md-option value="junk"><var:string label:value="Junk"/></md-option>
<md-option value="not_junk"><var:string label:value="Not Junk"/></md-option>
<md-option ng-value="key" ng-repeat="(key, value) in labels">{{ value[0] }}</md-option>
</md-select>
</md-input-container>
<!-- STOP -->
<!-- nada -->
<!-- STOP -->
<!-- nada -->
<md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterAction($index)">
<md-icon>remove</md-icon>
</md-button>
<md-button class="sg-icon-button" type="button"
ng-click="removeMailFilterAction($index)">
<md-icon>remove_circle</md-icon>
</md-button>
</md-list-item>
</md-list>
</md-list>
<div layout="row" layout-align="end center">
<md-button class="sg-icon-button" type="button"
ng-click="addMailFilterAction($event)">
<md-icon>add</md-icon>
<md-icon>add_circle</md-icon>
</md-button>
</div>
<div class="md-actions" layout="row">
<md-button type="button" ng-click="cancel()">Cancel</md-button>
<md-button type="button" class="md-primary" ng-click="save()">Save</md-button>
</div>
</form>
</md-dialog-content>
</md-dialog-content>
<div class="md-actions">
<md-button type="button" ng-click="save()"><var:string label:value="Save"/></md-button>
</div>
</form>
</md-dialog>
</container>
File diff suppressed because it is too large. Load diff
@@ -15,7 +15,8 @@
<label><var:string label:value="Title"/></label>
<input type="text"
class="md-title"
ng-model="editor.component.summary"/>
ng-model="editor.component.summary"
required="required"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
@@ -95,15 +96,17 @@
<var:string label:value="Send Appointment Notifications"/>
</md-checkbox>
<!-- start + end -->
<div layout="row">
<md-input-container>
<label><var:string label:value="From"/></label>
<input type="text" ng-model="editor.component.startDate"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="To"/></label>
<input type="text" ng-model="editor.component.endDate"/>
</md-input-container>
<div layout="column">
<div layout="row" layout-align="start center">
<span><var:string label:value="From"/></span>
<md-datepicker ng-model="editor.component.start"> <!-- date picker--></md-datepicker>
<sg-timepicker ng-model="editor.component.start"><!-- time picker --></sg-timepicker>
</div>
<div layout="row" layout-align="start center">
<span><var:string label:value="To"/></span>
<md-datepicker ng-model="editor.component.end"> <!-- date picker--></md-datepicker>
<sg-timepicker ng-model="editor.component.end"><!-- time picker --></sg-timepicker>
</div>
</div>
<!-- attach urls -->
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
@@ -240,7 +243,8 @@
<md-button type="button" ng-click="editor.component.$reset()">
<var:string label:value="Reset"/>
</md-button>
<md-button class="md-primary md-hue-3" type="submit">
<md-button class="md-primary md-hue-3" type="submit"
ng-disabled="editor.eventForm.$invalid">
<var:string label:value="Save"/>
</md-button>
</div>
+38 -13
View File
@@ -138,15 +138,12 @@
</div>
-->
<main class="view md-layout-fill" ui-view="calendars" layout="row" ng-controller="navController"><!-- calendars list --></main>
<main class="view layout-fill" ui-view="calendars" layout="row" ng-controller="navController"><!-- calendars list --></main>
<script type = "text/ng-template" id="UIxCalMainFrame">
<!-- calendars colors -->
<div sg-folder-stylesheet="true"
ng-repeat="calendar in calendars.service.$calendars"
ng-model="calendar"><!-- stylesheet --></div>
<div sg-folder-stylesheet="true"
ng-repeat="calendar in calendars.service.$subscriptions"
ng-repeat="calendar in calendars.service.$findAll()"
ng-model="calendar"><!-- stylesheet --></div>
<!-- Sidenav -->
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
@@ -308,10 +305,10 @@
</md-sidenav>
<!-- Main section -->
<section layout="column" class="sg-app-content md-layout-fill"
<section layout="column" class="sg-app-content layout-fill"
ng-controller="CalendarListController as list">
<md-toolbar layout="column" layout-align="space-between start" class="md-tall toolbar-main">
<div class="md-toolbar-tools md-toolbar-tools-top sg-padded" layout="row" layout-align="space-between start">
<div class="md-toolbar-tools md-toolbar-tools-top" layout="row" layout-align="space-between start">
<var:component className="UIxTopnavToolbarTemplate" />
<!-- <div class="sg-toolbar-group-2">
<md-button class="sg-icon-button" label:aria-label="Search">
@@ -319,7 +316,9 @@
</md-button>
</div> -->
</div><!-- .md-toolbar-tools -->
<div class="md-toolbar-tools" layout="row" layout-align="space-between center">
<div class="md-toolbar-tools" layout="row"
layout-align="space-between center"
ng-show="list.component.$selectedCount() == 0">
<!-- sort/filter mode -->
<div class="view-list" layout="row" layout-align="space-between center"
ng-hide="list.mode.search">
@@ -475,16 +474,18 @@
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item ng-if="list.componentType == 'events'">
<md-button ng-click="list.component.$filter(list.componentType)">
<md-button ng-href="#">
<md-checkbox
ng-change="list.component.$filter(list.componentType)"
ng-model="list.component.$queryEvents.asc"
ng-true-value="0"
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
</md-button>
</md-menu-item>
<md-menu-item ng-if="list.componentType == 'tasks'">
<md-button ng-click="list.component.$filter(list.componentType)">
<md-button ng-href="#">
<md-checkbox
ng-change="list.component.$filter(list.componentType)"
ng-model="list.component.$queryTasks.asc"
ng-true-value="0"
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
@@ -492,6 +493,9 @@
</md-menu-item>
</md-menu-content>
</md-menu>
<md-button class="sg-icon-button" ng-click="list.component.$filter(list.componentType)">
<md-icon>refresh</md-icon>
</md-button>
</div>
</div>
<!-- search mode -->
@@ -514,7 +518,7 @@
</md-input-container>
</div>
<!-- day/week/month views -->
<div class="sg-padded">
<div>
<a class="sg-icon-button md-button"
label:aria-label="Day"
href="#/calendar/day"><md-icon>view_day</md-icon></a>
@@ -526,6 +530,19 @@
href="#/calendar/month"><md-icon>view_module</md-icon></a>
</div>
</div>
<div layout="row" layout-align="start center" ng-show="list.component.$selectedCount() > 0">
<md-button class="sg-icon-button" ng-click="list.unselectComponents()">
<md-icon>arrow_back</md-icon>
</md-button>
<label>{{list.component.$selectedCount()}} selected</label>
<md-button class="sg-icon-button" ng-click="list.selectAll()">
<md-tooltip md-direction="left"><var:string label:value="Select All"/></md-tooltip>
<md-icon>select_all</md-icon>
</md-button>
<md-button class="sg-icon-button" ng-click="list.confirmDeleteSelectedComponents()">
<md-icon>delete</md-icon>
</md-button>
</div>
</md-toolbar>
<md-content layout="row" class="md-flex">
<md-content class="view-list md-flex" layout="column">
@@ -538,7 +555,11 @@
<md-list-item class="md-2-line"
ng-repeat="event in list.component.$events"
ng-click="list.openEvent($event, event)">
<i class="md-tile-left" ng-class="event.getClassName('bg')" ><!-- calendar color --></i>
<div class="sg-selected-avatar" ng-show="event.selected"
ng-click="event.selected = !event.selected">
<!-- selected avatar -->
</div>
<i class="md-tile-left" ng-class="event.getClassName('bg')" ng-show="!event.selected" ng-click="event.selected = !event.selected"><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{event.c_title}}</h3>
<p>{{event.c_location}}</p>
@@ -563,7 +584,11 @@
<md-list-item class="md-2-line"
ng-repeat="task in list.component.$tasks"
ng-click="list.openTask($event, task)">
<i class="md-tile-left" ng-class="task.getClassName('bg')" ><!-- calendar color --></i>
<div class="sg-selected-avatar" ng-show="task.selected"
ng-click="task.selected = !task.selected">
<!-- selected avatar -->
</div>
<i class="md-tile-left" ng-class="task.getClassName('bg')" ng-show="!task.selected" ng-click="task.selected = !task.selected"><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{task.c_title}}</h3>
<p class="md-secondary" layout="row">
@@ -7,14 +7,15 @@
xmlns:label="OGo:label"
>
<md-dialog flex="40">
<md-dialog flex="60" flex-sm="100">
<md-toolbar class="sg-padded">
<md-icon class="material-icons sg-icon-toolbar-bg">link</md-icon>
<div class="md-toolbar-tools">
<div class="pseudo-input-container md-flex">
<label class="pseudo-input-label"><var:string label:value="Links to this Calendar"/></label>
<div class="pseudo-input-field sg-md-title"><var:string value="calendar.displayName"/></div>
<div class="pseudo-input-field sg-md-title">{{links.calendar.name}}</div>
</div>
<md-button class="md-icon-button" ng-click="close()">
<md-button class="md-icon-button" ng-click="links.close()">
<md-icon label:aria-label="Close">close</md-icon>
</md-button>
</div>
@@ -24,50 +25,45 @@
<div layout="column" layout-padding="layout-padding">
<div layout="column" layout-padding="layout-padding">
<md-input-container ng-show="links.calendar.isWebCalendar">
<label><var:string label:value="URL"/></label>
<input type="text" ng-model="links.calendar.urls.webCalendarURL" ng-readonly="true"/>
</md-input-container>
<var:if condition="isWebCalendar">
<md-input-container>
<label><var:string label:value="URL"/></label>
<input var:value="webCalendarURL" ng-readonly="true"/>
</md-input-container>
</var:if>
<var:if condition="isWebCalendar" const:negate="YES">
<div ng-hide="links.calendar.isWebCalendar">
<div class="sg-md-title"><var:string label:value="Authenticated User Access"/></div>
<md-input-container>
<label><var:string label:value="CalDAV URL"/></label>
<input var:value="calDavURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.calDavURL" ng-readonly="true"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="WebDAV ICS URL"/></label>
<input var:value="webDavICSURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.webDavICSURL" ng-readonly="true"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="WebDAV XML URL"/></label>
<input var:value="webDavXMLURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.webDavXMLURL" ng-readonly="true"/>
</md-input-container>
</var:if>
</div>
</div>
<var:if condition="isPublicAccessEnabled">
<var:if condition="isWebCalendar" const:negate="YES">
<div layout="column" layout-padding="layout-padding">
<div layout="column" layout-padding="layout-padding" ng-hide="links.calendar.isWebCalendar">
<div class="sg-md-title"><var:string label:value="Public Access"/></div>
<md-input-container>
<label><var:string label:value="CalDAV URL"/></label>
<input var:value="publicCalDavURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.publicCalDavURL" ng-readonly="true"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="WebDAV ICS URL"/></label>
<input var:value="publicWebDavICSURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.publicWebDavICSURL" ng-readonly="true"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="WebDAV XML URL"/></label>
<input var:value="publicWebDavXMLURL" ng-readonly="true"/>
<input type="text" ng-model="links.calendar.urls.publicWebDavXMLURL" ng-readonly="true"/>
</md-input-container>
</div>
</var:if>
</var:if>
</div>
</md-dialog-content>
@@ -6,7 +6,7 @@
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<md-dialog>
<md-dialog flex-sm="100">
<md-toolbar ng-style="{ 'background-color': properties.calendar.color }">
<div class="md-toolbar-tools sg-padded--right">
@@ -22,15 +22,19 @@
<md-input-container class="md-input-number">
<input type="number" label:aria-label="Every" ng-model="editor.component.repeat.interval"/>
</md-input-container>
<var:string label:value="Week(s)"/> <var:string label:value="On"/>
<var:string label:value="Week(s)"/>
</div>
<div class="pseudo-input-container layout-padding" layout="row" layout-align="center center">
<label class="pseudo-input-label"><var:string label:value="On"/></label>
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-md="80" flex-sm="100"
sg-toggle-grid="editor.component.repeat.days"
sg-toggle-grid-attr="day">
<var:foreach list="shortWeekDaysList" item="item">
<md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile>
</var:foreach>
</md-grid-list>
</div>
<md-grid-list md-cols="7" md-row-height="1:1" md-gutter="0.5em"
sg-toggle-grid="editor.component.repeat.days"
sg-toggle-grid-attr="day">
<var:foreach list="shortWeekDaysList" item="item">
<md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile>
</var:foreach>
</md-grid-list>
</div>
<!-- monthly -->
@@ -46,40 +50,43 @@
<md-radio-button value="bymonthday">
<var:string label:value="Recur on day(s)"/>
</md-radio-button>
<md-grid-list md-cols="7" md-row-height="1:1" md-gutter="0.5em"
sg-toggle-grid="editor.component.repeat.monthdays">
<md-grid-tile value="1">1</md-grid-tile>
<md-grid-tile value="2">2</md-grid-tile>
<md-grid-tile value="3">3</md-grid-tile>
<md-grid-tile value="4">4</md-grid-tile>
<md-grid-tile value="5">5</md-grid-tile>
<md-grid-tile value="6">6</md-grid-tile>
<md-grid-tile value="7">7</md-grid-tile>
<md-grid-tile value="8">8</md-grid-tile>
<md-grid-tile value="9">9</md-grid-tile>
<md-grid-tile value="10">10</md-grid-tile>
<md-grid-tile value="11">11</md-grid-tile>
<md-grid-tile value="12">12</md-grid-tile>
<md-grid-tile value="13">13</md-grid-tile>
<md-grid-tile value="14">14</md-grid-tile>
<md-grid-tile value="15">15</md-grid-tile>
<md-grid-tile value="16">16</md-grid-tile>
<md-grid-tile value="17">17</md-grid-tile>
<md-grid-tile value="18">18</md-grid-tile>
<md-grid-tile value="19">19</md-grid-tile>
<md-grid-tile value="20">20</md-grid-tile>
<md-grid-tile value="21">21</md-grid-tile>
<md-grid-tile value="22">22</md-grid-tile>
<md-grid-tile value="23">23</md-grid-tile>
<md-grid-tile value="24">24</md-grid-tile>
<md-grid-tile value="25">25</md-grid-tile>
<md-grid-tile value="26">26</md-grid-tile>
<md-grid-tile value="27">27</md-grid-tile>
<md-grid-tile value="28">28</md-grid-tile>
<md-grid-tile value="29">29</md-grid-tile>
<md-grid-tile value="30">30</md-grid-tile>
<md-grid-tile value="31">31</md-grid-tile>
</md-grid-list>
<div layout="row" layout-align="start center">
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-md="80" flex-sm="100"
sg-toggle-grid="editor.component.repeat.monthdays">
<md-grid-tile value="1">1</md-grid-tile>
<md-grid-tile value="2">2</md-grid-tile>
<md-grid-tile value="3">3</md-grid-tile>
<md-grid-tile value="4">4</md-grid-tile>
<md-grid-tile value="5">5</md-grid-tile>
<md-grid-tile value="6">6</md-grid-tile>
<md-grid-tile value="7">7</md-grid-tile>
<md-grid-tile value="8">8</md-grid-tile>
<md-grid-tile value="9">9</md-grid-tile>
<md-grid-tile value="10">10</md-grid-tile>
<md-grid-tile value="11">11</md-grid-tile>
<md-grid-tile value="12">12</md-grid-tile>
<md-grid-tile value="13">13</md-grid-tile>
<md-grid-tile value="14">14</md-grid-tile>
<md-grid-tile value="15">15</md-grid-tile>
<md-grid-tile value="16">16</md-grid-tile>
<md-grid-tile value="17">17</md-grid-tile>
<md-grid-tile value="18">18</md-grid-tile>
<md-grid-tile value="19">19</md-grid-tile>
<md-grid-tile value="20">20</md-grid-tile>
<md-grid-tile value="21">21</md-grid-tile>
<md-grid-tile value="22">22</md-grid-tile>
<md-grid-tile value="23">23</md-grid-tile>
<md-grid-tile value="24">24</md-grid-tile>
<md-grid-tile value="25">25</md-grid-tile>
<md-grid-tile value="26">26</md-grid-tile>
<md-grid-tile value="27">27</md-grid-tile>
<md-grid-tile value="28">28</md-grid-tile>
<md-grid-tile value="29">29</md-grid-tile>
<md-grid-tile value="30">30</md-grid-tile>
<md-grid-tile value="31">31</md-grid-tile>
</md-grid-list>
</div>
<div layout="row" layout-align="start center">
<md-radio-button value="byday">
<var:string label:value="The"/>
@@ -111,27 +118,30 @@
</md-input-container>
<var:string label:value="Year(s)"/>
</div>
<md-grid-list md-cols="6" md-row-height="1:1" md-gutter="0.5em"
sg-toggle-grid="editor.component.repeat.months">
<var:foreach list="yearlyMonthList" item="item">
<md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile>
</var:foreach>
</md-grid-list>
<div layout="row" layout-align="start center">
<md-checkbox ng-model="editor.component.repeat.year.byday">
<var:string label:value="The"/>
</md-checkbox>
<md-select ng-model="editor.component.repeat.month.occurrence">
<var:foreach list="monthlyRepeatList" item="item">
<md-option var:value="valueForMonthlyRepeat"><var:string value="itemText"/></md-option>
</var:foreach>
</md-select>
<md-select ng-model="editor.component.repeat.month.day">
<var:foreach list="yearlyDayList" item="item">
<md-option var:value="valueForYearlyDay"><var:string value="item"/></md-option>
</var:foreach>
</md-select>
</div>
<div layout="row" layout-align="start center">
<md-grid-list md-cols="6" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-md="80" flex-sm="100"
sg-toggle-grid="editor.component.repeat.months">
<var:foreach list="yearlyMonthList" item="item">
<md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile>
</var:foreach>
</md-grid-list>
</div>
<div layout="row" layout-align="start center">
<md-checkbox ng-model="editor.component.repeat.year.byday">
<var:string label:value="The"/>
</md-checkbox>
<md-select ng-model="editor.component.repeat.month.occurrence">
<var:foreach list="monthlyRepeatList" item="item">
<md-option var:value="valueForMonthlyRepeat"><var:string value="itemText"/></md-option>
</var:foreach>
</md-select>
<md-select ng-model="editor.component.repeat.month.day">
<var:foreach list="yearlyDayList" item="item">
<md-option var:value="valueForYearlyDay"><var:string value="item"/></md-option>
</var:foreach>
</md-select>
</div>
</div>
</container>
@@ -15,7 +15,8 @@
<label><var:string label:value="Title"/></label>
<input type="text"
class="md-title"
ng-model="editor.component.summary"/>
ng-model="editor.component.summary"
required="required"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
@@ -79,15 +80,35 @@
<var:string label:value="All day Event"/>
</md-checkbox>
<!-- start + end -->
<div layout="row">
<md-input-container>
<label><var:string label:value="Start"/></label>
<input type="text" ng-model="editor.component.startDate"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Due"/></label>
<input type="text" ng-model="editor.component.dueDate"/>
</md-input-container>
<div class="section" layout="column">
<div layout="row" layout-align="start center" ng-show="editor.component.start">
<label><var:string label:value="From"/></label>
<md-datepicker ng-model="editor.component.start"> <!-- date picker--></md-datepicker>
<sg-timepicker ng-model="editor.component.start"><!-- time picker --></sg-timepicker>
<md-button class="sg-icon-button" type="button" ng-click="editor.component.$deleteStartDate()">
<md-icon>remove_circle</md-icon>
</md-button>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center" ng-hide="editor.component.start">
<md-button class="sg-icon-button" type="button" ng-click="editor.component.$addStartDate()">
<md-icon>add_circle</md-icon>
</md-button>
<label class="button-label"><var:string label:value="Add From"/></label>
</div>
</div>
<div layout="row" layout-align="start center" ng-show="editor.component.due">
<label><var:string label:value="Due"/></label>
<md-datepicker ng-model="editor.component.due"> <!-- date picker--></md-datepicker>
<sg-timepicker ng-model="editor.component.due"><!-- time picker --></sg-timepicker>
<md-button class="sg-icon-button" type="button" ng-click="editor.component.$deleteDueDate()">
<md-icon>remove_circle</md-icon>
</md-button>
</div>
<div class="md-layout-margin" layout="row" layout-align="start center" ng-hide="editor.component.due">
<md-button class="sg-icon-button" type="button" ng-click="editor.component.$addDueDate()">
<md-icon>add_circle</md-icon>
</md-button>
<label class="button-label"><var:string label:value="Add Due"/></label>
</div>
<!-- status -->
<div layout="row">
@@ -206,7 +227,8 @@
<md-button type="button" ng-click="editor.component.$reset()">
<var:string label:value="Reset"/>
</md-button>
<md-button class="md-primary md-hue-3" type="submit">
<md-button class="md-primary md-hue-3" type="submit"
ng-disabled="editor.eventForm.$invalid">
<var:string label:value="Save"/>
</md-button>
</div>
@@ -94,7 +94,7 @@
</md-list>
</md-dialog-content>
<!-- edit -->
<div class="md-actions">
<div class="md-actions" ng-show="editor.component.isEditable()">
<md-button ng-click="editor.edit()">
<var:string label:value="Edit"/>
</md-button>
+72 -187
View File
@@ -6,13 +6,11 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label"
>
xmlns:label="OGo:label">
<var:string var:value="doctype" const:escapeHTML="NO" />
<var:if condition="hideFrame" const:negate="YES"
>
<html const:xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en" const:lang="en">
<var:if condition="hideFrame" const:negate="YES">
<html const:xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" const:lang="en">
<head>
<title>
<var:string value="title" />
@@ -26,18 +24,13 @@
<link href="mailto:support@inverse.ca" rev="made" />
<link rel="shortcut icon" var:href="siteFavicon" type="image/x-icon" />
<link type="text/css" rel="stylesheet" rsrc:href="css/styles.css" />
<var:if condition="hasPageSpecificCSS"
>
<link type="text/css" rel="stylesheet" var:href="pageCSSURL"
/>
<var:if condition="hasPageSpecificCSS">
<link type="text/css" rel="stylesheet" var:href="pageCSSURL"/>
</var:if>
<var:foreach list="additionalCSSFiles" item="item"
>
<link type="text/css" rel="stylesheet" var:href="item"
/>
<var:foreach list="additionalCSSFiles" item="item">
<link type="text/css" rel="stylesheet" var:href="item"/>
</var:foreach>
<var:if-ie const:lte="9"
>
<var:if-ie const:lte="9">
<link type="text/css" rel="stylesheet" rsrc:href="iefixes.css" />
<script type="text/javascript" rsrc:src="XMLHttpRequest.js"><!-- space --></script>
</var:if-ie>
@@ -49,152 +42,26 @@
<div id="popupFrame" style="display: none;">
<iframe width="100%" height="100%" src="/SOGo/loading"><!-- space --></iframe>
</div>
</var:if
>
<var:if condition="shortUserNameForDisplay" const:value="anonymous"
const:negate="YES">
<var:if condition="hasUserSettingsKeys"
>
</var:if>
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
<var:if condition="hasUserSettingsKeys">
<script type="text/javascript">
var UserSettings =<var:string value="userSettings" const:escapeHTML="NO" />;
</script
>
</script>
</var:if>
<var:if condition="hasUserDefaultsKeys">
<script type="text/javascript">
var UserDefaults =<var:string value="userDefaults" const:escapeHTML="NO" />;
</script
>
</var:if
>
</var:if
>
<var:if condition="isPopup" const:negate="YES"
>
<var:if condition="isUIxDebugEnabled"
><!-- space --></var:if>
</script>
</var:if>
</var:if>
<var:if condition="isPopup" const:negate="YES">
<var:if condition="isUIxDebugEnabled"><!-- space --></var:if>
</var:if>
<!-- MAIN CONTENT ROW -->
<!-- MAIN CONTENT ROW -->
<var:component-content />
<!-- BOTTOM-SHEET -->
<script type="text/ng-template" id="bottomSheetTemplate.html">
<md-bottom-sheet class="md-list">
<md-list>
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
<!-- CALENDAR -->
<var:if condition="userHasCalendarAccess">
<var:if condition="isCalendar">
<md-list-item>
<md-button class="md-list-item-content" ng-disabled="true">
<md-icon>event</md-icon>
<var:string label:value="Calendar"/>
</md-button>
</md-list-item>
</var:if>
<var:if condition="isCalendar" const:negate="YES">
<md-list-item>
<md-button class="md-list-item-content" var:href="relativeCalendarPath">
<md-icon>event</md-icon>
<var:string label:value="Calendar"/>
</md-button>
</md-list-item>
</var:if>
</var:if>
<!-- CONTACTS -->
<var:if condition="isContacts">
<md-list-item>
<md-button class="md-list-item-content" ng-disabled="true">
<md-icon>contacts</md-icon>
<var:string label:value="Address Book"/>
</md-button>
</md-list-item>
</var:if>
<var:if condition="isContacts" const:negate="YES">
<md-list-item>
<md-button class="md-list-item-content" var:href="relativeContactsPath">
<md-icon>contacts</md-icon>
<var:string label:value="Address Book"/>
</md-button>
</md-list-item>
</var:if>
<!-- MAIL -->
<var:if condition="userHasMailAccess">
<var:if condition="isMail">
<md-list-item>
<md-button class="md-list-item-content" ng-disabled="true">
<md-icon>email</md-icon>
<var:string label:value="Mail"/>
</md-button>
</md-list-item>
</var:if>
<var:if condition="isMail" const:negate="YES">
<md-list-item>
<md-button class="md-list-item-content" var:href="relativeMailPath">
<md-icon>email</md-icon>
<var:string label:value="Mail"/>
</md-button>
</md-list-item>
</var:if>
</var:if>
<!-- PREFERENCES -->
<var:if condition="isPreferences">
<md-list-item>
<md-button class="md-list-item-content" ng-disabled="true">
<md-icon>settings</md-icon>
<var:string label:value="Preferences"/>
</md-button>
</md-list-item>
</var:if>
<var:if condition="isPreferences" const:negate="YES">
<md-list-item>
<md-button class="md-list-item-content" var:ng-href="relativePreferencesPath">
<md-icon>settings</md-icon>
<var:string label:value="Preferences"/>
</md-button>
</md-list-item>
</var:if>
<!-- ADMINISTRATION -->
<var:if condition="isSuperUser">
<var:if condition="isAdministration">
<md-list-item>
<md-button class="md-list-item-content" ng-disabled="true">
<md-icon>settings_applications</md-icon>
<var:string label:value="Administration"/>
</md-button>
</md-list-item>
</var:if>
<var:if condition="isAdministration" const:negate="YES">
<md-list-item>
<md-button class="md-list-item-content" var:href="relativeAdministrationPath">
<md-icon>settings_applications</md-icon>
<var:string label:value="Administration"/>
</md-button>
</md-list-item>
</var:if>
</var:if>
<!-- DISCONNECT -->
<var:if condition="canLogoff">
<md-list-item>
<md-button class="md-list-item-content" var:ng-href="logoffPath">
<md-icon>settings_power</md-icon>
<var:string label:value="Disconnect"/>
</md-button>
</md-list-item>
</var:if>
</var:if>
</md-list>
</md-bottom-sheet>
</script>
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
</var:if>
@@ -202,31 +69,58 @@
<script type="text/javascript">
var ApplicationBaseURL = '<var:string value="modulePath" />';
var ResourcesURL = '<var:string value="applicationPath" />.woa/WebServerResources';
var minimumSearchLength =<var:string value="minimumSearchLength" />;
<var:if condition="isSuperUser"
>var IsSuperUser = true;
var minimumSearchLength = <var:string value="minimumSearchLength" />;
<var:if condition="isSuperUser">
var IsSuperUser = true;
</var:if>
<var:if condition="isSuperUser" const:negate="YES"
>var IsSuperUser = false;
<var:if condition="isSuperUser" const:negate="YES">
var IsSuperUser = false;
</var:if>
<var:if condition="usesCASAuthentication"
>var usesCASAuthentication = true;
<var:if condition="usesCASAuthentication">
var usesCASAuthentication = true;
</var:if>
<var:if condition="usesCASAuthentication" const:negate="YES"
>var usesCASAuthentication = false;
<var:if condition="usesCASAuthentication" const:negate="YES">
var usesCASAuthentication = false;
</var:if>
<var:if condition="shortUserNameForDisplay" const:value="anonymous"
const:negate="YES"
>var UserFolderURL = '<var:string value="userFolderPath" const:escapeHTML="NO" />';
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
var UserFolderURL = '<var:string value="userFolderPath" const:escapeHTML="NO" />';
var UserLogin = '<var:string value="shortUserNameForDisplay" const:escapeHTML="NO" />';
var UserIdentification = '<var:string value="userIdentification" const:escapeHTML="NO" />';
var UserEmail = '<var:string value="userEmail" const:escapeHTML="NO" />';
var UserLanguage = '<var:string value="userLanguage" const:escapeHTML="NO" />';
// Application paths
var UserCalendarPath = '';
<var:if condition="userHasCalendarAccess">
UserCalendarPath = '<var:string value="relativeCalendarPath" const:escapeHTML="NO" />';
</var:if>
var UserContactsPath = '<var:string value="relativeContactsPath" const:escapeHTML="NO" />';
var UserMailPath = '';
<var:if condition="userHasMailAccess">
UserMailPath = '<var:string value="relativeMailPath" const:escapeHTML="NO" />';
</var:if>
var UserPreferencesPath = '<var:string value="relativePreferencesPath" const:escapeHTML="NO" />';
<var:if condition="isSuperUser">
var UserAdministrationPath = '<var:string value="relativeAdministrationPath" const:escapeHTML="NO" />';
</var:if>
var UserLogoffPath = '';
<var:if condition="canLogoff">
UserLogoffPath = '<var:string value="logoffPath" const:escapeHTML="NO" />';
</var:if>
</var:if>
// This is the equivalent of an AJAX call to /SOGo/so/_UserLogin_/date
var currentDay = <var:string value="currentDayDescription" const:escapeHTML="NO"/>;
// This is the equivalent of an AJAX call to /SOGo/so/_UserLogin_/date
var currentDay = <var:string value="currentDayDescription" const:escapeHTML="NO"/>;
<var:string value="commonLocalizableStrings" const:escapeHTML="NO" />
<var:string value="productLocalizableStrings" const:escapeHTML="NO" />
</script>
<script type="text/javascript" rsrc:src="js/vendor/lodash.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-animate.min.js"><!-- space --></script>
@@ -236,40 +130,31 @@
<script type="text/javascript" rsrc:src="js/vendor/angular-ui-router.min.js"><!-- space --></script>
<var:if condition="hasProductSpecificJavaScript">
<script type="text/javascript"
var:src="productJavaScriptURL"><!-- space --></script>
<script type="text/javascript" var:src="productJavaScriptURL"><!-- space --></script>
</var:if>
<var:if condition="hasPageSpecificJavaScript">
<script type="text/javascript"
var:src="pageJavaScriptURL"><!-- space --></script>
<script type="text/javascript" var:src="pageJavaScriptURL"><!-- space --></script>
</var:if>
<var:foreach list="additionalJSFiles" item="item"
>
<var:foreach list="additionalJSFiles" item="item">
<script type="text/javascript" var:src="item"><!-- space --></script>
</var:foreach>
<var:foreach list="systemAdditionalJSFiles" item="item"
>
<var:foreach list="systemAdditionalJSFiles" item="item">
<script type="text/javascript" var:src="item"><!-- space --></script>
</var:foreach>
</var:if>
<var:if condition="isCompatibleBrowser" const:negate="YES"
>
<var:component className="SOGoBrowsersPanel"
/>
<var:if condition="isCompatibleBrowser" const:negate="YES">
<var:component className="SOGoBrowsersPanel"/>
</var:if>
<noscript>
<div class="javascriptPopupBackground">
</div>
<div class="javascriptMessagePseudoWindow noJavascriptErrorMessage">
<var:string label:value="noJavascriptError"
/>
<br />
<br
/>
<a class="button" var:href="page.context.uri"
>
<var:string label:value="noJavascriptRetry"
/>
<var:string label:value="noJavascriptError"/>
<br/>
<br/>
<a class="button" var:href="page.context.uri">
<var:string label:value="noJavascriptRetry"/>
</a>
</div>
</noscript>
+10 -23
View File
@@ -3,27 +3,14 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
<md-toolbar class="md-tall">
<div class="md-toolbar-tools sg-padded" layout="row" layout-align="start start">
<md-button class="sg-icon-button"
label:aria-label="Apps"
ng-click="openBottomSheet()">
<md-icon>apps</md-icon>
</md-button>
<span class="sg-logo"><!-- logo.svg --></span>
</div>
<div class="md-toolbar-tools sg-padded" layout="row">
<div layout="column">
<p class="sg-md-title">{{activeUser.identification}}</p>
<!--fixme: implement this with the proper model and actions -->
<!-- <md-select class="sg-logout" ng-model="accounts.options" var:placeholder="shortUserNameForDisplay">
<md-option var:value="relativePreferencesPath"><var:string label:value="Preferences"/></md-option>
<var:if condition="canLogoff"><md-option var:value="logoffPath"><var:string label:value="Disconnect" /></md-option></var:if>
</md-select> -->
</div>
</div>
</md-toolbar>
xmlns:label="OGo:label">
<md-toolbar class="md-tall sg-padded">
<div layout="column" layout-align="center start">
<sg-avatar-image class="md-tile-left"
sg-email="activeUser.email"
size="48"><!-- avatar --></sg-avatar-image>
<p class="sg-md-title">{{activeUser.identification}}</p>
<p class="md-caption">{{activeUser.email}}</p>
</div>
</md-toolbar>
</container>
+52 -3
View File
@@ -3,19 +3,68 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
xmlns:label="OGo:label">
<div class="sg-toolbar-group-1" layout="row">
<md-button ng-click="toggleLeft()"
class="hide-gt-md sg-button-navicon sg-icon-button"
label:aria-label="Toggle Menu">
<md-icon>menu</md-icon>
</md-button>
<div class="sg-date-group" layout="column" layout-align="space-between end">
<div class="sg-date-group sg-padded" layout="column" layout-align="space-between end">
<p class="sg-day" ng-bind="currentDay.weekday"><!-- weekday --></p>
<p class="sg-month" ng-bind="currentDay.month"><!-- month --></p>
<p class="sg-year" ng-bind="currentDay.year"><!-- year --></p>
</div>
<p class="sg-md-display-3 sg-date-today" ng-bind="currentDay.day"><!-- day --></p>
</div>
<div class="sg-toolbar-group-last">
<md-menu layout-fill="layout-fill">
<md-button label:aria-label="Modules"
class="sg-icon-button" ng-click="$mdOpenMenu($event)">
<md-icon>apps</md-icon>
</md-button>
<md-menu-content width="8">
<div class="md-toolbar-tools sg-padded" layout="row"
layout-align="space-around start">
<md-button class="sg-icon-button"
ng-show="activeUser.path.calendar.length"
ng-disabled="baseURL.endsWith('/Calendar')"
ng-href="{{activeUser.path.calendar}}">
<md-icon>event</md-icon>
<md-tooltip><var:string label:value="Calendar"/></md-tooltip>
</md-button>
<md-button class="sg-icon-button"
ng-disabled="baseURL.endsWith('/Contacts')"
ng-href="{{activeUser.path.contacts}}">
<md-icon>contacts</md-icon>
<md-tooltip><var:string label:value="Address Book"/></md-tooltip>
</md-button>
<md-button class="sg-icon-button"
ng-show="activeUser.path.mail.length"
ng-disabled="baseURL.endsWith('/Mail')"
ng-href="{{activeUser.path.mail}}">
<md-icon>email</md-icon>
<md-tooltip><var:string label:value="Mail"/></md-tooltip>
</md-button>
<md-button class="sg-icon-button"
ng-disabled="baseURL.endsWith(activeUser.login)"
ng-href="{{activeUser.path.preferences}}">
<md-icon>settings</md-icon>
<md-tooltip><var:string label:value="Preferences"/></md-tooltip>
</md-button>
<md-button class="sg-icon-button" ng-show="activeUser.isSuperUser" ng-href="{{activeUser.path.administration}}">
<md-icon>settings_applications</md-icon>
<md-tooltip><var:string label:value="Administration"/></md-tooltip>
</md-button>
<md-button class="sg-icon-button" ng-show="activeUser.path.logoff.length" ng-href="{{activeUser.path.logoff}}">
<md-icon>settings_power</md-icon>
<md-tooltip><var:string label:value="Disconnect"/></md-tooltip>
</md-button>
</div>
</md-menu-content>
</md-menu>
</div>
</container>
+2 -2
View File
@@ -6,8 +6,8 @@ module.exports = function(grunt) {
'js/Scheduler.js': ['js/Scheduler/Scheduler.app.js', 'js/Scheduler/*Controller.js', 'js/Scheduler/*.directive.js'],
'js/Contacts.services.js': ['js/Contacts/*.service.js'],
'js/Contacts.js': ['js/Contacts/Contacts.app.js', 'js/Contacts/*Controller.js', 'js/Contacts/*.directive.js'],
'js/Mailer.services.js': ['js/Mailer/*.service.js'],
'js/Mailer.js': ['js/Mailer/Mailer.app.js', 'js/Mailer/*Controller.js', 'js/Mailer/*.directive.js'],
'js/Mailer.services.js': ['js/Mailer/*.service.js', 'js/Mailer/*Controller.js'],
'js/Mailer.js': ['js/Mailer/Mailer.app.js', 'js/Mailer/*.directive.js'],
'js/Preferences.services.js': ['js/Preferences/*.service.js'],
'js/Preferences.js': ['js/Preferences/Preferences.app.js', 'js/Preferences/*Controller.js']
};
+4 -4
View File
@@ -2,9 +2,9 @@
"name": "sogo-web",
"private": true,
"devDependencies": {
"angular": "1.3.x",
"angular-animate": "1.3.x",
"angular-sanitize": "1.3.x",
"angular": "1.4.x",
"angular-animate": "1.4.x",
"angular-sanitize": "1.4.x",
"angular-ui-router": "latest",
"angular-file-upload": "latest",
"angular-material": "master",
@@ -12,6 +12,6 @@
"breakpoint-sass": ">=2.4.2"
},
"resolutions": {
"angular": "1.3.x"
"angular": "1.4.x"
}
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../scss/components/_palette.scss","../scss/core/reset.scss","styles.css","../scss/core/angular.scss","../scss/styles.scss","../angular-material/src/core/style/mixins.scss","../angular-material/src/core/style/structure.scss","../scss/core/variables.scss","../scss/core/structure.scss","../angular-material/src/core/style/layout.scss","../scss/core/layout.scss","../bower_components/breakpoint-sass/stylesheets/_breakpoint.scss","../angular-material/src/core/style/typography.scss","../scss/core/typography.scss","../scss/core/_functions.scss","../angular-material/src/components/autocomplete/autocomplete.scss","../scss/components/backdrop/_extends.scss","../angular-material/src/components/backdrop/backdrop.scss","../scss/components/backdrop/backdrop.scss","../scss/components/bottomSheet/_extends.scss","../angular-material/src/components/bottomSheet/bottomSheet.scss","../scss/components/bottomSheet/bottomSheet.scss","../scss/components/button/_extends.scss","../angular-material/src/components/button/button.scss","../scss/components/button/button.scss","../scss/components/card/_extends.scss","../angular-material/src/components/card/card.scss","../scss/components/card/card.scss","../scss/components/checkbox/_extends.scss","../angular-material/src/components/checkbox/checkbox.scss","../scss/components/checkbox/checkbox.scss","../scss/components/chips/_extends.scss","../angular-material/src/components/chips/chips.scss","../scss/components/chips/chips.scss","../scss/components/content/_extends.scss","../angular-material/src/components/content/content.scss","../scss/components/content/content.scss","../scss/components/dialog/_extends.scss","../angular-material/src/components/dialog/dialog.scss","../scss/components/dialog/dialog.scss","../scss/components/divider/_extends.scss","../angular-material/src/components/divider/divider.scss","../scss/components/fabSpeedDial/_extends.scss","../angular-material/src/components/fabSpeedDial/fabSpeedDial.scss","../angular-material/src/components/gridList/gridList.scss","../scss/components/gridList/gridList.scss","../scss/components/icon/_extends.scss","../angular-material/src/components/icon/icon.scss","../scss/components/icon/icon.scss","../scss/components/input/_extends.scss","../angular-material/src/components/input/input.scss","../scss/components/input/input.scss","../scss/components/list/_extends.scss","../angular-material/src/components/list/list.scss","../scss/components/list/list.scss","../scss/components/menu/_extends.scss","../angular-material/src/components/menu/menu.scss","../scss/components/progressLinear/_extends.scss","../angular-material/src/components/progressLinear/progressLinear.scss","../scss/components/radioButton/_extends.scss","../angular-material/src/components/radioButton/radio-button.scss","../scss/components/select/_extends.scss","../angular-material/src/components/select/select.scss","../scss/components/select/select.scss","../scss/components/sidenav/_extends.scss","../angular-material/src/components/sidenav/sidenav.scss","../scss/components/sidenav/sidenav.scss","../scss/components/slider/_extends.scss","../angular-material/src/components/slider/slider.scss","../scss/components/sticky/_extends.scss","../angular-material/src/components/sticky/sticky.scss","../scss/components/subheader/_extends.scss","../angular-material/src/components/subheader/subheader.scss","../scss/components/subheader/subheader.scss","../scss/components/switch/_extends.scss","../angular-material/src/components/switch/switch.scss","../scss/components/tabs/_extends.scss","../angular-material/src/components/tabs/tabs.scss","../scss/components/toast/_extends.scss","../angular-material/src/components/toast/toast.scss","../scss/components/toolbar/_extends.scss","../angular-material/src/components/toolbar/toolbar.scss","../scss/components/toolbar/toolbar.scss","../scss/components/tooltip/_extends.scss","../angular-material/src/components/tooltip/tooltip.scss","../scss/components/virtualRepeat/_extends.scss","../angular-material/src/components/virtualRepeat/virtualRepeater.scss","../scss/components/virtualRepeat/virtualRepeat.scss","../scss/components/whiteframe/_extends.scss","../angular-material/src/components/whiteframe/whiteframe.scss","../scss/components/whiteframe/whiteframe.scss","../scss/components/pseudo-input/pseudo-input.scss","../scss/views/LoginUI.scss","../scss/views/MailerUI.scss","../scss/views/ContactsUI.scss","../scss/views/MessageEditorUI.scss","../scss/views/SchedulerUI.scss","../scss/views/_view.scss","../scss/core/base_styles/_base_style.scss","../scss/_devtools.scss"],"names":[],"mappings":"AAEA;;;;;GAKG;AAqYiC;EAE9B,eAzSO,EAwSP;;AAEA;EAEA,0BA5SO,EA2SP;;AAJ8B;EAE9B,eAxSO,EAuSP;;AAEA;EAEA,0BA3SO,EA0SP;;AAJ8B;EAE9B,eAvSO,EAsSP;;AAEA;EAEA,0BA1SO,EAySP;;AAJ8B;EAE9B,eAtSO,EAqSP;;AAEA;EAEA,0BAzSO,EAwSP;;AAJ8B;EAE9B,eArSO,EAoSP;;AAEA;EAEA,0BAxSO,EAuSP;;AAJ8B;EAE9B,eApSO,EAmSP;;AAEA;EAEA,0BAvSO,EAsSP;;AAJ8B;EAE9B,eAnSO,EAkSP;;AAEA;EAEA,0BAtSO,EAqSP;;AAJ8Line truncated
{"version":3,"sources":["../scss/components/_palette.scss","../scss/core/reset.scss","styles.css","../scss/core/angular.scss","../scss/styles.scss","../angular-material/src/core/style/structure.scss","../angular-material/src/core/style/mixins.scss","../scss/core/variables.scss","../scss/core/structure.scss","../angular-material/src/core/services/layout/layout.scss","../scss/core/layout.scss","../bower_components/breakpoint-sass/stylesheets/_breakpoint.scss","../angular-material/src/core/style/typography.scss","../scss/core/typography.scss","../scss/core/_functions.scss","../angular-material/src/components/autocomplete/autocomplete.scss","../scss/components/autocomplete/autocomplete.scss","../scss/components/backdrop/_extends.scss","../angular-material/src/components/backdrop/backdrop.scss","../scss/components/backdrop/backdrop.scss","../scss/components/button/_extends.scss","../angular-material/src/components/button/button.scss","../scss/components/button/button.scss","../scss/components/card/_extends.scss","../angular-material/src/components/card/card.scss","../scss/components/card/card.scss","../scss/components/checkbox/_extends.scss","../angular-material/src/components/checkbox/checkbox.scss","../scss/components/checkbox/checkbox.scss","../scss/components/chips/_extends.scss","../angular-material/src/components/chips/chips.scss","../scss/components/chips/chips.scss","../scss/components/content/_extends.scss","../angular-material/src/components/content/content.scss","../scss/components/content/content.scss","../scss/components/datepicker/_extends-calendar.scss","../angular-material/src/components/datepicker/calendar.scss","../scss/components/datepicker/_extends-datePicker.scss","../angular-material/src/components/datepicker/datePicker.scss","../scss/components/datepicker/datePicker.scss","../scss/components/dialog/_extends.scss","../angular-material/src/components/dialog/dialog.scss","../scss/components/dialog/dialog.scss","../scss/components/divider/_extends.scss","../angular-material/src/components/divider/divider.scss","../scss/components/fabSpeedDial/_extends.scss","../angular-material/src/components/fabSpeedDial/fabSpeedDial.scss","../angular-material/src/components/gridList/grid-list.scss","../scss/components/gridList/grid-list.scss","../scss/components/icon/_extends.scss","../angular-material/src/components/icon/icon.scss","../scss/components/icon/icon.scss","../scss/components/input/_extends.scss","../angular-material/src/components/input/input.scss","../scss/components/input/input.scss","../scss/components/list/_extends.scss","../angular-material/src/components/list/list.scss","../scss/components/list/list.scss","../scss/components/menu/_extends.scss","../angular-material/src/components/menu/menu.scss","../scss/components/progressCircular/_extends.scss","../angular-material/src/components/progressCircular/progress-circular.scss","../scss/components/progressCircular/progress-circular.scss","../scss/components/radioButton/_extends.scss","../angular-material/src/components/radioButton/radio-button.scss","../scss/components/select/_extends.scss","../angular-material/src/components/select/select.scss","../scss/components/select/select.scss","../scss/components/sidenav/_extends.scss","../angular-material/src/components/sidenav/sidenav.scss","../scss/components/sidenav/sidenav.scss","../scss/components/slider/_extends.scss","../angular-material/src/components/slider/slider.scss","../scss/components/sticky/_extends.scss","../angular-material/src/components/sticky/sticky.scss","../scss/components/subheader/_extends.scss","../angular-material/src/components/subheader/subheader.scss","../scss/components/subheader/subheader.scss","../scss/components/switch/_extends.scss","../angular-material/src/components/switch/switch.scss","../scss/components/tabs/_extends.scss","../angular-material/src/components/tabs/tabs.scss","../scss/components/toast/_extends.scss","../angular-material/src/components/toast/toast.scss","../scss/components/toolbar/_extends.scss","../angular-material/src/components/toolbar/toolbar.scss","../scss/components/toolbar/toolbar.scss","../scss/components/tooltip/_extends.scss","../angular-material/src/components/tooltip/tooltip.scss","../scss/components/virtualRepeat/_extends.scss","../angular-material/src/components/virtualRepeat/virtual-repeater.scss","../scss/components/virtualRepeat/virtual-repeat.scss","../scss/components/whiteframe/_extends.scss","../angular-material/src/components/whiteframe/whiteframe.scss","../scss/components/timepicker/timepicker.scss","../scss/components/pseudo-input/pseudo-input.scss","../scss/views/LoginUI.scss","../scss/views/MailerUI.scss","../scss/views/ContactsUI.scss","../scss/views/MessageEditorUI.scss","../scss/views/SchedulerUI.scss","../scss/views/_view.scss","../scss/core/base_styles/_base_style.scss"],"names":[],"mappings":"AAEA;;;;;GAKG;AAqYiC;EAE9B,eAzSO,EAwSP;;AAEA;EAEA,0BA5SO,EA2SP;;AAJ8B;EAE9B,eAxSO,EAuSP;;AAEA;EAEA,0BA3SO,EA0SP;;AAJ8B;EAE9B,eAvSOLine truncated
+2 -2
View File
@@ -1,3 +1,3 @@
function l(){var key=arguments[0],value=key;labels[key]?value=labels[key]:clabels[key]&&(value=clabels[key]);for(var i=1,j=0;i<arguments.length;i++,j++)value=value.replace("%{"+j+"}",arguments[i]);return value}!function(){"use strict";function configure($mdThemingProvider){$mdThemingProvider.definePalette("sogo-green",{50:"eaf5e9",100:"cbe5c8",200:"aad6a5",300:"88c781",400:"66b86a",500:"56b04c",600:"4da143",700:"388e3c",800:"367d2e",900:"225e1b",A100:"b9f6ca",A200:"69f0ae",A400:"00e676",A700:"00c853",contrastDefaultColor:"dark",contrastDarkColors:"50 100 200",contrastLightColors:"300 400 500 600 700 800 900"}),$mdThemingProvider.definePalette("sogo-blue",{50:"f0faf9",100:"e1f5f3",200:"ceebe8",300:"bfe0dd",400:"b2d6d3",500:"a1ccc8",600:"8ebfbb",700:"7db3b0",800:"639997",900:"4d8080",A100:"d4f7fa",A200:"c3f5fa",A400:"53e3f0",A700:"00b0c0",contrastDefaultColor:"light",contrastDarkColors:["50","100","200"],contrastLightColors:["300","400","500","600","700","800","900","A100","A200","A400","A700"]}),$mdThemingProvider.definePalette("sogo-paper",{50:"fcf7f8",100:"f7f1dc",200:"ede5ca",300:"e6d8ba",400:"e2d2a3",500:"d6c48d",600:"baa870",700:"857545",800:"524517",900:"433809",1000:"000000",A100:"ffffff",A200:"eeeeee",A400:"bdbdbd",A700:"616161",contrastDefaultColor:"dark",contrastLightColors:"800 900"}),$mdThemingProvider.theme("default").primaryPalette("sogo-blue",{"default":"300","hue-1":"100","hue-2":"400","hue-3":"A700"}).accentPalette("sogo-green",{"default":"500","hue-1":"200","hue-2":"300","hue-3":"A700"}).backgroundPalette("sogo-paper",{"default":"100","hue-1":"200","hue-2":"50","hue-3":"500"})}angular.module("SOGo.Common",["ngMaterial"]).value("sgSettings",{baseURL:function(){return ApplicationBaseURL||null},activeUser:function(param){var settings={login:UserLogin||null,identification:UserIdentification||null,language:UserLanguage||null,folderURL:UserFolderURL||null,isSuperUser:IsSuperUser||null};return param?settings[param]:settings}}).constant("sgColors",{selection:["#FFFFFF","#330033","#C0C0C0","#999999","#666666","#333333","#000000","#FFCCCC","#FF6666","#FF0000","#CC0000","#990000","#660000","#330000","#FFCC99","#FF9966","#FF9900","#FF6600","#CC6600","#993300","#663300","#FFFF99","#FFFF66","#FFCC66","#FFCC33","#CC9933","#996633","#663333","#FFFFCC","#FFFF33","#FFFF00","#FFCC00","#999900","#666600","#333300","#CCCCCC","#66FF99","#33FF33","#33CC00","#009900","#006600","#003300","#99FFFF","#33FFFF","#66CCCC","#00CCCC","#339999","#336666","#003333","#CCFFFF","#66FFFF","#33CCFF","#3366FF","#3333FF","#000099","#000066","#CCCCFF","#9999FF","#6666CC","#6633FF","#6600CC","#333399","#330099","#FFCCFF","#FF99FF","#CC66CC","#CC33CC","#993399","#663366","#99FF99"]}).constant("sgConstant",{sm:"(max-width: 600px)","gt-sm":"(min-width: 600px)",md:"(min-width: 600px) and (max-width: 1024px)","gt-md":"(min-width: 1025px)",lg:"(min-width: 1024px) and (max-width: 1280px)","gt-lg":"(min-width: 1280px)"}).config(configure),configure.$inject=["$mdThemingProvider"]}(),function(){"use strict";function decodeUri($window){return $window.decodeURIComponent}decodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("decodeUri",decodeUri)}(),function(){"use strict";function encodeUri($window){return $window.encodeURIComponent}encodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("encodeUri",encodeUri)}(),function(){"use strict";function loc(){return l}angular.module("SOGo.Common").filter("loc",loc)}(),function(){"use strict";function range(){return function(n){for(var res=[],i=0;i<parseInt(n);i++)res.push(i);return res}}angular.module("SOGo.Common").filter("range",range)}(),function(){"use strict";function AclController($mdDialog,Dialog,usersWithACL,User,folder){function userFilter($query){return User.$filter($query,folder.$acl.users)}function closeModal(){folder.$acl.$resetUsersRights(),$mdDialog.hide()}function saveModal(){folder.$acl.$saveUsersRights().then(function(){$mdDialog.hide()},function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function confirmChange(user){var confirmation=user.$confirmRights();confirmation&&(vm.confirmation.showing=!0,vm.confirmation.message=confirmation)}function removeUser(user){folder.$acl.$removeUser(user.uid)["catch"](function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function addUser(data){data&&folder.$acl.$addUser(data).then(function(){vm.userToAdd="",vm.searchText=""},function(error){Dialog.alert(l("Warning"),error)})}function selectUser(user){vm.selectedUser==user?vm.selectedUser=null:(vm.selectedUser=user,vm.selectedUser.$rights())}var vm=this;vm.users=usersWithACL,vm.folder=folder,vm.selectedUser=null,vm.userToAdd="",vm.searchText="",vm.userFilter=userFilter,vm.closeModal=closeModal,vm.saveModal=saveModal,vm.confirmChange=confirmChange,vm.removeUser=removeUser,vm.addUser=addUser,vm.selectUser=selectUser,vm.confirmation={showing:!1,message:""}}AclController.$inject=["$mdDialog","Dialog","usersLine truncated
}),ensureInitRunsOnce()}}),toggleClass=function(){var tile=angular.element(this),day=tile.attr("value");tile.toggleClass("sg-active"),toggle(day)},i=0;i<tiles.length;i++)tile=angular.element(tiles[i]),tile.addClass("iconButton"),tile.find("figure").addClass("md-icon"),tile.on("click",toggleClass)}return{restrict:"A",link:link}}sgToggleGrid.$inject=["$parse"],angular.module("SOGo.Common").directive("sgToggleGrid",sgToggleGrid)}(),String.prototype.endsWith=function(suffix){return-1!==this.indexOf(suffix,this.length-suffix.length)},String.prototype.startsWith=function(pattern,position){return position=angular.isNumber(position)?position:0,this.lastIndexOf(pattern,position)===position},String.prototype._base64_keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",String.prototype.base64encode=function(){for(var chr1,chr2,chr3,enc1,enc2,enc3,enc4,output="",i=0,input=this.utf8encode();i<input.length;)chr1=input.charCodeAt(i++),chr2=input.charCodeAt(i++),chr3=input.charCodeAt(i++),enc1=chr1>>2,enc2=(3&chr1)<<4|chr2>>4,enc3=(15&chr2)<<2|chr3>>6,enc4=63&chr3,isNaN(chr2)?enc3=enc4=64:isNaN(chr3)&&(enc4=64),output=output+this._base64_keyStr.charAt(enc1)+this._base64_keyStr.charAt(enc2)+this._base64_keyStr.charAt(enc3)+this._base64_keyStr.charAt(enc4);return output},String.prototype.base64decode=function(){for(var chr1,chr2,chr3,enc1,enc2,enc3,enc4,output="",i=0,input=""+this;i<input.length;)enc1=this._base64_keyStr.indexOf(input.charAt(i++)),enc2=this._base64_keyStr.indexOf(input.charAt(i++)),enc3=this._base64_keyStr.indexOf(input.charAt(i++)),enc4=this._base64_keyStr.indexOf(input.charAt(i++)),chr1=enc1<<2|enc2>>4,chr2=(15&enc2)<<4|enc3>>2,chr3=(3&enc3)<<6|enc4,output+=String.fromCharCode(chr1),64!=enc3&&(output+=String.fromCharCode(chr2)),64!=enc4&&(output+=String.fromCharCode(chr3));return output},String.prototype.md5=function(){if(this.length){var md5=function(s){function L(k,d){return k<<d|k>>>32-d}function K(G,k){var I,d,F,H,x;return F=2147483648&G,H=2147483648&k,I=1073741824&G,d=1073741824&k,x=(1073741823&G)+(1073741823&k),I&d?2147483648^x^F^H:I|d?1073741824&x?3221225472^x^F^H:1073741824^x^F^H:x^F^H}function r(d,F,k){return d&F|~d&k}function q(d,F,k){return d&k|F&~k}function p(d,F,k){return d^F^k}function n(d,F,k){return F^(d|~k)}function u(G,F,aa,Z,k,H,I){return G=K(G,K(K(r(F,aa,Z),k),I)),K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){return G=K(G,K(K(q(F,aa,Z),k),I)),K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){return G=K(G,K(K(p(F,aa,Z),k),I)),K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){return G=K(G,K(K(n(F,aa,Z),k),I)),K(L(G,H),F)}function e(G){for(var Z,F=G.length,x=F+8,k=(x-x%64)/64,I=16*(k+1),aa=Array(I-1),d=0,H=0;F>H;)Z=(H-H%4)/4,d=H%4*8,aa[Z]=aa[Z]|G.charCodeAt(H)<<d,H++;return Z=(H-H%4)/4,d=H%4*8,aa[Z]=aa[Z]|128<<d,aa[I-2]=F<<3,aa[I-1]=F>>>29,aa}function B(x){var G,d,k="",F="";for(d=0;3>=d;d++)G=x>>>8*d&255,F="0"+G.toString(16),k+=F.substr(F.length-2,2);return k}function J(k){k=k.replace(/rn/g,"n");for(var d="",F=0;F<k.length;F++){var x=k.charCodeAt(F);128>x?d+=String.fromCharCode(x):x>127&&2048>x?(d+=String.fromCharCode(x>>6|192),d+=String.fromCharCode(63&x|128)):(d+=String.fromCharCode(x>>12|224),d+=String.fromCharCode(x>>6&63|128),d+=String.fromCharCode(63&x|128))}return d}var P,h,E,v,g,Y,X,W,V,C=Array(),S=7,Q=12,N=17,M=22,A=5,z=9,y=14,w=20,o=4,m=11,l=16,j=23,U=6,T=10,R=15,O=21;for(s=J(s),C=e(s),Y=1732584193,X=4023233417,W=2562383102,V=271733878,P=0;P<C.length;P+=16)h=Y,E=X,v=W,g=V,Y=u(Y,X,W,V,C[P+0],S,3614090360),V=u(V,Y,X,W,C[P+1],Q,3905402710),W=u(W,V,Y,X,C[P+2],N,606105819),X=u(X,W,V,Y,C[P+3],M,3250441966),Y=u(Y,X,W,V,C[P+4],S,4118548399),V=u(V,Y,X,W,C[P+5],Q,1200080426),W=u(W,V,Y,X,C[P+6],N,2821735955),X=u(X,W,V,Y,C[P+7],M,4249261313),Y=u(Y,X,W,V,C[P+8],S,1770035416),V=u(V,Y,X,W,C[P+9],Q,2336552879),W=u(W,V,Y,X,C[P+10],N,4294925233),X=u(X,W,V,Y,C[P+11],M,2304563134),Y=u(Y,X,W,V,C[P+12],S,1804603682),V=u(V,Y,X,W,C[P+13],Q,4254626195),W=u(W,V,Y,X,C[P+14],N,2792965006),X=u(X,W,V,Y,C[P+15],M,1236535329),Y=f(Y,X,W,V,C[P+1],A,4129170786),V=f(V,Y,X,W,C[P+6],z,3225465664),W=f(W,V,Y,X,C[P+11],y,643717713),X=f(X,W,V,Y,C[P+0],w,3921069994),Y=f(Y,X,W,V,C[P+5],A,3593408605),V=f(V,Y,X,W,C[P+10],z,38016083),W=f(W,V,Y,X,C[P+15],y,3634488961),X=f(X,W,V,Y,C[P+4],w,3889429448),Y=f(Y,X,W,V,C[P+9],A,568446438),V=f(V,Y,X,W,C[P+14],z,3275163606),W=f(W,V,Y,X,C[P+3],y,4107603335),X=f(X,W,V,Y,C[P+8],w,1163531501),Y=f(Y,X,W,V,C[P+13],A,2850285829),V=f(V,Y,X,W,C[P+2],z,4243563512),W=f(W,V,Y,X,C[P+7],y,1735328473),X=f(X,W,V,Y,C[P+12],w,2368359562),Y=D(Y,X,W,V,C[P+5],o,4294588738),V=D(V,Y,X,W,C[P+8],m,2272392833),W=D(W,V,Y,X,C[P+11],l,1839030562),X=D(X,W,V,Y,C[P+14],j,4259657740),Y=D(Y,X,W,V,C[P+1],o,2763975236),V=D(V,Y,X,W,C[P+4],m,1272893353),W=D(W,V,Y,X,C[P+7],l,4139469664),X=D(X,W,V,Y,C[P+10],j,3200236656),Y=D(Y,X,W,V,C[P+13],o,681279174),V=D(V,Y,X,W,C[P+0],m,3936430074),W=D(W,V,Y,X,C[P+3],l,3572445317),X=D(X,W,V,Y,C[P+6],j,76029189),Y=D(Y,X,W,V,C[P+9],o,3654602809),V=D(V,Y,X,W,C[P+12],m,3873151461),W=D(W,V,Y,X,C[P+Line truncated
function l(){var key=arguments[0],value=key;labels[key]?value=labels[key]:clabels[key]&&(value=clabels[key]);for(var i=1,j=0;i<arguments.length;i++,j++)value=value.replace("%{"+j+"}",arguments[i]);return value}!function(){"use strict";function configure($mdThemingProvider){$mdThemingProvider.definePalette("sogo-green",{50:"eaf5e9",100:"cbe5c8",200:"aad6a5",300:"88c781",400:"66b86a",500:"56b04c",600:"4da143",700:"388e3c",800:"367d2e",900:"225e1b",A100:"b9f6ca",A200:"69f0ae",A400:"00e676",A700:"00c853",contrastDefaultColor:"dark",contrastDarkColors:"50 100 200",contrastLightColors:"300 400 500 600 700 800 900"}),$mdThemingProvider.definePalette("sogo-blue",{50:"f0faf9",100:"e1f5f3",200:"ceebe8",300:"bfe0dd",400:"b2d6d3",500:"a1ccc8",600:"8ebfbb",700:"7db3b0",800:"639997",900:"4d8080",A100:"d4f7fa",A200:"c3f5fa",A400:"53e3f0",A700:"00b0c0",contrastDefaultColor:"light",contrastDarkColors:["50","100","200"],contrastLightColors:["300","400","500","600","700","800","900","A100","A200","A400","A700"]}),$mdThemingProvider.definePalette("sogo-paper",{50:"fcf7f8",100:"f7f1dc",200:"ede5ca",300:"e6d8ba",400:"e2d2a3",500:"d6c48d",600:"baa870",700:"857545",800:"524517",900:"433809",1000:"000000",A100:"ffffff",A200:"eeeeee",A400:"bdbdbd",A700:"616161",contrastDefaultColor:"dark",contrastLightColors:"800 900"}),$mdThemingProvider.theme("default").primaryPalette("sogo-blue",{"default":"300","hue-1":"100","hue-2":"400","hue-3":"A700"}).accentPalette("sogo-green",{"default":"500","hue-1":"200","hue-2":"300","hue-3":"A700"}).backgroundPalette("sogo-paper",{"default":"100","hue-1":"200","hue-2":"50","hue-3":"500"})}angular.module("SOGo.Common",["ngMaterial"]).value("sgSettings",{baseURL:function(){return ApplicationBaseURL||null},activeUser:function(param){var settings={login:UserLogin||null,identification:UserIdentification||null,email:UserEmail||null,language:UserLanguage||null,folderURL:UserFolderURL||null,isSuperUser:IsSuperUser||null,path:{calendar:UserCalendarPath||null,contacts:UserContactsPath||null,mail:UserMailPath||null,preferences:UserPreferencesPath||null,administration:IsSuperUser?UserAdministrationPath:null,logoff:UserLogoffPath||null}};return param?settings[param]:settings}}).constant("sgColors",{selection:["#FFFFFF","#330033","#C0C0C0","#999999","#666666","#333333","#000000","#FFCCCC","#FF6666","#FF0000","#CC0000","#990000","#660000","#330000","#FFCC99","#FF9966","#FF9900","#FF6600","#CC6600","#993300","#663300","#FFFF99","#FFFF66","#FFCC66","#FFCC33","#CC9933","#996633","#663333","#FFFFCC","#FFFF33","#FFFF00","#FFCC00","#999900","#666600","#333300","#CCCCCC","#66FF99","#33FF33","#33CC00","#009900","#006600","#003300","#99FFFF","#33FFFF","#66CCCC","#00CCCC","#339999","#336666","#003333","#CCFFFF","#66FFFF","#33CCFF","#3366FF","#3333FF","#000099","#000066","#CCCCFF","#9999FF","#6666CC","#6633FF","#6600CC","#333399","#330099","#FFCCFF","#FF99FF","#CC66CC","#CC33CC","#993399","#663366","#99FF99"]}).constant("sgConstant",{sm:"(max-width: 600px)","gt-sm":"(min-width: 600px)",md:"(min-width: 600px) and (max-width: 1024px)","gt-md":"(min-width: 1025px)",lg:"(min-width: 1024px) and (max-width: 1280px)","gt-lg":"(min-width: 1280px)"}).config(configure),configure.$inject=["$mdThemingProvider"]}(),function(){"use strict";function decodeUri($window){return $window.decodeURIComponent}decodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("decodeUri",decodeUri)}(),function(){"use strict";function encodeUri($window){return $window.encodeURIComponent}encodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("encodeUri",encodeUri)}(),function(){"use strict";function loc(){return l}angular.module("SOGo.Common").filter("loc",loc)}(),function(){"use strict";function range(){return function(n){for(var res=[],i=0;i<parseInt(n);i++)res.push(i);return res}}angular.module("SOGo.Common").filter("range",range)}(),function(){"use strict";function AclController($mdDialog,Dialog,usersWithACL,User,folder){function userFilter($query){return User.$filter($query,folder.$acl.users)}function closeModal(){folder.$acl.$resetUsersRights(),$mdDialog.hide()}function saveModal(){folder.$acl.$saveUsersRights().then(function(){$mdDialog.hide()},function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function confirmChange(user){var confirmation=user.$confirmRights();confirmation&&(vm.confirmation.showing=!0,vm.confirmation.message=confirmation)}function removeUser(user){folder.$acl.$removeUser(user.uid)["catch"](function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function addUser(data){data&&folder.$acl.$addUser(data).then(function(){vm.userToAdd="",vm.searchText=""},function(error){Dialog.alert(l("Warning"),error)})}function selectUser(user){vm.selectedUser==user?vm.selectedUser=null:(vm.selectedUser=user,vm.selectedUser.$rights())}var vm=this;vm.users=usersWithACL,vm.folder=folder,vm.selectedUser=null,vm.userToAdd="",vm.searchText="",vm.userFilter=userFilter,Line truncated
return{template:'<div class="sg-time-pane"><div class="hours-pane"><div ng-repeat="hoursBigLine in hours" layout="row" layout-sm="column" ><div ng-repeat="hoursLine in hoursBigLine" layout="row" class="hours" ><div flex layout="row" layout-align="center center" ng-repeat="hour in hoursLine"><md-button class="hourBtn md-fab md-mini" id="{{hour.id}}" ng-click="hourClickHandler(hour.displayName)">{{hour.displayName}}</md-button></div></div></div></div><div ng-repeat="minutesLine in min5" layout="row" class="min5" ng-show="is5min()"><div flex layout="row" layout-align="center center" ng-repeat="minute in minutesLine"><md-button class="minuteBtn md-fab md-mini" id="{{minute.id}}" ng-click="minuteClickHandler(minute.displayName)">{{minute.displayName}}</md-button></div></div><div ng-repeat="minutesLine in min1" layout="row" class="min1" ng-hide="is5min()"><div flex layout="row" layout-align="center center" ng-repeat="minute in minutesLine"><md-button class="minuteBtn md-fab md-mini" id="{{minute.id}}" ng-click="minuteClickHandler(minute.displayName)">{{minute.displayName}}</md-button></div></div><div flex layout="row" layout-align="center center" class="toggle-pane"><md-button class="toggleBtn md-fab md-mini" ng-bind="getToggleBtnLbl()" ng-click="toggleManual5min()"></md-button></div></div>',scope:{},require:["ngModel","sgTimePane"],controller:TimePaneCtrl,controllerAs:"ctrl",bindToController:!0,link:function(scope,element,attrs,controllers){var ngModelCtrl=controllers[0],sgTimePaneCtrl=controllers[1];console.log(element);var timePaneElement=element;sgTimePaneCtrl.configureNgModel(ngModelCtrl,sgTimePaneCtrl,timePaneElement)}}}function TimePaneCtrl($element,$attrs,$scope,$animate,$q,$mdConstant,$mdTheming,$$mdDateUtil,$mdDateLocale,$mdInkRipple,$mdUtil){var m;this.$scope=$scope,this.$element=$element,this.timePaneElement=$element[0].querySelector(".sg-time-pane"),this.$animate=$animate,this.$q=$q,this.$mdInkRipple=$mdInkRipple,this.$mdUtil=$mdUtil,this.keyCode=$mdConstant.KEY_CODE,this.dateUtil=$$mdDateUtil,this.id=nextTimePaneUniqueId++,this.ngModelCtrl=null,this.selectedTime=null,this.displayTime=null,this.isInitialized=!1,$scope.hours=[],$scope.hours[0]=[],$scope.hours[0][0]=[],$scope.hours[0][1]=[],$scope.hours[1]=[],$scope.hours[1][0]=[],$scope.hours[1][1]=[];for(var i=0;6>i;i++)$scope.hours[0][0][i]={id:"tp-"+this.id+"-hour-"+i,displayName:10>i?"0"+i:""+i,selected:!1},$scope.hours[0][1][i]={id:"tp-"+this.id+"-hour-"+(i+6),displayName:10>i+6?"0"+(i+6):""+(i+6),selected:!1},$scope.hours[1][0][i]={id:"tp-"+this.id+"-hour-"+(i+12),displayName:""+(i+12),selected:!1},$scope.hours[1][1][i]={id:"tp-"+this.id+"-hour-"+(i+18),displayName:""+(i+18),selected:!1};for($scope.min5=[],$scope.min5[0]=[],$scope.min5[1]=[],i=0;6>i;i++)m=5*i,$scope.min5[0][i]={id:"tp-"+this.id+"-minute5-"+m,displayName:10>m?":0"+m:":"+m,selected:!0},$scope.min5[1][i]={id:"tp-"+this.id+"-minute5-"+(m+30),displayName:":"+(m+30),selected:!1};for($scope.min1=[],i=0;12>i;i++){$scope.min1[i]=[];for(var ii=0;5>ii;ii++)m=5*i+ii,$scope.min1[i][ii]={id:"tp-"+this.id+"-minute-"+m,displayName:10>m?":0"+m:":"+m,selected:!0}}$scope.show5min=!0,$scope.getToggleBtnLbl=function(){return $scope.is5min()?">>":"<<"},$scope.toggleManual5min=function(){$scope.manual5min=!$scope.is5min()},$scope.is5min=function(){return $scope.manual5min===!0||$scope.manual5min===!1?$scope.manual5min:$scope.show5min},$attrs.tabindex||$element.attr("tabindex","-1");var self=this;this.hourClickHandler=function(displayVal){var updated=new Date(self.displayTime).setHours(Number(displayVal));self.setNgModelValue(updated,"hours")},$scope.hourClickHandler=this.hourClickHandler,this.minuteClickHandler=function(displayVal){var val=displayVal.substr(1),updated=new Date(self.displayTime).setMinutes(Number(val));self.setNgModelValue(updated,"minutes")},$scope.minuteClickHandler=this.minuteClickHandler,this.attachTimePaneEventListeners()}angular.module("SOGo.Common").directive("sgTimePane",timePaneDirective);var SELECTED_TIME_CLASS2="md-primary",FOCUSED_TIME_CLASS="md-focus",nextTimePaneUniqueId=0;TimePaneCtrl.$inject=["$element","$attrs","$scope","$animate","$q","$mdConstant","$mdTheming","$$mdDateUtil","$mdDateLocale","$mdInkRipple","$mdUtil"],TimePaneCtrl.prototype.configureNgModel=function(ngModelCtrl,sgTimePaneCtrl,timePaneElement){this.ngModelCtrl=ngModelCtrl;var self=this;ngModelCtrl.$render=function(){self.changeSelectedTime(self.ngModelCtrl.$viewValue,sgTimePaneCtrl,timePaneElement)}},TimePaneCtrl.prototype.changeSelectedTime=function(date,sgTimePaneCtrl,timePaneElement){var previousSelectedTime=this.selectedTime;this.selectedTime=new Date(date),this.changeDisplayTime(date).then(function(){if(previousSelectedTime){var prevH=previousSelectedTime.getHours(),prevHCell=document.getElementById("tp-"+sgTimePaneCtrl.id+"-hour-"+prevH);prevHCell&&(prevHCell.classList.remove(SELECTED_TIME_CLASS2),prevHCell.setAttribute("aria-selected","false"));var prevM=previousSelectedTime.getMinutes(),prevMCeLine truncated
//# sourceMappingURL=Common.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Common.js","sources":["Common/utils.js","Common/Common.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Alarm.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/User.service.js","Common/sgFocus.service.js","Common/sgAvatarImage.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgSearch.directive.js","Common/sgSubscribe.directive.js","Common/sgToggleGrid.directive.js"],"names":["l","key","arguments","value","labels","clabels","i","j","length","replace","configure","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastDarkColors","contrastLightColors","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","angular","module","baseURL","ApplicationBaseURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","language","UserLanguage","folderURL","UserFolderURL","isSuperUser","IsSuperUser","constant","selection","sm","gt-sm","md","gt-md","lg","gt-lg","config","$inject","decodeUri","$window","decodeURIComponent","filter","encodeUri","encodeURIComponent","loc","range","n","res","parseInt","push","AclController","$mdDialog","Dialog","usersWithACL","User","folder","userFilter","$query","$filter","$acl","users","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","then","data","status","alert","confirmChange","user","confirmation","$confirmRights","vm","showing","message","removeUser","$removeUser","uid","addUser","$addUser","userToAdd","searchText","error","selectUser","selectedUser","$rights","this","controller","navController","$scope","$timeout","$interval","$http","$mdSidenav","$mdBottomSheet","$mdMedia","$log","sgConstant","sgSettings","Alarm","currentDay","window","get","success","secondsBeforeTomorrow","toggleLeft","toggle","debug","toggleRight","openBottomSheet","show","parent","element","document","getElementById","templateUrl","toggleDetailView","detail","toggleClass","$watch","newVal","isGtMedium","getAlarms","Acl","folderId","factory","$q","Settings","Resource","extend","$$resource","$User","prototype","$users","_this","deferred","defer","resolve","promise","fetch","response","forEach","canSubscribeUser","isSubscribed","wasSubscribed","bind","_","indexOf","pluck","userClass","isGroup","reject","splice","$resetRights","deferredSave","deferredSubscribe","action","$rightsAreDirty","$omit","save","$shadowRights","copy","rights","uids","join","all","currentAlarm","AlarmService","$mdToast","$toast","now","Date","browserTime","Math","floor","getTime","alarms","sort","a","b","x","y","next","pop","utc","url","alarmTime","delay","f","showAlarm","cancel","AlarmController","scope","reminder","ok","position","hideDelay","template","locals","Authentication","readCookie","name","foundCookie","prefix","pairs","currentPair","start","cookie","split","charAt","substr","readLoginCookie","loginValues","base64decode","redirectUrl","username","domain","userName","address","baseAddress","altBaseAddress","parts","hostpart","protocol","newAddress","location","href","startsWith","endsWith","getService","passwordPolicyConfig","service","d","password","rememberLogin","loginSuffix","method","loginCookie","expire","grace","msg","perr","LDAPPasswordPolicyError","PolicyNoError","PolicyAccountLocked","changePassword","newPassword","PolicyPasswordModNotAllowed","PolicyInsufficientPasswordQuality","PolicyPasswordTooShort","PolicyPasswordTooYoung","PolicyPasswordInHistory","formatted","PolicyPasswordUnknown","PolicyPasswordSystemUnknown","$get","PolicyPasswordChangeUnsupported","PolicyPasswordExpired","PolicyChangeAfterReset","PolicyMustSupplyOldPassword","provider","DialogService","$modal","title","content","confirm","options","prompt","label","PromptDialogController","o","body","clickOutsideToClose","escapeToClose","inputType","Gravatar","email","size","hash","s","substring","md5","path","_http","_q","_path","_activeUser","$factory","userResource","compact","escape","params","flatten","newguid","create","post","id","newValue","remove","userData","init","$gravatar","search","excludedUsers","when","results","index","compareUids","find","each","isUndefined","$$shortFormat","$shortFormat","$$image","image","c_email","empty","fullname","cn","no_email","$isAnonymous","$isSpecial","$confirmation","some","values","isEqual","zero","map","keys","isString","$folders","type","$$folders","folders","toString","sgFocus","$rootScope","$broadcast","sgAvatarImage","restrict","src","bindToController","controllerAs","sgAvatarImageContLine truncated
{"version":3,"file":"Common.js","sources":["Common/utils.js","Common/Common.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Alarm.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/User.service.js","Common/sgFocus.service.js","Common/sgAvatarImage.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgSearch.directive.js","Common/sgSubscribe.directive.js","Common/sgTarget.directive.js","Common/sgTimepicker.directive.js","Common/sgToggleGrid.directive.js"],"names":["l","key","arguments","value","labels","clabels","i","j","length","replace","configure","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastDarkColors","contrastLightColors","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","angular","module","baseURL","ApplicationBaseURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","email","UserEmail","language","UserLanguage","folderURL","UserFolderURL","isSuperUser","IsSuperUser","path","calendar","UserCalendarPath","contacts","UserContactsPath","mail","UserMailPath","preferences","UserPreferencesPath","administration","UserAdministrationPath","logoff","UserLogoffPath","constant","selection","sm","gt-sm","md","gt-md","lg","gt-lg","config","$inject","decodeUri","$window","decodeURIComponent","filter","encodeUri","encodeURIComponent","loc","range","n","res","parseInt","push","AclController","$mdDialog","Dialog","usersWithACL","User","folder","userFilter","$query","$filter","$acl","users","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","then","data","status","alert","confirmChange","user","confirmation","$confirmRights","vm","showing","message","removeUser","$removeUser","uid","addUser","$addUser","userToAdd","searchText","error","selectUser","selectedUser","$rights","this","controller","navController","$scope","$timeout","$interval","$http","$mdSidenav","$mdBottomSheet","$mdMedia","$log","sgConstant","sgSettings","Alarm","currentDay","window","get","success","secondsBeforeTomorrow","toggleLeft","toggle","debug","toggleRight","openBottomSheet","show","parent","element","document","getElementById","templateUrl","toggleDetailView","detail","toggleClass","$watch","newVal","isGtMedium","getAlarms","Acl","folderId","factory","$q","Settings","Resource","extend","$$resource","$User","prototype","$users","_this","deferred","defer","resolve","promise","fetch","response","forEach","canSubscribeUser","isSubscribed","wasSubscribed","bind","_","indexOf","pluck","userClass","isGroup","reject","splice","$resetRights","deferredSave","deferredSubscribe","action","$rightsAreDirty","$omit","save","$shadowRights","copy","rights","uids","join","all","currentAlarm","AlarmService","$mdToast","$toast","now","Date","browserTime","Math","floor","getTime","alarms","sort","a","b","x","y","next","pop","utc","url","alarmTime","delay","f","showAlarm","cancel","AlarmController","scope","reminder","ok","position","hideDelay","template","summary","locals","Authentication","readCookie","name","foundCookie","prefix","pairs","currentPair","start","cookie","split","charAt","substr","readLoginCookie","loginValues","base64decode","redirectUrl","username","domain","userName","address","baseAddress","altBaseAddress","parts","hostpart","protocol","newAddress","location","href","startsWith","endsWith","getService","passwordPolicyConfig","service","d","password","rememberLogin","loginSuffix","method","loginCookie","expire","grace","msg","perr","LDAPPasswordPolicyError","PolicyNoError","PolicyAccountLocked","changePassword","newPassword","PolicyPasswordModNotAllowed","PolicyInsufficientPasswordQuality","PolicyPasswordTooShort","PolicyPasswordTooYoung","PolicyPasswordInHistory","formatted","PolicyPasswordUnknown","PolicyPasswordSystemUnknown","$get","PolicyPasswordChangeUnsupported","PolicyPasswordExpired","PolicyChangeAfterReset","PolicyMustSupplyOldPassword","provider","DialogService","$modal","title","content","confirm","options","prompt","label","PromptDialogController","o","body","clickOutsideToClose","escapeToClose","inputType","Gravatar","size","hash","s","substring","md5","_http","_q","_path","_activeUser","$factory","userResource","compact","escape","params","flatten","newguid","create","post","id","newValue","remove","userData","init","$gravatar","search","excludedUsers","when","results","index","compareUids","find","each","isUndefined","$$shortFormat","$shortFormat","$$image","image","c_email","empty","fullname","cn","no_email"Line truncated
@@ -58,66 +58,67 @@
Alarm.showAlarm = function(url) {
var _this = this;
this.$$resource.fetch(url, '?resetAlarm=yes');
this.$toast.show({
position: 'top right',
hideDelay: 0,
template: [
'<md-toast>',
' <md-input-container>',
' <md-select ng-model="reminder">',
' <md-option value=5>',
l('5 minutes'),
' </md-option>',
' <md-option value=10>',
l('10 minutes'),
' </md-option>',
' <md-option value=15>',
l('15 minutes'),
' </md-option>',
' <md-option value=30>',
l('30 minutes'),
' </md-option>',
' <md-option value=45>',
l('45 minutes'),
' </md-option>',
' <md-option value=60>',
l('1 hour'),
' </md-option>',
' <md-option value=1440>',
l('1 day'),
' </md-option>',
' </md-select>',
' </md-input-container>',
' <md-button ng-click="cancel()">',
l('Cancel'),
' </md-button>',
' <md-button ng-click="ok()">',
l('Ok'),
' </md-button>',
'</md-toast>'
this.$$resource.fetch(url, '?resetAlarm=yes').then(function(data) {
_this.$toast.show({
position: 'top right',
hideDelay: 0,
template: [
'<md-toast>',
' <md-input-container>',
' <label style="color: white;">' + data.summary + '</label>',
' <md-select ng-model="reminder">',
' <md-option value=5>',
l('5 minutes'),
' </md-option>',
' <md-option value=10>',
l('10 minutes'),
' </md-option>',
' <md-option value=15>',
l('15 minutes'),
' </md-option>',
' <md-option value=30>',
l('30 minutes'),
' </md-option>',
' <md-option value=45>',
l('45 minutes'),
' </md-option>',
' <md-option value=60>',
l('1 hour'),
' </md-option>',
' <md-option value=1440>',
l('1 day'),
' </md-option>',
' </md-select>',
' </md-input-container>',
' <md-button ng-click="cancel()">',
l('Cancel'),
' </md-button>',
' <md-button ng-click="ok()">',
l('Ok'),
' </md-button>',
'</md-toast>'
].join(''),
locals: {
url: url
},
controller: AlarmController
locals: {
url: url
},
controller: AlarmController
});
/**
* @ngInject
*/
AlarmController.$inject = ['scope', '$mdToast', 'url'];
function AlarmController(scope, $mdToast, url) {
scope.reminder = '10';
scope.cancel = function() {
$mdToast.hide();
};
scope.ok = function() {
_this.$$resource.fetch(url, 'view?snoozeAlarm=' + scope.reminder);
$mdToast.hide();
};
}
});
/**
* @ngInject
*/
AlarmController.$inject = ['scope', '$mdToast', 'url'];
function AlarmController(scope, $mdToast, url) {
scope.reminder = '10';
scope.cancel = function() {
$mdToast.hide();
};
scope.ok = function() {
_this.$$resource.fetch(url, 'view?snoozeAlarm=' + scope.reminder);
$mdToast.hide();
};
}
};
/**
+10 -1
View File
@@ -12,9 +12,18 @@
var settings = {
login: UserLogin || null,
identification: UserIdentification || null,
email: UserEmail || null,
language: UserLanguage || null,
folderURL: UserFolderURL || null,
isSuperUser: IsSuperUser || null
isSuperUser: IsSuperUser || null,
path: {
calendar: UserCalendarPath || null,
contacts: UserContactsPath || null,
mail: UserMailPath || null,
preferences: UserPreferencesPath || null,
administration: (IsSuperUser ? UserAdministrationPath : null),
logoff: UserLogoffPath || null
}
};
if (param)
return settings[param];
@@ -13,6 +13,7 @@
function navController($scope, $timeout, $interval, $http, $mdSidenav, $mdBottomSheet, $mdMedia, $log, sgConstant, sgSettings, Alarm) {
$scope.activeUser = sgSettings.activeUser();
$scope.baseURL = sgSettings.baseURL();
// Show current day in top bar
$scope.currentDay = window.currentDay;
@@ -0,0 +1,743 @@
(function() {
'use strict';
angular
.module('SOGo.Common')
.directive('sgTimePane', timePaneDirective);
function timePaneDirective() {
return {
template:
'<div class="sg-time-pane">' +
'<div class="hours-pane"><div ng-repeat="hoursBigLine in hours" layout="row" layout-sm="column" ><div ng-repeat="hoursLine in hoursBigLine" layout="row" class="hours" >' +
'<div flex layout="row" layout-align="center center" ng-repeat="hour in hoursLine">' +
'<md-button class="hourBtn md-fab md-mini" id="{{hour.id}}" ng-click="hourClickHandler(hour.displayName)">{{hour.displayName}}</md-button>'+
'</div></div></div></div>' +
'<div ng-repeat="minutesLine in min5" layout="row" class="min5" ng-show="is5min()">' +
'<div flex layout="row" layout-align="center center" ng-repeat="minute in minutesLine">' +
'<md-button class="minuteBtn md-fab md-mini" id="{{minute.id}}" ng-click="minuteClickHandler(minute.displayName)">{{minute.displayName}}</md-button>'+
'</div></div>' +
'<div ng-repeat="minutesLine in min1" layout="row" class="min1" ng-hide="is5min()">' +
'<div flex layout="row" layout-align="center center" ng-repeat="minute in minutesLine">' +
'<md-button class="minuteBtn md-fab md-mini" id="{{minute.id}}" ng-click="minuteClickHandler(minute.displayName)">{{minute.displayName}}</md-button>' +
'</div></div>' +
'<div flex layout="row" layout-align="center center" class="toggle-pane"><md-button class="toggleBtn md-fab md-mini" ng-bind="getToggleBtnLbl()" ng-click="toggleManual5min()"></md-button></div></div>',
scope: {},
require: ['ngModel', 'sgTimePane'],
controller: TimePaneCtrl,
controllerAs: 'ctrl',
bindToController: true,
link: function(scope, element, attrs, controllers) {
var ngModelCtrl = controllers[0];
var sgTimePaneCtrl = controllers[1];
console.log(element);
var timePaneElement = element;
sgTimePaneCtrl.configureNgModel(ngModelCtrl,sgTimePaneCtrl, timePaneElement);
}
};
}
/** Class applied to the selected hour or minute cell/. */
//var SELECTED_TIME_CLASS = 'md-calendar-selected-date';
//var SELECTED_TIME_CLASS1 = 'md-raised';
var SELECTED_TIME_CLASS2 = 'md-primary';
/** Class applied to the focused hour or minute cell/. */
var FOCUSED_TIME_CLASS = 'md-focus';
/** Next identifier for calendar instance. */
var nextTimePaneUniqueId = 0;
function TimePaneCtrl($element, $attrs, $scope, $animate, $q, $mdConstant,
$mdTheming, $$mdDateUtil, $mdDateLocale, $mdInkRipple, $mdUtil) {
var m;
this.$scope = $scope;
this.$element = $element;
this.timePaneElement = $element[0].querySelector('.sg-time-pane');
this.$animate = $animate;
this.$q = $q;
this.$mdInkRipple = $mdInkRipple;
this.$mdUtil = $mdUtil;
this.keyCode = $mdConstant.KEY_CODE;
this.dateUtil = $$mdDateUtil;
this.id = nextTimePaneUniqueId++;
this.ngModelCtrl = null;
this.selectedTime = null;
this.displayTime = null;
this.isInitialized = false;
$scope.hours=[];
$scope.hours[0]=[];
$scope.hours[0][0]=[];
$scope.hours[0][1]=[];
$scope.hours[1]=[];
$scope.hours[1][0]=[];
$scope.hours[1][1]=[];
for(var i=0; i<6; i++){
$scope.hours[0][0][i] = {id:'tp-'+this.id+'-hour-'+i, displayName:i<10?"0"+i:""+i, selected:false};
$scope.hours[0][1][i] = {id:'tp-'+this.id+'-hour-'+(i+6),displayName:(i+6)<10?"0"+(i+6):""+(i+6), selected:false};
$scope.hours[1][0][i] = {id:'tp-'+this.id+'-hour-'+(i+12), displayName:""+(i+12), selected:false};
$scope.hours[1][1][i] = {id:'tp-'+this.id+'-hour-'+(i+18), displayName:""+(i+18), selected:false};
}
$scope.min5=[];
$scope.min5[0]=[];
$scope.min5[1]=[];
for(i=0; i<6; i++){
m=i*5;
$scope.min5[0][i] = {id:'tp-'+this.id+'-minute5-'+m, displayName:m<10?":0"+m:":"+m, selected:true};
$scope.min5[1][i] = {id:'tp-'+this.id+'-minute5-'+(m+30), displayName:":"+(m+30), selected:false};
}
$scope.min1=[];
for(i=0; i<12; i++){
$scope.min1[i]=[];
for(var ii=0; ii<5; ii++){
m=i*5 + ii;
$scope.min1[i][ii] = {id:'tp-'+this.id+'-minute-'+m, displayName:m<10?":0"+m:":"+m, selected:true};
}
}
$scope.show5min=true;
$scope.getToggleBtnLbl = function() {
return ($scope.is5min()) ? '>>' : '<<';
};
$scope.toggleManual5min = function() {
$scope.manual5min = !$scope.is5min();
};
$scope.is5min=function(){
if($scope.manual5min === true || $scope.manual5min === false) {
return $scope.manual5min;
}
else {
return $scope.show5min;
}
};
if (!$attrs.tabindex) {
$element.attr('tabindex', '-1');
}
var self = this;
this.hourClickHandler = function(displayVal) {
var updated = new Date(self.displayTime).setHours(Number(displayVal));
self.setNgModelValue(updated, 'hours');
};
$scope.hourClickHandler = this.hourClickHandler;
this.minuteClickHandler = function(displayVal) {
//remove leading ':'
var val = displayVal.substr(1);
var updated = new Date(self.displayTime).setMinutes(Number(val));
self.setNgModelValue(updated, 'minutes');
};
$scope.minuteClickHandler = this.minuteClickHandler;
this.attachTimePaneEventListeners();
}
TimePaneCtrl.$inject = ["$element", "$attrs", "$scope", "$animate", "$q", "$mdConstant", "$mdTheming", "$$mdDateUtil", "$mdDateLocale", "$mdInkRipple", "$mdUtil"];
TimePaneCtrl.prototype.configureNgModel = function(ngModelCtrl, sgTimePaneCtrl, timePaneElement) {
this.ngModelCtrl = ngModelCtrl;
var self = this;
ngModelCtrl.$render = function() {
self.changeSelectedTime(self.ngModelCtrl.$viewValue, sgTimePaneCtrl, timePaneElement);
};
};
/**
* Change the selected date in the time (ngModel value has already been changed).
*/
TimePaneCtrl.prototype.changeSelectedTime = function(date, sgTimePaneCtrl, timePaneElement) {
var self = this;
var previousSelectedTime = this.selectedTime;
this.selectedTime = new Date(date);
this.changeDisplayTime(date).then(function() {
// Remove the selected class from the previously selected date, if any.
if (previousSelectedTime) {
var prevH = previousSelectedTime.getHours();
var prevHCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+prevH);
if (prevHCell) {
prevHCell.classList.remove(SELECTED_TIME_CLASS2);
prevHCell.setAttribute('aria-selected', 'false');
}
var prevM = previousSelectedTime.getMinutes();
var prevMCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+prevM);
if (prevMCell) {
prevMCell.classList.remove(SELECTED_TIME_CLASS2);
prevMCell.setAttribute('aria-selected', 'false');
}
var prevM5Cell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+prevM);
if (prevM5Cell) {
prevM5Cell.classList.remove(SELECTED_TIME_CLASS2);
prevM5Cell.setAttribute('aria-selected', 'false');
}
}
// Apply the select class to the new selected date if it is set.
if (date) {
var d = new Date(date);
var newH = d.getHours();
var mCell, hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);
if (hCell) {
hCell.classList.add(SELECTED_TIME_CLASS2);
hCell.setAttribute('aria-selected', 'true');
}
var newM = d.getMinutes();
if (newM % 5 === 0) {
sgTimePaneCtrl.$scope.show5min = true;
mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+newM);
if (mCell) {
mCell.classList.add(SELECTED_TIME_CLASS2);
mCell.setAttribute('aria-selected', 'true');
}
}
else {
sgTimePaneCtrl.$scope.show5min = false;
}
mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+newM);
if (mCell) {
mCell.classList.add(SELECTED_TIME_CLASS2);
mCell.setAttribute('aria-selected', 'true');
}
}
});
};
TimePaneCtrl.prototype.changeDisplayTime = function(date) {
var d = new Date(date);
if (!this.isInitialized) {
this.buildInitialTimePaneDisplay();
return this.$q.when();
}
if (!this.dateUtil.isValidDate(d)) {
return this.$q.when();
}
this.displayTime = d;
return this.$q.when();
};
TimePaneCtrl.prototype.buildInitialTimePaneDisplay = function() {
this.displayTime = this.selectedTime || this.today;
this.isInitialized = true;
};
TimePaneCtrl.prototype.attachTimePaneEventListeners = function() {
// Keyboard interaction.
this.$element.on('keydown', angular.bind(this, this.handleKeyEvent));
};
/*** User input handling ***/
/**
* Handles a key event in the calendar with the appropriate action. The action will either
* be to select the focused date or to navigate to focus a new date.
* @param {KeyboardEvent} event
*/
TimePaneCtrl.prototype.handleKeyEvent = function(event) {
var self = this;
this.$scope.$apply(function() {
// Capture escape and emit back up so that a wrapping component
// (such as a time-picker) can decide to close.
if (event.which == self.keyCode.ESCAPE || event.which == self.keyCode.TAB) {
self.$scope.$emit('md-time-pane-close');
if (event.which == self.keyCode.TAB) {
event.preventDefault();
}
return;
}
// Remaining key events fall into two categories: selection and navigation.
// Start by checking if this is a selection event.
if (event.which === self.keyCode.ENTER) {
self.setNgModelValue(self.displayTime, 'enter');
event.preventDefault();
return;
}
// Selection isn't occuring, so the key event is either navigation or nothing.
/*var date = self.getFocusDateFromKeyEvent(event);
if (date) {
event.preventDefault();
event.stopPropagation();
// Since this is a keyboard interaction, actually give the newly focused date keyboard
// focus after the been brought into view.
self.changeDisplayTime(date).then(function () {
self.focus(date);
});
}*/
});
};
/**
* Sets the ng-model value for the time pane and emits a change event.
* @param {Date} date
*/
TimePaneCtrl.prototype.setNgModelValue = function(date, mode) {
this.$scope.$emit('sg-time-pane-change', {date:date, changed:mode});
this.ngModelCtrl.$setViewValue(date);
this.ngModelCtrl.$render();
};
/**
* Focus the cell corresponding to the given date.
* @param {Date=} opt_date
*/
TimePaneCtrl.prototype.focus = function(opt_date, sgTimePaneCtrl) {
var date = opt_date || this.selectedTime || this.today;
var previousFocus = this.timePaneElement.querySelector('.md-focus');
if (previousFocus) {
previousFocus.classList.remove(FOCUSED_TIME_CLASS);
}
if (date) {
var newH = date.getHours();
var hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);
if (hCell) {
hCell.classList.add(FOCUSED_TIME_CLASS);
hCell.focus();
}
}
};
})();
(function() {
'use strict';
angular.module('SOGo.Common')
.directive('sgTimepicker', timePickerDirective);
/**
* @ngdoc directive
* @name mdTimepicker
* @module material.components.timepicker
*
* @param {Date} ng-model The component's model. Expects a JavaScript Date object.
* @param {expression=} ng-change Expression evaluated when the model value changes.
* @param {boolean=} disabled Whether the timepicker is disabled.
*
* @description
* `<sg-timepicker>` is a component used to select a single time.
* For information on how to configure internationalization for the time picker,
* see `$mdTimeLocaleProvider`.
*
* @usage
* <hljs lang="html">
* <sg-timepicker ng-model="birthday"></sg-timepicker>
* </hljs>
*
*/
function timePickerDirective() {
return {
template:
// Buttons are not in the tab order because users can open the hours pane via keyboard
// interaction on the text input, and multiple tab stops for one component (picker)
// may be confusing.
'<md-button class="sg-timepicker-button md-icon-button" type="button" ' +
'tabindex="-1" aria-hidden="true" ' +
'ng-click="ctrl.openTimePane($event)">' +
//'<md-icon class="md-timepicker-calendar-icon" md-svg-icon="md-calendar"></md-icon>' +
'<i class="material-icons">access_time</i>' +
'</md-button>' +
'<div class="sg-timepicker-input-container" ' +
'ng-class="{\'sg-timepicker-focused\': ctrl.isFocused}">' +
'<input class="sg-timepicker-input" aria-haspopup="true" ' +
'ng-focus="ctrl.setFocused(true)" ng-blur="ctrl.setFocused(false)">' +
'<md-button type="button" md-no-ink ' +
'class="sg-timepicker-triangle-button md-icon-button" ' +
'ng-click="ctrl.openTimePane($event)" ' +
'aria-label="{{::ctrl.dateLocale.msgOpenCalendar}}">' +
'<div class="sg-timepicker-expand-triangle"></div>' +
'</md-button>' +
'</div>' +
// This pane will be detached from here and re-attached to the document body.
'<div class="sg-timepicker-time-pane md-whiteframe-z1">' +
'<div class="sg-timepicker-input-mask">' +
'<div class="sg-timepicker-input-mask-opaque"></div>' +
'</div>' +
'<div class="sg-timepicker-time">' +
'<sg-time-pane role="dialog" aria-label="{{::ctrl.dateLocale.msgCalendar}}" ' +
'ng-model="ctrl.time" ng-if="ctrl.isTimeOpen"></sg-time-pane>' +
'</div>' +
'</div>',
require: ['ngModel', 'sgTimepicker'],
scope: {
placeholder: '@mdPlaceholder'
},
controller: TimePickerCtrl,
controllerAs: 'ctrl',
bindToController: true,
link: function(scope, element, attr, controllers) {
var ngModelCtrl = controllers[0];
var mdTimePickerCtrl = controllers[1];
mdTimePickerCtrl.configureNgModel(ngModelCtrl);
}
};
}
/** Additional offset for the input's `size` attribute, which is updated based on its content. */
var EXTRA_INPUT_SIZE = 3;
/** Class applied to the container if the date is invalid. */
var INVALID_CLASS = 'sg-timepicker-invalid';
/** Default time in ms to debounce input event by. */
var DEFAULT_DEBOUNCE_INTERVAL = 500;
/**
* Controller for sg-timepicker.
*
* ngInject @constructor
*/
function TimePickerCtrl($scope, $element, $attrs, $compile, $timeout, $mdConstant, $mdTheming,
$mdUtil, $mdDateLocale, $$mdDateUtil, $$rAF) {
/** @final */
this.$compile = $compile;
/** @final */
this.$timeout = $timeout;
/** @final */
this.dateLocale = $mdDateLocale;
/** @final */
this.dateUtil = $$mdDateUtil;
/** @final */
this.$mdConstant = $mdConstant;
/* @final */
this.$mdUtil = $mdUtil;
/** @final */
this.$$rAF = $$rAF;
/** @type {!angular.NgModelController} */
this.ngModelCtrl = null;
/** @type {HTMLInputElement} */
this.inputElement = $element[0].querySelector('input');
/** @type {HTMLElement} */
this.inputContainer = $element[0].querySelector('.sg-timepicker-input-container');
/** @type {HTMLElement} Floating time pane. */
this.timePane = $element[0].querySelector('.sg-timepicker-time-pane');
/** @type {HTMLElement} Time icon button. */
this.timeButton = $element[0].querySelector('.sg-timepicker-button');
/**
* Element covering everything but the input in the top of the floating calendar pane.
* @type {HTMLElement}
*/
this.inputMask = $element[0].querySelector('.sg-timepicker-input-mask-opaque');
/** @final {!angular.JQLite} */
this.$element = $element;
/** @final {!angular.Attributes} */
this.$attrs = $attrs;
/** @final {!angular.Scope} */
this.$scope = $scope;
/** @type {Date} */
this.date = null;
/** @type {boolean} */
this.isFocused = false;
/** @type {boolean} */
this.isDisabled = false;
this.setDisabled($element[0].disabled || angular.isString($attrs.disabled));
/** @type {boolean} Whether the date-picker's calendar pane is open. */
this.isTimeOpen = false;
/**
* Element from which the calendar pane was opened. Keep track of this so that we can return
* focus to it when the pane is closed.
* @type {HTMLElement}
*/
this.timePaneOpenedFrom = null;
this.timePane.id = 'sg-time-pane' + $mdUtil.nextUid();
$mdTheming($element);
/** Pre-bound click handler is saved so that the event listener can be removed. */
this.bodyClickHandler = angular.bind(this, this.handleBodyClick);
// Unless the user specifies so, the datepicker should not be a tab stop.
// This is necessary because ngAria might add a tabindex to anything with an ng-model
// (based on whether or not the user has turned that particular feature on/off).
if (!$attrs.tabindex) {
$element.attr('tabindex', '-1');
}
this.installPropertyInterceptors();
this.attachChangeListeners();
this.attachInteractionListeners();
var self = this;
$scope.$on('$destroy', function() {
self.detachTimePane();
});
}
TimePickerCtrl.$inject = ["$scope", "$element", "$attrs", "$compile", "$timeout", "$mdConstant", "$mdTheming",
"$mdUtil", "$mdDateLocale", "$$mdDateUtil", "$$rAF"];
/**
* Sets up the controller's reference to ngModelController.
* @param {!angular.NgModelController} ngModelCtrl
*/
TimePickerCtrl.prototype.configureNgModel = function(ngModelCtrl) {
this.ngModelCtrl = ngModelCtrl;
var self = this;
ngModelCtrl.$render = function() {
self.time = self.ngModelCtrl.$viewValue;
self.inputElement.value = self.formatTime(self.time);
self.resizeInputElement();
};
};
TimePickerCtrl.prototype.formatTime = function(time) {
var t = new Date(time);
if(t) {
var h= t.getHours();
var m= t.getMinutes();
return (h<10?('0'+ h) : h) + ':' + (m<10?'0'+ m : m);
}
else return '';
};
/**
* Attach event listeners for both the text input and the md-time.
* Events are used instead of ng-model so that updates don't infinitely update the other
* on a change. This should also be more performant than using a $watch.
*/
TimePickerCtrl.prototype.attachChangeListeners = function() {
var self = this;
self.$scope.$on('sg-time-pane-change', function(event, data) {
var time = new Date(data.date);
self.ngModelCtrl.$setViewValue(time);
self.time = time;
self.inputElement.value = self.formatTime(self.time);
if(data.changed == 'minutes') {
self.closeTimePane();
}
self.resizeInputElement();
self.inputContainer.classList.remove(INVALID_CLASS);
});
var ngElement = angular.element(self.inputElement);
ngElement.on('input', angular.bind(self, self.resizeInputElement));
ngElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,
DEFAULT_DEBOUNCE_INTERVAL, self));
};
/** Attach event listeners for user interaction. */
TimePickerCtrl.prototype.attachInteractionListeners = function() {
var self = this;
var $scope = this.$scope;
var keyCodes = this.$mdConstant.KEY_CODE;
// Add event listener through angular so that we can triggerHandler in unit tests.
angular.element(self.inputElement).on('keydown', function(event) {
if (event.altKey && event.keyCode == keyCodes.DOWN_ARROW) {
self.openTimePane(event);
$scope.$digest();
}
});
$scope.$on('md-time-close', function() {
self.closeTimePane();
});
};
/**
* Capture properties set to the time-picker and imperitively handle internal changes.
* This is done to avoid setting up additional $watches.
*/
TimePickerCtrl.prototype.installPropertyInterceptors = function() {
var self = this;
if (this.$attrs.ngDisabled) {
// The expression is to be evaluated against the directive element's scope and not
// the directive's isolate scope.
this.$element.scope().$watch(this.$attrs.ngDisabled, function(isDisabled) {
self.setDisabled(isDisabled);
});
}
Object.defineProperty(this, 'placeholder', {
get: function() { return self.inputElement.placeholder; },
set: function(value) { self.inputElement.placeholder = value || ''; }
});
};
/**
* Sets whether the date-picker is disabled.
* @param {boolean} isDisabled
*/
TimePickerCtrl.prototype.setDisabled = function(isDisabled) {
this.isDisabled = isDisabled;
this.inputElement.disabled = isDisabled;
this.timeButton.disabled = isDisabled;
};
/**
* Resizes the input element based on the size of its content.
*/
TimePickerCtrl.prototype.resizeInputElement = function() {
this.inputElement.size = this.inputElement.value.length + EXTRA_INPUT_SIZE;
};
/**
* Sets the model value if the user input is a valid time.
* Adds an invalid class to the input element if not.
*/
TimePickerCtrl.prototype.handleInputEvent = function(self) {
var inputString = this.inputElement.value;
var arr = inputString.split(':');
if(arr.length < 2) {return;}
var h=Number(arr[0]);
var m=Number(arr[1]);
var newVal = new Date(this.time);
if (h && h>=0 && h<=23 && m && m>=0 && m<= 59 && angular.isDate(newVal)) {
newVal.setHours(h);
newVal.setMinutes(m);
this.ngModelCtrl.$setViewValue(newVal);
this.time = newVal;
this.inputContainer.classList.remove(INVALID_CLASS);
}
else {
// If there's an input string, it's an invalid time.
this.inputContainer.classList.toggle(INVALID_CLASS, inputString);
}
};
/** Position and attach the floating calendar to the document. */
TimePickerCtrl.prototype.attachTimePane = function() {
var timePane = this.timePane;
this.$element.addClass('sg-timepicker-open');
var elementRect = this.inputContainer.getBoundingClientRect();
var bodyRect = document.body.getBoundingClientRect();
timePane.style.left = (elementRect.left - bodyRect.left) + 'px';
timePane.style.top = (elementRect.top - bodyRect.top) + 'px';
document.body.appendChild(this.timePane);
// The top of the calendar pane is a transparent box that shows the text input underneath.
// Since the pane is flowing, though, the page underneath the pane *adjacent* to the input is
// also shown unless we cover it up. The inputMask does this by filling up the remaining space
// based on the width of the input.
this.inputMask.style.left = elementRect.width + 'px';
// Add CSS class after one frame to trigger open animation.
this.$$rAF(function() {
timePane.classList.add('md-pane-open');
});
};
/** Detach the floating time pane from the document. */
TimePickerCtrl.prototype.detachTimePane = function() {
this.$element.removeClass('sg-timepicker-open');
this.timePane.classList.remove('md-pane-open');
if (this.timePane.parentNode) {
// Use native DOM removal because we do not want any of the angular state of this element
// to be disposed.
this.timePane.parentNode.removeChild(this.timePane);
}
};
/**
* Open the floating time pane.
* @param {Event} event
*/
TimePickerCtrl.prototype.openTimePane = function(event) {
if (!this.isTimeOpen && !this.isDisabled) {
this.isTimeOpen = true;
this.timePaneOpenedFrom = event.target;
this.attachTimePane();
this.focusTime();
// Because the time pane is attached directly to the body, it is possible that the
// rest of the component (input, etc) is in a different scrolling container, such as
// an md-content. This means that, if the container is scrolled, the pane would remain
// stationary. To remedy this, we disable scrolling while the time pane is open, which
// also matches the native behavior for things like `<select>` on Mac and Windows.
this.$mdUtil.disableScrollAround(this.timePane);
// Attach click listener inside of a timeout because, if this open call was triggered by a
// click, we don't want it to be immediately propogated up to the body and handled.
var self = this;
this.$mdUtil.nextTick(function() {
document.body.addEventListener('click', self.bodyClickHandler);
}, false);
}
};
/** Close the floating time pane. */
TimePickerCtrl.prototype.closeTimePane = function() {
this.isTimeOpen = false;
this.detachTimePane();
this.timePaneOpenedFrom.focus();
this.timePaneOpenedFrom = null;
this.$mdUtil.enableScrolling();
document.body.removeEventListener('click', this.bodyClickHandler);
};
/** Gets the controller instance for the time in the floating pane. */
TimePickerCtrl.prototype.getTimePaneCtrl = function() {
return angular.element(this.timePane.querySelector('sg-time-pane')).controller('sgTimePane');
};
/** Focus the time in the floating pane. */
TimePickerCtrl.prototype.focusTime = function() {
// Use a timeout in order to allow the time to be rendered, as it is gated behind an ng-if.
var self = this;
this.$mdUtil.nextTick(function() {
var ctrl = self.getTimePaneCtrl();
self.getTimePaneCtrl().focus(null, ctrl);
}, false);
};
/**
* Sets whether the input is currently focused.
* @param {boolean} isFocused
*/
TimePickerCtrl.prototype.setFocused = function(isFocused) {
this.isFocused = isFocused;
};
/**
* Handles a click on the document body when the floating time pane is open.
* Closes the floating time pane if the click is not inside of it.
* @param {MouseEvent} event
*/
TimePickerCtrl.prototype.handleBodyClick = function(event) {
if (this.isTimeOpen) {
// TODO(jelbourn): way want to also include the md-datepicker itself in this check.
var isInTime = this.$mdUtil.getClosest(event.target, 'sg-time-pane');
if (!isInTime) {
this.closeTimePane();
}
this.$scope.$digest();
}
};
})();
+1 -1
View File
@@ -1,2 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("app",{url:"/addressbooks","abstract":!0,views:{addressbooks:{templateUrl:"UIxContactFoldersView",controller:"AddressBooksController",controllerAs:"app"}},resolve:{stateAddressbooks:stateAddressbooks}}).state("app.addressbook",{url:"/:addressbookId",views:{addressbook:{templateUrl:"addressbook",controller:"AddressBookController",controllerAs:"addressbook"}},resolve:{stateAddressbook:stateAddressbook}}).state("app.addressbook.new",{url:"/{contactType:(?:card|list)}/new",views:{card:{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}},resolve:{stateCard:stateNewCard}}).state("app.addressbook.card",{url:"/:cardId","abstract":!0,views:{card:{template:"<ui-view/>"}},resolve:{stateCard:stateCard}}).state("app.addressbook.card.view",{url:"/view",views:{"card@app.addressbook":{templateUrl:"UIxContactViewTemplate",controller:"CardController",controllerAs:"editor"}}}).state("app.addressbook.card.editor",{url:"/edit",views:{"card@app.addressbook":{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}}}),$urlRouterProvider.otherwise("/addressbooks/personal")}function stateAddressbooks(AddressBook){return AddressBook.$findAll(window.contactFolders)}function stateAddressbook($stateParams,AddressBook){return AddressBook.$find($stateParams.addressbookId).$futureAddressBookData}function stateNewCard($stateParams,stateAddressbook,Card){var tag="v"+$stateParams.contactType,card=new Card({pid:$stateParams.addressbookId,c_component:tag});return stateAddressbook.selectedCard=!0,card}function stateCard($stateParams,stateAddressbook){return stateAddressbook.selectedCard=$stateParams.cardId,stateAddressbook.$getCard($stateParams.cardId)}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.ContactsUI",["ngSanitize","ui.router","SOGo.Common","SOGo.PreferencesUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAddressbooks.$inject=["AddressBook"],stateAddressbook.$inject=["$stateParams","AddressBook"],stateNewCard.$inject=["$stateParams","stateAddressbook","Card"],stateCard.$inject=["$stateParams","stateAddressbook"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AddressBookController($scope,$state,$timeout,$mdDialog,focus,Card,AddressBook,Dialog,Settings,stateAddressbooks,stateAddressbook){function selectCard(card){$state.go("app.addressbook.card.view",{addressbookId:stateAddressbook.id,cardId:card.id})}function newComponent(ev){function ComponentDialogController(scope,$mdDialog,$state,addressbookId){scope.create=function(type){$mdDialog.hide(),$state.go("app.addressbook.new",{addressbookId:addressbookId,contactType:type})}}$mdDialog.show({parent:angular.element(document.body),targetEvent:ev,clickOutsideToClose:!0,escapeToClose:!0,template:['<md-dialog aria-label="'+l("Create component")+'">'," <md-dialog-content>",' <div layout="column">'," <md-button ng-click=\"create('card')\">"," "+l("Contact")," </md-button>"," <md-button ng-click=\"create('list')\">"," "+l("List")," </md-button>"," </div>"," </md-dialog-content>","</md-dialog>"].join(""),locals:{addressbookId:vm.selectedFolder.id},controller:ComponentDialogController}),ComponentDialogController.$inject=["scope","$mdDialog","$state","addressbookId"]}function notSelectedComponent(currentCard,type){return currentCard&&currentCard.c_component==type&&!currentCard.selected}function unselectCards(){_.each(vm.selectedFolder.cards,function(card){card.selected=!1})}function confirmDeleteSelectedCards(){Dialog.confirm(l("Warning"),l("Are you sure you want to delete the selected contacts?")).then(function(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$deleteCards(selectedCards),delete vm.selectedFolder.selectedCard},function(data,status){})}function saveSelectedCards(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected}),selectedUIDs=_.pluck(selectedCards,"id");window.location.href=ApplicationBaseURL+"/"+vm.selectedFolder.id+"/export?uid="+selectedUIDs.join("&uid=")}function copySelectedCards(folder){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$copyCards(selectedCards,folder).then(function(){},function(error){Dialog.alert(l("Error"),error)})}function selectAll(){_.each(vm.selectedFolder.cards,function(card){card.selected=!0})}function sort(field){vm.selectedFolder.$filter("",{sort:field})}function sortedBy(field){return vm.selectedFolder.$query.sort==field}function cancelSearch(){vm.mode.search=!1,vm.selectedFolder.$filter("")}var vm=this;AddressBook.selectedFolder=stateAddressbook,vm.selectedFolder=stateAddressbook,vm.selecLine truncated
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("app",{url:"/addressbooks","abstract":!0,views:{addressbooks:{templateUrl:"UIxContactFoldersView",controller:"AddressBooksController",controllerAs:"app"}},resolve:{stateAddressbooks:stateAddressbooks}}).state("app.addressbook",{url:"/:addressbookId",views:{addressbook:{templateUrl:"addressbook",controller:"AddressBookController",controllerAs:"addressbook"}},resolve:{stateAddressbook:stateAddressbook}}).state("app.addressbook.new",{url:"/{contactType:(?:card|list)}/new",views:{card:{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}},resolve:{stateCard:stateNewCard}}).state("app.addressbook.card",{url:"/:cardId","abstract":!0,views:{card:{template:"<ui-view/>"}},resolve:{stateCard:stateCard}}).state("app.addressbook.card.view",{url:"/view",views:{"card@app.addressbook":{templateUrl:"UIxContactViewTemplate",controller:"CardController",controllerAs:"editor"}}}).state("app.addressbook.card.editor",{url:"/edit",views:{"card@app.addressbook":{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}}}),$urlRouterProvider.otherwise("/addressbooks/personal")}function stateAddressbooks(AddressBook){return AddressBook.$findAll(window.contactFolders)}function stateAddressbook($stateParams,AddressBook){return AddressBook.$find($stateParams.addressbookId).$futureAddressBookData}function stateNewCard($stateParams,stateAddressbook,Card){var tag="v"+$stateParams.contactType,card=new Card({pid:$stateParams.addressbookId,c_component:tag});return stateAddressbook.selectedCard=!0,card}function stateCard($stateParams,stateAddressbook){return stateAddressbook.selectedCard=$stateParams.cardId,stateAddressbook.$getCard($stateParams.cardId)}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.ContactsUI",["ngSanitize","ui.router","angularFileUpload","ck","SOGo.Common","SOGo.PreferencesUI","SOGo.MailerUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAddressbooks.$inject=["AddressBook"],stateAddressbook.$inject=["$stateParams","AddressBook"],stateNewCard.$inject=["$stateParams","stateAddressbook","Card"],stateCard.$inject=["$stateParams","stateAddressbook"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AddressBookController($scope,$q,$state,$timeout,$mdDialog,focus,Account,Card,AddressBook,Dialog,Settings,stateAddressbooks,stateAddressbook){function selectCard(card){$state.go("app.addressbook.card.view",{addressbookId:stateAddressbook.id,cardId:card.id})}function newComponent(ev){function ComponentDialogController(scope,$mdDialog,$state,addressbookId){scope.create=function(type){$mdDialog.hide(),$state.go("app.addressbook.new",{addressbookId:addressbookId,contactType:type})}}$mdDialog.show({parent:angular.element(document.body),targetEvent:ev,clickOutsideToClose:!0,escapeToClose:!0,template:['<md-dialog aria-label="'+l("Create component")+'">'," <md-dialog-content>",' <div layout="column">'," <md-button ng-click=\"create('card')\">"," "+l("Contact")," </md-button>"," <md-button ng-click=\"create('list')\">"," "+l("List")," </md-button>"," </div>"," </md-dialog-content>","</md-dialog>"].join(""),locals:{addressbookId:vm.selectedFolder.id},controller:ComponentDialogController}),ComponentDialogController.$inject=["scope","$mdDialog","$state","addressbookId"]}function notSelectedComponent(currentCard,type){return currentCard&&currentCard.c_component==type&&!currentCard.selected}function unselectCards(){_.each(vm.selectedFolder.cards,function(card){card.selected=!1})}function confirmDeleteSelectedCards(){Dialog.confirm(l("Warning"),l("Are you sure you want to delete the selected contacts?")).then(function(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$deleteCards(selectedCards),delete vm.selectedFolder.selectedCard},function(data,status){})}function saveSelectedCards(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected}),selectedUIDs=_.pluck(selectedCards,"id");window.location.href=ApplicationBaseURL+"/"+vm.selectedFolder.id+"/export?uid="+selectedUIDs.join("&uid=")}function copySelectedCards(folder){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$copyCards(selectedCards,folder).then(function(){},function(error){Dialog.alert(l("Error"),error)})}function selectAll(){_.each(vm.selectedFolder.cards,function(card){card.selected=!0})}function sort(field){vm.selectedFolder.$filter("",{sort:field})}function sortedBy(field){return AddressBook.$query.sort==field}function cancelSearch(){vm.mode.search=!1,vm.selectedFolder.$filter("")}function newMessage($event,recipients){Account.$findALine truncated
//# sourceMappingURL=Contacts.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Contacts.js","sources":["Contacts/Contacts.app.js","Contacts/AddressBookController.js","Contacts/AddressBooksController.js","Contacts/CardController.js","Contacts/sgAddress.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","abstract","views","addressbooks","templateUrl","controller","controllerAs","resolve","stateAddressbooks","addressbook","stateAddressbook","card","stateCard","stateNewCard","template","card@app.addressbook","otherwise","AddressBook","$findAll","window","contactFolders","$stateParams","$find","addressbookId","$futureAddressBookData","Card","tag","contactType","pid","c_component","selectedCard","cardId","$getCard","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","module","config","run","$inject","AddressBookController","$scope","$state","$timeout","$mdDialog","focus","Dialog","Settings","selectCard","go","id","newComponent","ev","ComponentDialogController","scope","create","type","hide","show","parent","element","document","body","targetEvent","clickOutsideToClose","escapeToClose","l","join","locals","vm","selectedFolder","notSelectedComponent","currentCard","selected","unselectCards","_","each","cards","confirmDeleteSelectedCards","confirm","then","selectedCards","filter","$deleteCards","data","status","saveSelectedCards","selectedUIDs","pluck","location","href","ApplicationBaseURL","copySelectedCards","folder","$copyCards","alert","selectAll","sort","field","$filter","sortedBy","$query","cancelSearch","mode","search","this","AddressBooksController","User","select","editMode","newAddressbook","prompt","name","isEditable","isRemote","owner","UserLogin","$add","edit","originalAddressbook","extend","$omit","revertEditing","save","length","$rename","confirmDelete","service","isSubscription","$delete","importCards","exportCards","showLinks","LinksDialogController","close","share","$acl","$users","usersWithACL","users","subscribeToFolder","addressbookData","debug","$subscribe","activeUser","CardController","addOrgUnit","i","$addOrgUnit","addEmail","$addEmail","addPhone","$addPhone","addUrl","$addUrl","addAddress","$addAddress","addMember","$addMember","userFilter","excludedCards","dry","excludeLists","$cards","form","$valid","$save","indexOf","$reload","copy","err","log","reset","$reset","cancel","isNew","$fullname","ok","reject","o","viewRawSource","$event","$$resource","post","currentFolder","CardRawSourceDialogController","allEmailTypes","$EMAIL_TYPES","allTelTypes","$TEL_TYPES","allUrlTypes","$URL_TYPES","allAddressTypes","$ADDRESS_TYPES","categories","userFilterResults","sgAddress","restrict","addressLines","lines","locality_region","street","push","street2","locality","region","country","postalcode","directive"],"mappings":"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 truncated
{"version":3,"file":"Contacts.js","sources":["Contacts/Contacts.app.js","Contacts/AddressBookController.js","Contacts/AddressBooksController.js","Contacts/CardController.js","Contacts/sgAddress.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","abstract","views","addressbooks","templateUrl","controller","controllerAs","resolve","stateAddressbooks","addressbook","stateAddressbook","card","stateCard","stateNewCard","template","card@app.addressbook","otherwise","AddressBook","$findAll","window","contactFolders","$stateParams","$find","addressbookId","$futureAddressBookData","Card","tag","contactType","pid","c_component","selectedCard","cardId","$getCard","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","module","config","run","$inject","AddressBookController","$scope","$q","$state","$timeout","$mdDialog","focus","Account","Dialog","Settings","selectCard","go","id","newComponent","ev","ComponentDialogController","scope","create","type","hide","show","parent","element","document","body","targetEvent","clickOutsideToClose","escapeToClose","l","join","locals","vm","selectedFolder","notSelectedComponent","currentCard","selected","unselectCards","_","each","cards","confirmDeleteSelectedCards","confirm","then","selectedCards","filter","$deleteCards","data","status","saveSelectedCards","selectedUIDs","pluck","location","href","ApplicationBaseURL","copySelectedCards","folder","$copyCards","alert","selectAll","sort","field","$filter","sortedBy","$query","cancelSearch","mode","search","newMessage","$event","recipients","accounts","account","o","$getMailboxes","mailboxes","$newMessage","message","stateAccounts","stateMessage","stateRecipients","newMessageWithRecipient","recipient","fn","full","newMessageWithSelectedCards","promises","c_mail","length","push","c_cn","isDefined","refs","ref","email","$futureCardData","all","this","AddressBooksController","$mdToast","FileUploader","User","select","editMode","value","newAddressbook","prompt","name","isEditable","isRemote","owner","UserLogin","$add","edit","originalAddressbook","extend","$omit","revertEditing","save","$rename","confirmDelete","service","isSubscription","$delete","importCards","CardsImportDialogController","uploader","onProgressItem","item","progress","debug","onSuccessItem","response","headers","JSON","stringify","undefined","simple","content","imported","position","hideDelay","$reload","onCancelItem","onErrorItem","close","upload","uploadAll","exportCards","showLinks","LinksDialogController","share","$acl","$users","usersWithACL","users","subscribeToFolder","addressbookData","$subscribe","activeUser","CardController","addOrgUnit","i","$addOrgUnit","addBirthday","birthday","Date","addEmail","$addEmail","addPhone","$addPhone","addUrl","$addUrl","addAddress","$addAddress","addMember","$addMember","userFilter","excludedCards","dry","excludeLists","$cards","form","$valid","$save","indexOf","copy","err","log","reset","$reset","cancel","isNew","$fullname","ok","reject","exportCard","currentFolder","viewRawSource","$$resource","post","CardRawSourceDialogController","allEmailTypes","$EMAIL_TYPES","allTelTypes","$TEL_TYPES","allUrlTypes","$URL_TYPES","allAddressTypes","$ADDRESS_TYPES","categories","userFilterResults","sgAddress","restrict","addressLines","lines","locality_region","street","street2","locality","region","country","postalcode","directive"],"mappings":"CAGA,WACE,YAUA,SAASA,WAAUC,eAAgBC,oBACjCD,eACGE,MAAM,OACLC,IAAK,gBACLC,YAAU,EACVC,OACEC,cACEC,YAAa,wBACbC,WAAY,yBACZC,aAAc,QAGlBC,SACEC,kBAAmBA,qBAGtBT,MAAM,mBACLC,IAAK,kBACLE,OACEO,aACEL,YAAa,cACbC,WAAY,wBACZC,aAAc,gBAGlBC,SACEG,iBAAkBA,oBAGrBX,MAAM,uBACLC,IAAK,mCACLE,OACES,MACEP,YAAa,2BACbC,WAAY,iBACZC,aAAc,WAGlBC,SACEK,UAAWC,gBAGdd,MAAM,wBACLC,IAAK,WACLC,YAAU,EACVC,OACES,MACEG,SAAU,eAGdP,SACEK,UAAWA,aAGdb,MAAM,6BACLC,IAAK,QACLE,OACEa,wBACEX,YAAa,yBACbC,WAAY,iBACZC,aAAc,aAInBP,MAAM,+BACLC,IAAK,QACLE,OACEa,wBACEX,YAAa,2BACbC,WAAY,iBACZC,aAAc,aAMtBR,mBAAmBkB,UAAU,0BAO/B,QAASR,mBAAkBS,aACzB,MAAOA,aAAYC,SAASC,OAAOC,gBAOrC,QAASV,kBAAiBW,aAAcJ,aACtC,MAAOA,aAAYK,MAAMD,aAAaE,eAAeC,uBAOvD,QAASX,cAAaQ,aAAcX,iBAAkBe,MACpD,GAAIC,KAAM,IAAML,aAAaM,YACzBhB,KAAO,GAAIc,OAAOG,IAAKP,aAAaE,cAAeM,YAAaH,KAEpE,OADAhB,kBAAiBoB,cAAe,EACzBnB,KAOT,QAASC,WAAUS,aAAcX,kBAE/B,MADAA,kBAAiBoB,aAAeT,aAAaU,OACtCrB,iBAAiBsB,SAASX,aAAaU,QAOhD,QAASE,UAASC,YAChBA,WAAWC,IAAI,oBAAqB,SAASC,MAAOC,QAASC,SAAUC,WACrEC,QAAQC,MAAML,MAAOC,QAASC,SAAUC,aAjI5CG,QAAQC,OAAO,mBAAoB,aAAc,YAAa,oBAAqB,KAAM,cAAe,qBAAsB,kBAC3HC,OAAOhD,WACPiD,IAAIZ,UAKPrC,UAAUkD,SAAW,iBAAkB,sBAmFvCtC,kBAAkBsC,SAAW,eAQ7BpC,iBAAiBoC,SAAW,eAAgB,eAQ5CjC,aAAaiC,SAAW,eAAgB,mBAAoB,QAW5DlC,UAAUkC,SAAW,eAAgB,oBASrCb,SAASa,SAAW,iBClItB,WACE,YAMA,SAASC,uBAAsBC,OAAQC,GAAIC,OAAQC,SAAUC,UAAWC,MAAOC,QAAS7B,KAAMR,YAAasC,OAAQC,SAAUhD,kBAAmBE,kBAsB9I,QAAS+C,YAAW9C,MAClBuC,OAAOQ,GAAG,6BAA8BnC,cAAeb,iBAAiBiD,GAAI5B,OAAQpB,KAAKgD,KAG3F,QAASC,cAAaC,IA8BpB,QAASC,2BAA0BC,MAAOX,UAAWF,OAAQ3B,eAC3DwC,MAAMC,OAAS,SAASC,MACtBLine truncated
@@ -1,2 +1,2 @@
!function(){"use strict";function AddressBook(futureAddressBookData){if("function"!=typeof futureAddressBookData.then)if(this.init(futureAddressBookData),this.name&&!this.id){var newAddressBookData=AddressBook.$$resource.create("createFolder",this.name);this.$unwrap(newAddressBookData)}else this.id&&(this.$acl=new AddressBook.$$Acl("Contacts/"+this.id));else this.$unwrap(futureAddressBookData)}AddressBook.$factory=["$q","$timeout","$log","sgSettings","Resource","Card","Acl","Preferences",function($q,$timeout,$log,Settings,Resource,Card,Acl,Preferences){return angular.extend(AddressBook,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Contacts",Settings.activeUser()),$Card:Card,$$Acl:Acl,$Preferences:Preferences,activeUser:Settings.activeUser(),selectedFolder:null,$refreshTimeout:null}),AddressBook}];try{angular.module("SOGo.ContactsUI")}catch(e){angular.module("SOGo.ContactsUI",["SOGo.Common"])}angular.module("SOGo.ContactsUI").factory("AddressBook",AddressBook.$factory),AddressBook.$filterAll=function(search,options,excludedCards){var params={search:search};if(!search)return AddressBook.$cards=[],AddressBook.$q.when(AddressBook.$cards);if(angular.isUndefined(AddressBook.$cards))AddressBook.$cards=[];else if(AddressBook.$query==search)return AddressBook.$q.when(AddressBook.$cards);return AddressBook.$query=search,angular.extend(params,options),AddressBook.$$resource.fetch(null,"allContactSearch",params).then(function(response){var results,card,index,compareIds=function(data){return this.id==data.id};for(results=excludedCards?_.filter(response.contacts,function(data){return _.isUndefined(_.find(excludedCards,compareIds,data))}):response.contacts,index=AddressBook.$cards.length-1;index>=0;index--)card=AddressBook.$cards[index],_.isUndefined(_.find(results,compareIds,card))&&AddressBook.$cards.splice(index,1);return _.each(results,function(data,index){if(_.isUndefined(_.find(AddressBook.$cards,compareIds,data))){var card=new AddressBook.$Card(data,search);AddressBook.$cards.splice(index,0,card)}}),AddressBook.$cards})},AddressBook.$add=function(addressbook){var list,sibling,i;list=addressbook.isSubscription?this.$subscriptions:this.$addressbooks,sibling=_.find(list,function(o){return"personal"==addressbook.id||"personal"!=o.id&&1===o.name.localeCompare(addressbook.name)}),i=sibling?_.indexOf(_.pluck(list,"id"),sibling.id):1,list.splice(i,0,addressbook)},AddressBook.$findAll=function(data){var _this=this;return data&&(this.$addressbooks=[],this.$subscriptions=[],this.$remotes=[],angular.forEach(data,function(o,i){var addressbook=new AddressBook(o);addressbook.isRemote?_this.$remotes.push(addressbook):addressbook.isSubscription?_this.$subscriptions.push(addressbook):_this.$addressbooks.push(addressbook)})),this.$addressbooks},AddressBook.$find=function(addressbookId){var futureAddressBookData=AddressBook.$$resource.fetch(addressbookId,"view");return new AddressBook(futureAddressBookData)},AddressBook.$subscribe=function(uid,path){var _this=this;return AddressBook.$$resource.userResource(uid).fetch(path,"subscribe").then(function(addressbookData){var addressbook=new AddressBook(addressbookData);return _.isUndefined(_.find(_this.$subscriptions,function(o){return o.id==addressbookData.id}))&&AddressBook.$add(addressbook),addressbook})},AddressBook.prototype.init=function(data){this.$cards=[],this.cards=[],angular.extend(this,data),this.isOwned=AddressBook.activeUser.isSuperUser||this.owner==AddressBook.activeUser.login,this.isSubscription=!this.isRemote&&this.owner!=AddressBook.activeUser.login,this.$query={search:"name_or_address",value:"",sort:"c_cn",asc:"true"}},AddressBook.prototype.$id=function(){return this.id?AddressBook.$q.when(this.id):this.$futureAddressBookData.then(function(addressbook){return addressbook.id})},AddressBook.prototype.$selectedCount=function(){var count;return count=0,this.cards&&(count=_.filter(this.cards,function(card){return card.selected}).length),count},AddressBook.prototype.$startRefreshTimeout=function(){var _this=this;AddressBook.$refreshTimeout&&AddressBook.$timeout.cancel(AddressBook.$refreshTimeout),AddressBook.$Preferences.ready().then(function(){var refreshViewCheck=AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;if(refreshViewCheck&&"manually"!=refreshViewCheck){var f=angular.bind(_this,AddressBook.prototype.$reload);AddressBook.$refreshTimeout=AddressBook.$timeout(f,1e3*refreshViewCheck.timeInterval())}})},AddressBook.prototype.$reload=function(){var _this=this;return this.$startRefreshTimeout(),AddressBook.$$resource.fetch(this.id,"view").then(function(response){var index,card,results=response.cards,cards=_this.cards,compareIds=function(data){return this.id==data.id};for(index=cards.length-1;index>=0;index--)card=cards[index],_.isUndefined(_.find(results,compareIds,card))&&cards.splice(index,1);return _.each(results,function(data,index){if(_.isUndefined(_.find(cards,compareIds,data))){var card=new AddressBook.$Card(data);Line truncated
!function(){"use strict";function AddressBook(futureAddressBookData){if("function"!=typeof futureAddressBookData.then)if(this.init(futureAddressBookData),this.name&&!this.id){var newAddressBookData=AddressBook.$$resource.create("createFolder",this.name);this.$unwrap(newAddressBookData)}else this.id&&(this.$acl=new AddressBook.$$Acl("Contacts/"+this.id));else this.$unwrap(futureAddressBookData)}AddressBook.$factory=["$q","$timeout","$log","sgSettings","Resource","Card","Acl","Preferences",function($q,$timeout,$log,Settings,Resource,Card,Acl,Preferences){return angular.extend(AddressBook,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Contacts",Settings.activeUser()),$Card:Card,$$Acl:Acl,$Preferences:Preferences,$query:{search:"name_or_address",value:"",sort:"c_cn",asc:1},activeUser:Settings.activeUser(),selectedFolder:null,$refreshTimeout:null}),Preferences.ready().then(function(){Preferences.settings.Contact.SortingState&&(AddressBook.$query.sort=Preferences.settings.Contact.SortingState[0],AddressBook.$query.asc=parseInt(Preferences.settings.Contact.SortingState[1]))}),AddressBook}];try{angular.module("SOGo.ContactsUI")}catch(e){angular.module("SOGo.ContactsUI",["SOGo.Common"])}angular.module("SOGo.ContactsUI").factory("AddressBook",AddressBook.$factory),AddressBook.$filterAll=function(search,options,excludedCards){var params={search:search};if(!search)return AddressBook.$cards=[],AddressBook.$q.when(AddressBook.$cards);if(angular.isUndefined(AddressBook.$cards))AddressBook.$cards=[];else if(AddressBook.$query==search)return AddressBook.$q.when(AddressBook.$cards);return AddressBook.$query=search,angular.extend(params,options),AddressBook.$$resource.fetch(null,"allContactSearch",params).then(function(response){var results,card,index,compareIds=function(data){return this.id==data.id};for(results=excludedCards?_.filter(response.contacts,function(data){return _.isUndefined(_.find(excludedCards,compareIds,data))}):response.contacts,index=AddressBook.$cards.length-1;index>=0;index--)card=AddressBook.$cards[index],_.isUndefined(_.find(results,compareIds,card))&&AddressBook.$cards.splice(index,1);return _.each(results,function(data,index){if(_.isUndefined(_.find(AddressBook.$cards,compareIds,data))){var card=new AddressBook.$Card(data,search);AddressBook.$cards.splice(index,0,card)}}),AddressBook.$cards})},AddressBook.$add=function(addressbook){var list,sibling,i;list=addressbook.isSubscription?this.$subscriptions:this.$addressbooks,sibling=_.find(list,function(o){return"personal"==addressbook.id||"personal"!=o.id&&1===o.name.localeCompare(addressbook.name)}),i=sibling?_.indexOf(_.pluck(list,"id"),sibling.id):1,list.splice(i,0,addressbook)},AddressBook.$findAll=function(data){var _this=this;return data&&(this.$addressbooks=[],this.$subscriptions=[],this.$remotes=[],angular.forEach(data,function(o,i){var addressbook=new AddressBook(o);addressbook.isRemote?_this.$remotes.push(addressbook):addressbook.isSubscription?_this.$subscriptions.push(addressbook):_this.$addressbooks.push(addressbook)})),_.union(this.$addressbooks,this.$subscriptions,this.$remotes)},AddressBook.$find=function(addressbookId){var futureAddressBookData=AddressBook.$Preferences.ready().then(function(){return AddressBook.$$resource.fetch(addressbookId,"view",AddressBook.$query)});return new AddressBook(futureAddressBookData)},AddressBook.$subscribe=function(uid,path){var _this=this;return AddressBook.$$resource.userResource(uid).fetch(path,"subscribe").then(function(addressbookData){var addressbook=new AddressBook(addressbookData);return _.isUndefined(_.find(_this.$subscriptions,function(o){return o.id==addressbookData.id}))&&AddressBook.$add(addressbook),addressbook})},AddressBook.prototype.init=function(data){this.$isLoading=!0,this.$cards=[],this.cards=[],angular.extend(this,data),this.isOwned=AddressBook.activeUser.isSuperUser||this.owner==AddressBook.activeUser.login,this.isSubscription=!this.isRemote&&this.owner!=AddressBook.activeUser.login},AddressBook.prototype.$id=function(){return this.id?AddressBook.$q.when(this.id):this.$futureAddressBookData.then(function(addressbook){return addressbook.id})},AddressBook.prototype.$selectedCount=function(){var count;return count=0,this.cards&&(count=_.filter(this.cards,function(card){return card.selected}).length),count},AddressBook.prototype.$startRefreshTimeout=function(){var _this=this;AddressBook.$refreshTimeout&&AddressBook.$timeout.cancel(AddressBook.$refreshTimeout),AddressBook.$Preferences.ready().then(function(){var refreshViewCheck=AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;if(refreshViewCheck&&"manually"!=refreshViewCheck){var f=angular.bind(_this,AddressBook.prototype.$reload);AddressBook.$refreshTimeout=AddressBook.$timeout(f,1e3*refreshViewCheck.timeInterval())}})},AddressBook.prototype.$reload=function(){return this.$startRefreshTimeout(),this.$filter()},AddressBook.prototype.$filter=function(search,options,excludedCards){var _tLine truncated
//# sourceMappingURL=Contacts.services.js.map
@@ -1 +1 @@
{"version":3,"file":"Contacts.services.js","sources":["Contacts/AddressBook.service.js","Contacts/Card.service.js"],"names":["AddressBook","futureAddressBookData","then","this","init","name","id","newAddressBookData","$$resource","create","$unwrap","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Card","Acl","Preferences","angular","extend","activeUser","$Card","$Preferences","selectedFolder","$refreshTimeout","module","e","factory","$filterAll","search","options","excludedCards","params","$cards","when","isUndefined","$query","fetch","response","results","card","index","compareIds","data","_","filter","contacts","find","length","splice","each","$add","addressbook","list","sibling","i","isSubscription","$subscriptions","$addressbooks","o","localeCompare","indexOf","pluck","$findAll","_this","$remotes","forEach","isRemote","push","$find","addressbookId","$subscribe","uid","path","userResource","addressbookData","prototype","cards","isOwned","isSuperUser","owner","login","value","sort","asc","$id","$futureAddressBookData","$selectedCount","count","selected","$startRefreshTimeout","cancel","ready","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","$reload","timeInterval","$filter","dry","oldIndex","removedCards","findIndex","$rename","$save","$delete","promise","d","defer","remove","resolve","status","reject","$deleteCards","uids","map","post","difference","$copyCards","folder","save","$omit","$getCard","cardId","isError","isObject","key","futureCardData","partial","pid","newCardData","newguid","isNew","$TEL_TYPES","$EMAIL_TYPES","$URL_TYPES","$ADDRESS_TYPES","Gravatar","$gravatar","SOGoContactsCategories","$categories","join","$unwrapCollection","filterCategories","query","re","RegExp","category","collection","$futureCardData","refs","$$fullname","$fullname","$$email","$preferredEmail","$$image","image","empty","action","c_component","$shadowData","attribute","names","fn","c_cn","c_givenname","nickname","c_sn","c_org","emails","$description","description","title","role","orgUnits","unit","org","email","test","type","$shortFormat","fullname","$birthday","Date","birthday","$isCard","$isList","$addOrgUnit","orgUnit","$addCategory","categories","$addEmail","$addPhone","phones","$addUrl","url","urls","$addAddress","postoffice","street","street2","locality","region","country","postalcode","addresses","$addMember","$reset","reference","deep","copy","toString","desc"],"mappings":"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 truncated
{"version":3,"file":"Contacts.services.js","sources":["Contacts/AddressBook.service.js","Contacts/Card.service.js"],"names":["AddressBook","futureAddressBookData","then","this","init","name","id","newAddressBookData","$$resource","create","$unwrap","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Card","Acl","Preferences","angular","extend","activeUser","$Card","$Preferences","$query","search","value","sort","asc","selectedFolder","$refreshTimeout","ready","settings","Contact","SortingState","parseInt","module","e","factory","$filterAll","options","excludedCards","params","$cards","when","isUndefined","fetch","response","results","card","index","compareIds","data","_","filter","contacts","find","length","splice","each","$add","addressbook","list","sibling","i","isSubscription","$subscriptions","$addressbooks","o","localeCompare","indexOf","pluck","$findAll","_this","$remotes","forEach","isRemote","push","union","$find","addressbookId","$subscribe","uid","path","userResource","addressbookData","prototype","$isLoading","cards","isOwned","isSuperUser","owner","login","$id","$futureAddressBookData","$selectedCount","count","selected","$startRefreshTimeout","cancel","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","$reload","timeInterval","$filter","dry","isDefined","oldIndex","removedCards","findIndex","$rename","$save","$delete","promise","d","defer","remove","resolve","status","reject","$deleteCards","uids","map","post","difference","$copyCards","folder","save","$omit","$getCard","cardId","fullCard","cachedCard","$futureCardData","isError","isObject","key","futureCardData","partial","pid","newCardData","newguid","isNew","$TEL_TYPES","$EMAIL_TYPES","$URL_TYPES","$ADDRESS_TYPES","Gravatar","$gravatar","SOGoContactsCategories","$categories","join","$unwrapCollection","filterCategories","query","re","RegExp","category","collection","refs","$$fullname","$fullname","$$email","$preferredEmail","$$image","image","empty","action","c_component","$shadowData","attribute","names","fn","c_cn","c_givenname","nickname","c_sn","c_org","emails","$description","description","title","role","orgUnits","unit","org","email","test","type","$shortFormat","fullname","$birthday","birthday","getFullYear","getMonth","getDate","$isCard","$isList","$addOrgUnit","orgUnit","$addCategory","categories","$addEmail","$addPhone","phones","$addUrl","url","urls","$addAddress","postoffice","street","street2","locality","region","country","postalcode","addresses","$addMember","$reset","reference","Date","deep","copy","getTime","toString","desc"],"mappings":"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Line truncated
@@ -41,11 +41,18 @@
$Card: Card,
$$Acl: Acl,
$Preferences: Preferences,
$query: {search: 'name_or_address', value: '', sort: 'c_cn', asc: 1},
activeUser: Settings.activeUser(),
selectedFolder: null,
$refreshTimeout: null
});
// Initialize sort parameters from user's settings
Preferences.ready().then(function() {
if (Preferences.settings.Contact.SortingState) {
AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0];
AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]);
}
});
return AddressBook; // return constructor
}];
@@ -164,7 +171,7 @@
_this.$addressbooks.push(addressbook);
});
}
return this.$addressbooks;
return _.union(this.$addressbooks, this.$subscriptions, this.$remotes);
};
/**
@@ -174,8 +181,9 @@
* @returns an AddressBook object instance
*/
AddressBook.$find = function(addressbookId) {
var futureAddressBookData = AddressBook.$$resource.fetch(addressbookId, 'view');
var futureAddressBookData = AddressBook.$Preferences.ready().then(function() {
return AddressBook.$$resource.fetch(addressbookId, 'view', AddressBook.$query);
});
return new AddressBook(futureAddressBookData);
};
@@ -207,13 +215,13 @@
* @param {object} data - attributes of addressbook
*/
AddressBook.prototype.init = function(data) {
this.$isLoading = true;
this.$cards = [];
this.cards = [];
angular.extend(this, data);
// Add 'isOwned' and 'isSubscription' attributes based on active user (TODO: add it server-side?)
this.isOwned = AddressBook.activeUser.isSuperUser || this.owner == AddressBook.activeUser.login;
this.isSubscription = !this.isRemote && this.owner != AddressBook.activeUser.login;
this.$query = {search: 'name_or_address', value: '', sort: 'c_cn', asc: 'true'};
};
/**
@@ -282,34 +290,7 @@
var _this = this;
this.$startRefreshTimeout();
return AddressBook.$$resource.fetch(this.id, 'view')
.then(function(response) {
var index, card,
results = response.cards,
cards = _this.cards,
compareIds = function(data) {
return this.id == data.id;
};
// Remove cards that no longer exist
for (index = cards.length - 1; index >= 0; index--) {
card = cards[index];
if (_.isUndefined(_.find(results, compareIds, card))) {
cards.splice(index, 1);
}
}
// Add new cards
_.each(results, function(data, index) {
if (_.isUndefined(_.find(cards, compareIds, data))) {
var card = new AddressBook.$Card(data);
cards.splice(index, 0, card);
}
});
return cards;
});
return this.$filter();
};
/**
@@ -323,72 +304,78 @@
AddressBook.prototype.$filter = function(search, options, excludedCards) {
var _this = this;
if (options) {
angular.extend(this.$query, options);
this.$isLoading = true;
if (options.dry) {
if (!search) {
// No query specified
this.$cards = [];
return AddressBook.$q.when(this.$cards);
}
else if (this.$query.value == search) {
// Query hasn't changed
return AddressBook.$q.when(this.$cards);
return AddressBook.$Preferences.ready().then(function() {
if (options) {
angular.extend(AddressBook.$query, options);
if (options.dry) {
if (!search) {
// No query specified
_this.$cards = [];
return AddressBook.$q.when(_this.$cards);
}
else if (AddressBook.$query.value == search) {
// Query hasn't changed
return AddressBook.$q.when(_this.$cards);
}
}
}
}
this.$query.value = search;
if (angular.isDefined(search))
AddressBook.$query.value = search;
return this.$id().then(function(addressbookId) {
return AddressBook.$$resource.fetch(addressbookId, 'view', _this.$query);
}).then(function(response) {
var results, cards, card, index,
compareIds = function(data) {
return this.id == data.id;
};
if (options && options.dry) {
// Don't keep a copy of the resulting cards.
// This is usefull when doing autocompletion.
cards = _this.$cards;
}
else {
cards = _this.cards;
}
if (excludedCards) {
// Remove excluded cards from results
results = _.filter(response.cards, function(card) {
return _.isUndefined(_.find(excludedCards, compareIds, card));
return _this.$id().then(function(addressbookId) {
return AddressBook.$$resource.fetch(addressbookId, 'view', AddressBook.$query);
}).then(function(response) {
var results, cards, card, index,
compareIds = function(data) {
return _this.id == data.id;
};
if (options && options.dry) {
// Don't keep a copy of the resulting cards.
// This is usefull when doing autocompletion.
cards = _this.$cards;
}
else {
cards = _this.cards;
}
if (excludedCards) {
// Remove excluded cards from results
results = _.filter(response.cards, function(card) {
return _.isUndefined(_.find(excludedCards, compareIds, card));
});
}
else {
results = response.cards;
}
// Remove cards that no longer match the search query
for (index = cards.length - 1; index >= 0; index--) {
card = cards[index];
if (_.isUndefined(_.find(results, compareIds, card))) {
cards.splice(index, 1);
}
}
// Add new cards matching the search query
_.each(results, function(data, index) {
if (_.isUndefined(_.find(cards, compareIds, data))) {
var card = new AddressBook.$Card(data, search);
cards.splice(index, 0, card);
}
});
}
else {
results = response.cards;
}
// Remove cards that no longer match the search query
for (index = cards.length - 1; index >= 0; index--) {
card = cards[index];
if (_.isUndefined(_.find(results, compareIds, card))) {
cards.splice(index, 1);
}
}
// Add new cards matching the search query
_.each(results, function(data, index) {
if (_.isUndefined(_.find(cards, compareIds, data))) {
var card = new AddressBook.$Card(data, search);
cards.splice(index, 0, card);
}
// Respect the order of the results
_.each(results, function(data, index) {
var oldIndex, removedCards;
if (cards[index].id != data.id) {
oldIndex = _.findIndex(cards, compareIds, data);
removedCards = cards.splice(oldIndex, 1);
cards.splice(index, 0, removedCards[0]);
}
});
_this.$isLoading = false;
return cards;
});
// Respect the order of the results
_.each(results, function(data, index) {
var oldIndex, removedCards;
if (cards[index].id != data.id) {
oldIndex = _.findIndex(cards, compareIds, data);
removedCards = cards.splice(oldIndex, 1);
cards.splice(index, 0, removedCards[0]);
}
});
return cards;
});
};
@@ -484,8 +471,25 @@
* @returns a promise of the HTTP operation
*/
AddressBook.prototype.$getCard = function(cardId) {
var _this = this;
return this.$id().then(function(addressbookId) {
return AddressBook.$Card.$find(addressbookId, cardId);
var fullCard,
cachedCard = _.find(_this.cards, function(data) {
return cardId == data.id;
});
if (cachedCard && cachedCard.$futureCardData)
// Full card is available
return cachedCard;
fullCard = AddressBook.$Card.$find(addressbookId, cardId);
fullCard.$id().then(function(cardId) {
// Extend the Card object of the addressbook list with the full card description
if (cachedCard)
angular.extend(cachedCard, fullCard);
});
return fullCard;
});
};
@@ -519,6 +523,8 @@
_this.$startRefreshTimeout();
_this.$isLoading = false;
return _this;
});
}, function(data) {
@@ -6,8 +6,8 @@
/**
* @ngInject
*/
AddressBookController.$inject = ['$scope', '$state', '$timeout', '$mdDialog', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'stateAddressbooks', 'stateAddressbook'];
function AddressBookController($scope, $state, $timeout, $mdDialog, focus, Card, AddressBook, Dialog, Settings, stateAddressbooks, stateAddressbook) {
AddressBookController.$inject = ['$scope', '$q', '$state', '$timeout', '$mdDialog', 'sgFocus', 'Account', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'stateAddressbooks', 'stateAddressbook'];
function AddressBookController($scope, $q, $state, $timeout, $mdDialog, focus, Account, Card, AddressBook, Dialog, Settings, stateAddressbooks, stateAddressbook) {
var vm = this;
AddressBook.selectedFolder = stateAddressbook;
@@ -24,6 +24,9 @@
vm.sort = sort;
vm.sortedBy = sortedBy;
vm.cancelSearch = cancelSearch;
vm.newMessage = newMessage;
vm.newMessageWithSelectedCards = newMessageWithSelectedCards;
vm.newMessageWithRecipient = newMessageWithRecipient;
vm.mode = { search: false };
function selectCard(card) {
@@ -115,13 +118,83 @@
}
function sortedBy(field) {
return vm.selectedFolder.$query.sort == field;
return AddressBook.$query.sort == field;
}
function cancelSearch() {
vm.mode.search = false;
vm.selectedFolder.$filter('');
}
function newMessage($event, recipients) {
Account.$findAll().then(function(accounts) {
var account = _.filter(accounts, function(o) {
if (o.id === 0)
return o;
})[0];
// We must initialize the Account with its mailbox
// list before proceeding with message's creation
account.$getMailboxes().then(function(mailboxes) {
account.$newMessage().then(function(message) {
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: '../Mail/UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: accounts,
stateMessage: message,
stateRecipients: recipients
}
});
});
});
});
}
function newMessageWithRecipient($event, recipient, fn) {
var recipients = [{full: fn + ' <' + recipient + '>'}];
vm.newMessage($event, recipients);
}
function newMessageWithSelectedCards($event) {
var selectedCards = _.filter(vm.selectedFolder.cards, function(card) { return card.selected; });
var promises = [], recipients = [];
_.each(selectedCards, function(card) {
if (card.c_component == 'vcard' && card.c_mail.length) {
recipients.push({full: card.c_cn + ' <' + card.c_mail + '>'});
}
else if (card.c_component == 'vlist') {
// If the list's members were already fetch, use them
if (angular.isDefined(card.refs) && card.refs.length) {
_.each(card.refs, function(ref) {
if (ref.email.length)
recipients.push({full: ref.c_cn + ' <' + ref.email + '>'});
});
}
else {
promises.push(vm.selectedFolder.$getCard(card.id).then(function(card) {
return card.$futureCardData.then(function(data) {
_.each(data.refs, function(ref) {
if (ref.email.length)
recipients.push({full: ref.c_cn + ' <' + ref.email + '>'});
});
});
}));
}
}
});
$q.all(promises).then(function() {
if (recipients.length)
vm.newMessage($event, recipients);
});
}
}
angular
@@ -6,8 +6,8 @@
/**
* @ngInject
*/
AddressBooksController.$inject = ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$mdDialog', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'User', 'stateAddressbooks'];
function AddressBooksController($state, $scope, $rootScope, $stateParams, $timeout, $mdDialog, focus, Card, AddressBook, Dialog, Settings, User, stateAddressbooks) {
AddressBooksController.$inject = ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$mdDialog', '$mdToast', 'FileUploader', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'User', 'stateAddressbooks'];
function AddressBooksController($state, $scope, $rootScope, $stateParams, $timeout, $mdDialog, $mdToast, FileUploader, focus, Card, AddressBook, Dialog, Settings, User, stateAddressbooks) {
var vm = this;
vm.activeUser = Settings.activeUser;
@@ -26,6 +26,7 @@
function select(folder) {
vm.editMode = false;
AddressBook.$query.value = '';
$state.go('app.addressbook', {addressbookId: folder.id});
}
@@ -101,33 +102,116 @@
}
}
function importCards() {
function importCards($event, folder) {
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: true,
escapeToClose: true,
template: [
'<md-dialog flex="40" flex-sm="100" aria-label="' + l('Import Cards') + '">',
' <md-toolbar class="sg-padded">',
' <div class="md-toolbar-tools">',
' <md-icon class="material-icons sg-icon-toolbar-bg">import_export</md-icon>',
' <div class="md-flex">',
' <div class="sg-md-title">' + l('Import Cards') + '</div>',
' </div>',
' <md-button class="md-icon-button" ng-click="close()">',
' <md-icon aria-label="Close dialog">close</md-icon>',
' </md-button>',
' </div>',
' </md-toolbar>',
' <md-dialog-content>',
' <div layout="column">',
' <div layout="row" layout-align="start center">',
' <span>' + l('Select a vCard or LDIF file.') + '</span>',
' <label class="md-button" for="file-input">',
' <span>' + l('Choose File') + '</span>',
' </label>',
' <input id="file-input" type="file" nv-file-select="nv-file-select" uploader="uploader" ng-show="false"/>',
' </div>',
' <span ng-show="uploader.queue.length == 0">' + l('No file chosen') + '</span>',
' <span ng-show="uploader.queue.length > 0">{{ uploader.queue[0].file.name }}</span>',
' </div>',
' </md-dialog-content>',
' <div class="md-actions">',
' <md-button ng-disabled="uploader.queue.length == 0" ng-click="upload()">' + l('Upload') + '</md-button>',
' </div>',
'</md-dialog>'
].join(''),
controller: CardsImportDialogController,
locals: {
folder: folder
}
});
/**
* @ngInject
*/
CardsImportDialogController.$inject = ['scope', '$mdDialog', 'folder'];
function CardsImportDialogController(scope, $mdDialog, folder) {
scope.uploader = new FileUploader({
url: ApplicationBaseURL + '/' + folder.id + '/import',
onProgressItem: function(item, progress) {
console.debug(item); console.debug(progress);
},
onSuccessItem: function(item, response, status, headers) {
console.debug(item); console.debug('success = ' + JSON.stringify(response, undefined, 2));
$mdDialog.hide();
$mdToast.show(
$mdToast.simple()
.content(l('A total of %{0} cards were imported in the addressbook.', response.imported))
.position('top right')
.hideDelay(3000));
AddressBook.selectedFolder.$reload();
},
onCancelItem: function(item, response, status, headers) {
console.debug(item); console.debug('cancel = ' + JSON.stringify(response, undefined, 2));
},
onErrorItem: function(item, response, status, headers) {
console.debug(item); console.debug('error = ' + JSON.stringify(response, undefined, 2));
}
});
scope.close = function() {
$mdDialog.hide();
};
scope.upload = function() {
scope.uploader.uploadAll();
};
}
}
function exportCards() {
window.location.href = ApplicationBaseURL + '/' + vm.service.selectedFolder.id + '/exportFolder';
}
function showLinks(selectedFolder) {
function showLinks(addressbook) {
$mdDialog.show({
parent: angular.element(document.body),
clickOutsideToClose: true,
escapeToClose: true,
templateUrl: selectedFolder.id + '/links',
templateUrl: addressbook.id + '/links',
controller: LinksDialogController,
controllerAs: 'links',
locals: {
},
controller: LinksDialogController
addressbook: addressbook
}
});
/**
* @ngInject
*/
LinksDialogController.$inject = ['scope', '$mdDialog'];
function LinksDialogController(scope, $mdDialog) {
scope.close = function() {
LinksDialogController.$inject = ['$mdDialog', 'addressbook'];
function LinksDialogController($mdDialog, addressbook) {
var vm = this;
this.addressbook = addressbook;
this.close = close;
function close() {
$mdDialog.hide();
};
}
}
}
@@ -176,6 +176,8 @@
if (index > -1 && this[attribute].length > index) {
this[attribute].splice(index, 1);
}
else
delete this[attribute];
}
else {
// No arguments -- delete card
@@ -274,8 +276,16 @@
return fullname;
};
/**
* @function $birthday
* @memberof Card.prototype
* @returns the formatted birthday object
*/
Card.prototype.$birthday = function() {
return new Date(this.birthday * 1000);
if (this.birthday) {
return [this.birthday.getFullYear(), this.birthday.getMonth() + 1, this.birthday.getDate()].join('/');
}
return '';
};
Card.prototype.$isCard = function() {
@@ -437,25 +447,20 @@
var _this = this;
// Expose the promise
this.$futureCardData = futureCardData;
// Resolve the promise
this.$futureCardData.then(function(data) {
// Calling $timeout will force Angular to refresh the view
Card.$timeout(function() {
_this.init(data);
// Instanciate Card objects for list members
angular.forEach(_this.refs, function(o, i) {
if (o.email) o.emails = [{value: o.email}];
o.id = o.reference;
_this.refs[i] = new Card(o);
});
if (_this.birthday) {
_this.birthday = new Date(_this.birthday * 1000);
}
// Make a copy of the data for an eventual reset
_this.$shadowData = _this.$omit(true);
this.$futureCardData = futureCardData.then(function(data) {
_this.init(data);
// Instanciate Card objects for list members
angular.forEach(_this.refs, function(o, i) {
if (o.email) o.emails = [{value: o.email}];
o.id = o.reference;
_this.refs[i] = new Card(o);
});
if (_this.birthday) {
_this.birthday = new Date(_this.birthday * 1000);
}
// Make a copy of the data for an eventual reset
_this.$shadowData = _this.$omit(true);
return _this;
});
};
@@ -481,6 +486,15 @@
card[key] = value;
}
});
// We convert back our birthday object
if (!deep) {
if (card.birthday)
card.birthday = card.birthday.getTime()/1000;
else
card.birthday = 0;
}
return card;
};
@@ -21,6 +21,7 @@
vm.categories = {};
vm.userFilterResults = [];
vm.addOrgUnit = addOrgUnit;
vm.addBirthday = addBirthday;
vm.addEmail = addEmail;
vm.addPhone = addPhone;
vm.addUrl = addUrl;
@@ -28,15 +29,20 @@
vm.addMember = addMember;
vm.userFilter = userFilter;
vm.save = save;
vm.close = close;
vm.reset = reset;
vm.cancel = cancel;
vm.confirmDelete = confirmDelete;
vm.exportCard = exportCard;
vm.viewRawSource = viewRawSource;
function addOrgUnit() {
var i = vm.card.$addOrgUnit('');
focus('orgUnit_' + i);
}
function addBirthday() {
vm.card.birthday = new Date();
}
function addEmail() {
var i = vm.card.$addEmail('');
focus('email_' + i);
@@ -81,6 +87,12 @@
});
}
}
function close() {
$state.go('app.addressbook', { addressbookId: AddressBook.selectedFolder.id }).then(function() {
vm.card = null;
delete AddressBook.selectedFolder.selectedCard;
});
}
function reset() {
vm.card.$reset();
}
@@ -119,6 +131,10 @@
});
}
function exportCard() {
window.location.href = ApplicationBaseURL + '/' + vm.currentFolder.id + '/export?uid=' + vm.card.id;
}
function viewRawSource($event) {
Card.$$resource.post(vm.currentFolder.id + '/' + vm.card.id, "raw").then(function(data) {
$mdDialog.show({
@@ -4,7 +4,7 @@
(function() {
'use strict';
angular.module('SOGo.ContactsUI', ['ngSanitize', 'ui.router', 'SOGo.Common', 'SOGo.PreferencesUI'])
angular.module('SOGo.ContactsUI', ['ngSanitize', 'ui.router', 'angularFileUpload', 'ck', 'SOGo.Common', 'SOGo.PreferencesUI', 'SOGo.MailerUI'])
.config(configure)
.run(runBlock);
+1 -1
View File
@@ -1,2 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("mail",{url:"/Mail",views:{mailboxes:{templateUrl:"UIxMailMainFrame",controller:"MailboxesController",controllerAs:"app"}},resolve:{stateAccounts:stateAccounts}}).state("mail.account",{url:"/:accountId","abstract":!0,views:{mailbox:{template:"<ui-view/>"}},resolve:{stateAccount:stateAccount}}).state("mail.account.mailbox",{url:"/:mailboxId",views:{"mailbox@mail":{templateUrl:"UIxMailFolderTemplate",controller:"MailboxController",controllerAs:"mailbox"}},resolve:{stateMailbox:stateMailbox,stateMessages:stateMessages}}).state("mail.account.mailbox.message",{url:"/:messageId",views:{message:{templateUrl:"UIxMailViewTemplate",controller:"MessageController",controllerAs:"viewer"}},resolve:{stateMessage:stateMessage}}),$urlRouterProvider.otherwise("/Mail")}function stateAccounts($q,Account){var accounts=Account.$findAll(mailAccounts),promises=[];return angular.forEach(accounts,function(account,i){var mailboxes=account.$getMailboxes();promises.push(mailboxes.then(function(objects){return account}))}),$q.all(promises)}function stateAccount($stateParams,stateAccounts){return _.find(stateAccounts,function(account){return account.id==$stateParams.accountId})}function stateMailbox($stateParams,stateAccount,decodeUriFilter){var _find,mailboxId=decodeUriFilter($stateParams.mailboxId);return(_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==mailboxId});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox})(stateAccount.$mailboxes)}function stateMessages(stateMailbox){return stateMailbox.$filter()}function stateMessage(encodeUriFilter,$stateParams,$state,stateMailbox,stateMessages){var message=_.find(stateMailbox.$messages,function(messageObject){return messageObject.uid==$stateParams.messageId});return message?(stateMailbox.selectedMessage=$stateParams.messageId,message.$reload()):void $state.go("mail.account.mailbox",{accountId:stateMailbox.$account.id,mailboxId:encodeUriFilter(stateMailbox.path)})}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.MailerUI",["ngSanitize","ui.router","ck","angularFileUpload","SOGo.Common","SOGo.ContactsUI","ngAnimate","SOGo.PreferencesUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAccounts.$inject=["$q","Account"],stateAccount.$inject=["$stateParams","stateAccounts"],stateMailbox.$inject=["$stateParams","stateAccount","decodeUriFilter"],stateMessages.$inject=["stateMailbox"],stateMessage.$inject=["encodeUriFilter","$stateParams","$state","stateMailbox","stateMessages"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function MailboxController($state,$timeout,$mdDialog,stateAccounts,stateAccount,stateMailbox,encodeUriFilter,focus,Dialog,Account,Mailbox){function selectMessage(message){$state.go("mail.account.mailbox.message",{accountId:stateAccount.id,mailboxId:encodeUriFilter(stateMailbox.path),messageId:message.uid})}function unselectMessages(){_.each(vm.selectedFolder.$messages,function(message){message.selected=!1})}function confirmDeleteSelectedMessages(){Dialog.confirm(l("Warning"),l("Are you sure you want to delete the selected messages?")).then(function(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$deleteMessages(selectedUIDs).then(function(){var unseenCount=_.filter(selectedMessages,function(message){return!message.isread});vm.selectedFolder.$messages=_.difference(vm.selectedFolder.$messages,selectedMessages),vm.selectedFolder.unseenCount=-unseenCount},function(error){Dialog.alert(l("Error"),error)})})}function copySelectedMessages(folder){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$copyMessages(selectedUIDs,"/"+folder).then(function(){},function(error){Dialog.alert(l("Error"),error)})}function saveSelectedMessages(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");window.location.href=ApplicationBaseURL+"/"+vm.selectedFolder.id+"/saveMessages?uid="+selectedUIDs.join(",")}function selectAll(){_.each(vm.selectedFolder.$messages,function(message){message.selected=!0})}function markSelectedMessagesAsFlagged(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$flagMessages(selectedUIDs,"\\Flagged","add").then(function(d){_.forEach(selectedMessages,function(message){message.isflagged=!0})})}function markSelectedMessagesAsUnread(){var seLine truncated
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("mail",{url:"/Mail",views:{mailboxes:{templateUrl:"UIxMailMainFrame",controller:"MailboxesController",controllerAs:"app"}},resolve:{stateAccounts:stateAccounts}}).state("mail.account",{url:"/:accountId","abstract":!0,views:{mailbox:{template:"<ui-view/>"}},resolve:{stateAccount:stateAccount}}).state("mail.account.mailbox",{url:"/:mailboxId",views:{"mailbox@mail":{templateUrl:"UIxMailFolderTemplate",controller:"MailboxController",controllerAs:"mailbox"}},resolve:{stateMailbox:stateMailbox,stateMessages:stateMessages}}).state("mail.account.mailbox.message",{url:"/:messageId",views:{message:{templateUrl:"UIxMailViewTemplate",controller:"MessageController",controllerAs:"viewer"}},resolve:{stateMessage:stateMessage}}),$urlRouterProvider.otherwise("/Mail")}function stateAccounts($q,Account){var accounts=Account.$findAll(mailAccounts),promises=[];return angular.forEach(accounts,function(account,i){var mailboxes=account.$getMailboxes();promises.push(mailboxes.then(function(objects){return account}))}),$q.all(promises)}function stateAccount($stateParams,stateAccounts){return _.find(stateAccounts,function(account){return account.id==$stateParams.accountId})}function stateMailbox($stateParams,stateAccount,decodeUriFilter){var _find,mailboxId=decodeUriFilter($stateParams.mailboxId);return(_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==mailboxId});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox})(stateAccount.$mailboxes)}function stateMessages(stateMailbox){return stateMailbox.$filter()}function stateMessage(encodeUriFilter,$stateParams,$state,stateMailbox,stateMessages){var message=_.find(stateMailbox.$messages,function(messageObject){return messageObject.uid==$stateParams.messageId});return message?(stateMailbox.selectedMessage=$stateParams.messageId,message.$reload()):void $state.go("mail.account.mailbox",{accountId:stateMailbox.$account.id,mailboxId:encodeUriFilter(stateMailbox.path)})}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.MailerUI",["ngSanitize","ui.router","ck","angularFileUpload","SOGo.Common","SOGo.ContactsUI","ngAnimate","SOGo.PreferencesUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAccounts.$inject=["$q","Account"],stateAccount.$inject=["$stateParams","stateAccounts"],stateMailbox.$inject=["$stateParams","stateAccount","decodeUriFilter"],stateMessages.$inject=["stateMailbox"],stateMessage.$inject=["encodeUriFilter","$stateParams","$state","stateMailbox","stateMessages"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function sgImip(){function link(scope,iElement,attrs,ctrl){ctrl.pathToAttachment=attrs.sgImipPath}return{restrict:"A",link:link,controller:"sgImipController"}}function sgImipController($scope,User){var vm=this;$scope.delegateInvitation=!1,$scope.delegatedTo="",$scope.searchText="",$scope.userFilter=function($query){return User.$filter($query)},$scope.iCalendarAction=function(action){var data;"delegate"==action&&(data={receiveUpdates:!1,delegatedTo:$scope.delegatedTo.c_email}),$scope.viewer.message.$imipAction(vm.pathToAttachment,action,data)}}sgImipController.$inject=["$scope","User"],angular.module("SOGo.MailerUI").controller("sgImipController",sgImipController).directive("sgImip",sgImip)}();
//# sourceMappingURL=Mailer.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Mailer.js","sources":["Mailer/Mailer.app.js","Mailer/MailboxController.js","Mailer/MailboxesController.js","Mailer/MessageController.js","Mailer/MessageEditorController.js","Mailer/sgIMIP.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","views","mailboxes","templateUrl","controller","controllerAs","resolve","stateAccounts","abstract","mailbox","template","stateAccount","mailbox@mail","stateMailbox","stateMessages","message","stateMessage","otherwise","$q","Account","accounts","$findAll","mailAccounts","promises","angular","forEach","account","i","$getMailboxes","push","then","objects","all","$stateParams","_","find","id","accountId","decodeUriFilter","_find","mailboxId","o","path","children","length","$mailboxes","$filter","encodeUriFilter","$state","$messages","messageObject","uid","messageId","selectedMessage","$reload","go","$account","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","module","config","run","$inject","MailboxController","$timeout","$mdDialog","focus","Dialog","Mailbox","selectMessage","unselectMessages","each","vm","selectedFolder","selected","confirmDeleteSelectedMessages","confirm","l","selectedMessages","filter","selectedUIDs","pluck","$deleteMessages","unseenCount","isread","difference","alert","copySelectedMessages","folder","$copyMessages","saveSelectedMessages","window","location","href","ApplicationBaseURL","join","selectAll","markSelectedMessagesAsFlagged","$flagMessages","d","isflagged","markSelectedMessagesAsUnread","sort","field","sortedBy","$query","cancelSearch","mode","search","newMessage","$event","$newMessage","show","parent","element","document","body","targetEvent","clickOutsideToClose","escapeToClose","locals","stateRecipients","this","service","MailboxesController","Settings","User","Preferences","newFolder","parentFolder","prompt","name","$newMailbox","data","status","delegate","MailboxDelegationController","$scope","userFilter","delegates","closeModal","hide","removeUser","user","$removeDelegate","addUser","$addDelegate","userToAdd","searchText","users","editFolder","editMode","revertEditing","$reset","selectFolder","saveFolder","$rename","compactFolder","$compact","emptyTrashFolder","$emptyTrash","exportMails","confirmDelete","$delete","markFolderRead","$markAsRead","share","$acl","$users","usersWithACL","metadataForFolder","type","icon","setFolderAs","$setFolderAs","reload","refreshUnseenCount","unseenCountFolders","includes","$$flattenMailboxes","isDefined","$$resource","post","ready","refreshViewCheck","defaults","SOGoRefreshViewCheck","timeInterval","MessageController","Message","doDelete","index","findIndex","splice","showMailEditor","recipients","reply","$reply","replyAll","$replyAll","forward","$forward","edit","$editableContent","recipient","viewRawSource","MessageRawSourceDialogController","scope","close","tags","$watchCollection","oldTags","newTags","tag","removeTag","MessageEditorController","FileUploader","AddressBook","cancel","autosave","send","$send","contactFilter","deferred","defer","$filterAll","results","invoke","promise","autosaveDrafts","$save","SOGoMailAutoSave","autocomplete","to","cc","bcc","hideCc","hideBcc","identities","flatten","uploader","$absolutePath","asDraft","autoUpload","alias","onProgressItem","item","progress","debug","onSuccessItem","response","headers","$setUID","JSON","stringify","undefined","onCancelItem","$deleteAttachment","file","removeFromQueue","onErrorItem","actionName","msgObject","editable","union","localeCode","LocaleCode","sgImip","link","iElement","attrs","ctrl","pathToAttachment","sgImipPath","restrict","sgImipController","delegateInvitation","delegatedTo","iCalendarAction","action","receiveUpdates","c_email","viewer","$imipAction","directive"],"mappings":"CAGA,WACE,YAUA,SAASA,WAAUC,eAAgBC,oBACjCD,eACGE,MAAM,QACLC,IAAK,QACLC,OACEC,WACEC,YAAa,mBACbC,WAAY,sBACZC,aAAc,QAGlBC,SACEC,cAAeA,iBAGlBR,MAAM,gBACLC,IAAK,cACLQ,YAAU,EACVP,OACEQ,SACEC,SAAU,eAGdJ,SACEK,aAAcA,gBAGjBZ,MAAM,wBACLC,IAAK,cACLC,OACEW,gBACET,YAAa,wBACbC,WAAY,oBACZC,aAAc,YAGlBC,SACEO,aAAcA,aACdC,cAAeA,iBAgBlBf,MAAM,gCACLC,IAAK,cACLC,OACEc,SACEZ,YAAa,sBACbC,WAAY,oBACZC,aAAc,WAGlBC,SACEU,aAAcA,gBA4BpBlB,mBAAmBmB,UAAU,SAc/B,QAASV,eAAcW,GAAIC,SACzB,GAAIC,UAAWD,QAAQE,SAASC,cAC5BC,WAQJ,OANAC,SAAQC,QAAQL,SAAU,SAASM,QAASC,GAC1C,GAAIzB,WAAYwB,QAAQE,eACxBL,UAASM,KAAK3B,UAAU4B,KAAK,SAASC,SACpC,MAAOL,cAGJR,GAAGc,IAAIT,UAOhB,QAASZ,cAAasB,aAAc1B,eAClC,MAAO2B,GAAEC,KAAK5B,cAAe,SAASmB,SACpC,MAAOA,SAAQU,IAAMH,aAAaI,YAQtC,QAASxB,cAAaoB,aAActB,aAAc2B,iBAChD,GACIC,OADAC,UAAYF,gBAAgBL,aAAaO,UAgB7C,QAbAD,MAAQ,SAASrC,WACf,GAAIO,SAAUyB,EAAEC,KAAKjC,UAAW,SAASuC,GACvC,MAAOA,GAAEC,MAAQF,WASnB,OAPK/B,UACHe,QAAQC,QAAQvB,UAAW,SAASuC,IAC7BhC,SAAWgC,EAAEE,UAAYF,EAAEE,SAASC,OAAS,IAChDnC,QAAU8B,MAAME,EAAEE,aAIjBlC,UAEIE,aAAakC,YAO5B,QAAS/B,eAAcD,cACrB,MAAOA,cAAaiC,UAetB,QAAS9B,cAAa+B,gBAAiBd,aAAce,OAAQnC,aAAcC,eACzE,GAAIC,SAAUmB,EAAEC,KAAKtB,aAAaoC,UAAW,SAASC,eACpD,MAAOA,eAAcC,KAAOlB,aAALine truncated
{"version":3,"file":"Mailer.js","sources":["Mailer/Mailer.app.js","Mailer/sgIMIP.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","views","mailboxes","templateUrl","controller","controllerAs","resolve","stateAccounts","abstract","mailbox","template","stateAccount","mailbox@mail","stateMailbox","stateMessages","message","stateMessage","otherwise","$q","Account","accounts","$findAll","mailAccounts","promises","angular","forEach","account","i","$getMailboxes","push","then","objects","all","$stateParams","_","find","id","accountId","decodeUriFilter","_find","mailboxId","o","path","children","length","$mailboxes","$filter","encodeUriFilter","$state","$messages","messageObject","uid","messageId","selectedMessage","$reload","go","$account","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","module","config","run","$inject","sgImip","link","scope","iElement","attrs","ctrl","pathToAttachment","sgImipPath","restrict","sgImipController","$scope","User","vm","this","delegateInvitation","delegatedTo","searchText","userFilter","$query","iCalendarAction","action","data","receiveUpdates","c_email","viewer","$imipAction","directive"],"mappings":"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","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* JavaScript for SOGo.MailerUI module */\n\n(function() {\n 'use strict';\n\n angular.module('SOGo.MailerUI', ['ngSanitize', 'ui.router', 'ck', 'angularFileUpload', 'SOGo.Common', 'SOGo.ContactsUI', 'ngAnimate', 'SOGo.PreferencesUI'])\n .config(configure)\n .run(runBlock);\n\n /**\n * @ngInject\n */\n configure.$inject = ['$stateProvider', '$urlRouterProvider'];\n function configure($stateProvider, $urlRouterProvider) {\n $stateProvider\n .state('mail', {\n url: '/Mail',\n views: {\n mailboxes: {\n templateUrl: 'UIxMailMainFrame', // UI/Templates/MailerUI/UIxMailMainFrame.wox\n controller: 'MailboxesController',\n controllerAs: 'app'\n }\n },\n resolve: {\n stateAccounts: stateAccounts\n }\n })\n .state('mail.account', {\n url: '/:accountId',\n abstract: true,\n views: {\n mailbox: {\n template: '<ui-view/>'\n }\n },\n resolve: {\n stateAccount: stateAccount\n }\n })\n .state('mail.account.mailbox', {\n url: '/:mailboxId',\n views: {\n 'mailbox@mail': {\n templateUrl: 'UIxMailFolderTemplate', // UI/Templates/MailerUI/UIxMailFolderTemplate.wox\n controller: 'MailboxController',\n controllerAs: 'mailbox'\n }\n },\n resolve: {\n Line truncated
+2 -1
View File
@@ -1,2 +1,3 @@
!function(){"use strict";function Account(futureAccountData){"function"!=typeof futureAccountData.then&&(angular.extend(this,futureAccountData),_.each(this.identities,function(identity){identity.fullName?identity.full=identity.fullName+" <"+identity.email+">":identity.full="<"+identity.email+">"}),Account.$log.debug("Account: "+JSON.stringify(futureAccountData,void 0,2)))}Account.$factory=["$q","$timeout","$log","sgSettings","Resource","Mailbox","Message",function($q,$timeout,$log,Settings,Resource,Mailbox,Message){return angular.extend(Account,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.baseURL(),Settings.activeUser()),$Mailbox:Mailbox,$Message:Message}),Account}];try{angular.module("SOGo.MailerUI")}catch(e){angular.module("SOGo.MailerUI",["SOGo.Common"])}angular.module("SOGo.MailerUI").factory("Account",Account.$factory),Account.$findAll=function(data){var collection=[];return data&&angular.forEach(data,function(o,i){o.id=i,collection[i]=new Account(o)}),collection},Account.prototype.$getMailboxes=function(options){var _this=this,deferred=Account.$q.defer();return!this.$mailboxes||options&&options.reload?Account.$Mailbox.$find(this).then(function(data){_this.$mailboxes=data,_this.$flattenMailboxes({reload:!0}),deferred.resolve(_this.$mailboxes)}):deferred.resolve(this.$mailboxes),deferred.promise},Account.prototype.$flattenMailboxes=function(options){var _this=this,allMailboxes=[],_visit=function(mailboxes){_.each(mailboxes,function(o){allMailboxes.push(o),o.children&&o.children.length>0&&_visit(o.children)})};return!this.$$flattenMailboxes||options&&options.reload?(_visit(this.$mailboxes),_this.$$flattenMailboxes=allMailboxes):allMailboxes=this.$$flattenMailboxes,allMailboxes},Account.prototype.$getMailboxByType=function(type){var mailbox,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.type==type});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};mailbox=_find(this.$mailboxes),console.debug(mailbox),console.debug(this.specialMailboxes)},Account.prototype.$getMailboxByPath=function(path){var mailbox=null,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==path});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};return mailbox=_find(this.$mailboxes)},Account.prototype.$newMailbox=function(path,name){var _this=this,deferred=Account.$q.defer();return Account.$$resource.post(path,"createFolder",{name:name}).then(function(){_this.$getMailboxes({reload:!0}),deferred.resolve()},function(response){deferred.reject(response.error)}),deferred.promise},Account.prototype.$newMessage=function(){var _this=this;return Account.$$resource.fetch(this.id.toString(),"compose").then(function(data){Account.$log.debug("New message (compose): "+JSON.stringify(data,void 0,2));var message=new Account.$Message(data.accountId,_this.$getMailboxByPath(data.mailboxPath),data);return message}).then(function(message){return Account.$$resource.fetch(message.$absolutePath({asDraft:!0}),"edit").then(function(data){return Account.$log.debug("New message (edit): "+JSON.stringify(data,void 0,2)),angular.extend(message.editable,data),message})})},Account.prototype.$addDelegate=function(user){var _this=this,deferred=Account.$q.defer(),param={uid:user.uid};return!user.uid||_.indexOf(_.pluck(this.delegates,"uid"),user.uid)>-1?deferred.resolve():Account.$$resource.fetch(this.id.toString(),"addDelegate",param).then(function(){_this.delegates.push(user),deferred.resolve(_this.users)},function(data,status){deferred.reject(l("An error occured please try again."))}),deferred.promise},Account.prototype.$removeDelegate=function(uid){var _this=this,param={uid:uid};return Account.$$resource.fetch(this.id.toString(),"removeDelegate",param).then(function(){var i=_.indexOf(_.pluck(_this.delegates,"uid"),uid);i>=0&&_this.delegates.splice(i,1)})}}(),function(){"use strict";function Mailbox(account,futureMailboxData){if(this.$account=account,"function"!=typeof futureMailboxData.then){if(this.init(futureMailboxData),this.name&&!this.path){var newMailboxData=Mailbox.$$resource.create("createFolder",this.name);this.$unwrap(newMailboxData)}}else this.$unwrap(futureMailboxData)}Mailbox.$factory=["$q","$timeout","$log","sgSettings","Resource","Message","Acl","Preferences","sgMailbox_PRELOAD",function($q,$timeout,$log,Settings,Resource,Message,Acl,Preferences,PRELOAD){return angular.extend(Mailbox,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Mail",Settings.activeUser()),$Message:Message,$$Acl:Acl,$Preferences:Preferences,$query:{sort:"date",asc:0},selectedFolder:null,$refreshTimeout:null,PRELOAD:PRELOAD}),Preferences.ready().then(function(){Preferences.settings.Mail.SortingState&&(Mailbox.$query.sort=Preferences.settings.Mail.SortingState[0],Mailbox.$query.asc=parseInt(PreLine truncated
!function(){"use strict";function Account(futureAccountData){"function"!=typeof futureAccountData.then&&(angular.extend(this,futureAccountData),_.each(this.identities,function(identity){identity.fullName?identity.full=identity.fullName+" <"+identity.email+">":identity.full="<"+identity.email+">"}),Account.$log.debug("Account: "+JSON.stringify(futureAccountData,void 0,2)))}Account.$factory=["$q","$timeout","$log","sgSettings","Resource","Mailbox","Message",function($q,$timeout,$log,Settings,Resource,Mailbox,Message){return angular.extend(Account,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Mail",Settings.activeUser()),$Mailbox:Mailbox,$Message:Message}),Account}];try{angular.module("SOGo.MailerUI")}catch(e){angular.module("SOGo.MailerUI",["SOGo.Common"])}angular.module("SOGo.MailerUI").factory("Account",Account.$factory),Account.$findAll=function(data){return data?Account.$unwrapCollection(data):Account.$$resource.fetch("","mailAccounts").then(function(o){return Account.$unwrapCollection(o)})},Account.$unwrapCollection=function(data){var collection=[];return angular.forEach(data,function(o,i){o.id=i,collection[i]=new Account(o)}),collection},Account.prototype.$getMailboxes=function(options){var _this=this;return!this.$mailboxes||options&&options.reload?Account.$Mailbox.$find(this).then(function(data){return _this.$mailboxes=data,_this.$flattenMailboxes({reload:!0}),_this.$mailboxes}):Account.$q.when(this.$mailboxes)},Account.prototype.$flattenMailboxes=function(options){var _this=this,allMailboxes=[],_visit=function(mailboxes){_.each(mailboxes,function(o){allMailboxes.push(o),o.children&&o.children.length>0&&_visit(o.children)})};return!this.$$flattenMailboxes||options&&options.reload?(_visit(this.$mailboxes),_this.$$flattenMailboxes=allMailboxes):allMailboxes=this.$$flattenMailboxes,allMailboxes},Account.prototype.$getMailboxByType=function(type){var mailbox,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.type==type});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};mailbox=_find(this.$mailboxes),console.debug(mailbox),console.debug(this.specialMailboxes)},Account.prototype.$getMailboxByPath=function(path){var mailbox=null,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==path});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};return mailbox=_find(this.$mailboxes)},Account.prototype.$newMailbox=function(path,name){var _this=this;return Account.$$resource.post(path.toString(),"createFolder",{name:name}).then(function(){_this.$getMailboxes({reload:!0})})},Account.prototype.$newMessage=function(){var _this=this;return Account.$$resource.fetch(this.id.toString(),"compose").then(function(data){Account.$log.debug("New message (compose): "+JSON.stringify(data,void 0,2));var message=new Account.$Message(data.accountId,_this.$getMailboxByPath(data.mailboxPath),data);return message}).then(function(message){return Account.$$resource.fetch(message.$absolutePath({asDraft:!0}),"edit").then(function(data){return Account.$log.debug("New message (edit): "+JSON.stringify(data,void 0,2)),angular.extend(message.editable,data),message})})},Account.prototype.$addDelegate=function(user){var _this=this,deferred=Account.$q.defer(),param={uid:user.uid};return!user.uid||_.indexOf(_.pluck(this.delegates,"uid"),user.uid)>-1?deferred.resolve():Account.$$resource.fetch(this.id.toString(),"addDelegate",param).then(function(){_this.delegates.push(user),deferred.resolve(_this.users)},function(data,status){deferred.reject(l("An error occured please try again."))}),deferred.promise},Account.prototype.$removeDelegate=function(uid){var _this=this,param={uid:uid};return Account.$$resource.fetch(this.id.toString(),"removeDelegate",param).then(function(){var i=_.indexOf(_.pluck(_this.delegates,"uid"),uid);i>=0&&_this.delegates.splice(i,1)})}}(),function(){"use strict";function Mailbox(account,futureMailboxData){if(this.$account=account,"function"!=typeof futureMailboxData.then){if(this.init(futureMailboxData),this.name&&!this.path){var newMailboxData=Mailbox.$$resource.create("createFolder",this.name);this.$unwrap(newMailboxData)}}else this.$unwrap(futureMailboxData)}Mailbox.$factory=["$q","$timeout","$log","sgSettings","Resource","Message","Acl","Preferences","sgMailbox_PRELOAD",function($q,$timeout,$log,Settings,Resource,Message,Acl,Preferences,PRELOAD){return angular.extend(Mailbox,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Mail",Settings.activeUser()),$Message:Message,$$Acl:Acl,$Preferences:Preferences,$query:{sort:"date",asc:0},selectedFolder:null,$refreshTimeout:null,PRELOAD:PRELOAD}),Preferences.ready().then(function(){Preferences.settings.Mail.SortingState&&(Mailbox.$query.sort=Preferences.settings.Mail.SortingStLine truncated
mailbox=account.$mailboxes[0],$state.go("mail.account.mailbox",{accountId:account.id,mailboxId:encodeUriFilter(mailbox.path)})),vm.refreshUnseenCount()}MailboxesController.$inject=["$state","$timeout","$mdDialog","sgFocus","encodeUriFilter","Dialog","sgSettings","Account","Mailbox","User","Preferences","stateAccounts"],angular.module("SOGo.MailerUI").controller("MailboxesController",MailboxesController)}(),function(){"use strict";function MessageController($scope,$state,$mdDialog,stateAccounts,stateAccount,stateMailbox,stateMessage,encodeUriFilter,focus,Dialog,Account,Mailbox,Message){function doDelete(){stateMailbox.$deleteMessages([stateMessage.uid]).then(function(){var index=_.findIndex(stateMailbox.$messages,function(o){return o.uid==stateMessage.uid});-1!=index&&stateMailbox.$messages.splice(index,1),vm.message=null,$state.go("mail.account.mailbox",{accountId:stateAccount.id,mailboxId:encodeUriFilter(stateMailbox.path)})})}function showMailEditor($event,message,recipients){null===messageDialog&&(angular.isDefined(recipients)||(recipients=[]),messageDialog=$mdDialog.show({parent:angular.element(document.body),targetEvent:$event,clickOutsideToClose:!1,escapeToClose:!1,templateUrl:"UIxMailEditor",controller:"MessageEditorController",controllerAs:"editor",locals:{stateAccounts:vm.accounts,stateMessage:message,stateRecipients:recipients}})["finally"](function(){messageDialog=null}))}function close(){$state.go("mail.account.mailbox",{accountId:stateAccount.id,mailboxId:encodeUriFilter(stateMailbox.path)}).then(function(){vm.message=null,delete stateMailbox.selectedMessage})}function reply($event){var message=vm.message.$reply();showMailEditor($event,message)}function replyAll($event){var message=vm.message.$replyAll();showMailEditor($event,message)}function forward($event){var message=vm.message.$forward();showMailEditor($event,message)}function edit($event){vm.message.$editableContent().then(function(){showMailEditor($event,vm.message)})}function newMessage($event,recipient){var message=vm.account.$newMessage();showMailEditor($event,message,[recipient])}function saveMessage(){window.location.href=ApplicationBaseURL+"/"+vm.mailbox.id+"/saveMessages?uid="+vm.message.uid}function viewRawSource($event){Message.$$resource.post(vm.message.id,"viewsource").then(function(data){function MessageRawSourceDialogController(scope,$mdDialog){scope.close=function(){$mdDialog.hide()}}$mdDialog.show({parent:angular.element(document.body),targetEvent:$event,clickOutsideToClose:!0,escapeToClose:!0,template:['<md-dialog flex="80" flex-sm="100" aria-label="'+l("View Message Source")+'">'," <md-dialog-content>"," <pre>",data," </pre>"," </md-dialog-content>",' <div class="md-actions">',' <md-button ng-click="close()">'+l("Close")+"</md-button>"," </div>","</md-dialog>"].join(""),controller:MessageRawSourceDialogController}),MessageRawSourceDialogController.$inject=["scope","$mdDialog"]})}var vm=this,messageDialog=null;vm.accounts=stateAccounts,vm.account=stateAccount,vm.mailbox=stateMailbox,vm.message=stateMessage,vm.service=Message,vm.tags={searchText:"",selected:""},vm.doDelete=doDelete,vm.close=close,vm.reply=reply,vm.replyAll=replyAll,vm.forward=forward,vm.edit=edit,vm.newMessage=newMessage,vm.saveMessage=saveMessage,vm.viewRawSource=viewRawSource,$scope.$watchCollection("viewer.message.flags",function(oldTags,newTags){_.each(_.difference(newTags,oldTags),function(tag){vm.message.removeTag(tag)})})}MessageController.$inject=["$scope","$state","$mdDialog","stateAccounts","stateAccount","stateMailbox","stateMessage","encodeUriFilter","sgFocus","Dialog","Account","Mailbox","Message"],angular.module("SOGo.MailerUI").controller("MessageController",MessageController)}(),function(){"use strict";function MessageEditorController($stateParams,$state,$q,$mdDialog,FileUploader,stateAccounts,stateMessage,stateRecipients,$timeout,encodeUriFilter,focus,Dialog,Account,Mailbox,AddressBook,Preferences){function cancel(){vm.autosave&&$timeout.cancel(vm.autosave),$mdDialog.cancel()}function send(){vm.autosave&&$timeout.cancel(vm.autosave),vm.message.$send().then(function(data){$mdDialog.hide()},function(data){Dialog.alert(l(data.status),l(data.message))})}function contactFilter($query){return AddressBook.$filterAll($query)}function addRecipient(user){var recipient=[];return angular.isString(user)?user:(user.$$fullname&&recipient.push(user.$$fullname),user.$$email&&recipient.push("<"+user.$$email+">"),recipient.join(" "))}function autosaveDrafts(){vm.message.$save(),Preferences.defaults.SOGoMailAutoSave&&(vm.autosave=$timeout(vm.autosaveDrafts,1e3*Preferences.defaults.SOGoMailAutoSave*60))}var vm=this;vm.addRecipient=addRecipient,vm.autocomplete={to:{},cc:{},bcc:{}},vm.autosave=null,vm.autosaveDrafts=autosaveDrafts,vm.hideCc=!0,vm.hideBcc=!0,vm.cancel=cancel,vm.send=send,vm.contactFilter=contactFilter,vm.identities=_.pluck(_.flatten(_.pluck(stateAccounts,"identities")),"full"),vm.uploader=new FileUploader({url:stateMessage.$absoluteLine truncated
//# sourceMappingURL=Mailer.services.js.map
@@ -1 +1 @@
{"version":3,"file":"Mailer.services.js","sources":["Mailer/Account.service.js","Mailer/Mailbox.service.js","Mailer/Message.service.js"],"names":["Account","futureAccountData","then","angular","extend","this","_","each","identities","identity","fullName","full","email","$log","debug","JSON","stringify","undefined","$factory","$q","$timeout","Settings","Resource","Mailbox","Message","$$resource","baseURL","activeUser","$Mailbox","$Message","module","e","factory","$findAll","data","collection","forEach","o","i","id","prototype","$getMailboxes","options","_this","deferred","defer","$mailboxes","reload","$find","$flattenMailboxes","resolve","promise","allMailboxes","_visit","mailboxes","push","children","length","$$flattenMailboxes","$getMailboxByType","type","mailbox","_find","find","console","specialMailboxes","$getMailboxByPath","path","$newMailbox","name","post","response","reject","error","$newMessage","fetch","toString","message","accountId","mailboxPath","$absolutePath","asDraft","editable","$addDelegate","user","param","uid","indexOf","pluck","delegates","users","status","l","$removeDelegate","splice","account","futureMailboxData","$account","init","newMailboxData","create","$unwrap","Acl","Preferences","PRELOAD","$$Acl","$Preferences","$query","sort","asc","selectedFolder","$refreshTimeout","ready","settings","Mail","SortingState","parseInt","constant","LOOKAHEAD","SIZE","$unwrapCollection","createMailboxes","level","index","map","split","component","asCSSIdentifier","join","$isLoading","$messages","uidsMap","$id","$acl","$isEditable","isEditable","isUndefined","$shadowData","$omit","$selectedCount","count","filter","selected","$filter","sortingAttributes","filters","isDefined","unseenCount","cancel","searchInput","secondFilter","match","searchBy","copy","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","timeInterval","$loadMessage","messageId","endIndex","uids","futureHeadersData","startIndex","max","loaded","subject","Math","min","loading","$unwrapHeaders","$rename","findParent","parent","parentMailbox","$save","sibling","localeCompare","$compact","$setFolderAs","$emptyTrash","$markAsRead","$flagMessages","flags","operation","msgUIDs","$delete","remove","$deleteMessages","$copyMessages","folder","$moveMessages","$reset","value","key","save","$futureMailboxData","headers","invoke","threaded","reduce","msgs","msg","object","isError","j","messageHeaders","futureMessageData","$mailbox","$hasUnsafeContent","$loadUnsafeContent","to","cc","bcc","$formatFullAddresses","$sce","Gravatar","$gravatar","SOGoMailLabelsColors","$tags","filterTags","query","re","RegExp","keys","tag","search","draftId","$setUID","oldUID","$shortAddress","address","loadUnsafeContent","$content","parts","part","msgclass","content","alternatePart","preferredPart","contentType","isArray","mixedPart","safeContent","html","unsafeContent","document","createElement","innerHTML","suffix","element","elements","querySelectorAll","attr","removeAttr","trustAs","participants","participant","image","compile","$editableContent","text","addTag","$addOrRemoveTag","removeTag","$imipAction","action","$reload","$sendMDN","shouldAskReceipt","$deleteAttachment","filename","attachmentAttrs","attachment","toggleFlag","isflagged","$reply","$newDraft","$replyAll","$forward","$send","$futureMessageData","isread"],"mappings":"CAEA,WACE,YAOA,SAASA,SAAQC,mBAEuB,kBAA3BA,mBAAkBC,OAC3BC,QAAQC,OAAOC,KAAMJ,mBACrBK,EAAEC,KAAKF,KAAKG,WAAY,SAASC,UAC3BA,SAASC,SACXD,SAASE,KAAOF,SAASC,SAAW,KAAOD,SAASG,MAAQ,IAE5DH,SAASE,KAAO,IAAMF,SAASG,MAAQ,MAE3CZ,QAAQa,KAAKC,MAAM,YAAcC,KAAKC,UAAUf,kBAAmBgB,OAAW,KAalFjB,QAAQkB,UAAY,KAAM,WAAY,OAAQ,aAAc,WAAY,UAAW,UAAW,SAASC,GAAIC,SAAUP,KAAMQ,SAAUC,SAAUC,QAASC,SAUtJ,MATArB,SAAQC,OAAOJ,SACbmB,GAAIA,GACJC,SAAUA,SACVP,KAAMA,KACNY,WAAY,GAAIH,UAASD,SAASK,UAAWL,SAASM,cACtDC,SAAUL,QACVM,SAAUL,UAGLxB,SAOT,KACEG,QAAQ2B,OAAO,iBAEjB,MAAMC,GACJ5B,QAAQ2B,OAAO,iBAAkB,gBAEnC3B,QAAQ2B,OAAO,iBACZE,QAAQ,UAAWhC,QAAQkB,UAQ9BlB,QAAQiC,SAAW,SAASC,MAC1B,GAAIC,cAQJ,OAPID,OAEF/B,QAAQiC,QAAQF,KAAM,SAASG,EAAGC,GAChCD,EAAEE,GAAKD,EACPH,WAAWG,GAAK,GAAItC,SAAQqC,KAGzBF,YAUTnC,QAAQwC,UAAUC,cAAgB,SAASC,SACzC,GAAIC,OAAQtC,KACRuC,SAAW5C,QAAQmB,GAAG0B,OAa1B,QAXIxC,KAAKyC,YAAgBJ,SAAWA,QAAQK,OAI1C/C,QAAQ4B,SAASoB,MAAM3C,MAAMH,KAAK,SAASgC,MACzCS,MAAMG,WAAaZ,KACnBS,MAAMM,mBAAmBF,QAAQ,IACjCH,SAASM,QAAQP,MAAMG,cANzBF,SAASM,QAAQ7C,KAAKyC,YAUjBF,SAASO,SAUlBnD,QAAQwC,UAAUS,kBAAoB,SAASP,SAC7C,GAAIC,OAAQtC,KACR+C,gBACAC,OAAS,SAASC,WAChBhD,EAAEC,KAAK+C,UAAW,SAASjB,GACzBe,aAAaG,KAAKlB,GACdA,EAAEmB,UAAYnB,EAAEmB,SAASC,OAAS,GACpCJ,OAAOhB,EAAEmB,YAanB,QARInD,KAAKqD,oBAAwBhB,SAAWA,QAAQK,QAIlDM,OAAOhD,KAAKyC,YACZH,MAAMe,mBAAqBN,cAJ3BA,aAAe/C,KAAKqD,mBAOfN,cAGTpD,QAAQwC,UAAUmB,kBAAoB,SAASC,MAC7C,GAAIC,SAEAC,MAAQ,SAASR,WACf,GAAIO,SAAUvD,EAAEyD,KAAKT,UAAW,SAASjB,GACvC,MAAOA,GAAEuB,MAAQA,MASnB,OAPKC,UACH1D,QAAQiC,QAAQkB,UAAW,SAASjB,IAC7BwB,SAAWxB,EAAEmB,UAAYnB,EAAEmB,SAASC,OAAS,IAChDI,QAAUC,MAAMzB,EAAEmB,aAIjBK,QAEbA,SAAUC,MAAMzD,KAAKyC,YAErBkB,QAAQlD,MAAM+C,SACdG,QAAQlD,MAAMT,KAAK4D,mLine truncated
{"version":3,"file":"Mailer.services.js","sources":["Mailer/Account.service.js","Mailer/Mailbox.service.js","Mailer/Message.service.js","Mailer/MailboxController.js","Mailer/MailboxesController.js","Mailer/MessageController.js","Mailer/MessageEditorController.js"],"names":["Account","futureAccountData","then","angular","extend","this","_","each","identities","identity","fullName","full","email","$log","debug","JSON","stringify","undefined","$factory","$q","$timeout","Settings","Resource","Mailbox","Message","$$resource","activeUser","$Mailbox","$Message","module","e","factory","$findAll","data","$unwrapCollection","fetch","o","collection","forEach","i","id","prototype","$getMailboxes","options","_this","$mailboxes","reload","$find","$flattenMailboxes","when","allMailboxes","_visit","mailboxes","push","children","length","$$flattenMailboxes","$getMailboxByType","type","mailbox","_find","find","console","specialMailboxes","$getMailboxByPath","path","$newMailbox","name","post","toString","$newMessage","message","accountId","mailboxPath","$absolutePath","asDraft","editable","$addDelegate","user","deferred","defer","param","uid","indexOf","pluck","delegates","resolve","users","status","reject","l","promise","$removeDelegate","splice","account","futureMailboxData","$account","init","newMailboxData","create","$unwrap","Acl","Preferences","PRELOAD","$$Acl","$Preferences","$query","sort","asc","selectedFolder","$refreshTimeout","ready","settings","Mail","SortingState","parseInt","constant","LOOKAHEAD","SIZE","createMailboxes","level","index","map","split","component","asCSSIdentifier","join","$isLoading","$messages","uidsMap","$id","$acl","$isEditable","isEditable","isUndefined","$shadowData","$omit","getLength","getItemAtIndex","$loadMessage","$selectedCount","count","filter","selected","$filter","sortingAttributes","filters","isDefined","unseenCount","cancel","searchInput","secondFilter","match","searchBy","copy","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","timeInterval","messageId","endIndex","uids","futureHeadersData","startIndex","max","loaded","subject","Math","min","loading","$unwrapHeaders","$rename","findParent","parent","parentMailbox","$save","sibling","localeCompare","$compact","$setFolderAs","$emptyTrash","$markAsRead","$flagMessages","flags","operation","msgUIDs","$delete","remove","$deleteMessages","$copyMessages","folder","$moveMessages","$reset","value","key","save","error","$futureMailboxData","headers","invoke","threaded","reduce","msgs","msg","object","isError","j","messageHeaders","futureMessageData","lazy","$mailbox","$hasUnsafeContent","$loadUnsafeContent","$showDetailedRecipients","to","cc","bcc","$formatFullAddresses","$sce","Gravatar","$gravatar","SOGoMailLabelsColors","$tags","filterTags","query","re","RegExp","keys","tag","search","draftId","$setUID","oldUID","shortname","replace","image","$shortRecipients","result","$shortAddress","address","loadUnsafeContent","showDetailedRecipients","$content","parts","part","msgclass","content","alternatePart","preferredPart","contentType","isArray","mixedPart","safeContent","html","unsafeContent","document","createElement","innerHTML","suffix","element","elements","querySelectorAll","attr","removeAttr","trustAs","participants","participant","compile","$editableContent","text","addTag","$addOrRemoveTag","removeTag","$imipAction","action","$reload","$sendMDN","shouldAskReceipt","$deleteAttachment","filename","attachmentAttrs","attachment","toggleFlag","isflagged","$reply","$newDraft","$replyAll","$forward","origin","response","$send","startsWith","isanswered","isforwarded","$futureMessageData","isread","MailboxController","$state","$mdDialog","stateAccounts","stateAccount","stateMailbox","encodeUriFilter","focus","Dialog","selectMessage","go","mailboxId","unselectMessages","vm","confirmDeleteSelectedMessages","confirm","selectedMessages","selectedUIDs","difference","alert","copySelectedMessages","saveSelectedMessages","window","location","href","ApplicationBaseURL","selectAll","markSelectedMessagesAsFlagged","d","markSelectedMessagesAsUnread","field","sortedBy","cancelSearch","mode","newMessage","$event","messageDialog","show","body","targetEvent","clickOutsideToClose","escapeToClose","templateUrl","controller","controllerAs","locals","accounts","stateMessage","stateRecipients","service","$inject","MailboxesController","User","newFolder","parentFolder","prompt","delegate","MailboxDelegationController","$scope","userFilter","closeModal","hide","removeUser","addUser","userToAdd","searchText","editFolder","editMode","revertEditing","selectFolder","saveFolder","compactFolder","emptyTrashFolder","exportMails","confirmDelete","markFolderRead","share","$users","usersWithACL","metadataForFolder","icon","setFolderAs","refreshUnseenCount","unseenCountFolders","includes","current","MessageController","doDelete","findIndex","showMailEditor","recipients","close","selectedMessage","reply","replyAll","forward","edit","recipient","saveMessage","viLine truncated
@@ -36,7 +36,7 @@
$q: $q,
$timeout: $timeout,
$log: $log,
$$resource: new Resource(Settings.baseURL(), Settings.activeUser()),
$$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()),
$Mailbox: Mailbox,
$Message: Message
});
@@ -64,14 +64,27 @@
* @returns the list of accounts
*/
Account.$findAll = function(data) {
var collection = [];
if (data) {
// Each entry is spun up as an Account instance
angular.forEach(data, function(o, i) {
o.id = i;
collection[i] = new Account(o);
if (!data) {
return Account.$$resource.fetch('', 'mailAccounts').then(function(o) {
return Account.$unwrapCollection(o);
});
}
return Account.$unwrapCollection(data);
};
/**
* @memberof Account
* @desc Unwrap to a collection of Account instances.
* @param {object} data - the accounts information
* @returns a collection of Account objects
*/
Account.$unwrapCollection = function(data) {
var collection = [];
angular.forEach(data, function(o, i) {
o.id = i;
collection[i] = new Account(o);
});
return collection;
};
@@ -83,21 +96,18 @@
* @returns a promise of the HTTP operation
*/
Account.prototype.$getMailboxes = function(options) {
var _this = this,
deferred = Account.$q.defer();
var _this = this;
if (this.$mailboxes && !(options && options.reload)) {
deferred.resolve(this.$mailboxes);
return Account.$q.when(this.$mailboxes);
}
else {
Account.$Mailbox.$find(this).then(function(data) {
return Account.$Mailbox.$find(this).then(function(data) {
_this.$mailboxes = data;
_this.$flattenMailboxes({reload: true});
deferred.resolve(_this.$mailboxes);
return _this.$mailboxes;
});
}
return deferred.promise;
};
/**
@@ -186,17 +196,11 @@
* @returns a promise of the HTTP operations
*/
Account.prototype.$newMailbox = function(path, name) {
var _this = this,
deferred = Account.$q.defer();
var _this = this;
Account.$$resource.post(path, 'createFolder', {name: name}).then(function() {
return Account.$$resource.post(path.toString(), 'createFolder', {name: name}).then(function() {
_this.$getMailboxes({reload: true});
deferred.resolve();
}, function(response) {
deferred.reject(response.error);
});
return deferred.promise;
};
/**
@@ -150,7 +150,7 @@
*/
Mailbox.prototype.init = function(data) {
var _this = this;
this.$isLoading = false;
this.$isLoading = true;
this.$messages = [];
this.uidsMap = {};
angular.extend(this, data);
@@ -167,6 +167,35 @@
}
};
/**
* @function getLength
* @memberof Mailbox.prototype
* @desc Used by md-virtual-repeat / md-on-demand
* @returns the number of items in the mailbox
*/
Mailbox.prototype.getLength = function() {
return this.$messages.length;
};
/**
* @function getItemAtIndex
* @memberof Mailbox.prototype
* @desc Used by md-virtual-repeat / md-on-demand
* @returns the message as the specified index
*/
Mailbox.prototype.getItemAtIndex = function(index) {
var message;
if (index >= 0 && index < this.$messages.length) {
message = this.$messages[index];
if (this.$loadMessage(message.uid))
return message;
}
return null;
};
/**
* @function $id
* @memberof Mailbox.prototype
@@ -413,22 +442,18 @@
* @returns a promise of the HTTP operation
*/
Mailbox.prototype.$emptyTrash = function() {
var _this = this,
deferred = Mailbox.$q.defer(),
promise;
var _this = this;
promise = Mailbox.$$resource.post(this.id, 'emptyTrash');
promise.then(function() {
return Mailbox.$$resource.post(this.id, 'emptyTrash').then(function() {
// Remove all messages from the mailbox
_this.$messages = [];
_this.uidsMap = {};
_this.unseenCount = 0;
}, function(data, status) {
deferred.reject(data);
});
return deferred.promise;
// If we had any submailboxes, lets do a refresh of the mailboxes list
if (angular.isDefined(_this.children) && _this.children.length)
_this.$account.$getMailboxes({reload: true});
});
};
/**
@@ -592,7 +617,7 @@
if (_this.uids) {
Mailbox.$log.debug('unwrapping ' + data.uids.length + ' messages');
// First entry of 'headers' are keys
headers = _.invoke(_this.headers[0], 'toLowerCase');
_this.headers.splice(0, 1);
@@ -614,7 +639,7 @@
// Build map of UID <=> index
_this.uidsMap[data.uid] = i;
msgs.push(new Mailbox.$Message(_this.$account.id, _this, data));
msgs.push(new Mailbox.$Message(_this.$account.id, _this, data, true));
return msgs;
}, _this.$messages);
@@ -8,7 +8,7 @@
*/
MailboxController.$inject = ['$state', '$timeout', '$mdDialog', 'stateAccounts', 'stateAccount', 'stateMailbox', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
function MailboxController($state, $timeout, $mdDialog, stateAccounts, stateAccount, stateMailbox, encodeUriFilter, focus, Dialog, Account, Mailbox) {
var vm = this;
var vm = this, messageDialog = null;
Mailbox.selectedFolder = stateMailbox;
@@ -127,22 +127,29 @@
}
function newMessage($event) {
var message = vm.account.$newMessage();
var message;
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: 'UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: message,
stateRecipients: []
}
});
if (messageDialog === null) {
message = vm.account.$newMessage();
messageDialog = $mdDialog
.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: 'UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: message,
stateRecipients: []
}
})
.finally(function() {
messageDialog = null;
});
}
}
}
@@ -9,25 +9,32 @@
* @param {string} accountId - the account ID
* @param {string} mailboxPath - an array of the mailbox path components
* @param {object} futureAddressBookData - either an object literal or a promise
* @param {bool} lazy - do "lazy loading" so we are very quick at initializing message instances
*/
function Message(accountId, mailbox, futureMessageData) {
function Message(accountId, mailbox, futureMessageData, lazy) {
this.accountId = accountId;
this.$mailbox = mailbox;
this.$hasUnsafeContent = false;
this.$loadUnsafeContent = false;
this.$showDetailedRecipients = false;
this.editable = {to: [], cc: [], bcc: []};
this.selected = false;
// Data is immediately available
if (typeof futureMessageData.then !== 'function') {
//console.debug(JSON.stringify(futureMessageData, undefined, 2));
angular.extend(this, futureMessageData);
this.id = this.$absolutePath();
this.$formatFullAddresses();
if (angular.isDefined(lazy) && lazy) {
this.uid = futureMessageData.uid;
}
else {
angular.extend(this, futureMessageData);
this.$formatFullAddresses();
}
}
else {
// The promise will be unwrapped first
this.$unwrap(futureMessageData);
}
this.selected = false;
}
/**
@@ -89,20 +96,23 @@
* @returns a string representing the path relative to the mail module
*/
Message.prototype.$absolutePath = function(options) {
var path;
if (angular.isUndefined(this.id)) {
var path;
path = _.map(this.$mailbox.path.split('/'), function(component) {
return 'folder' + component.asCSSIdentifier();
});
path.splice(0, 0, this.accountId); // insert account ID
if (options && options.asDraft && this.draftId) {
path.push(this.draftId); // add draft ID
}
else {
path.push(this.uid); // add message UID
}
path = _.map(this.$mailbox.path.split('/'), function(component) {
return 'folder' + component.asCSSIdentifier();
});
path.splice(0, 0, this.accountId); // insert account ID
if (options && options.asDraft && this.draftId) {
path.push(this.draftId); // add draft ID
}
else {
path.push(this.uid); // add message UID
this.id = path.join('/');
}
return path.join('/');
return this.id;
};
/**
@@ -116,7 +126,6 @@
if (oldUID != uid) {
this.uid = uid;
this.id = this.$absolutePath();
if (oldUID > -1 && this.$mailbox.uidsMap[oldUID]) {
this.$mailbox.uidsMap[uid] = this.$mailbox.uidsMap[oldUID];
this.$mailbox.uidsMap[oldUID] = null;
@@ -128,21 +137,58 @@
* @function $formatFullAddresses
* @memberof Message.prototype
* @desc Format all sender and recipients addresses with a complete description (name <email>).
* This function also generates a gravatar for each email address, and a short name
*/
Message.prototype.$formatFullAddresses = function() {
var _this = this;
var identities = _.pluck(_this.$mailbox.$account.identities, 'email');
// Build long representation of email addresses
_.each(['from', 'to', 'cc', 'bcc', 'reply-to'], function(type) {
_.each(_this[type], function(data, i) {
if (data.name && data.name != data.email)
if (data.name && data.name != data.email) {
data.full = data.name + ' <' + data.email + '>';
else
// If we have "Alice Foo" as name, we grab "Alice"
if (data.name.split(' ').length)
data.shortname = data.name.split(' ')[0].replace('\'','');
}
else {
data.full = '<' + data.email + '>';
data.shortname = data.email.split('@')[0];
}
// Generate the gravatar
data.image = Message.$gravatar(data.email, 32);
// If the current user is the recepient, overwrite
// the short name with 'me'
if (_.indexOf(identities, data.email) >= 0)
data.shortname = l('me');
});
});
};
/**
* @function $shortRecipients
* @memberof Message.prototype
* @desc Format all recipients into a very compact string
* @returns a compacted string of all recipients
*/
Message.prototype.$shortRecipients = function() {
var _this = this;
var result = [];
// Build long representation of email addresses
_.each(['to', 'cc', 'bcc'], function(type) {
_.each(_this[type], function(data, i) {
result.push(data.shortname);
});
});
return result.join(', ');
};
/**
* @function $shortAddress
* @memberof Message.prototype
@@ -167,6 +213,15 @@
this.$loadUnsafeContent = true;
};
/**
* @function showDetailedRecipients
* @memberof Message.prototype
* @desc Mark the message to show all to/cc recipients.
*/
Message.prototype.showDetailedRecipients = function() {
this.$showDetailedRecipients = true;
};
/**
* @function $content
* @memberof Message.prototype
@@ -261,7 +316,7 @@
Message.prototype.$editableContent = function() {
var _this = this;
return Message.$$resource.fetch(this.id, 'edit').then(function(data) {
return Message.$$resource.fetch(this.$absolutePath(), 'edit').then(function(data) {
angular.extend(_this, data);
return Message.$$resource.fetch(_this.$absolutePath({asDraft: true}), 'edit').then(function(data) {
Message.$log.debug('editable = ' + JSON.stringify(data, undefined, 2));
@@ -322,7 +377,7 @@
*/
Message.prototype.$imipAction = function(path, action, data) {
var _this = this;
Message.$$resource.post([this.id, path].join('/'), action, data).then(function(data) {
Message.$$resource.post([this.$absolutePath(), path].join('/'), action, data).then(function(data) {
Message.$timeout(function() {
_this.$reload();
}, function() {
@@ -338,7 +393,7 @@
*/
Message.prototype.$sendMDN = function() {
this.shouldAskReceipt = 0;
return Message.$$resource.post(this.id, 'sendMDN');
return Message.$$resource.post(this.$absolutePath(), 'sendMDN');
};
/**
@@ -374,7 +429,7 @@
if (this.isflagged)
action = 'markMessageUnflagged';
return Message.$$resource.post(this.id, action).then(function(data) {
return Message.$$resource.post(this.$absolutePath(), action).then(function(data) {
Message.$timeout(function() {
_this.isflagged = !_this.isflagged;
});
@@ -390,7 +445,7 @@
Message.prototype.$reload = function() {
var futureMessageData;
futureMessageData = Message.$$resource.fetch(this.id, 'view');
futureMessageData = Message.$$resource.fetch(this.$absolutePath(), 'view');
return this.$unwrap(futureMessageData);
};
@@ -442,15 +497,18 @@
var _this = this;
// Query server for draft folder and draft UID
return Message.$$resource.fetch(this.id, action).then(function(data) {
return Message.$$resource.fetch(this.$absolutePath(), action).then(function(data) {
var mailbox, message;
Message.$log.debug('New ' + action + ': ' + JSON.stringify(data, undefined, 2));
mailbox = _this.$mailbox.$account.$getMailboxByPath(data.mailboxPath);
message = new Message(data.accountId, mailbox, data);
// Fetch draft initial data
return Message.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
Message.$log.debug('New ' + action + ': ' + JSON.stringify(data, undefined, 2));
Message.$log.debug('New ' + action + ': ' + JSON.stringify(data, undefined, 2) + ' original UID: ' + _this.uid);
angular.extend(message.editable, data);
// We keep a reference to our original message in order to update the flags
message.origin = {message: _this, action: action};
return message;
});
});
@@ -482,7 +540,8 @@
* @returns a promise of the HTTP operation
*/
Message.prototype.$send = function() {
var data = angular.copy(this.editable),
var _this = this,
data = angular.copy(this.editable),
deferred = Message.$q.defer();
Message.$log.debug('send = ' + JSON.stringify(data, undefined, 2));
@@ -490,6 +549,12 @@
Message.$$resource.post(this.$absolutePath({asDraft: true}), 'send', data).then(function(data) {
if (data.status == 'success') {
deferred.resolve(data);
if (angular.isDefined(_this.origin)) {
if (_this.origin.action.startsWith('reply'))
_this.origin.message.isanswered = true;
else if (_this.origin.action == 'forward')
_this.origin.message.isforwarded = true;
}
}
else {
deferred.reject(data);
@@ -506,38 +571,28 @@
* @param {promise} futureMessageData - a promise of some of the Message's data
*/
Message.prototype.$unwrap = function(futureMessageData) {
var _this = this,
deferred = Message.$q.defer();
var _this = this;
// Expose the promise
this.$futureMessageData = futureMessageData;
// Resolve the promise
this.$futureMessageData.then(function(data) {
// Resolve and expose the promise
this.$futureMessageData = futureMessageData.then(function(data) {
// Calling $timeout will force Angular to refresh the view
Message.$timeout(function() {
angular.extend(_this, data);
_this.id = _this.$absolutePath();
_this.$formatFullAddresses();
_this.$loadUnsafeContent = false;
deferred.resolve(_this);
});
if (!_this.isread) {
Message.$$resource.fetch(_this.id, 'markMessageRead').then(function() {
if (_this.isread === 0) {
Message.$$resource.fetch(_this.$absolutePath(), 'markMessageRead').then(function() {
Message.$timeout(function() {
_this.isread = true;
_this.$mailbox.unseenCount--;
});
});
}
}, function(data) {
angular.extend(_this, data);
_this.isError = true;
Message.$log.error(_this.error);
deferred.reject();
return Message.$timeout(function() {
angular.extend(_this, data);
_this.$formatFullAddresses();
_this.$loadUnsafeContent = false;
return _this;
});
});
return deferred.promise;
return this.$futureMessageData;
};
/**
@@ -8,7 +8,7 @@
*/
MessageController.$inject = ['$scope', '$state', '$mdDialog', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'Message'];
function MessageController($scope, $state, $mdDialog, stateAccounts, stateAccount, stateMailbox, stateMessage, encodeUriFilter, focus, Dialog, Account, Mailbox, Message) {
var vm = this;
var vm = this, messageDialog = null;
vm.accounts = stateAccounts;
vm.account = stateAccount;
@@ -17,11 +17,13 @@
vm.service = Message;
vm.tags = { searchText: '', selected: '' };
vm.doDelete = doDelete;
vm.close = close;
vm.reply = reply;
vm.replyAll = replyAll;
vm.forward = forward;
vm.edit = edit;
vm.newMessage = newMessage;
vm.saveMessage = saveMessage;
vm.viewRawSource = viewRawSource;
// Watch the message model "flags" attribute to remove on-the-fly a tag from the IMAP message
@@ -48,23 +50,35 @@
}
function showMailEditor($event, message, recipients) {
if (messageDialog === null) {
if (!angular.isDefined(recipients))
recipients = [];
if (!angular.isDefined(recipients))
recipients = [];
messageDialog = $mdDialog
.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: 'UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: message,
stateRecipients: recipients
}
})
.finally(function() {
messageDialog = null;
});
}
}
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: 'UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: message,
stateRecipients: recipients
}
function close() {
$state.go('mail.account.mailbox', { accountId: stateAccount.id, mailboxId: encodeUriFilter(stateMailbox.path) }).then(function() {
vm.message = null;
delete stateMailbox.selectedMessage;
});
}
@@ -94,6 +108,9 @@
showMailEditor($event, message, [recipient]);
}
function saveMessage() {
window.location.href = ApplicationBaseURL + '/' + vm.mailbox.id + '/saveMessages?uid=' + vm.message.uid;
}
function viewRawSource($event) {
Message.$$resource.post(vm.message.id, "viewsource").then(function(data) {
@@ -10,6 +10,7 @@
function MessageEditorController($stateParams, $state, $q, $mdDialog, FileUploader, stateAccounts, stateMessage, stateRecipients, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox, AddressBook, Preferences) {
var vm = this;
vm.addRecipient = addRecipient;
vm.autocomplete = {to: {}, cc: {}, bcc: {}};
vm.autosave = null;
vm.autosaveDrafts = autosaveDrafts;
@@ -90,11 +91,20 @@
}
function contactFilter($query) {
var deferred = $q.defer();
AddressBook.$filterAll($query).then(function(results) {
deferred.resolve(_.invoke(results, '$shortFormat', $query));
});
return deferred.promise;
return AddressBook.$filterAll($query);
}
function addRecipient(user) {
var recipient = [];
if (angular.isString(user))
return user;
if (user.$$fullname)
recipient.push(user.$$fullname);
if (user.$$email)
recipient.push('<' + user.$$email + '>');
return recipient.join(' ');
}
// Drafts autosaving
+1 -1
View File
@@ -1,2 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("preferences",{"abstract":!0,views:{preferences:{templateUrl:"preferences.html",controller:"PreferencesController",controllerAs:"app"}},resolve:{statePreferences:statePreferences}}).state("preferences.general",{url:"/general",views:{module:{templateUrl:"generalPreferences.html"}}}).state("preferences.calendars",{url:"/calendars",views:{module:{templateUrl:"calendarsPreferences.html"}}}).state("preferences.addressbooks",{url:"/addressbooks",views:{module:{templateUrl:"addressbooksPreferences.html"}}}).state("preferences.mailer",{url:"/mailer",views:{module:{templateUrl:"mailerPreferences.html"}}}),$urlRouterProvider.otherwise("/general")}function statePreferences(Preferences){return Preferences}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.PreferencesUI",["ngSanitize","ui.router","ck","SOGo.Common","SOGo.MailerUI","SOGo.ContactsUI","SOGo.Authentication"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],statePreferences.$inject=["Preferences"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AccountDialogController($mdDialog,defaults,account,accountId,mailCustomFromEnabled){function customFromIsReadonly(){return accountId>0?!1:!mailCustomFromEnabled}function cancel(){$mdDialog.cancel()}function save(){$mdDialog.hide()}var vm=this;vm.defaults=defaults,vm.account=account,vm.accountId=accountId,vm.customFromIsReadonly=customFromIsReadonly,vm.cancel=cancel,vm.save=save}AccountDialogController.$inject=["$mdDialog","defaults","account","accountId","mailCustomFromEnabled"],angular.module("SOGo.PreferencesUI").controller("AccountDialogController",AccountDialogController)}(),function(){"use strict";function FiltersDialogController($scope,$mdDialog,filter,mailboxes,labels){$scope.filter=filter,$scope.mailboxes=mailboxes,$scope.labels=labels,$scope.fieldLabels={subject:l("Subject"),from:l("From"),to:l("To"),cc:l("Cc"),to_or_cc:l("To or Cc"),size:l("Size (Kb)"),header:l("Header"),body:l("Body")},$scope.methodLabels={addflag:l("Flag the message with:"),discard:l("Discard the message"),fileinto:l("File the message in:"),keep:l("Keep the message"),redirect:l("Forward the message to:"),reject:l("Send a reject message:"),vacation:l("Send a vacation message"),stop:l("Stop processing filter rules")},$scope.numberOperatorLabels={under:l("is under"),over:l("is over")},$scope.textOperatorLabels={is:l("is"),is_not:l("is not"),contains:l("contains"),contains_not:l("does not contain"),matches:l("matches"),matches_not:l("does not match"),regex:l("matches regex"),regex_not:l("does not match regex")},$scope.flagLabels={seen:l("Seen"),deleted:l("Deleted"),answered:l("Answered"),flagged:l("Flagged"),junk:l("Junk"),not_junk:l("Not Junk")},$scope.cancel=function(){$mdDialog.cancel()},$scope.save=function(){$mdDialog.hide()},$scope.addMailFilterRule=function(event){$scope.filter.rules||($scope.filter.rules=[]),$scope.filter.rules.push({})},$scope.removeMailFilterRule=function(index){$scope.filter.rules.splice(index,1)},$scope.addMailFilterAction=function(event){$scope.filter.actions||($scope.filter.actions=[]),$scope.filter.actions.push({})},$scope.removeMailFilterAction=function(index){$scope.filter.actions.splice(index,1)}}FiltersDialogController.$inject=["$scope","$mdDialog","filter","mailboxes","labels"],angular.module("SOGo.PreferencesUI").controller("FiltersDialogController",FiltersDialogController)}(),function(){"use strict";function PreferencesController($state,$mdDialog,User,Mailbox,statePreferences,Authentication){function go(module){$state.go("preferences."+module)}function addCalendarCategory(){vm.preferences.defaults.SOGoCalendarCategoriesColors["New category"]="#aaa",vm.preferences.defaults.SOGoCalendarCategories.push("New category")}function removeCalendarCategory(index){var key=vm.preferences.defaults.SOGoCalendarCategories[index];vm.preferences.defaults.SOGoCalendarCategories.splice(index,1),delete vm.preferences.defaults.SOGoCalendarCategoriesColors[key]}function addContactCategory(){vm.preferences.defaults.SOGoContactsCategories.push("")}function removeContactCategory(index){vm.preferences.defaults.SOGoContactsCategories.splice(index,1)}function addMailAccount(ev){var account;vm.preferences.defaults.AuxiliaryMailAccounts.push({}),account=_.last(vm.preferences.defaults.AuxiliaryMailAccounts),account.name=l("New account"),account.identities=[{fullName:"",email:""}],account.receipts={receiptAction:"ignore",receiptNonRecipientAction:"ignore",receiptOutsideDomainAction:"ignore",receiptAnyAction:"ignore"},$mdDialog.show({controller:"AccountDialogController",controllerAs:"$AccountDialogController",templateUrl:"editAccount?account=new",targetEvent:ev,locals:{defaults:vm.preferences.defaults,account:account,accountId:vm.preferences.defaults.ALine truncated
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("preferences",{"abstract":!0,views:{preferences:{templateUrl:"preferences.html",controller:"PreferencesController",controllerAs:"app"}},resolve:{statePreferences:statePreferences}}).state("preferences.general",{url:"/general",views:{module:{templateUrl:"generalPreferences.html"}}}).state("preferences.calendars",{url:"/calendars",views:{module:{templateUrl:"calendarsPreferences.html"}}}).state("preferences.addressbooks",{url:"/addressbooks",views:{module:{templateUrl:"addressbooksPreferences.html"}}}).state("preferences.mailer",{url:"/mailer",views:{module:{templateUrl:"mailerPreferences.html"}}}),$urlRouterProvider.otherwise("/general")}function statePreferences(Preferences){return Preferences}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.PreferencesUI",["ngSanitize","ui.router","ck","SOGo.Common","SOGo.MailerUI","SOGo.ContactsUI","SOGo.Authentication"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],statePreferences.$inject=["Preferences"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AccountDialogController($mdDialog,defaults,account,accountId,mailCustomFromEnabled){function customFromIsReadonly(){return accountId>0?!1:!mailCustomFromEnabled}function cancel(){$mdDialog.cancel()}function save(){$mdDialog.hide()}var vm=this;vm.defaults=defaults,vm.account=account,vm.accountId=accountId,vm.customFromIsReadonly=customFromIsReadonly,vm.cancel=cancel,vm.save=save}AccountDialogController.$inject=["$mdDialog","defaults","account","accountId","mailCustomFromEnabled"],angular.module("SOGo.PreferencesUI").controller("AccountDialogController",AccountDialogController)}(),function(){"use strict";function FiltersDialogController($scope,$mdDialog,filter,mailboxes,labels,sieveCapabilities){$scope.filter=filter,$scope.mailboxes=mailboxes,$scope.labels=labels,$scope.fieldLabels={subject:l("Subject"),from:l("From"),to:l("To"),cc:l("Cc"),to_or_cc:l("To or Cc"),size:l("Size (Kb)"),header:l("Header")},sieveCapabilities.indexOf("body")>-1&&($scope.fieldLabels.body=l("Body")),$scope.methodLabels={discard:l("Discard the message"),keep:l("Keep the message"),redirect:l("Forward the message to:"),vacation:l("Send a vacation message"),stop:l("Stop processing filter rules")},sieveCapabilities.indexOf("reject")>-1&&($scope.methodLabels.reject=l("Send a reject message:")),sieveCapabilities.indexOf("fileinto")>-1&&($scope.methodLabels.fileinto=l("File the message in:")),(sieveCapabilities.indexOf("imapflags")>-1||sieveCapabilities.indexOf("imap4flags")>-1)&&($scope.methodLabels.addflag=l("Flag the message with:")),$scope.numberOperatorLabels={under:l("is under"),over:l("is over")},$scope.textOperatorLabels={is:l("is"),is_not:l("is not"),contains:l("contains"),contains_not:l("does not contain"),matches:l("matches"),matches_not:l("does not match")},sieveCapabilities.indexOf("regex")>-1&&($scope.textOperatorLabels.regex=l("matches regex"),$scope.textOperatorLabels.regex_not=l("does not match regex")),$scope.flagLabels={seen:l("Seen"),deleted:l("Deleted"),answered:l("Answered"),flagged:l("Flagged"),junk:l("Junk"),not_junk:l("Not Junk")},$scope.cancel=function(){$mdDialog.cancel()},$scope.save=function(){$mdDialog.hide()},$scope.addMailFilterRule=function(event){$scope.filter.rules||($scope.filter.rules=[]),$scope.filter.rules.push({})},$scope.removeMailFilterRule=function(index){$scope.filter.rules.splice(index,1)},$scope.addMailFilterAction=function(event){$scope.filter.actions||($scope.filter.actions=[]),$scope.filter.actions.push({})},$scope.removeMailFilterAction=function(index){$scope.filter.actions.splice(index,1)}}FiltersDialogController.$inject=["$scope","$mdDialog","filter","mailboxes","labels","sieveCapabilities"],angular.module("SOGo.PreferencesUI").controller("FiltersDialogController",FiltersDialogController)}(),function(){"use strict";function PreferencesController($state,$mdDialog,$mdToast,Dialog,User,Mailbox,statePreferences,Authentication){function go(module){$state.go("preferences."+module)}function addCalendarCategory(){vm.preferences.defaults.SOGoCalendarCategoriesColors["New category"]="#aaa",vm.preferences.defaults.SOGoCalendarCategories.push("New category")}function removeCalendarCategory(index){var key=vm.preferences.defaults.SOGoCalendarCategories[index];vm.preferences.defaults.SOGoCalendarCategories.splice(index,1),delete vm.preferences.defaults.SOGoCalendarCategoriesColors[key]}function addContactCategory(){vm.preferences.defaults.SOGoContactsCategories.push("")}function removeContactCategory(index){vm.preferences.defaults.SOGoContactsCategories.splice(index,1)}function addMailAccount(ev){var account;vm.preferences.defaults.AuxiliaryMailAccounts.push({}),account=_.last(vm.preferences.defaults.AuxiliaryMailAccounts),account.Line truncated
//# sourceMappingURL=Preferences.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"Preferences.js","sources":["Preferences/Preferences.app.js","Preferences/AccountDialogController.js","Preferences/FiltersDialogController.js","Preferences/PreferencesController.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","abstract","views","preferences","templateUrl","controller","controllerAs","resolve","statePreferences","url","module","otherwise","Preferences","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","config","run","$inject","AccountDialogController","$mdDialog","defaults","account","accountId","mailCustomFromEnabled","customFromIsReadonly","cancel","save","hide","vm","this","FiltersDialogController","$scope","filter","mailboxes","labels","fieldLabels","subject","l","from","to","cc","to_or_cc","size","header","body","methodLabels","addflag","discard","fileinto","keep","redirect","reject","vacation","stop","numberOperatorLabels","under","over","textOperatorLabels","is","is_not","contains","contains_not","matches","matches_not","regex","regex_not","flagLabels","seen","deleted","answered","flagged","junk","not_junk","addMailFilterRule","rules","push","removeMailFilterRule","index","splice","addMailFilterAction","actions","removeMailFilterAction","PreferencesController","$state","User","Mailbox","Authentication","go","addCalendarCategory","SOGoCalendarCategoriesColors","SOGoCalendarCategories","removeCalendarCategory","key","addContactCategory","SOGoContactsCategories","removeContactCategory","addMailAccount","ev","AuxiliaryMailAccounts","_","last","name","identities","fullName","email","receipts","receiptAction","receiptNonRecipientAction","receiptOutsideDomainAction","receiptAnyAction","show","targetEvent","locals","length","window","editMailAccount","then","removeMailAccount","addMailLabel","SOGoMailLabelsColors","new_label","removeMailLabel","addMailFilter","SOGoSieveFilters","editMailFilter","copy","removeMailFilter","$save","canChangePassword","passwords","newPassword","newPasswordConfirmation","changePassword","alert","title","content","ok","undefined","msg","timeZonesListFilter","timeZonesList","value","toUpperCase","indexOf","userFilter","$filter","timeZonesSearchText","$find","id"],"mappings":"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 truncated
{"version":3,"file":"Preferences.js","sources":["Preferences/Preferences.app.js","Preferences/AccountDialogController.js","Preferences/FiltersDialogController.js","Preferences/PreferencesController.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","abstract","views","preferences","templateUrl","controller","controllerAs","resolve","statePreferences","url","module","otherwise","Preferences","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","config","run","$inject","AccountDialogController","$mdDialog","defaults","account","accountId","mailCustomFromEnabled","customFromIsReadonly","cancel","save","hide","vm","this","FiltersDialogController","$scope","filter","mailboxes","labels","sieveCapabilities","fieldLabels","subject","l","from","to","cc","to_or_cc","size","header","indexOf","body","methodLabels","discard","keep","redirect","vacation","stop","reject","fileinto","addflag","numberOperatorLabels","under","over","textOperatorLabels","is","is_not","contains","contains_not","matches","matches_not","regex","regex_not","flagLabels","seen","deleted","answered","flagged","junk","not_junk","addMailFilterRule","rules","push","removeMailFilterRule","index","splice","addMailFilterAction","actions","removeMailFilterAction","PreferencesController","$state","$mdToast","Dialog","User","Mailbox","Authentication","go","addCalendarCategory","SOGoCalendarCategoriesColors","SOGoCalendarCategories","removeCalendarCategory","key","addContactCategory","SOGoContactsCategories","removeContactCategory","addMailAccount","ev","AuxiliaryMailAccounts","_","last","name","identities","fullName","email","receipts","receiptAction","receiptNonRecipientAction","receiptOutsideDomainAction","receiptAnyAction","show","targetEvent","locals","length","window","editMailAccount","then","removeMailAccount","addMailLabel","SOGoMailLabelsColors","new_label","removeMailLabel","addMailFilter","SOGoSieveFilters","editMailFilter","copy","removeMailFilter","addDefaultEmailAddresses","v","isDefined","Vacation","autoReplyEmailAddresses","split","union","defaultEmailAddresses","join","sendForm","forwardConstraints","Forward","enabled","forwardAddress","addresses","defaultAddresses","domains","forEach","adr","domain","toLowerCase","i","alert","$save","data","simple","content","position","hideDelay","canChangePassword","passwords","newPassword","newPasswordConfirmation","changePassword","title","ok","undefined","msg","timeZonesListFilter","timeZonesList","value","toUpperCase","userFilter","$filter","timeZonesSearchText","$find","id"],"mappings":"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 truncated
@@ -1,2 +1,2 @@
!function(){"use strict";function Preferences(){var _this=this;this.defaults={},this.settings={},this.defaultsPromise=Preferences.$$resource.fetch("jsonDefaults").then(function(data){var labels=_.object(_.map(data.SOGoMailLabelsColors,function(value,key){return"$"==key.charAt(0)?["_"+key,value]:[key,value]}));return data.SOGoMailLabelsColors=labels,data.Vacation&&data.Vacation.autoReplyEmailAddresses&&(data.Vacation.autoReplyEmailAddresses=data.Vacation.autoReplyEmailAddresses.join(",")),data.Forward&&data.Forward.forwardAddress&&(data.Forward.forwardAddress=data.Forward.forwardAddress.join(",")),angular.extend(_this.defaults,data),_this.defaults}),this.settingsPromise=Preferences.$$resource.fetch("jsonSettings").then(function(data){return data.Calendar&&data.Calendar.PreventInvitationsWhitelist?data.Calendar.PreventInvitationsWhitelist=_.map(data.Calendar.PreventInvitationsWhitelist,function(value,key){var match=/^(.+)\s<(\S+)>$/.exec(value);return new Preferences.$User({uid:key,cn:match[1],c_email:match[2]})}):data.Calendar.PreventInvitationsWhitelist=[],angular.extend(_this.settings,data),_this.settings})}Preferences.$factory=["$q","$timeout","$log","sgSettings","Resource","User",function($q,$timeout,$log,Settings,Resource,User){return angular.extend(Preferences,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL"),Settings.activeUser()),activeUser:Settings.activeUser(),$User:User}),new Preferences}];try{angular.module("SOGo.PreferencesUI")}catch(e){angular.module("SOGo.PreferencesUI",["SOGo.Common"])}angular.module("SOGo.PreferencesUI").factory("Preferences",Preferences.$factory),Preferences.prototype.ready=function(){return Preferences.$q.all([this.defaultsPromise,this.settingsPromise])},Preferences.prototype.$save=function(){return Preferences.$$resource.save("Preferences",this.$omit(!0)).then(function(data){return data})},Preferences.prototype.$omit=function(deep){var preferences={};angular.forEach(this,function(value,key){"constructor"!=key&&"$"!=key[0]&&(deep?preferences[key]=angular.copy(value):preferences[key]=value)});var labels=_.object(_.map(preferences.defaults.SOGoMailLabelsColors,function(value,key){return"_"==key.charAt(0)&&"$"==key.charAt(1)?[key.substring(1),value]:[key,value]}));if(preferences.defaults.SOGoMailLabelsColors=labels,preferences.defaults.Vacation&&preferences.defaults.Vacation.autoReplyEmailAddresses&&(preferences.defaults.Vacation.autoReplyEmailAddresses=preferences.defaults.Vacation.autoReplyEmailAddresses.split(",")),preferences.defaults.Forward&&preferences.defaults.Forward.forwardAddress&&(preferences.defaults.Forward.forwardAddress=preferences.defaults.Forward.forwardAddress.split(",")),preferences.settings.Calendar&&preferences.settings.Calendar.PreventInvitationsWhitelist){var h={};_.each(preferences.settings.Calendar.PreventInvitationsWhitelist,function(user){h[user.uid]=user.$shortFormat()}),preferences.settings.Calendar.PreventInvitationsWhitelist=h}return preferences}}();
!function(){"use strict";function Preferences(){var _this=this;this.defaults={},this.settings={},this.defaultsPromise=Preferences.$$resource.fetch("jsonDefaults").then(function(data){var labels=_.object(_.map(data.SOGoMailLabelsColors,function(value,key){return"$"==key.charAt(0)?["_"+key,value]:[key,value]}));return data.SOGoMailLabelsColors=labels,data.Vacation?(data.Vacation.endDate?data.Vacation.endDate=new Date(1e3*parseInt(data.Vacation.endDate)):(data.Vacation.endDateEnabled=0,data.Vacation.endDate=new Date),data.Vacation.autoReplyEmailAddresses&&(data.Vacation.autoReplyEmailAddresses=data.Vacation.autoReplyEmailAddresses.join(","))):(data.Vacation={},data.Vacation.endDateEnabled=0,data.Vacation.endDate=new Date),data.Forward&&data.Forward.forwardAddress&&(data.Forward.forwardAddress=data.Forward.forwardAddress.join(",")),angular.extend(_this.defaults,data),_this.defaults}),this.settingsPromise=Preferences.$$resource.fetch("jsonSettings").then(function(data){return data.Calendar&&data.Calendar.PreventInvitationsWhitelist&&(data.Calendar.PreventInvitationsWhitelist=_.map(data.Calendar.PreventInvitationsWhitelist,function(value,key){var match=/^(.+)\s<(\S+)>$/.exec(value);return new Preferences.$User({uid:key,cn:match[1],c_email:match[2]})})),angular.extend(_this.settings,data),_this.settings})}Preferences.$factory=["$q","$timeout","$log","sgSettings","Resource","User",function($q,$timeout,$log,Settings,Resource,User){return angular.extend(Preferences,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL"),Settings.activeUser()),activeUser:Settings.activeUser(),$User:User}),new Preferences}];try{angular.module("SOGo.PreferencesUI")}catch(e){angular.module("SOGo.PreferencesUI",["SOGo.Common"])}angular.module("SOGo.PreferencesUI").factory("Preferences",Preferences.$factory),Preferences.prototype.ready=function(){return Preferences.$q.all([this.defaultsPromise,this.settingsPromise])},Preferences.prototype.$save=function(){return Preferences.$$resource.save("Preferences",this.$omit(!0)).then(function(data){return data})},Preferences.prototype.$omit=function(deep){var preferences={};angular.forEach(this,function(value,key){"constructor"!=key&&"$"!=key[0]&&(deep?preferences[key]=angular.copy(value):preferences[key]=value)});var labels=_.object(_.map(preferences.defaults.SOGoMailLabelsColors,function(value,key){return"_"==key.charAt(0)&&"$"==key.charAt(1)?[key.substring(1),value]:[key,value]}));if(preferences.defaults.SOGoMailLabelsColors=labels,preferences.defaults.Vacation&&(preferences.defaults.Vacation.endDateEnabled?preferences.defaults.Vacation.endDate=preferences.defaults.Vacation.endDate.getTime()/1e3:preferences.defaults.Vacation.endDate=0,preferences.defaults.Vacation.autoReplyEmailAddresses&&(preferences.defaults.Vacation.autoReplyEmailAddresses=preferences.defaults.Vacation.autoReplyEmailAddresses.split(","))),preferences.defaults.Forward&&preferences.defaults.Forward.forwardAddress&&(preferences.defaults.Forward.forwardAddress=preferences.defaults.Forward.forwardAddress.split(",")),preferences.settings.Calendar&&preferences.settings.Calendar.PreventInvitationsWhitelist){var h={};_.each(preferences.settings.Calendar.PreventInvitationsWhitelist,function(user){h[user.uid]=user.$shortFormat()}),preferences.settings.Calendar.PreventInvitationsWhitelist=h}return preferences}}();
//# sourceMappingURL=Preferences.services.js.map
@@ -1 +1 @@
{"version":3,"file":"Preferences.services.js","sources":["Preferences/Preferences.service.js"],"names":["Preferences","_this","this","defaults","settings","defaultsPromise","$$resource","fetch","then","data","labels","_","object","map","SOGoMailLabelsColors","value","key","charAt","Vacation","autoReplyEmailAddresses","join","Forward","forwardAddress","angular","extend","settingsPromise","Calendar","PreventInvitationsWhitelist","match","exec","$User","uid","cn","c_email","$factory","$q","$timeout","$log","Settings","Resource","User","activeUser","module","e","factory","prototype","ready","all","$save","save","$omit","deep","preferences","forEach","copy","substring","split","h","each","user","$shortFormat"],"mappings":"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","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Preferences\n * @constructor\n */\n function Preferences() {\n var _this = this;\n\n this.defaults = {};\n this.settings = {};\n\n this.defaultsPromise = Preferences.$$resource.fetch(\"jsonDefaults\").then(function(data) {\n // We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266)\n var labels = _.object(_.map(data.SOGoMailLabelsColors, function(value, key) {\n if (key.charAt(0) == '$')\n return ['_' + key, value];\n return [key, value];\n }));\n\n data.SOGoMailLabelsColors = labels;\n\n // We convert our list of autoReplyEmailAddresses/forwardAddress into a string.\n if (data.Vacation && data.Vacation.autoReplyEmailAddresses)\n data.Vacation.autoReplyEmailAddresses = data.Vacation.autoReplyEmailAddresses.join(\",\");\n\n if (data.Forward && data.Forward.forwardAddress)\n data.Forward.forwardAddress = data.Forward.forwardAddress.join(\",\");\n\n angular.extend(_this.defaults, data);\n\n return _this.defaults;\n });\n\n this.settingsPromise = Preferences.$$resource.fetch(\"jsonSettings\").then(function(data) {\n // We convert our PreventInvitationsWhitelist hash into a array of user\n if (data.Calendar && data.Calendar.PreventInvitationsWhitelist)\n data.Calendar.PreventInvitationsWhitelist = _.map(data.Calendar.PreventInvitationsWhitelist, function(value, key) {\n var match = /^(.+)\\s<(\\S+)>$/.exec(value);\n return new Preferences.$User({uid: key, cn: match[1], c_email: match[2]});\n });\n else\n data.Calendar.PreventInvitationsWhitelist = [];\n\n angular.extend(_this.settings, data);\n\n return _this.settings;\n });\n }\n\n /**\n * @memberof Preferences\n * @desc The factory we'll use to register with Angular\n * @returns the Preferences constructor\n */\n Line truncated
{"version":3,"file":"Preferences.services.js","sources":["Preferences/Preferences.service.js"],"names":["Preferences","_this","this","defaults","settings","defaultsPromise","$$resource","fetch","then","data","labels","_","object","map","SOGoMailLabelsColors","value","key","charAt","Vacation","endDate","Date","parseInt","endDateEnabled","autoReplyEmailAddresses","join","Forward","forwardAddress","angular","extend","settingsPromise","Calendar","PreventInvitationsWhitelist","match","exec","$User","uid","cn","c_email","$factory","$q","$timeout","$log","Settings","Resource","User","activeUser","module","e","factory","prototype","ready","all","$save","save","$omit","deep","preferences","forEach","copy","substring","getTime","split","h","each","user","$shortFormat"],"mappings":"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","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Preferences\n * @constructor\n */\n function Preferences() {\n var _this = this;\n\n this.defaults = {};\n this.settings = {};\n\n this.defaultsPromise = Preferences.$$resource.fetch(\"jsonDefaults\").then(function(data) {\n // We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266)\n var labels = _.object(_.map(data.SOGoMailLabelsColors, function(value, key) {\n if (key.charAt(0) == '$')\n return ['_' + key, value];\n return [key, value];\n }));\n\n data.SOGoMailLabelsColors = labels;\n\n // We convert our list of autoReplyEmailAddresses/forwardAddress into a string.\n // We also convert our date objects into real date, otherwise we'll have strings\n // or undefined values and the md-datepicker does NOT like this.\n if (data.Vacation) {\n if (data.Vacation.endDate)\n data.Vacation.endDate = new Date(parseInt(data.Vacation.endDate) * 1000);\n else {\n data.Vacation.endDateEnabled = 0;\n data.Vacation.endDate = new Date();\n }\n\n if (data.Vacation.autoReplyEmailAddresses)\n data.Vacation.autoReplyEmailAddresses = data.Vacation.autoReplyEmailAddresses.join(\",\");\n } else {\n data.Vacation = {};\n data.Vacation.endDateEnabled = 0;\n data.Vacation.endDate = new Date();\n }\n\n if (data.Forward && data.Forward.forwardAddress)\n data.Forward.forwardAddress = data.Forward.forwardAddress.join(\",\");\n\n angular.extend(_this.defaultsLine truncated
@@ -7,8 +7,8 @@
/**
* @ngInject
*/
FiltersDialogController.$inject = ['$scope', '$mdDialog', 'filter', 'mailboxes', 'labels'];
function FiltersDialogController($scope, $mdDialog, filter, mailboxes, labels) {
FiltersDialogController.$inject = ['$scope', '$mdDialog', 'filter', 'mailboxes', 'labels', 'sieveCapabilities'];
function FiltersDialogController($scope, $mdDialog, filter, mailboxes, labels, sieveCapabilities) {
$scope.filter = filter;
$scope.mailboxes = mailboxes;
$scope.labels = labels;
@@ -20,21 +20,29 @@
"cc": l("Cc"),
"to_or_cc": l("To or Cc"),
"size": l("Size (Kb)"),
"header": l("Header"),
"body": l("Body")
"header": l("Header")
};
if (sieveCapabilities.indexOf("body") > -1)
$scope.fieldLabels.body = l("Body");
$scope.methodLabels = {
"addflag": l("Flag the message with:"),
"discard": l("Discard the message"),
"fileinto": l("File the message in:"),
"keep": l("Keep the message"),
"redirect": l("Forward the message to:"),
"reject": l("Send a reject message:"),
"vacation": l("Send a vacation message"),
"stop": l("Stop processing filter rules")
};
if (sieveCapabilities.indexOf("reject") > -1)
$scope.methodLabels.reject = l("Send a reject message:");
if (sieveCapabilities.indexOf("fileinto") > -1)
$scope.methodLabels.fileinto = l("File the message in:");
if (sieveCapabilities.indexOf("imapflags") > -1 || sieveCapabilities.indexOf("imap4flags") > -1)
$scope.methodLabels.addflag = l("Flag the message with:");
$scope.numberOperatorLabels = {
"under": l("is under"),
"over": l("is over")
@@ -46,11 +54,14 @@
"contains": l("contains"),
"contains_not": l("does not contain"),
"matches": l("matches"),
"matches_not": l("does not match"),
"regex": l("matches regex"),
"regex_not": l("does not match regex")
"matches_not": l("does not match")
};
if (sieveCapabilities.indexOf("regex") > -1) {
$scope.textOperatorLabels.regex = l("matches regex");
$scope.textOperatorLabels.regex_not = l("does not match regex");
}
$scope.flagLabels = {
"seen": l("Seen"),
"deleted": l("Deleted"),
@@ -14,23 +14,38 @@
this.settings = {};
this.defaultsPromise = Preferences.$$resource.fetch("jsonDefaults").then(function(data) {
// We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266)
var labels = _.object(_.map(data.SOGoMailLabelsColors, function(value, key) {
if (key.charAt(0) == '$')
return ['_' + key, value];
return [key, value];
}));
// We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266)
var labels = _.object(_.map(data.SOGoMailLabelsColors, function(value, key) {
if (key.charAt(0) == '$')
return ['_' + key, value];
return [key, value];
}));
data.SOGoMailLabelsColors = labels;
data.SOGoMailLabelsColors = labels;
// We convert our list of autoReplyEmailAddresses/forwardAddress into a string.
if (data.Vacation && data.Vacation.autoReplyEmailAddresses)
// We convert our list of autoReplyEmailAddresses/forwardAddress into a string.
// We also convert our date objects into real date, otherwise we'll have strings
// or undefined values and the md-datepicker does NOT like this.
if (data.Vacation) {
if (data.Vacation.endDate)
data.Vacation.endDate = new Date(parseInt(data.Vacation.endDate) * 1000);
else {
data.Vacation.endDateEnabled = 0;
data.Vacation.endDate = new Date();
}
if (data.Vacation.autoReplyEmailAddresses)
data.Vacation.autoReplyEmailAddresses = data.Vacation.autoReplyEmailAddresses.join(",");
} else {
data.Vacation = {};
data.Vacation.endDateEnabled = 0;
data.Vacation.endDate = new Date();
}
if (data.Forward && data.Forward.forwardAddress)
data.Forward.forwardAddress = data.Forward.forwardAddress.join(",");
if (data.Forward && data.Forward.forwardAddress)
data.Forward.forwardAddress = data.Forward.forwardAddress.join(",");
angular.extend(_this.defaults, data);
angular.extend(_this.defaults, data);
return _this.defaults;
});
@@ -42,8 +57,6 @@
var match = /^(.+)\s<(\S+)>$/.exec(value);
return new Preferences.$User({uid: key, cn: match[1], c_email: match[2]});
});
else
data.Calendar.PreventInvitationsWhitelist = [];
angular.extend(_this.settings, data);
@@ -134,8 +147,15 @@
preferences.defaults.SOGoMailLabelsColors = labels;
if (preferences.defaults.Vacation && preferences.defaults.Vacation.autoReplyEmailAddresses)
preferences.defaults.Vacation.autoReplyEmailAddresses = preferences.defaults.Vacation.autoReplyEmailAddresses.split(",");
if (preferences.defaults.Vacation) {
if (preferences.defaults.Vacation.endDateEnabled)
preferences.defaults.Vacation.endDate = preferences.defaults.Vacation.endDate.getTime()/1000;
else
preferences.defaults.Vacation.endDate = 0;
if (preferences.defaults.Vacation.autoReplyEmailAddresses)
preferences.defaults.Vacation.autoReplyEmailAddresses = preferences.defaults.Vacation.autoReplyEmailAddresses.split(",");
}
if (preferences.defaults.Forward && preferences.defaults.Forward.forwardAddress)
preferences.defaults.Forward.forwardAddress = preferences.defaults.Forward.forwardAddress.split(",");
Loaded 100 of 151 files, more files were not shown because too many files have changed in this diff. Show more