mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-30 02:37:16 +00:00
Merge branch 'master' into feature/addMissingStrings2
Conflicts: UI/AdministrationUI/English.lproj/Localizable.strings UI/PreferencesUI/English.lproj/Localizable.strings UI/Templates/PreferencesUI/UIxFilterEditor.wox
This commit is contained in:
@@ -15,3 +15,12 @@
|
||||
"ACLs_description" = "<p>The Access Control Lists administration module allows to change the ACLs of each user's Calendars and Address books.</p><p>To modify the ACLs of a user's folder, type the name of the user in the search field at the top of the window and double-click on the desired folder.</p>";
|
||||
|
||||
"Name or Email" = "Name or Email";
|
||||
|
||||
/* Rights module: initial search message */
|
||||
"Start a search to edit the rights" = "Start a search to edit the rights";
|
||||
|
||||
/* Rights module: Empty search result */
|
||||
"No matching user" = "No matching user";
|
||||
|
||||
/* Rights module: no selection */
|
||||
"No resource selected" = "No resource selected";
|
||||
|
||||
@@ -12,6 +12,7 @@ AdministrationUI_OBJC_FILES = \
|
||||
AdministrationUIProduct.m \
|
||||
\
|
||||
UIxAdministration.m \
|
||||
UIxAdministrationAclEditor.m \
|
||||
UIxAdministrationFilterPanel.m
|
||||
|
||||
AdministrationUI_RESOURCE_FILES += \
|
||||
|
||||
@@ -46,6 +46,11 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
return @"Administration";
|
||||
}
|
||||
|
||||
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
||||
inContext: (WOContext*) context
|
||||
{
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* UIxAdministrationAclEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2014 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.
|
||||
*/
|
||||
|
||||
#ifndef UIXACLEDITOR_H
|
||||
#define UIXACLEDITOR_H
|
||||
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
@interface UIxAdministrationAclEditor : UIxComponent
|
||||
{
|
||||
BOOL prepared;
|
||||
BOOL publishInFreeBusy;
|
||||
NSArray *aclUsers;
|
||||
NSArray *savedUIDs;
|
||||
NSMutableDictionary *users;
|
||||
NSString *currentUser;
|
||||
NSString *defaultUserID;
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForObject;
|
||||
- (void) setCurrentUser: (NSString *) newCurrentUser;
|
||||
- (NSString *) currentUser;
|
||||
- (NSString *) currentUserClass;
|
||||
- (NSDictionary *) currentUserInfos;
|
||||
- (NSString *) currentUserDisplayName;
|
||||
- (BOOL) currentUserIsSubscribed;
|
||||
- (BOOL) isPublicAccessEnabled;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* UIXACLEDITOR_H */
|
||||
@@ -0,0 +1,279 @@
|
||||
/* UIxAdministrationAclEditor.m - this file is part of SOGo
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSKeyValueCoding.h>
|
||||
|
||||
#import <NGObjWeb/SoSecurityManager.h>
|
||||
#import <NGObjWeb/SoUser.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/SOGoContentObject.h>
|
||||
#import <SOGo/SOGoGCSFolder.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
||||
#import "UIxAdministrationAclEditor.h"
|
||||
|
||||
@implementation UIxAdministrationAclEditor
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
aclUsers = nil;
|
||||
prepared = NO;
|
||||
publishInFreeBusy = NO;
|
||||
users = [NSMutableDictionary new];
|
||||
currentUser = nil;
|
||||
defaultUserID = nil;
|
||||
savedUIDs = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[savedUIDs release];
|
||||
[users release];
|
||||
[currentUser release];
|
||||
[defaultUserID release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForObject
|
||||
{
|
||||
if (!aclUsers)
|
||||
aclUsers = [[self clientObject] aclUsers];
|
||||
|
||||
return aclUsers;
|
||||
}
|
||||
|
||||
- (NSString *) defaultUserID
|
||||
{
|
||||
if (!defaultUserID)
|
||||
ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
|
||||
|
||||
return defaultUserID;
|
||||
}
|
||||
|
||||
- (BOOL) canSubscribeUsers
|
||||
{
|
||||
return [[self clientObject]
|
||||
respondsToSelector: @selector (subscribeUserOrGroup:reallyDo:response:)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} /so/:username/:folderPath/acls List users with rights
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName GetAcls
|
||||
* @apiGroup Common
|
||||
* @apiExample {curl} Example usage:
|
||||
* curl -i http://localhost/SOGo/so/sogo1/Calendar/personal/acls
|
||||
*
|
||||
* @apiSuccess (Success 200) {Object[]} users List of users with ACL for the folder
|
||||
* @apiSuccess (Success 200) {String} users.uid User ID
|
||||
* @apiSuccess (Success 200) {String} users.userClass Either 'normal-user', 'normal-group' or 'public-access'
|
||||
* @apiSuccess (Success 200) {Number} users.isSubscribed 1 if the user is subscribed to the folder
|
||||
* @apiSuccess (Success 200) {String} [users.cn] User fullname
|
||||
* @apiSuccess (Success 200) {String} [users.c_email] User main email address
|
||||
*/
|
||||
- (id <WOActionResults>) aclsAction
|
||||
{
|
||||
NSString *currentUID, *ownerLogin, *info;
|
||||
NSDictionary *currentUserInfos;
|
||||
NSMutableDictionary *userData;
|
||||
id <WOActionResults> result;
|
||||
NSEnumerator *aclsEnum;
|
||||
|
||||
if (!prepared)
|
||||
{
|
||||
ownerLogin = [[self clientObject] ownerInContext: context];
|
||||
if (!defaultUserID)
|
||||
ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
|
||||
|
||||
aclsEnum = [[self aclsForObject] objectEnumerator];
|
||||
while ((currentUID = [aclsEnum nextObject]))
|
||||
{
|
||||
if (!([currentUID isEqualToString: ownerLogin]
|
||||
|| [currentUID isEqualToString: defaultUserID]
|
||||
|| [currentUID isEqualToString: @"anonymous"]))
|
||||
{
|
||||
// Set the current user in order to get information associated with it
|
||||
[self setCurrentUser: currentUID];
|
||||
|
||||
// Build the object associated to the current UID
|
||||
currentUserInfos = [self currentUserInfos];
|
||||
userData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
currentUser, @"uid",
|
||||
[self currentUserClass], @"userClass",
|
||||
[NSNumber numberWithBool: [self currentUserIsSubscribed]], @"isSubscribed",
|
||||
nil];
|
||||
if ((info = [currentUserInfos objectForKey: @"cn"]) && [info length])
|
||||
[userData setObject: info forKey: @"cn"];
|
||||
if ((info = [currentUserInfos objectForKey: @"c_email"]) && [info length])
|
||||
[userData setObject: info forKey: @"c_email"];
|
||||
[users setObject: userData forKey: currentUID];
|
||||
}
|
||||
}
|
||||
|
||||
// Add the 'Any authenticated' user
|
||||
if ([self canSubscribeUsers])
|
||||
{
|
||||
userData = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"<default>", @"uid",
|
||||
[self labelForKey: @"Any Authenticated User"], @"cn",
|
||||
@"public-user", @"userClass",
|
||||
nil];
|
||||
[users setObject: userData forKey: @"<default>"];
|
||||
}
|
||||
|
||||
if ([self canSubscribeUsers] && [self isPublicAccessEnabled])
|
||||
{
|
||||
// Add the 'public access' user
|
||||
userData = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"anonymous", @"uid",
|
||||
[self labelForKey: @"Public Access"], @"cn",
|
||||
@"public-user", @"userClass",
|
||||
nil];
|
||||
[users setObject: userData forKey: @"anonymous"];
|
||||
}
|
||||
|
||||
prepared = YES;
|
||||
}
|
||||
|
||||
result = [self responseWithStatus: 200
|
||||
andJSONRepresentation: [NSDictionary dictionaryWithObject: users forKey: @"users"]];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) setCurrentUser: (NSString *) newCurrentUser
|
||||
{
|
||||
ASSIGN (currentUser, newCurrentUser);
|
||||
}
|
||||
|
||||
- (NSString *) currentUser
|
||||
{
|
||||
return ([currentUser hasPrefix: @"@"]
|
||||
? [currentUser substringFromIndex: 1]
|
||||
: currentUser);
|
||||
}
|
||||
|
||||
- (NSString *) currentUserClass
|
||||
{
|
||||
return ([currentUser hasPrefix: @"@"]
|
||||
? @"normal-group"
|
||||
: @"normal-user");
|
||||
}
|
||||
|
||||
- (NSString *) currentUserDisplayName
|
||||
{
|
||||
NSDictionary *infos;
|
||||
NSString *uid;
|
||||
SOGoUserManager *um;
|
||||
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
uid = [self currentUser];
|
||||
infos = [um contactInfosForUserWithUIDorEmail: uid inDomain: [[context activeUser] domain]];
|
||||
if (infos)
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@ <%@>",
|
||||
[infos objectForKey: @"cn"],
|
||||
[infos objectForKey: @"c_email"]];
|
||||
}
|
||||
else
|
||||
return uid;
|
||||
}
|
||||
|
||||
- (NSDictionary *) currentUserInfos
|
||||
{
|
||||
SOGoUserManager *um;
|
||||
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
|
||||
return [um contactInfosForUserWithUIDorEmail: [self currentUser]];
|
||||
}
|
||||
|
||||
- (BOOL) currentUserIsSubscribed
|
||||
{
|
||||
SOGoGCSFolder *folder;
|
||||
|
||||
folder = [self clientObject];
|
||||
|
||||
return ([folder respondsToSelector: @selector (userIsSubscriber:)]
|
||||
&& [folder userIsSubscriber: currentUser]);
|
||||
}
|
||||
|
||||
- (void) setUserUIDS: (NSString *) retainedUsers
|
||||
{
|
||||
if ([retainedUsers length] > 0)
|
||||
{
|
||||
savedUIDs = [retainedUsers componentsSeparatedByString: @","];
|
||||
[savedUIDs retain];
|
||||
}
|
||||
else
|
||||
savedUIDs = [NSArray new];
|
||||
}
|
||||
|
||||
- (NSString *) folderID
|
||||
{
|
||||
return [[self clientObject] nameInContainer];
|
||||
}
|
||||
|
||||
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
return ([[request method] isEqualToString: @"POST"]);
|
||||
}
|
||||
|
||||
- (id <WOActionResults>) saveAclsAction
|
||||
{
|
||||
NSEnumerator *aclsEnum;
|
||||
SOGoObject *clientObject;
|
||||
NSString *currentUID, *ownerLogin;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
ownerLogin = [clientObject ownerInContext: context];
|
||||
aclsEnum = [[self aclsForObject] objectEnumerator];
|
||||
while ((currentUID = [[aclsEnum nextObject] objectForKey: @"c_uid"]))
|
||||
if ([currentUID isEqualToString: ownerLogin]
|
||||
|| [savedUIDs containsObject: currentUID])
|
||||
[users removeObjectForKey: currentUID];
|
||||
[clientObject removeAclsForUsers: [users allKeys]];
|
||||
|
||||
return [self jsCloseWithRefreshMethod: nil];
|
||||
}
|
||||
|
||||
- (BOOL) isPublicAccessEnabled
|
||||
{
|
||||
return [[SOGoSystemDefaults sharedSystemDefaults] enablePublicAccess];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -15,6 +15,10 @@
|
||||
protectedBy = "View";
|
||||
pageName = "UIxAdministration";
|
||||
};
|
||||
UIxAdministrationAclEditor = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxAdministrationAclEditor";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -249,14 +249,7 @@
|
||||
|
||||
- (NSString *) commonLocalizableStrings
|
||||
{
|
||||
NSString *rc;
|
||||
|
||||
if (isPopup)
|
||||
rc = @"";
|
||||
else
|
||||
rc = [NSString stringWithFormat: @"var clabels = %@;", [self _stringsForFramework: nil]];
|
||||
|
||||
return rc;
|
||||
return [NSString stringWithFormat: @"var clabels = %@;", [self _stringsForFramework: nil]];
|
||||
}
|
||||
|
||||
- (NSString *) productLocalizableStrings
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
[self errorWithFormat:
|
||||
@"not toolbar configuration found on SoObject: %@ (%@)",
|
||||
[self clientObject], [[self clientObject] soClass]];
|
||||
toolbarConfig = [[NSNull null] retain];
|
||||
toolbarConfig = (NSArray *)[[NSNull null] retain];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSBundle.h>
|
||||
#import <Foundation/NSKeyValueCoding.h>
|
||||
|
||||
#import <NGObjWeb/SoObjects.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
@@ -31,6 +32,8 @@
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserDefaults.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "WODirectAction+SOGo.h"
|
||||
|
||||
static SoProduct *commonProduct = nil;
|
||||
|
||||
@@ -44,6 +44,27 @@
|
||||
"Copy To" = "Copy To";
|
||||
"Add to:" = "Add to:";
|
||||
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "No contact";
|
||||
|
||||
/* Subheader of system addressbook */
|
||||
"Start a search to browse this address book" = "Start a search to browse this address book";
|
||||
|
||||
/* Number of contacts in addressbook; string is prefixed by number */
|
||||
"contacts" = "contacts";
|
||||
|
||||
/* No contact matching search criteria */
|
||||
"No matching contact" = "No matching contact";
|
||||
|
||||
/* Number of contacts matching search criteria; string is prefixed by number */
|
||||
"matching contacts" = "matching contacts";
|
||||
|
||||
/* 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";
|
||||
|
||||
@@ -23,7 +23,8 @@ ContactsUI_OBJC_FILES = \
|
||||
UIxContactsListActions.m \
|
||||
UIxContactFoldersView.m \
|
||||
UIxContactFolderActions.m \
|
||||
UIxContactFolderLinksTemplate.m
|
||||
UIxContactFolderLinksTemplate.m \
|
||||
UIxContactFolderProperties.m
|
||||
|
||||
ContactsUI_RESOURCE_FILES += \
|
||||
product.plist \
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
content = [NSMutableString string];
|
||||
response = [context response];
|
||||
|
||||
[content appendFormat: [[self clientObject] contentAsString]];
|
||||
[content appendFormat: @"%@", [[self clientObject] contentAsString]];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
[response appendContentString: content];
|
||||
|
||||
@@ -349,7 +349,7 @@ static Class SOGoContactGCSEntryK = Nil;
|
||||
NSMutableArray *units, *categories;
|
||||
NSCalendarDate *date;
|
||||
id o;
|
||||
unsigned int i, year, month, day;
|
||||
unsigned int i, year, month, day, seconds;
|
||||
|
||||
[card setNWithFamily: [attributes objectForKey: @"c_sn"]
|
||||
given: [attributes objectForKey: @"c_givenname"]
|
||||
@@ -357,8 +357,14 @@ static Class SOGoContactGCSEntryK = Nil;
|
||||
[card setNickname: [attributes objectForKey: @"nickname"]];
|
||||
[card setFn: [attributes objectForKey: @"c_cn"]];
|
||||
[card setTitle: [attributes objectForKey: @"title"]];
|
||||
[card setRole: [attributes objectForKey: @"role"]];
|
||||
|
||||
unsigned int seconds = [[NSString stringWithFormat: @"%@", [attributes objectForKey: @"birthday"]] intValue];
|
||||
if ([attributes objectForKey: @"c_screenname"])
|
||||
[[card uniqueChildWithTag: @"x-aim"]
|
||||
setSingleValue: [attributes objectForKey: @"c_screenname"]
|
||||
forKey: @""];
|
||||
|
||||
seconds = [[NSString stringWithFormat: @"%@", [attributes objectForKey: @"birthday"]] intValue];
|
||||
if (seconds > 0)
|
||||
{
|
||||
date = [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
|
||||
@@ -519,6 +525,7 @@ static Class SOGoContactGCSEntryK = Nil;
|
||||
* @apiParam {String} nickname Nickname
|
||||
* @apiParam {String} c_sn Lastname
|
||||
* @apiParam {String} c_cn Fullname
|
||||
* @apiParam {String} c_screenname Screen Name (X-AIM for now)
|
||||
* @apiParam {String} tz Timezone
|
||||
* @apiParam {String} note Note
|
||||
* @apiParam {String[]} allCategories All available categories
|
||||
|
||||
@@ -28,10 +28,14 @@
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#define COMPILING_NGOBJWEB 1 /* we want httpRequest for parsing multi-part
|
||||
form data */
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#undef COMPILING_NGOBJWEB
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
#import <NGMime/NGMimeMultipartBody.h>
|
||||
|
||||
#import <Contacts/SOGoContactObject.h>
|
||||
#import <Contacts/SOGoContactFolder.h>
|
||||
@@ -81,9 +85,9 @@
|
||||
inContext: [self context]
|
||||
acquire: NO];
|
||||
if ([currentChild respondsToSelector: @selector (vCard)])
|
||||
[content appendFormat: [[currentChild ldifRecord] ldifRecordAsString]];
|
||||
[content appendFormat: @"%@", [[currentChild ldifRecord] ldifRecordAsString]];
|
||||
else if ([currentChild respondsToSelector: @selector (vList)])
|
||||
[content appendFormat: [[currentChild vList] ldifString]];
|
||||
[content appendFormat: @"%@", [[currentChild vList] ldifString]];
|
||||
[content appendString: @"\n"];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* UIxContactFolderProperties.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
@class NSString;
|
||||
|
||||
@class SOGoContactGCSFolder;
|
||||
|
||||
@interface UIxContactFolderProperties : UIxComponent
|
||||
{
|
||||
SOGoContactGCSFolder *addressbook;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,84 @@
|
||||
/* UIxContactFolderProperties.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import <Contacts/SOGoContactGCSFolder.h>
|
||||
|
||||
#import "UIxContactFolderProperties.h"
|
||||
|
||||
@implementation UIxContactFolderProperties
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
addressbook = [self clientObject];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /so/:username/Contacts/:addressbookId/save Save addressbook
|
||||
* @apiDescription Save an addressbook's properties.
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName PostSaveProperties
|
||||
* @apiGroup AddressBook
|
||||
*
|
||||
* @apiParam {String} name Human readable name
|
||||
* @apiParam {Number} synchronize 1 if we enable EAS synchronization for this addressbook
|
||||
*/
|
||||
- (WOResponse *) savePropertiesAction
|
||||
{
|
||||
WORequest *request;
|
||||
NSDictionary *params;
|
||||
id o, values;
|
||||
|
||||
request = [context request];
|
||||
params = [[request contentAsString] objectFromJSONString];
|
||||
|
||||
o = [params objectForKey: @"name"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[addressbook renameTo: o];
|
||||
|
||||
o = [params objectForKey: @"synchronize"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[addressbook setSynchronize: [o boolValue]];
|
||||
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -71,6 +71,11 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
return @"Contacts";
|
||||
}
|
||||
|
||||
- (void) _setupContext
|
||||
{
|
||||
SOGoUser *activeUser;
|
||||
@@ -291,7 +296,7 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
|
||||
NSDictionary *folderAttrs;
|
||||
id currentFolder;
|
||||
|
||||
BOOL objectCreator, objectEditor, objectEraser;
|
||||
BOOL objectCreator, objectEditor, objectEraser, synchronize;
|
||||
int max, i;
|
||||
|
||||
userLogin = [[context activeUser] login];
|
||||
@@ -328,11 +333,20 @@ Class SOGoContactSourceFolderK, SOGoGCSFolderK;
|
||||
[NSNumber numberWithBool: objectEditor], @"objectEditor",
|
||||
[NSNumber numberWithBool: objectEraser], @"objectEraser", nil];
|
||||
|
||||
if ([currentFolder isKindOfClass: SOGoGCSFolderK])
|
||||
synchronize = [currentFolder synchronize];
|
||||
else
|
||||
synchronize = NO;
|
||||
|
||||
if ([[currentFolder nameInContainer] isEqualToString: @"personal"])
|
||||
synchronize = YES;
|
||||
|
||||
// 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",
|
||||
[NSNumber numberWithBool: synchronize], @"synchronize",
|
||||
owner, @"owner",
|
||||
[NSNumber numberWithBool: [currentFolder isKindOfClass: SOGoGCSFolderK]], @"isEditable",
|
||||
[NSNumber numberWithBool: [currentFolder isKindOfClass: SOGoContactSourceFolderK]
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
Copyright (C) 2004 SKYRIX Software AG
|
||||
Copyright (C) 2005-2015 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
|
||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
@@ -35,7 +35,7 @@
|
||||
NSMutableArray *photosURL;
|
||||
}
|
||||
|
||||
- (NSString *) fullName;
|
||||
//- (NSString *) fullName;
|
||||
- (NSArray *) orgUnits;
|
||||
- (NSString *) photoURL;
|
||||
|
||||
|
||||
+414
-410
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
Copyright (C) 2004 SKYRIX Software AG
|
||||
Copyright (C) 2005-2015 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
@@ -69,70 +68,70 @@
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
byEscapingHTMLString: (BOOL) escapeHTML
|
||||
asLinkScheme: (NSString *) scheme
|
||||
withLinkAttributes: (NSString *) attrs
|
||||
{
|
||||
NSMutableString *cardString;
|
||||
// - (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
// value: (NSString *) value
|
||||
// byEscapingHTMLString: (BOOL) escapeHTML
|
||||
// asLinkScheme: (NSString *) scheme
|
||||
// withLinkAttributes: (NSString *) attrs
|
||||
// {
|
||||
// NSMutableString *cardString;
|
||||
|
||||
cardString = [NSMutableString stringWithCapacity: 80];
|
||||
value = [value stringByReplacingString: @"\r" withString: @""];
|
||||
if ([value length] > 0)
|
||||
{
|
||||
if (escapeHTML)
|
||||
value = [value stringByEscapingHTMLString];
|
||||
if ([scheme length] > 0)
|
||||
value = [NSString stringWithFormat: @"<a href=\"%@%@\" %@>%@</a>", scheme, value, attrs, value];
|
||||
// cardString = [NSMutableString stringWithCapacity: 80];
|
||||
// value = [value stringByReplacingString: @"\r" withString: @""];
|
||||
// if ([value length] > 0)
|
||||
// {
|
||||
// if (escapeHTML)
|
||||
// value = [value stringByEscapingHTMLString];
|
||||
// if ([scheme length] > 0)
|
||||
// value = [NSString stringWithFormat: @"<a href=\"%@%@\" %@>%@</a>", scheme, value, attrs, value];
|
||||
|
||||
if (label)
|
||||
[cardString appendFormat: @"<dt>%@</dt><dd>%@</dd>\n",
|
||||
[self labelForKey: label], value];
|
||||
else
|
||||
[cardString appendFormat: @"<dt></dt><dd>%@</dd>\n", value];
|
||||
}
|
||||
// if (label)
|
||||
// [cardString appendFormat: @"<dt>%@</dt><dd>%@</dd>\n",
|
||||
// [self labelForKey: label], value];
|
||||
// else
|
||||
// [cardString appendFormat: @"<dt></dt><dd>%@</dd>\n", value];
|
||||
// }
|
||||
|
||||
return cardString;
|
||||
}
|
||||
// return cardString;
|
||||
// }
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
{
|
||||
return [self _cardStringWithLabel: label
|
||||
value: value
|
||||
byEscapingHTMLString: YES
|
||||
asLinkScheme: nil
|
||||
withLinkAttributes: nil];
|
||||
}
|
||||
// - (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
// value: (NSString *) value
|
||||
// {
|
||||
// return [self _cardStringWithLabel: label
|
||||
// value: value
|
||||
// byEscapingHTMLString: YES
|
||||
// asLinkScheme: nil
|
||||
// withLinkAttributes: nil];
|
||||
// }
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
asLinkScheme: (NSString *) scheme
|
||||
{
|
||||
return [self _cardStringWithLabel: label
|
||||
value: value
|
||||
byEscapingHTMLString: YES
|
||||
asLinkScheme: scheme
|
||||
withLinkAttributes: nil];
|
||||
}
|
||||
// - (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
// value: (NSString *) value
|
||||
// asLinkScheme: (NSString *) scheme
|
||||
// {
|
||||
// return [self _cardStringWithLabel: label
|
||||
// value: value
|
||||
// byEscapingHTMLString: YES
|
||||
// asLinkScheme: scheme
|
||||
// withLinkAttributes: nil];
|
||||
// }
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Display Name:"
|
||||
value: [card fn]];
|
||||
}
|
||||
// - (NSString *) displayName
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Display Name:"
|
||||
// value: [card fn]];
|
||||
// }
|
||||
|
||||
- (NSString *) nickName
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Nickname:"
|
||||
value: [card nickname]];
|
||||
}
|
||||
// - (NSString *) nickName
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Nickname:"
|
||||
// value: [card nickname]];
|
||||
// }
|
||||
|
||||
- (NSString *) fullName
|
||||
{
|
||||
return [card fullName];
|
||||
}
|
||||
// - (NSString *) fullName
|
||||
// {
|
||||
// return [card fullName];
|
||||
// }
|
||||
|
||||
- (NSArray *) _languageContactsCategories
|
||||
{
|
||||
@@ -173,345 +172,345 @@
|
||||
return cats;
|
||||
}
|
||||
|
||||
- (NSString *) primaryEmail
|
||||
{
|
||||
NSString *email, *fn, *attrs;
|
||||
// - (NSString *) primaryEmail
|
||||
// {
|
||||
// NSString *email, *fn, *attrs;
|
||||
|
||||
email = [card preferredEMail];
|
||||
if ([email length] > 0)
|
||||
{
|
||||
fn = [card fn];
|
||||
if ([fn length] > 0)
|
||||
attrs = [NSString stringWithFormat: @"%@ <%@>", fn, email];
|
||||
else
|
||||
attrs = email;
|
||||
attrs = [attrs stringByReplacingString: @"'" withString: @"\\'"];
|
||||
attrs = [attrs stringByReplacingString: @"\"" withString: @"\\\""];
|
||||
attrs = [NSString stringWithFormat: @"onclick=\"return openMailTo('%@');\"", attrs];
|
||||
}
|
||||
else
|
||||
{
|
||||
attrs = nil;
|
||||
}
|
||||
// email = [card preferredEMail];
|
||||
// if ([email length] > 0)
|
||||
// {
|
||||
// fn = [card fn];
|
||||
// if ([fn length] > 0)
|
||||
// attrs = [NSString stringWithFormat: @"%@ <%@>", fn, email];
|
||||
// else
|
||||
// attrs = email;
|
||||
// attrs = [attrs stringByReplacingString: @"'" withString: @"\\'"];
|
||||
// attrs = [attrs stringByReplacingString: @"\"" withString: @"\\\""];
|
||||
// attrs = [NSString stringWithFormat: @"onclick=\"return openMailTo('%@');\"", attrs];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// attrs = nil;
|
||||
// }
|
||||
|
||||
return [self _cardStringWithLabel: @"Email:"
|
||||
value: email
|
||||
byEscapingHTMLString: YES
|
||||
asLinkScheme: @"mailto:"
|
||||
withLinkAttributes: attrs];
|
||||
}
|
||||
// return [self _cardStringWithLabel: @"Email:"
|
||||
// value: email
|
||||
// byEscapingHTMLString: YES
|
||||
// asLinkScheme: @"mailto:"
|
||||
// withLinkAttributes: attrs];
|
||||
// }
|
||||
|
||||
- (NSArray *) secondaryEmails
|
||||
{
|
||||
NSMutableArray *secondaryEmails;
|
||||
NSString *email, *fn, *attrs;
|
||||
NSArray *emails;
|
||||
// - (NSArray *) secondaryEmails
|
||||
// {
|
||||
// NSMutableArray *secondaryEmails;
|
||||
// NSString *email, *fn, *attrs;
|
||||
// NSArray *emails;
|
||||
|
||||
emails = [card secondaryEmails];
|
||||
secondaryEmails = [NSMutableArray array];
|
||||
attrs = nil;
|
||||
// emails = [card secondaryEmails];
|
||||
// secondaryEmails = [NSMutableArray array];
|
||||
// attrs = nil;
|
||||
|
||||
// We might not have a preferred item but rather something like this:
|
||||
// EMAIL;TYPE=work:dd@ee.com
|
||||
// EMAIL;TYPE=home:ff@gg.com
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// EMAIL;TYPE=INTERNET:a@a.com
|
||||
// EMAIL;TYPE=INTERNET,HOME:b@b.com
|
||||
//
|
||||
// In this case, we always return the entry NOT matching the primaryEmail
|
||||
if ([emails count] > 0)
|
||||
{
|
||||
int i;
|
||||
// // We might not have a preferred item but rather something like this:
|
||||
// // EMAIL;TYPE=work:dd@ee.com
|
||||
// // EMAIL;TYPE=home:ff@gg.com
|
||||
// //
|
||||
// // or:
|
||||
// //
|
||||
// // EMAIL;TYPE=INTERNET:a@a.com
|
||||
// // EMAIL;TYPE=INTERNET,HOME:b@b.com
|
||||
// //
|
||||
// // In this case, we always return the entry NOT matching the primaryEmail
|
||||
// if ([emails count] > 0)
|
||||
// {
|
||||
// int i;
|
||||
|
||||
for (i = 0; i < [emails count]; i++)
|
||||
{
|
||||
email = [[emails objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
if ([email length])
|
||||
{
|
||||
fn = [card fn];
|
||||
if ([fn length])
|
||||
attrs = [NSString stringWithFormat: @"%@ <%@>", fn, email];
|
||||
else
|
||||
attrs = email;
|
||||
attrs = [attrs stringByReplacingString: @"'" withString: @"\\'"];
|
||||
attrs = [attrs stringByReplacingString: @"\"" withString: @"\\\""];
|
||||
attrs = [NSString stringWithFormat: @"onclick=\"return openMailTo('%@');\"", attrs];
|
||||
// for (i = 0; i < [emails count]; i++)
|
||||
// {
|
||||
// email = [[emails objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
// if ([email length])
|
||||
// {
|
||||
// fn = [card fn];
|
||||
// if ([fn length])
|
||||
// attrs = [NSString stringWithFormat: @"%@ <%@>", fn, email];
|
||||
// else
|
||||
// attrs = email;
|
||||
// attrs = [attrs stringByReplacingString: @"'" withString: @"\\'"];
|
||||
// attrs = [attrs stringByReplacingString: @"\"" withString: @"\\\""];
|
||||
// attrs = [NSString stringWithFormat: @"onclick=\"return openMailTo('%@');\"", attrs];
|
||||
|
||||
[secondaryEmails addObject: [self _cardStringWithLabel: nil
|
||||
value: email
|
||||
byEscapingHTMLString: YES
|
||||
asLinkScheme: @"mailto:"
|
||||
withLinkAttributes: attrs]];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[secondaryEmails addObject: [self _cardStringWithLabel: nil
|
||||
value: nil]];
|
||||
}
|
||||
// [secondaryEmails addObject: [self _cardStringWithLabel: nil
|
||||
// value: email
|
||||
// byEscapingHTMLString: YES
|
||||
// asLinkScheme: @"mailto:"
|
||||
// withLinkAttributes: attrs]];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// [secondaryEmails addObject: [self _cardStringWithLabel: nil
|
||||
// value: nil]];
|
||||
// }
|
||||
|
||||
|
||||
return secondaryEmails;
|
||||
}
|
||||
// return secondaryEmails;
|
||||
// }
|
||||
|
||||
- (NSString *) screenName
|
||||
{
|
||||
NSString *screenName;
|
||||
// - (NSString *) screenName
|
||||
// {
|
||||
// NSString *screenName;
|
||||
|
||||
screenName = [[card uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""];
|
||||
// screenName = [[card uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""];
|
||||
|
||||
return [self _cardStringWithLabel: @"Screen Name:"
|
||||
value: screenName
|
||||
asLinkScheme: @"aim:goim?screenname="];
|
||||
}
|
||||
// return [self _cardStringWithLabel: @"Screen Name:"
|
||||
// value: screenName
|
||||
// asLinkScheme: @"aim:goim?screenname="];
|
||||
// }
|
||||
|
||||
- (NSString *) preferredTel
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Phone Number:"
|
||||
value: [card preferredTel] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) preferredTel
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Phone Number:"
|
||||
// value: [card preferredTel] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (NSString *) preferredAddress
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
// - (NSString *) preferredAddress
|
||||
// {
|
||||
// return @"";
|
||||
// }
|
||||
|
||||
- (BOOL) hasTelephones
|
||||
{
|
||||
if (!phones)
|
||||
phones = [card childrenWithTag: @"tel"];
|
||||
// - (BOOL) hasTelephones
|
||||
// {
|
||||
// if (!phones)
|
||||
// phones = [card childrenWithTag: @"tel"];
|
||||
|
||||
return ([phones count] > 0);
|
||||
}
|
||||
// return ([phones count] > 0);
|
||||
// }
|
||||
|
||||
- (NSString *) workPhone
|
||||
{
|
||||
// We do this (exclude FAX) in order to avoid setting the WORK number as the FAX
|
||||
// one if we do see the FAX field BEFORE the WORK number.
|
||||
return [self _cardStringWithLabel: @"Work:" value: [card workPhone] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) workPhone
|
||||
// {
|
||||
// // We do this (exclude FAX) in order to avoid setting the WORK number as the FAX
|
||||
// // one if we do see the FAX field BEFORE the WORK number.
|
||||
// return [self _cardStringWithLabel: @"Work:" value: [card workPhone] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (NSString *) homePhone
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Home:" value: [card homePhone] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) homePhone
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Home:" value: [card homePhone] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (NSString *) fax
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Fax:" value: [card fax] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) fax
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Fax:" value: [card fax] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (NSString *) mobile
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Mobile:" value: [card mobile] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) mobile
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Mobile:" value: [card mobile] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (NSString *) pager
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Pager:" value: [card pager] asLinkScheme: @"tel:"];
|
||||
}
|
||||
// - (NSString *) pager
|
||||
// {
|
||||
// return [self _cardStringWithLabel: @"Pager:" value: [card pager] asLinkScheme: @"tel:"];
|
||||
// }
|
||||
|
||||
- (BOOL) hasHomeInfos
|
||||
{
|
||||
BOOL result;
|
||||
NSArray *elements;
|
||||
// - (BOOL) hasHomeInfos
|
||||
// {
|
||||
// BOOL result;
|
||||
// NSArray *elements;
|
||||
|
||||
elements = [card childrenWithTag: @"adr"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"home"];
|
||||
if ([elements count] > 0)
|
||||
{
|
||||
result = YES;
|
||||
homeAdr = [elements objectAtIndex: 0];
|
||||
}
|
||||
else
|
||||
result = ([[card childrenWithTag: @"url"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"home"] count] > 0);
|
||||
// elements = [card childrenWithTag: @"adr"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: @"home"];
|
||||
// if ([elements count] > 0)
|
||||
// {
|
||||
// result = YES;
|
||||
// homeAdr = [elements objectAtIndex: 0];
|
||||
// }
|
||||
// else
|
||||
// result = ([[card childrenWithTag: @"url"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: @"home"] count] > 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
// return result;
|
||||
// }
|
||||
|
||||
- (NSString *) homePobox
|
||||
{
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 0
|
||||
forKey: @""]];
|
||||
}
|
||||
// - (NSString *) homePobox
|
||||
// {
|
||||
// return [self _cardStringWithLabel: nil
|
||||
// value: [homeAdr flattenedValueAtIndex: 0
|
||||
// forKey: @""]];
|
||||
// }
|
||||
|
||||
- (NSString *) homeExtendedAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 1
|
||||
forKey: @""]];
|
||||
}
|
||||
// - (NSString *) homeExtendedAddress
|
||||
// {
|
||||
// return [self _cardStringWithLabel: nil
|
||||
// value: [homeAdr flattenedValueAtIndex: 1
|
||||
// forKey: @""]];
|
||||
// }
|
||||
|
||||
- (NSString *) homeStreetAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 2
|
||||
forKey: @""]];
|
||||
}
|
||||
// - (NSString *) homeStreetAddress
|
||||
// {
|
||||
// return [self _cardStringWithLabel: nil
|
||||
// value: [homeAdr flattenedValueAtIndex: 2
|
||||
// forKey: @""]];
|
||||
// }
|
||||
|
||||
- (NSString *) homeCityAndProv
|
||||
{
|
||||
NSString *city, *prov;
|
||||
NSMutableString *data;
|
||||
// - (NSString *) homeCityAndProv
|
||||
// {
|
||||
// NSString *city, *prov;
|
||||
// NSMutableString *data;
|
||||
|
||||
city = [homeAdr flattenedValueAtIndex: 3 forKey: @""];
|
||||
prov = [homeAdr flattenedValueAtIndex: 4 forKey: @""];
|
||||
// city = [homeAdr flattenedValueAtIndex: 3 forKey: @""];
|
||||
// prov = [homeAdr flattenedValueAtIndex: 4 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: city];
|
||||
if ([city length] > 0 && [prov length] > 0)
|
||||
[data appendString: @", "];
|
||||
[data appendString: prov];
|
||||
// data = [NSMutableString string];
|
||||
// [data appendString: city];
|
||||
// if ([city length] > 0 && [prov length] > 0)
|
||||
// [data appendString: @", "];
|
||||
// [data appendString: prov];
|
||||
|
||||
return [self _cardStringWithLabel: nil value: data];
|
||||
}
|
||||
// return [self _cardStringWithLabel: nil value: data];
|
||||
// }
|
||||
|
||||
- (NSString *) homePostalCodeAndCountry
|
||||
{
|
||||
NSString *postalCode, *country;
|
||||
NSMutableString *data;
|
||||
// - (NSString *) homePostalCodeAndCountry
|
||||
// {
|
||||
// NSString *postalCode, *country;
|
||||
// NSMutableString *data;
|
||||
|
||||
postalCode = [homeAdr flattenedValueAtIndex: 5 forKey: @""];
|
||||
country = [homeAdr flattenedValueAtIndex: 6 forKey: @""];
|
||||
// postalCode = [homeAdr flattenedValueAtIndex: 5 forKey: @""];
|
||||
// country = [homeAdr flattenedValueAtIndex: 6 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: postalCode];
|
||||
if ([postalCode length] > 0 && [country length] > 0)
|
||||
[data appendFormat: @", ", country];
|
||||
[data appendString: country];
|
||||
// data = [NSMutableString string];
|
||||
// [data appendString: postalCode];
|
||||
// if ([postalCode length] > 0 && [country length] > 0)
|
||||
// [data appendFormat: @", "];
|
||||
// [data appendString: country];
|
||||
|
||||
return [self _cardStringWithLabel: nil value: data];
|
||||
}
|
||||
// return [self _cardStringWithLabel: nil value: data];
|
||||
// }
|
||||
|
||||
- (NSString *) _formattedURL: (NSString *) url
|
||||
{
|
||||
NSRange schemaR;
|
||||
NSString *schema, *data;
|
||||
// - (NSString *) _formattedURL: (NSString *) url
|
||||
// {
|
||||
// NSRange schemaR;
|
||||
// NSString *schema, *data;
|
||||
|
||||
if ([url length] > 0)
|
||||
{
|
||||
schemaR = [url rangeOfString: @"://"];
|
||||
if (schemaR.length > 0)
|
||||
{
|
||||
schema = [url substringToIndex: schemaR.location + schemaR.length];
|
||||
data = [url substringFromIndex: schemaR.location + schemaR.length];
|
||||
}
|
||||
else
|
||||
{
|
||||
schema = @"http://";
|
||||
data = url;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
schema = nil;
|
||||
data = nil;
|
||||
}
|
||||
// if ([url length] > 0)
|
||||
// {
|
||||
// schemaR = [url rangeOfString: @"://"];
|
||||
// if (schemaR.length > 0)
|
||||
// {
|
||||
// schema = [url substringToIndex: schemaR.location + schemaR.length];
|
||||
// data = [url substringFromIndex: schemaR.location + schemaR.length];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// schema = @"http://";
|
||||
// data = url;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// schema = nil;
|
||||
// data = nil;
|
||||
// }
|
||||
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: data
|
||||
byEscapingHTMLString: YES
|
||||
asLinkScheme: schema
|
||||
withLinkAttributes: @"target=\"_blank\""];
|
||||
}
|
||||
// return [self _cardStringWithLabel: nil
|
||||
// value: data
|
||||
// byEscapingHTMLString: YES
|
||||
// asLinkScheme: schema
|
||||
// withLinkAttributes: @"target=\"_blank\""];
|
||||
// }
|
||||
|
||||
|
||||
- (NSString *) _urlOfType: (NSString *) aType
|
||||
{
|
||||
NSArray *elements;
|
||||
NSString *url;
|
||||
// - (NSString *) _urlOfType: (NSString *) aType
|
||||
// {
|
||||
// NSArray *elements;
|
||||
// NSString *url;
|
||||
|
||||
elements = [card childrenWithTag: @"url"
|
||||
andAttribute: @"type"
|
||||
havingValue: aType];
|
||||
if ([elements count] > 0)
|
||||
url = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
else
|
||||
url = nil;
|
||||
// elements = [card childrenWithTag: @"url"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: aType];
|
||||
// if ([elements count] > 0)
|
||||
// url = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
// else
|
||||
// url = nil;
|
||||
|
||||
return [self _formattedURL: url];
|
||||
}
|
||||
// return [self _formattedURL: url];
|
||||
// }
|
||||
|
||||
- (NSString *) homeUrl
|
||||
{
|
||||
NSString *s;
|
||||
// - (NSString *) homeUrl
|
||||
// {
|
||||
// NSString *s;
|
||||
|
||||
s = [self _urlOfType: @"home"];
|
||||
// s = [self _urlOfType: @"home"];
|
||||
|
||||
if (!s || [s length] == 0)
|
||||
{
|
||||
NSArray *elements;
|
||||
NSString *workURL;
|
||||
int i;
|
||||
// if (!s || [s length] == 0)
|
||||
// {
|
||||
// NSArray *elements;
|
||||
// NSString *workURL;
|
||||
// int i;
|
||||
|
||||
elements = [card childrenWithTag: @"url"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"work"];
|
||||
workURL = nil;
|
||||
// elements = [card childrenWithTag: @"url"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: @"work"];
|
||||
// workURL = nil;
|
||||
|
||||
if ([elements count] > 0)
|
||||
workURL = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
// if ([elements count] > 0)
|
||||
// workURL = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
|
||||
elements = [card childrenWithTag: @"url"];
|
||||
// elements = [card childrenWithTag: @"url"];
|
||||
|
||||
if (workURL && [elements count] > 1)
|
||||
{
|
||||
for (i = 0; i < [elements count]; i++)
|
||||
{
|
||||
if ([[[elements objectAtIndex: i] flattenedValuesForKey: @""]
|
||||
caseInsensitiveCompare: workURL] != NSOrderedSame)
|
||||
{
|
||||
s = [[elements objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if (workURL && [elements count] > 1)
|
||||
// {
|
||||
// for (i = 0; i < [elements count]; i++)
|
||||
// {
|
||||
// if ([[[elements objectAtIndex: i] flattenedValuesForKey: @""]
|
||||
// caseInsensitiveCompare: workURL] != NSOrderedSame)
|
||||
// {
|
||||
// s = [[elements objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
else if (!workURL && [elements count] > 0)
|
||||
{
|
||||
s = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
}
|
||||
// }
|
||||
// else if (!workURL && [elements count] > 0)
|
||||
// {
|
||||
// s = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
// }
|
||||
|
||||
if (s && [s length] > 0)
|
||||
s = [self _formattedURL: s];
|
||||
}
|
||||
// if (s && [s length] > 0)
|
||||
// s = [self _formattedURL: s];
|
||||
// }
|
||||
|
||||
return s;
|
||||
}
|
||||
// return s;
|
||||
// }
|
||||
|
||||
- (BOOL) hasWorkInfos
|
||||
{
|
||||
BOOL result;
|
||||
NSArray *elements;
|
||||
// - (BOOL) hasWorkInfos
|
||||
// {
|
||||
// BOOL result;
|
||||
// NSArray *elements;
|
||||
|
||||
elements = [card childrenWithTag: @"adr"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"work"];
|
||||
if ([elements count] > 0)
|
||||
{
|
||||
result = YES;
|
||||
workAdr = [elements objectAtIndex: 0];
|
||||
}
|
||||
else
|
||||
result = (([[card childrenWithTag: @"url"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"work"] count] > 0)
|
||||
|| [[card childrenWithTag: @"org"] count] > 0);
|
||||
// elements = [card childrenWithTag: @"adr"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: @"work"];
|
||||
// if ([elements count] > 0)
|
||||
// {
|
||||
// result = YES;
|
||||
// workAdr = [elements objectAtIndex: 0];
|
||||
// }
|
||||
// else
|
||||
// result = (([[card childrenWithTag: @"url"
|
||||
// andAttribute: @"type"
|
||||
// havingValue: @"work"] count] > 0)
|
||||
// || [[card childrenWithTag: @"org"] count] > 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
// return result;
|
||||
// }
|
||||
|
||||
- (NSString *) workTitle
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [card title]];
|
||||
}
|
||||
// - (NSString *) workTitle
|
||||
// {
|
||||
// return [self _cardStringWithLabel: nil value: [card title]];
|
||||
// }
|
||||
|
||||
- (NSArray *) orgUnits
|
||||
{
|
||||
@@ -608,65 +607,65 @@
|
||||
return addresses;
|
||||
}
|
||||
|
||||
- (NSString *) workService
|
||||
{
|
||||
NSMutableArray *orgServices;
|
||||
NSArray *values;
|
||||
CardElement *org;
|
||||
NSString *service, *services;
|
||||
NSUInteger count, max;
|
||||
// - (NSString *) workService
|
||||
// {
|
||||
// NSMutableArray *orgServices;
|
||||
// NSArray *values;
|
||||
// CardElement *org;
|
||||
// NSString *service, *services;
|
||||
// NSUInteger count, max;
|
||||
|
||||
org = [card org];
|
||||
values = [org valuesForKey: @""];
|
||||
max = [values count];
|
||||
if (max > 1)
|
||||
{
|
||||
orgServices = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 1; count < max; count++)
|
||||
{
|
||||
service = [org flattenedValueAtIndex: count forKey: @""];
|
||||
if ([service length] > 0)
|
||||
[orgServices addObject: service];
|
||||
}
|
||||
// org = [card org];
|
||||
// values = [org valuesForKey: @""];
|
||||
// max = [values count];
|
||||
// if (max > 1)
|
||||
// {
|
||||
// orgServices = [NSMutableArray arrayWithCapacity: max];
|
||||
// for (count = 1; count < max; count++)
|
||||
// {
|
||||
// service = [org flattenedValueAtIndex: count forKey: @""];
|
||||
// if ([service length] > 0)
|
||||
// [orgServices addObject: service];
|
||||
// }
|
||||
|
||||
services = [orgServices componentsJoinedByString: @", "];
|
||||
}
|
||||
else
|
||||
services = nil;
|
||||
// services = [orgServices componentsJoinedByString: @", "];
|
||||
// }
|
||||
// else
|
||||
// services = nil;
|
||||
|
||||
return [self _cardStringWithLabel: nil value: services];
|
||||
}
|
||||
// return [self _cardStringWithLabel: nil value: services];
|
||||
// }
|
||||
|
||||
- (NSString *) workUrl
|
||||
{
|
||||
return [self _urlOfType: @"work"];
|
||||
}
|
||||
// - (NSString *) workUrl
|
||||
// {
|
||||
// return [self _urlOfType: @"work"];
|
||||
// }
|
||||
|
||||
- (BOOL) hasOtherInfos
|
||||
{
|
||||
return ([[card note] length] > 0
|
||||
|| [[card bday] length] > 0
|
||||
|| [[card tz] length] > 0);
|
||||
}
|
||||
// - (BOOL) hasOtherInfos
|
||||
// {
|
||||
// return ([[card note] length] > 0
|
||||
// || [[card bday] length] > 0
|
||||
// || [[card tz] length] > 0);
|
||||
// }
|
||||
|
||||
- (NSString *) bday
|
||||
{
|
||||
SOGoDateFormatter *dateFormatter;
|
||||
NSCalendarDate *date;
|
||||
NSString *bday;
|
||||
// - (NSString *) bday
|
||||
// {
|
||||
// SOGoDateFormatter *dateFormatter;
|
||||
// NSCalendarDate *date;
|
||||
// NSString *bday;
|
||||
|
||||
date = [card birthday];
|
||||
bday = nil;
|
||||
// date = [card birthday];
|
||||
// bday = nil;
|
||||
|
||||
if (date)
|
||||
{
|
||||
dateFormatter = [[[self context] activeUser] dateFormatterInContext: context];
|
||||
bday = [dateFormatter formattedDate: date];
|
||||
}
|
||||
// if (date)
|
||||
// {
|
||||
// dateFormatter = [[[self context] activeUser] dateFormatterInContext: context];
|
||||
// bday = [dateFormatter formattedDate: date];
|
||||
// }
|
||||
|
||||
return bday;
|
||||
//return [self _cardStringWithLabel: @"Birthday:" value: bday];
|
||||
}
|
||||
// return bday;
|
||||
// //return [self _cardStringWithLabel: @"Birthday:" value: bday];
|
||||
// }
|
||||
|
||||
// - (NSString *) tz
|
||||
// {
|
||||
@@ -693,29 +692,29 @@
|
||||
|
||||
/* hrefs */
|
||||
|
||||
- (NSString *) completeHrefForMethod: (NSString *) _method
|
||||
withParameter: (NSString *) _param
|
||||
forKey: (NSString *) _key
|
||||
{
|
||||
NSString *href;
|
||||
// - (NSString *) completeHrefForMethod: (NSString *) _method
|
||||
// withParameter: (NSString *) _param
|
||||
// forKey: (NSString *) _key
|
||||
// {
|
||||
// NSString *href;
|
||||
|
||||
[self setQueryParameter:_param forKey:_key];
|
||||
href = [self completeHrefForMethod:[self ownMethodName]];
|
||||
[self setQueryParameter:nil forKey:_key];
|
||||
// [self setQueryParameter:_param forKey:_key];
|
||||
// href = [self completeHrefForMethod:[self ownMethodName]];
|
||||
// [self setQueryParameter:nil forKey:_key];
|
||||
|
||||
return href;
|
||||
}
|
||||
// return href;
|
||||
// }
|
||||
|
||||
- (NSString *)attributesTabLink {
|
||||
return [self completeHrefForMethod:[self ownMethodName]
|
||||
withParameter:@"attributes"
|
||||
forKey:@"tab"];
|
||||
}
|
||||
- (NSString *)debugTabLink {
|
||||
return [self completeHrefForMethod:[self ownMethodName]
|
||||
withParameter:@"debug"
|
||||
forKey:@"tab"];
|
||||
}
|
||||
// - (NSString *)attributesTabLink {
|
||||
// return [self completeHrefForMethod:[self ownMethodName]
|
||||
// withParameter:@"attributes"
|
||||
// forKey:@"tab"];
|
||||
// }
|
||||
// - (NSString *)debugTabLink {
|
||||
// return [self completeHrefForMethod:[self ownMethodName]
|
||||
// withParameter:@"debug"
|
||||
// forKey:@"tab"];
|
||||
// }
|
||||
|
||||
/* action */
|
||||
|
||||
@@ -751,6 +750,7 @@
|
||||
* @apiSuccess (Success 200) {String} [nickname] Nickname
|
||||
* @apiSuccess (Success 200) {String} [c_sn] Lastname
|
||||
* @apiSuccess (Success 200) {String} [c_fn] Fullname
|
||||
* @apiSuccess (Success 200) {String} [c_screenname] Screen Name (X-AIM for now)
|
||||
* @apiSuccess (Success 200) {String} [tz] Timezone
|
||||
* @apiSuccess (Success 200) {String} [note] Note
|
||||
* @apiSuccess (Success 200) {String[]} allCategories All available categories
|
||||
@@ -812,6 +812,10 @@
|
||||
if ([firstName length] > 0)
|
||||
[data setObject: firstName forKey: @"c_givenname"];
|
||||
}
|
||||
|
||||
o = [[card uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""];
|
||||
if ([o length]) [data setObject: o forKey: @"c_screenname"];
|
||||
|
||||
o = [card nickname];
|
||||
if (o) [data setObject: o forKey: @"nickname"];
|
||||
o = [card title];
|
||||
|
||||
@@ -136,6 +136,15 @@
|
||||
protectedBy = "View";
|
||||
pageName = "UIxContactFolderLinksTemplate";
|
||||
};
|
||||
properties = {
|
||||
protectedBy = "Access Contents Information";
|
||||
pageName = "UIxContactFolderProperties";
|
||||
};
|
||||
save = {
|
||||
protectedBy = "Access Contents Information";
|
||||
pageName = "UIxContactFolderProperties";
|
||||
actionName = "saveProperties";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -157,11 +166,6 @@
|
||||
pageName = "UIxContactEditor";
|
||||
actionName = "new";
|
||||
};
|
||||
save = {
|
||||
protectedBy = "Change Permissions";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "renameFolder";
|
||||
};
|
||||
mailer-contacts = {
|
||||
protectedBy = "<public>";
|
||||
pageName = "UIxContactFoldersView";
|
||||
|
||||
@@ -161,10 +161,10 @@ static NSData* _sanitizeContent(NSData *theData)
|
||||
if (i < len-5)
|
||||
{
|
||||
if ((*bytes == '<') &&
|
||||
(*(bytes+1) == 'm' || *(bytes+2) == 'M') &&
|
||||
(*(bytes+2) == 'e' || *(bytes+3) == 'E') &&
|
||||
(*(bytes+3) == 't' || *(bytes+4) == 'T') &&
|
||||
(*(bytes+4) == 'a' || *(bytes+5) == 'A') &&
|
||||
(*(bytes+1) == 'm' || *(bytes+1) == 'M') &&
|
||||
(*(bytes+2) == 'e' || *(bytes+2) == 'E') &&
|
||||
(*(bytes+3) == 't' || *(bytes+3) == 'T') &&
|
||||
(*(bytes+4) == 'a' || *(bytes+4) == 'A') &&
|
||||
(*(bytes+5) == ' '))
|
||||
in_meta = YES;
|
||||
}
|
||||
@@ -551,9 +551,9 @@ static NSData* _sanitizeContent(NSData *theData)
|
||||
else
|
||||
skipAttribute = YES;
|
||||
}
|
||||
else if ([name isEqualToString: @"background"] ||
|
||||
else if (([name isEqualToString: @"background"] ||
|
||||
([name isEqualToString: @"data"]
|
||||
|| [name isEqualToString: @"classid"])
|
||||
|| [name isEqualToString: @"classid"]))
|
||||
&& [lowerName isEqualToString: @"object"])
|
||||
{
|
||||
value = [_attributes valueAtIndex: count];
|
||||
@@ -741,7 +741,7 @@ static NSData* _sanitizeContent(NSData *theData)
|
||||
|
||||
/* SaxLexicalHandler */
|
||||
- (void) comment: (unichar *) _chars
|
||||
length: (NSUInteger) _len
|
||||
length: (int) _len
|
||||
{
|
||||
showWhoWeAre();
|
||||
if (inStyle)
|
||||
@@ -807,7 +807,7 @@ static NSData* _sanitizeContent(NSData *theData)
|
||||
}
|
||||
[dump appendFormat: @"--- end ---\n"];
|
||||
|
||||
NSLog(dump);
|
||||
NSLog(@"%@", dump);
|
||||
[dump release];
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <SOGo/SOGoParentFolder.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <Mailer/SOGoMailBodyPart.h>
|
||||
|
||||
#import "UIxMailPartICalActions.h"
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
info = [parts objectAtIndex: i];
|
||||
viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
|
||||
[viewer setBodyInfo: info];
|
||||
[viewer setPartPath: [[self contentPartPath] arrayByAddingObject: [NSString stringWithFormat: @"%d", i+1]]];
|
||||
[viewer setPartPath: [[self contentPartPath] arrayByAddingObject: [NSString stringWithFormat: @"%d", (int)i+1]]];
|
||||
[renderedParts addObject: [viewer renderedPart]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
- (void) setChildInfo: (id) _info;
|
||||
- (id) childInfo;
|
||||
- (void) setChildIndex: (unsigned int) _index;
|
||||
- (void) setChildIndex: (NSUInteger) _index;
|
||||
- (id) childPartPath;
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
return [NSString stringWithFormat: @"%u",
|
||||
(unsigned int) ([self childIndex] + 1)];
|
||||
char buf[8];
|
||||
sprintf(buf, "%d", [self childIndex] + 1);
|
||||
sprintf(buf, "%d", (int)[self childIndex] + 1);
|
||||
return [NSString stringWithCString:buf];
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
id info, viewer;
|
||||
NSArray *parts;
|
||||
NSMutableArray *renderedParts;
|
||||
NSString *contentType;
|
||||
NSUInteger i, max;
|
||||
|
||||
parts = [[self bodyInfo] objectForKey: @"parts"];
|
||||
@@ -102,9 +103,13 @@
|
||||
[viewer setPartPath: [self childPartPath]];
|
||||
[renderedParts addObject: [viewer renderedPart]];
|
||||
}
|
||||
contentType = [NSString stringWithFormat: @"%@/%@",
|
||||
[[self bodyInfo] objectForKey: @"type"],
|
||||
[[self bodyInfo] objectForKey: @"subtype"]];
|
||||
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[self className], @"type",
|
||||
contentType, @"contentType",
|
||||
renderedParts, @"content",
|
||||
nil];
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
if ([filename length])
|
||||
// We replace any slash by a dash since Apache won't allow encoded slashes by default.
|
||||
// See http://httpd.apache.org/docs/2.2/mod/core.html#allowencodedslashes
|
||||
filename = [filename stringByReplacingString: @"/" withString: @"-"];
|
||||
filename = (NSMutableString *)[filename stringByReplacingString: @"/" withString: @"-"];
|
||||
else
|
||||
[filename appendFormat: @"%@-%@",
|
||||
[self labelForKey: @"Untitled"],
|
||||
|
||||
@@ -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";
|
||||
@@ -228,6 +231,9 @@
|
||||
"Delete Message" = "Delete Message";
|
||||
"Delete Selected Messages" = "Delete Selected Messages";
|
||||
|
||||
/* Number of selected messages in list */
|
||||
"selected" = "selected";
|
||||
|
||||
"This Folder" = "This Folder";
|
||||
|
||||
/* Label popup menu */
|
||||
|
||||
@@ -639,6 +639,7 @@ static NSArray *infoKeys = nil;
|
||||
|
||||
co = [self clientObject];
|
||||
[co fetchInfo];
|
||||
[co setIsHTML: isHTML];
|
||||
|
||||
if ([[mimeType type] isEqualToString: @"multipart"])
|
||||
{
|
||||
@@ -648,7 +649,6 @@ static NSArray *infoKeys = nil;
|
||||
{
|
||||
info = [self infoFromRequest];
|
||||
[co setHeaders: info];
|
||||
[co setIsHTML: isHTML];
|
||||
[co setText: (isHTML ? [NSString stringWithFormat: @"<html>%@</html>", text] : text)];;
|
||||
error = [co storeInfo];
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
newKeyForMsgUIDs = [[NSString stringWithFormat:@"/%@/folder%@", currentAccount, newFolderName] asCSSIdentifier];
|
||||
newKeyForMsgUIDs = [NSString stringWithFormat:@"/%@/folder%@", [currentAccount asCSSIdentifier], [newFolderName asCSSIdentifier]];
|
||||
error = [co renameTo: newFolderName];
|
||||
if (error)
|
||||
{
|
||||
@@ -451,7 +451,7 @@
|
||||
NSMutableDictionary *moduleSettings, *threadsCollapsed;
|
||||
NSMutableArray *mailboxThreadsCollapsed;
|
||||
NSString *destinationFolder;
|
||||
SOGoUserSettings *us;
|
||||
SOGoUserSettings *us=nil;
|
||||
WOResponse *response;
|
||||
NSDictionary *data;
|
||||
SOGoMailFolder *co;
|
||||
@@ -739,6 +739,7 @@
|
||||
NSDictionary *content, *result;
|
||||
BOOL addOrRemove;
|
||||
NGImap4Client *client;
|
||||
id flag;
|
||||
|
||||
int i;
|
||||
|
||||
@@ -751,7 +752,13 @@
|
||||
|
||||
// We unescape our flags
|
||||
for (i = [flags count]-1; i >= 0; i--)
|
||||
[flags replaceObjectAtIndex: i withObject: [[flags objectAtIndex: i] fromCSSIdentifier]];
|
||||
{
|
||||
flag = [flags objectAtIndex: i];
|
||||
if ([flag isKindOfClass: [NSString class]])
|
||||
[flags replaceObjectAtIndex: i withObject: [flag fromCSSIdentifier]];
|
||||
else
|
||||
[flags removeObjectAtIndex: i];
|
||||
}
|
||||
|
||||
co = [self clientObject];
|
||||
client = [[co imap4Connection] client];
|
||||
|
||||
@@ -164,13 +164,15 @@
|
||||
//
|
||||
// Sometimes, the MUAs don't send over the string in () so we ignore it.
|
||||
//
|
||||
- (NSString *) messagePriority
|
||||
- (NSDictionary *) messagePriority
|
||||
{
|
||||
NSString *result;
|
||||
NSUInteger priority;
|
||||
NSString *description;
|
||||
NSData *data;
|
||||
|
||||
data = [message objectForKey: @"header"];
|
||||
result = @"";
|
||||
priority = 3;
|
||||
description = [self labelForKey: @"normal" inContext: context];
|
||||
|
||||
if (data)
|
||||
{
|
||||
@@ -191,15 +193,34 @@
|
||||
s = [[s substringFromIndex: r.location+1]
|
||||
stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
|
||||
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];
|
||||
if ([s hasPrefix: @"1"])
|
||||
{
|
||||
priority = 1;
|
||||
description = [self labelForKey: @"highest" inContext: context];
|
||||
}
|
||||
else if ([s hasPrefix: @"2"])
|
||||
{
|
||||
priority = 2;
|
||||
description = [self labelForKey: @"high" inContext: context];
|
||||
}
|
||||
else if ([s hasPrefix: @"4"])
|
||||
{
|
||||
priority = 4;
|
||||
description = [self labelForKey: @"low" inContext: context];
|
||||
}
|
||||
else if ([s hasPrefix: @"5"])
|
||||
{
|
||||
priority = 5;
|
||||
description = [self labelForKey: @"lowest" inContext: context];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt: priority], @"level",
|
||||
description, @"name",
|
||||
nil];
|
||||
}
|
||||
|
||||
- (NSString *) messageSubject
|
||||
@@ -623,11 +644,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];
|
||||
@@ -645,10 +667,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"];
|
||||
@@ -717,6 +743,8 @@
|
||||
* @apiSuccess (Success 200) {String} headers.From.email Sender's email address
|
||||
* @apiSuccess (Success 200) {Number} headers.isRead 1 if message is read
|
||||
* @apiSuccess (Success 200) {String} headers.Priority Priority
|
||||
* @apiSuccess (Success 200) {String} headers.Priority.level Priority number
|
||||
* @apiSuccess (Success 200) {String} headers.Priority.name Priority description
|
||||
* @apiSuccess (Success 200) {String} headers.RelativeDate Message date relative to now
|
||||
* @apiSuccess (Success 200) {String} headers.Size Formatted message size
|
||||
* @apiSuccess (Success 200) {String[]} headers.Flags Flags, such as "answered" and "seen"
|
||||
@@ -745,7 +773,6 @@
|
||||
noHeaders = [[[requestContent objectForKey: @"sortingAttributes"] objectForKey:@"noHeaders"] boolValue];
|
||||
data = [self getUIDsInFolder: folder
|
||||
withHeaders: !noHeaders];
|
||||
|
||||
[response appendContentString: [data jsonRepresentation]];
|
||||
|
||||
return response;
|
||||
@@ -879,7 +906,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"];
|
||||
|
||||
@@ -87,6 +87,11 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
return @"Mail";
|
||||
}
|
||||
|
||||
- (void) _setupContext
|
||||
{
|
||||
SOGoUser *activeUser;
|
||||
@@ -118,6 +123,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;
|
||||
@@ -311,12 +328,17 @@
|
||||
|
||||
- (WOResponse *) getFoldersStateAction
|
||||
{
|
||||
NSString *expandedFolders;
|
||||
id o;
|
||||
NSArray *expandedFolders;
|
||||
|
||||
[self _setupContext];
|
||||
expandedFolders = [moduleSettings objectForKey: @"ExpandedFolders"];
|
||||
o = [moduleSettings objectForKey: @"ExpandedFolders"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
expandedFolders = [o componentsSeparatedByString: @","];
|
||||
else
|
||||
expandedFolders = o;
|
||||
|
||||
return [self responseWithStatus: 200 andString: expandedFolders];
|
||||
return [self responseWithStatus: 200 andJSONRepresentation: expandedFolders];
|
||||
}
|
||||
|
||||
- (NSString *) verticalDragHandleStyle
|
||||
@@ -374,14 +396,14 @@
|
||||
- (WOResponse *) saveFoldersStateAction
|
||||
{
|
||||
WORequest *request;
|
||||
NSString *expandedFolders;
|
||||
NSArray *expandedFolders;
|
||||
|
||||
[self _setupContext];
|
||||
request = [context request];
|
||||
expandedFolders = [request formValueForKey: @"expandedFolders"];
|
||||
expandedFolders = [[request contentAsString] objectFromJSONString];
|
||||
|
||||
[moduleSettings setObject: expandedFolders
|
||||
forKey: @"ExpandedFolders"];
|
||||
forKey: @"ExpandedFolders"];
|
||||
|
||||
[us synchronize];
|
||||
|
||||
@@ -603,7 +625,7 @@
|
||||
|
||||
- (NSString *) columnsDisplayCount
|
||||
{
|
||||
return [NSString stringWithFormat: @"%d", [[self columnsDisplayOrder] count]];
|
||||
return [NSString stringWithFormat: @"%d", (int)[[self columnsDisplayOrder] count]];
|
||||
}
|
||||
|
||||
- (void) setCurrentColumn: (NSDictionary *) newCurrentColumn
|
||||
@@ -709,8 +731,8 @@
|
||||
|
||||
for (k = 0; k < [pathComponents count]; k++)
|
||||
{
|
||||
component = [NSString stringWithFormat: @"folder%@", [pathComponents objectAtIndex: k]];
|
||||
[path appendString: [component asCSSIdentifier]];
|
||||
component = [[pathComponents objectAtIndex: k] asCSSIdentifier];
|
||||
[path appendString: [NSString stringWithFormat: @"folder%@", component]];
|
||||
if (k < [pathComponents count] - 1)
|
||||
[path appendString: @"/"];
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#import <Mailer/SOGoMailFolder.h>
|
||||
#import <MailPartViewers/UIxMailRenderingContext.h> // cyclic
|
||||
#import <MailPartViewers/UIxMailSizeFormatter.h>
|
||||
#import <MailPartViewers/UIxMailPartViewer.h>
|
||||
|
||||
#import "WOContext+UIxMailer.h"
|
||||
#import "UIxMailFormatter.h"
|
||||
@@ -229,7 +230,7 @@ static NSString *mailETag = nil;
|
||||
|
||||
- (id <WOActionResults>) defaultAction
|
||||
{
|
||||
id <WOActionResults> response;
|
||||
WOResponse *response;
|
||||
NSString *s;
|
||||
NSMutableDictionary *data;
|
||||
NSArray *addresses;
|
||||
|
||||
@@ -342,10 +342,19 @@
|
||||
actionClass = "UIxMailMainFrame";
|
||||
actionName = "unseenCount";
|
||||
};
|
||||
mailAccounts = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailMainFrame";
|
||||
actionName = "mailAccounts";
|
||||
};
|
||||
// viewerTemplate = {
|
||||
// protectedBy = "View";
|
||||
// pageName = "UIxMailViewTemplate";
|
||||
// };
|
||||
UIxMailPopupView = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailPopupView";
|
||||
};
|
||||
UIxMailEditor = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxMailEditor";
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
|
||||
#import <Common/WODirectAction+SOGo.h>
|
||||
#import <ActiveSync/SOGoActiveSyncDispatcher.h>
|
||||
|
||||
@interface SOGoMicrosoftActiveSyncActions : WODirectAction
|
||||
@end
|
||||
|
||||
@@ -47,7 +50,7 @@
|
||||
id dispatcher;
|
||||
Class clazz;
|
||||
|
||||
request = [context request];
|
||||
request = (WORequest *)[context request];
|
||||
response = [self responseWithStatus: 200];
|
||||
|
||||
bundle = [NSBundle bundleForClass: NSClassFromString(@"ActiveSyncProduct")];
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
timeZone: [currentStartDate timeZone]];
|
||||
|
||||
// Increment counters for quarters of first hour
|
||||
hourKey = [NSString stringWithFormat: @"%u", [currentDate hourOfDay]];
|
||||
hourKey = [NSString stringWithFormat: @"%u", (unsigned int)[currentDate hourOfDay]];
|
||||
hourData = [dayData objectForKey: hourKey];
|
||||
if (!hourData)
|
||||
{
|
||||
@@ -224,7 +224,7 @@
|
||||
while ([currentDate compare: currentEndDate] == NSOrderedAscending &&
|
||||
[currentEndDate timeIntervalSinceDate: currentDate] >= 3600) // 1 hour
|
||||
{
|
||||
hourKey = [NSString stringWithFormat: @"%u", [currentDate hourOfDay]];
|
||||
hourKey = [NSString stringWithFormat: @"%u", (unsigned int)[currentDate hourOfDay]];
|
||||
hourData = [dayData objectForKey: hourKey];
|
||||
if (!hourData)
|
||||
{
|
||||
@@ -251,7 +251,7 @@
|
||||
// Increment counters for quarters of last hour
|
||||
if ([currentEndDate timeIntervalSinceDate: currentDate] > 0)
|
||||
{
|
||||
hourKey = [NSString stringWithFormat: @"%u", [currentDate hourOfDay]];
|
||||
hourKey = [NSString stringWithFormat: @"%u", (unsigned int)[currentDate hourOfDay]];
|
||||
hourData = [dayData objectForKey: hourKey];
|
||||
if (!hourData)
|
||||
{
|
||||
@@ -636,7 +636,7 @@
|
||||
* @apiExample {curl} Example usage:
|
||||
* curl -i http://localhost/SOGo/so/sogo1/foldersSearch?type=contact
|
||||
*
|
||||
* @apiParam {String} type Either 'calendar' or 'contact'
|
||||
* @apiParam {String} type Either 'calendar' or 'contact'. If nothing is specifed, its both.
|
||||
*
|
||||
* @apiSuccess (Success 200) {Object[]} folders List of matching folders
|
||||
* @apiSuccess (Success 200) {String} folders.name Path of folder
|
||||
@@ -648,27 +648,31 @@
|
||||
- (id <WOActionResults>) foldersSearchAction
|
||||
{
|
||||
NSString *folderType;
|
||||
NSArray *folders;
|
||||
NSMutableArray *folders;
|
||||
NSDictionary *message;
|
||||
id <WOActionResults> result;
|
||||
SOGoUserFolder *userFolder;
|
||||
|
||||
|
||||
folderType = [self queryParameterForKey: @"type"];
|
||||
folders = [NSMutableArray array];
|
||||
userFolder = [self clientObject];
|
||||
|
||||
if ([folderType length])
|
||||
{
|
||||
userFolder = [self clientObject];
|
||||
folders = [userFolder foldersOfType: folderType
|
||||
forUID: [userFolder ownerInContext: context]];
|
||||
result = [self _foldersResponseForResults: folders];
|
||||
[folders addObjectsFromArray: [userFolder foldersOfType: folderType
|
||||
forUID: [userFolder ownerInContext: context]]];
|
||||
}
|
||||
else
|
||||
{
|
||||
message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing type parameter"]
|
||||
forKey: @"error"];
|
||||
result = [self responseWithStatus: 400 andJSONRepresentation: message];
|
||||
[folders addObjectsFromArray: [userFolder foldersOfType: @"calendar"
|
||||
forUID: [userFolder ownerInContext: context]]];
|
||||
[folders addObjectsFromArray: [userFolder foldersOfType: @"contact"
|
||||
forUID: [userFolder ownerInContext: context]]];
|
||||
}
|
||||
|
||||
result = [self _foldersResponseForResults: folders];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
|
||||
/* Event+task categories */
|
||||
"category_none" = "Nenhum";
|
||||
"calendar_category_labels" = "Aniversário,Negócios,Ligações,Concorrência,Cliente,Favoritos,Acompanhamento,Presentes,Feriados,Idéias,Meeting,Problemas,Miscelânea,Pessoal,Projetos,Feriado público,Posição,Fornecedores,Viagem,Férias";
|
||||
"calendar_category_labels" = "Celebração Anual,Aniversário,Negócios,Ligações,Clientes,Concorrência,Comprador,Favoritos,Acompanhamento,Presentes,Feriados,Idéias,Reunião,Problemas,Miscelânea,Pessoal,Projetos,Feriado,Posição,Fornecedores,Viagem,Férias";
|
||||
|
||||
/* Default module */
|
||||
"Calendar" = "Calendário";
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
/* vacation (auto-reply) */
|
||||
"Enable vacation auto reply" = "Enable vacation auto reply";
|
||||
"Auto reply message" ="Auto reply message";
|
||||
"Email addresses (separated by commas)" ="Email addresses (separated by commas)";
|
||||
"Auto reply message" = "Auto reply message";
|
||||
"Email addresses (separated by commas)" = "Email addresses (separated by commas)";
|
||||
"Add default email addresses" = "Add default email addresses";
|
||||
"Days between responses" ="Days between responses";
|
||||
"Days between responses" = "Days between responses";
|
||||
"Do not send responses to mailing lists" = "Do not send responses to mailing lists";
|
||||
"Disable auto reply on" = "Disable auto reply on";
|
||||
"Always send vacation message response" = "Always send vacation message response";
|
||||
@@ -47,10 +47,10 @@
|
||||
|
||||
|
||||
/* d & t */
|
||||
"Current Time Zone" ="Current Time Zone";
|
||||
"Short Date Format" ="Short Date Format";
|
||||
"Long Date Format" ="Long Date Format";
|
||||
"Time Format" ="Time Format";
|
||||
"Current Time Zone" = "Current Time Zone";
|
||||
"Short Date Format" = "Short Date Format";
|
||||
"Long Date Format" = "Long Date Format";
|
||||
"Time Format" = "Time Format";
|
||||
|
||||
"default" = "Default";
|
||||
"Default Module" = "Default Module";
|
||||
@@ -98,15 +98,15 @@
|
||||
"timeFmt_4" = "";
|
||||
|
||||
/* calendar */
|
||||
"Week begins on" ="Week begins on";
|
||||
"Day start time" ="Day start time";
|
||||
"Day end time" ="Day end time";
|
||||
"Week begins on" = "Week begins on";
|
||||
"Day start time" = "Day start time";
|
||||
"Day end time" = "Day end time";
|
||||
"Day start time must be prior to day end time." = "Day start time must be prior to day end time.";
|
||||
"Show time as busy outside working hours" = "Show time as busy outside working hours";
|
||||
"First week of year" ="First week of year";
|
||||
"First week of year" = "First week of year";
|
||||
"Enable reminders for Calendar items" = "Enable reminders for Calendar items";
|
||||
"Play a sound when a reminder comes due" = "Play a sound when a reminder comes due";
|
||||
"Default reminder" ="Default reminder";
|
||||
"Default reminder" = "Default reminder";
|
||||
|
||||
"firstWeekOfYear_January1" = "Starts on january 1";
|
||||
"firstWeekOfYear_First4DayWeek" = "First 4-day week";
|
||||
@@ -117,7 +117,7 @@
|
||||
"Contacts Names" = "Contacts Names";
|
||||
|
||||
/* Default Calendar */
|
||||
"Default calendar" ="Default calendar";
|
||||
"Default calendar" = "Default calendar";
|
||||
"selectedCalendar" = "Selected calendar";
|
||||
"personalCalendar" = "Personal calendar";
|
||||
"firstCalendar" = "First enabled calendar";
|
||||
@@ -200,8 +200,8 @@
|
||||
"Change" = "Change";
|
||||
|
||||
/* Event+task classifications */
|
||||
"Default events classification" ="Default events classification";
|
||||
"Default tasks classification" ="Default tasks classification";
|
||||
"Default events classification" = "Default events classification";
|
||||
"Default tasks classification" = "Default tasks classification";
|
||||
"PUBLIC_item" = "Public";
|
||||
"CONFIDENTIAL_item" = "Confidential";
|
||||
"PRIVATE_item" = "Private";
|
||||
@@ -222,9 +222,11 @@
|
||||
"Mail" = "Mail";
|
||||
"Last" = "Last used";
|
||||
"Default Module " = "Default Module";
|
||||
"SOGo Version" ="SOGo Version";
|
||||
"SOGo Version" = "SOGo Version";
|
||||
|
||||
"Language" ="Language";
|
||||
/* Confirmation asked when changing the language */
|
||||
"Save preferences and reload page now?" = "Save preferences and reload page now?";
|
||||
"Language" = "Language";
|
||||
"choose" = "Choose ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
@@ -253,7 +255,7 @@
|
||||
"Ukrainian" = "Українська";
|
||||
"Welsh" = "Cymraeg";
|
||||
|
||||
"Refresh View" ="Refresh View";
|
||||
"Refresh View" = "Refresh View";
|
||||
"refreshview_manually" = "Manually";
|
||||
"refreshview_every_minute" = "Every minute";
|
||||
"refreshview_every_2_minutes" = "Every 2 minutes";
|
||||
@@ -320,6 +322,9 @@
|
||||
"matches regex" = "matches regex";
|
||||
"does not match regex" = "does not match regex";
|
||||
|
||||
/* Placeholder for the value field of a condition */
|
||||
"Value" = "Value";
|
||||
|
||||
"Seen" = "Seen";
|
||||
"Deleted" = "Deleted";
|
||||
"Answered" = "Answered";
|
||||
@@ -357,3 +362,10 @@
|
||||
"SSL" = "SSL";
|
||||
"TLS" = "TLS";
|
||||
|
||||
/* Avatars */
|
||||
"Alternate Avatar" = "Alternate Avatar";
|
||||
"none" = "None";
|
||||
"identicon" = "Ident Icon";
|
||||
"monsterid" = "Monster";
|
||||
"wavatar" = "Wavatar";
|
||||
"retro" = "Retro";
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/SOGoUserProfile.h>
|
||||
#import <SOGo/WOResourceManager+SOGo.h>
|
||||
#import <Mailer/SOGoMailLabel.h>
|
||||
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
@@ -95,6 +96,9 @@ static SoProduct *preferencesProduct = nil;
|
||||
if (![[defaults source] objectForKey: @"SOGoRefreshViewCheck"])
|
||||
[[defaults source] setObject: [defaults refreshViewCheck] forKey: @"SOGoRefreshViewCheck"];
|
||||
|
||||
if (![[defaults source] objectForKey: @"SOGoAlternateAvatar"])
|
||||
[[defaults source] setObject: [defaults alternateAvatar] forKey: @"SOGoAlternateAvatar"];
|
||||
|
||||
//
|
||||
// Default Calendar preferences
|
||||
//
|
||||
|
||||
@@ -169,6 +169,11 @@ static NSArray *reminderValues = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
return @"Preferences";
|
||||
}
|
||||
|
||||
// - (void) setHasChanged: (BOOL) newHasChanged
|
||||
// {
|
||||
// hasChanged = newHasChanged;
|
||||
@@ -1375,6 +1380,18 @@ static NSArray *reminderValues = nil;
|
||||
return [self labelForKey: item];
|
||||
}
|
||||
|
||||
- (NSArray *) alternateAvatar
|
||||
{
|
||||
// See: https://en.gravatar.com/site/implement/images/
|
||||
return [NSArray arrayWithObjects: @"none", @"identicon", @"monsterid", @"wavatar", @"retro", nil];
|
||||
}
|
||||
|
||||
- (NSString *) itemAlternateAvatarText
|
||||
{
|
||||
return [self labelForKey: item];
|
||||
}
|
||||
|
||||
|
||||
// - (NSString *) userDefaultModule
|
||||
// {
|
||||
// NSString *userDefaultModule;
|
||||
@@ -1466,15 +1483,15 @@ static NSArray *reminderValues = nil;
|
||||
// if ([account updateFilters])
|
||||
// // If Sieve is not enabled, the SOGoSieveManager will immediatly return a positive answer
|
||||
// // See [SOGoSieveManager updateFiltersForAccount:withUsername:andPassword:]
|
||||
// results = [self responseWithStatus: 200
|
||||
// results = (id <WOActionResults>)[self responseWithStatus: 200
|
||||
// andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:hasChanged], @"hasChanged", nil]];
|
||||
|
||||
// else
|
||||
// results = [self responseWithStatus: 502
|
||||
// results = (id <WOActionResults>)[self responseWithStatus: 502
|
||||
// andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Connection error", @"textStatus", nil]];
|
||||
// }
|
||||
// else
|
||||
// results = [self responseWithStatus: 503
|
||||
// results = (id <WOActionResults>)[self responseWithStatus: 503
|
||||
// andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"textStatus", nil]];
|
||||
// }
|
||||
// else
|
||||
@@ -2086,6 +2103,10 @@ static NSArray *reminderValues = nil;
|
||||
// We convert our object into a mutable one
|
||||
v = [[v mutableCopy] autorelease];
|
||||
|
||||
if ([[v objectForKey: @"SOGoLoginModule"] isEqualToString: @"Last"])
|
||||
[v setObject: [NSNumber numberWithBool: YES] forKey: @"SOGoRememberLastModule"];
|
||||
else
|
||||
[v setObject: [NSNumber numberWithBool: NO] forKey: @"SOGoRememberLastModule"];
|
||||
|
||||
// We remove short/long date formats if they are default ones
|
||||
if ([[v objectForKey: @"SOGoShortDateFormat"] isEqualToString: @"default"])
|
||||
@@ -2158,12 +2179,12 @@ static NSArray *reminderValues = nil;
|
||||
|
||||
if (![account updateFilters])
|
||||
{
|
||||
results = [self responseWithStatus: 502
|
||||
results = (id <WOActionResults>) [self responseWithStatus: 502
|
||||
andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Connection error", @"textStatus", nil]];
|
||||
}
|
||||
}
|
||||
else
|
||||
results = [self responseWithStatus: 503
|
||||
results = (id <WOActionResults>) [self responseWithStatus: 503
|
||||
andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"textStatus", nil]];
|
||||
}
|
||||
}
|
||||
@@ -2175,7 +2196,7 @@ static NSArray *reminderValues = nil;
|
||||
}
|
||||
|
||||
if (!results)
|
||||
results = [self responseWithStatus: 200];
|
||||
results = (id <WOActionResults>) [self responseWithStatus: 200];
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -155,14 +155,14 @@
|
||||
*/
|
||||
|
||||
[_buf appendFormat:@"%02i:%02i",
|
||||
[_date hourOfDay],
|
||||
[_date minuteOfHour]];
|
||||
(int)[_date hourOfDay],
|
||||
(int)[_date minuteOfHour]];
|
||||
if (_refDate && ![_date isDateOnSameDay:_refDate]) {
|
||||
[_buf appendFormat:@" (%02i-%02i",
|
||||
[_date monthOfYear],
|
||||
[_date dayOfMonth]];
|
||||
(int)[_date monthOfYear],
|
||||
(int)[_date dayOfMonth]];
|
||||
if ([_date yearOfCommonEra] != [_refDate yearOfCommonEra])
|
||||
[_buf appendFormat:@"-%04i", [_date yearOfCommonEra]];
|
||||
[_buf appendFormat:@"-%04i", (int)[_date yearOfCommonEra]];
|
||||
[_buf appendString:@")"];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,40 +360,19 @@ static SoProduct *commonProduct = nil;
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
SOGoObject *currentClient, *parent;
|
||||
BOOL found;
|
||||
NSString *hostLessURL;
|
||||
Class objectClass, userFolderClass;
|
||||
// , groupFolderClass
|
||||
|
||||
currentClient = [self clientObject];
|
||||
if (currentClient
|
||||
&& [currentClient isKindOfClass: [SOGoObject class]])
|
||||
if ([[self parent] respondsToSelector: @selector(modulePath)])
|
||||
{
|
||||
// groupFolderClass = [SOGoCustomGroupFolder class];
|
||||
userFolderClass = [SOGoUserFolder class];
|
||||
NSString *baseURL;
|
||||
|
||||
objectClass = [currentClient class];
|
||||
// found = (objectClass == groupFolderClass || objectClass == userFolderClass);
|
||||
found = (objectClass == userFolderClass);
|
||||
while (!found && currentClient)
|
||||
{
|
||||
parent = [currentClient container];
|
||||
objectClass = [parent class];
|
||||
if (// objectClass == groupFolderClass
|
||||
// ||
|
||||
objectClass == userFolderClass)
|
||||
found = YES;
|
||||
else
|
||||
currentClient = parent;
|
||||
}
|
||||
baseURL = [[self clientObject] baseURLInContext: context];
|
||||
|
||||
if ([baseURL hasSuffix: [NSString stringWithFormat: @"%@/", [[self parent] modulePath]]])
|
||||
return baseURL;
|
||||
|
||||
return [NSString stringWithFormat: @"%@%@", baseURL, [[self parent] modulePath]];
|
||||
}
|
||||
else
|
||||
currentClient = [WOApplication application];
|
||||
|
||||
hostLessURL = [[currentClient baseURLInContext: context] hostlessURL];
|
||||
|
||||
return [hostLessURL substringToIndex: [hostLessURL length] - 1];
|
||||
return @"SOGo";
|
||||
}
|
||||
|
||||
- (NSString *) ownPath
|
||||
|
||||
@@ -446,6 +446,9 @@ validate_endbeforestart = "The end date that you entered occurs before the st
|
||||
"Month View" = "Month View";
|
||||
"Reload" = "Reload";
|
||||
|
||||
/* Number of selected components in events or tasks list */
|
||||
"selected" = "selected";
|
||||
|
||||
"eventPartStatModificationError" = "Your participation status could not be modified.";
|
||||
|
||||
/* menu */
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
|
||||
/* Searching */
|
||||
|
||||
"view_all" = "Todos los eventos";
|
||||
"view_all" = "Todos";
|
||||
"view_today" = "Hoy";
|
||||
"view_next7" = "Próximos 7 días";
|
||||
"view_next14" = "Próximos 14 días";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#import <SOGo/NSCalendarDate+SOGo.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <Appointments/iCalEvent+SOGo.h>
|
||||
@@ -59,23 +60,25 @@
|
||||
SoSecurityManager *sm;
|
||||
iCalEvent *event;
|
||||
NSCalendarDate *start, *newStart, *end, *newEnd;
|
||||
NSDictionary *params;
|
||||
NSTimeInterval newDuration;
|
||||
SOGoUserDefaults *ud;
|
||||
NSString *daysDelta, *startDelta, *durationDelta, *destionationCalendar;
|
||||
NSNumber *daysDelta, *startDelta, *durationDelta;
|
||||
NSString *destionationCalendar;
|
||||
NSTimeZone *tz;
|
||||
NSException *ex;
|
||||
SOGoAppointmentFolder *targetCalendar, *sourceCalendar;
|
||||
SOGoAppointmentFolders *folders;
|
||||
|
||||
rq = [context request];
|
||||
params = [[rq contentAsString] objectFromJSONString];
|
||||
|
||||
daysDelta = [rq formValueForKey: @"days"];
|
||||
startDelta = [rq formValueForKey: @"start"];
|
||||
durationDelta = [rq formValueForKey: @"duration"];
|
||||
destionationCalendar = [rq formValueForKey: @"destination"];
|
||||
daysDelta = [params objectForKey: @"days"];
|
||||
startDelta = [params objectForKey: @"start"];
|
||||
durationDelta = [params objectForKey: @"duration"];
|
||||
destionationCalendar = [params objectForKey: @"destination"];
|
||||
|
||||
if ([daysDelta length] > 0
|
||||
|| [startDelta length] > 0 || [durationDelta length] > 0)
|
||||
if (daysDelta || startDelta || durationDelta)
|
||||
{
|
||||
co = [self clientObject];
|
||||
event = (iCalEvent *) [[self clientObject] occurence];
|
||||
@@ -119,7 +122,7 @@
|
||||
[event setLastModified: [NSCalendarDate calendarDate]];
|
||||
ex = [co saveComponent: event];
|
||||
// This condition will be executed only if the event is moved from a calendar to another. If destionationCalendar == 0; there is no calendar change
|
||||
if (![destionationCalendar isEqualToString:@"0"])
|
||||
if ([destionationCalendar length] > 0)
|
||||
{
|
||||
folders = [[self->context activeUser] calendarsFolderInContext: self->context];
|
||||
sourceCalendar = [co container];
|
||||
@@ -151,9 +154,8 @@
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
response
|
||||
= (WOResponse *) [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"missing 'days', 'start' and/or 'duration' parameters"];
|
||||
response = (WOResponse *) [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"missing 'days', 'start' and/or 'duration' parameters"];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -595,12 +595,12 @@
|
||||
* @apiSuccess (Success 200) {Boolean} alarm.attendees Alert attendees by email if true and action is email
|
||||
* @apiSuccess (Success 200) {Boolean} alarm.organizer Alert organizer by email if true and action is email
|
||||
*
|
||||
* @apiSuccess {_} ... _From [iCalEvent+SOGo attributes]_
|
||||
* @apiSuccess {_} ... _From [iCalEvent+SOGo attributesInContext:]_
|
||||
*
|
||||
* @apiSuccess (Success 200) {Number} isAllDay 1 if event is all-day
|
||||
* @apiSuccess (Success 200) {Number} isTransparent 1 if the event is not opaque
|
||||
*
|
||||
* @apiSuccess {_} .... _From [iCalEntityObject+SOGo attributes]_
|
||||
* @apiSuccess {_} .... _From [iCalEntityObject+SOGo attributesInContext:]_
|
||||
*
|
||||
* @apiSuccess (Success 200) {Number} sendAppointmentNotifications 1 if notifications must be sent
|
||||
* @apiSuccess (Success 200) {String} component "vevent"
|
||||
@@ -626,7 +626,7 @@
|
||||
* @apiSuccess (Success 200) {String} [attendees.delegatedTo] User that the original request was delegated to
|
||||
* @apiSuccess (Success 200) {String} [attendees.delegatedFrom] User the request was delegated from
|
||||
*
|
||||
* @apiSuccess {_} ..... _From [iCalRepeatableEntityObject+SOGo attributes]_
|
||||
* @apiSuccess {_} ..... _From [iCalRepeatableEntityObject+SOGo attributesInContext:]_
|
||||
*
|
||||
* @apiSuccess (Success 200) {Object} [repeat] Recurrence rule definition
|
||||
* @apiSuccess (Success 200) {String} repeat.frequency Either daily, (every weekday), weekly, (bi-weekly), monthly, or yearly
|
||||
@@ -652,7 +652,8 @@
|
||||
iCalEvent *event;
|
||||
|
||||
BOOL resetAlarm;
|
||||
unsigned int snoozeAlarm;
|
||||
NSInteger offset;
|
||||
NSUInteger snoozeAlarm;
|
||||
|
||||
event = [self event];
|
||||
co = [self clientObject];
|
||||
@@ -662,12 +663,23 @@
|
||||
timeZone = [ud timeZone];
|
||||
eventStartDate = [event startDate];
|
||||
eventEndDate = [event endDate];
|
||||
if (!isAllDay)
|
||||
|
||||
if (isAllDay)
|
||||
{
|
||||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
eventEndDate = [eventEndDate dateByAddingYears: 0 months: 0 days: -1];
|
||||
|
||||
// Convert the dates to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: eventStartDate];
|
||||
eventStartDate = [eventStartDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
offset = [timeZone secondsFromGMTForDate: eventEndDate];
|
||||
eventEndDate = [eventEndDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
}
|
||||
|
||||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
|
||||
// resetAlarm=yes is set only when we are about to show the alarm popup in the Web
|
||||
// interface of SOGo. See generic.js for details. snoozeAlarm=X is called when the
|
||||
// user clicks on "Snooze for" X minutes, when the popup is being displayed.
|
||||
@@ -704,8 +716,11 @@
|
||||
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[componentCalendar nameInContainer], @"pid",
|
||||
[componentCalendar displayName], @"calendar",
|
||||
[NSNumber numberWithBool: isAllDay], @"isAllDay",
|
||||
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
|
||||
[NSNumber numberWithBool: [self userHasRSVP]], @"userHasRSVP",
|
||||
[eventStartDate iso8601DateString], @"startDate",
|
||||
[eventEndDate iso8601DateString], @"endDate",
|
||||
[dateFormatter formattedDate: eventStartDate], @"localizedStartDate",
|
||||
[dateFormatter formattedDate: eventEndDate], @"localizedEndDate",
|
||||
[self alarm], @"alarm",
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
date = [self startDate];
|
||||
|
||||
return [NSString stringWithFormat: @"%.2d", [date monthOfYear]];
|
||||
return [NSString stringWithFormat: @"%.2d", (int)[date monthOfYear]];
|
||||
}
|
||||
|
||||
- (NSString *) headerMonthString
|
||||
@@ -136,7 +136,7 @@
|
||||
|
||||
date = [self startDate];
|
||||
|
||||
return [NSString stringWithFormat: @"%d", [date yearOfCommonEra]];
|
||||
return [NSString stringWithFormat: @"%d", (int)[date yearOfCommonEra]];
|
||||
}
|
||||
|
||||
- (NSString *) localizedDayOfWeekName
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
NSArray *weekDays;
|
||||
NSString *currentView, *timeFormat, *currentTableHour;
|
||||
NSCalendarDate *startDate, *currentTableDay;
|
||||
NSMutableArray *daysToDisplay, *calendarsToDisplay, *currentCalendar, *hoursToDisplay;
|
||||
NSMutableArray *daysToDisplay, *calendarsToDisplay, *hoursToDisplay;
|
||||
NSMutableDictionary *currentCalendar;
|
||||
unsigned int numberOfDays;
|
||||
}
|
||||
|
||||
@@ -55,7 +56,7 @@
|
||||
- (NSArray *) calendarsToDisplay;
|
||||
- (void) setCurrentTableDay: (NSCalendarDate *) aTableDay;
|
||||
- (NSCalendarDate *) currentTableDay;
|
||||
- (NSMutableArray *) currentCalendar;
|
||||
- (NSMutableDictionary *) currentCalendar;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/WOResourceManager+SOGo.h>
|
||||
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolders.h>
|
||||
|
||||
#import "UIxCalDayTable.h"
|
||||
|
||||
@class SOGoAppointment;
|
||||
@@ -184,14 +187,13 @@
|
||||
{
|
||||
if (!calendarsToDisplay)
|
||||
{
|
||||
int max=0, i;
|
||||
NSArray *folders;
|
||||
SOGoAppointmentFolders *co;
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSMutableDictionary *calendar;
|
||||
unsigned int count, foldersCount;
|
||||
NSString *folderName, *fDisplayName;
|
||||
NSNumber *isActive;
|
||||
BOOL isActive;
|
||||
|
||||
co = [self clientObject];
|
||||
folders = [co subFolders];
|
||||
@@ -200,8 +202,8 @@
|
||||
for (count = 0; count < foldersCount; count++)
|
||||
{
|
||||
folder = [folders objectAtIndex: count];
|
||||
isActive = [NSNumber numberWithBool: [folder isActive]];
|
||||
if ([isActive intValue] != 0) {
|
||||
isActive = [folder isActive];
|
||||
if (isActive != NO) {
|
||||
calendar = [NSMutableDictionary dictionary];
|
||||
folderName = [folder nameInContainer];
|
||||
fDisplayName = [folder displayName];
|
||||
@@ -214,7 +216,7 @@
|
||||
[calendar setObject: fDisplayName forKey: @"displayName"];
|
||||
[calendar setObject: folderName forKey: @"folder"];
|
||||
[calendar setObject: [folder calendarColor] forKey: @"color"];
|
||||
[calendar setObject: isActive forKey: @"active"];
|
||||
[calendar setObject: [NSNumber numberWithBool:isActive] forKey: @"active"];
|
||||
[calendar setObject: [folder ownerInContext: context]
|
||||
forKey: @"owner"];
|
||||
[calendarsToDisplay addObject: calendar];
|
||||
@@ -235,12 +237,12 @@
|
||||
return currentTableDay;
|
||||
}
|
||||
|
||||
- (void) setCurrentCalendar: (NSMutableArray *) aCalendar
|
||||
- (void) setCurrentCalendar: (NSMutableDictionary *) aCalendar
|
||||
{
|
||||
ASSIGN(currentCalendar, aCalendar);
|
||||
}
|
||||
|
||||
- (NSMutableArray *) currentCalendar
|
||||
- (NSMutableDictionary *) currentCalendar
|
||||
{
|
||||
return currentCalendar;
|
||||
}
|
||||
@@ -282,9 +284,9 @@
|
||||
return [daysToDisplay indexOfObject: currentTableDay];
|
||||
}
|
||||
|
||||
- (NSString *) currentAppointmentHour
|
||||
- (NSNumber *) currentAppointmentHour
|
||||
{
|
||||
return [NSString stringWithFormat: @"%.2d00", [currentTableHour intValue]];
|
||||
return [NSNumber numberWithInt: [currentTableHour intValue]];
|
||||
}
|
||||
|
||||
- (NSString *) labelForDay
|
||||
@@ -292,6 +294,39 @@
|
||||
return [weekDays objectAtIndex: [currentTableDay dayOfWeek]];
|
||||
}
|
||||
|
||||
- (NSString *) labelForMonth
|
||||
{
|
||||
NSCalendarDate *nextDay;
|
||||
NSString *calendarFormat;
|
||||
BOOL isLastOrFirstDay;
|
||||
|
||||
isLastOrFirstDay = NO;
|
||||
calendarFormat = @"%b";
|
||||
|
||||
if ([currentView hasSuffix: @"dayview"])
|
||||
{
|
||||
isLastOrFirstDay = YES;
|
||||
calendarFormat = @"%B";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([currentTableDay dayOfMonth] == 1)
|
||||
{
|
||||
isLastOrFirstDay = YES;
|
||||
}
|
||||
else if ([currentTableDay dayOfMonth] > 27)
|
||||
{
|
||||
nextDay = [currentTableDay dateByAddingYears: 0
|
||||
months: 0
|
||||
days: 1];
|
||||
if ([nextDay dayOfMonth] == 1)
|
||||
isLastOrFirstDay = YES;
|
||||
}
|
||||
}
|
||||
|
||||
return isLastOrFirstDay? [currentTableDay descriptionWithCalendarFormat: calendarFormat locale: locale] : nil;
|
||||
}
|
||||
|
||||
- (NSString *) labelForDate
|
||||
{
|
||||
return [dateFormatter shortFormattedDate: currentTableDay];
|
||||
@@ -397,18 +432,23 @@
|
||||
numberOfDays];
|
||||
}
|
||||
|
||||
- (NSString *) daysViewClasses
|
||||
{
|
||||
NSString *daysView;
|
||||
// - (NSString *) daysViewClasses
|
||||
// {
|
||||
// NSString *daysView;
|
||||
|
||||
if ([currentView isEqualToString:@"multicolumndayview"])
|
||||
daysView = @"daysView daysViewForMultipleDays";
|
||||
// if ([currentView isEqualToString:@"multicolumndayview"])
|
||||
// daysView = @"daysView daysViewForMultipleDays";
|
||||
|
||||
else
|
||||
daysView = [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays];
|
||||
// else
|
||||
// daysView = [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays];
|
||||
|
||||
return daysView;
|
||||
}
|
||||
// return daysView;
|
||||
//}
|
||||
|
||||
// - (NSString *) daysViewHeaderClasses
|
||||
// {
|
||||
// return [NSString stringWithFormat: @"%@ daysHeader", [self daysViewClasses]];
|
||||
// }
|
||||
|
||||
- (NSString *) dayClasses
|
||||
{
|
||||
@@ -416,22 +456,18 @@
|
||||
unsigned int currentDayNbr, realDayOfWeek;
|
||||
|
||||
classes = [NSMutableString string];
|
||||
if ([currentView isEqualToString:@"multicolumndayview"])
|
||||
[classes appendFormat:@"day dayColumn"];
|
||||
else {
|
||||
currentDayNbr = [daysToDisplay indexOfObject: currentTableDay];
|
||||
realDayOfWeek = [currentTableDay dayOfWeek];
|
||||
currentDayNbr = [daysToDisplay indexOfObject: currentTableDay];
|
||||
realDayOfWeek = [currentTableDay dayOfWeek];
|
||||
|
||||
[classes appendFormat: @"day day%d", currentDayNbr];
|
||||
[classes appendFormat: @"day day%d", currentDayNbr];
|
||||
|
||||
if (numberOfDays > 1)
|
||||
if (numberOfDays > 1)
|
||||
{
|
||||
if (realDayOfWeek == 0 || realDayOfWeek == 6)
|
||||
[classes appendString: @" weekEndDay"];
|
||||
if ([currentTableDay isToday])
|
||||
[classes appendString: @" dayOfToday"];
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
@@ -468,4 +504,9 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) isWeekView
|
||||
{
|
||||
return [currentView isEqualToString:@"weekview"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
|
||||
date = [self selectedDate];
|
||||
hmString = [NSString stringWithFormat:@"%.2d%.2d",
|
||||
[date hourOfDay], [date minuteOfHour]];
|
||||
(int)[date hourOfDay], (int)[date minuteOfHour]];
|
||||
qp = [[self queryParameters] mutableCopy];
|
||||
[self setSelectedDateQueryParameter:date inDictionary:qp];
|
||||
[qp setObject: hmString forKey:@"hm"];
|
||||
|
||||
@@ -72,18 +72,14 @@
|
||||
rc = [NSMutableDictionary dictionary];
|
||||
request = [context request];
|
||||
folder = [self clientObject];
|
||||
data = [request formValueForKey: @"calendarFile"];
|
||||
if ([data respondsToSelector: @selector(isEqualToString:)])
|
||||
fileContent = (NSString *) data;
|
||||
else
|
||||
{
|
||||
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
if (fileContent == nil)
|
||||
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
||||
encoding: NSISOLatin1StringEncoding];
|
||||
[fileContent autorelease];
|
||||
}
|
||||
data = [[[[[request httpRequest] body] parts] lastObject] body];
|
||||
|
||||
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
if (fileContent == nil)
|
||||
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
||||
encoding: NSISOLatin1StringEncoding];
|
||||
[fileContent autorelease];
|
||||
|
||||
if (fileContent && [fileContent length]
|
||||
&& [fileContent hasPrefix: @"BEGIN:"])
|
||||
|
||||
@@ -328,16 +328,24 @@ static NSArray *tasksFields = nil;
|
||||
iCalPersonPartStat stat;
|
||||
NSUInteger count, max;
|
||||
|
||||
if ([[theRecord objectForKey: @"c_partmails"] length] > 0 &&
|
||||
[[theRecord objectForKey: @"c_partstates"] length] > 0)
|
||||
states = nil;
|
||||
|
||||
if ([[theRecord objectForKey: @"c_partmails"] length] > 0)
|
||||
{
|
||||
mails = [[theRecord objectForKey: @"c_partmails"] componentsSeparatedByString: @"\n"];
|
||||
states = [[theRecord objectForKey: @"c_partstates"] componentsSeparatedByString: @"\n"];
|
||||
|
||||
// We add some robustness here, in case the quick table had c_partmails defined but
|
||||
// no corresponding c_partstates entries. This can happen if folks toy around the database
|
||||
// or if Funambol was used in the past, with a broken connector.
|
||||
if ([[theRecord objectForKey: @"c_partstates"] length] > 0)
|
||||
states = [[theRecord objectForKey: @"c_partstates"] componentsSeparatedByString: @"\n"];
|
||||
|
||||
max = [mails count];
|
||||
statesDescription = [NSMutableArray arrayWithCapacity: max];
|
||||
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
stat = [[states objectAtIndex: count] intValue];
|
||||
stat = (states ? [[states objectAtIndex: count] intValue] : 0);
|
||||
[statesDescription addObject: [[iCalPerson descriptionForParticipationStatus: stat] lowercaseString]];
|
||||
}
|
||||
|
||||
@@ -356,10 +364,10 @@ static NSArray *tasksFields = nil;
|
||||
NSMutableDictionary *newInfo;
|
||||
NSMutableArray *infos, *quickInfos, *allInfos, *quickInfosName;
|
||||
NSNull *marker;
|
||||
NSString *owner, *role, *calendarName, *iCalString, *recurrenceTime;
|
||||
NSString *owner, *role, *calendarName, *iCalString, *recurrenceTime, *categories;
|
||||
NSRange match;
|
||||
iCalCalendar *calendar;
|
||||
iCalObject *master;
|
||||
iCalEntityObject *master;
|
||||
SOGoAppointmentFolder *currentFolder;
|
||||
SOGoAppointmentFolders *clientObject;
|
||||
SOGoUser *ownerUser;
|
||||
@@ -392,7 +400,7 @@ static NSArray *tasksFields = nil;
|
||||
else if ([criteria isEqualToString:@"entireContent"])
|
||||
{
|
||||
// First search : Through the quick table inside the location, category and title columns
|
||||
quickInfos = [currentFolder fetchCoreInfosFrom: startDate
|
||||
quickInfos = (NSMutableArray *)[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
title: value
|
||||
component: component
|
||||
@@ -408,14 +416,14 @@ static NSArray *tasksFields = nil;
|
||||
}
|
||||
|
||||
// Second research : Every objects except for those already in the quickInfos array
|
||||
allInfos = [currentFolder fetchCoreInfosFrom: startDate
|
||||
allInfos = (NSMutableArray *)[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
title: nil
|
||||
component: component];
|
||||
if (quickInfosFlag == YES)
|
||||
{
|
||||
for (i = ([allInfos count] - 1); i >= 0 ; i--) {
|
||||
if([quickInfosName containsObject:[[allInfos objectAtIndex:i] objectForKey:@"c_name"]])
|
||||
if ([quickInfosName containsObject:[[allInfos objectAtIndex:i] objectForKey:@"c_name"]])
|
||||
[allInfos removeObjectAtIndex:i];
|
||||
}
|
||||
}
|
||||
@@ -425,7 +433,7 @@ static NSArray *tasksFields = nil;
|
||||
{
|
||||
iCalString = [[allInfos objectAtIndex:i] objectForKey:@"c_content"];
|
||||
calendar = [iCalCalendar parseSingleFromSource: iCalString];
|
||||
master = [calendar firstChildWithTag:component];
|
||||
master = (iCalEntityObject *)[calendar firstChildWithTag:component];
|
||||
if (master) {
|
||||
if ([[master comment] length] > 0)
|
||||
{
|
||||
@@ -463,10 +471,10 @@ static NSArray *tasksFields = nil;
|
||||
role = [currentFolder roleForComponentsWithAccessClass: [[newInfo objectForKey: @"c_classification"] intValue]
|
||||
forUser : userLogin];
|
||||
|
||||
if ([role isEqualToString: @"ComponentViewer"])
|
||||
[newInfo setObject: [NSNumber numberWithInt: 1] forKey: @"viewable"];
|
||||
else
|
||||
if ([role isEqualToString: @"ComponentDAndTViewer"])
|
||||
[newInfo setObject: [NSNumber numberWithInt: 0] forKey: @"viewable"];
|
||||
else
|
||||
[newInfo setObject: [NSNumber numberWithInt: 1] forKey: @"viewable"];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,6 +522,11 @@ static NSArray *tasksFields = nil;
|
||||
[newInfo setObject: calendarName
|
||||
forKey: @"calendarName"];
|
||||
|
||||
// Split comma-delimited categories
|
||||
categories = [newInfo objectForKey: @"c_category"];
|
||||
if ([categories length])
|
||||
[newInfo setObject: [categories componentsSeparatedByString: @","] forKey: @"c_category"];
|
||||
|
||||
// Fix empty title
|
||||
if (![[newInfo objectForKey: @"c_title"] length])
|
||||
[self _fixComponentTitle: newInfo withType: component];
|
||||
@@ -892,10 +905,10 @@ static inline iCalPersonPartStat _userStateInEvent (NSArray *event)
|
||||
states = [event objectAtIndex: eventPartStatesIndex];
|
||||
count = 0;
|
||||
max = [participants count];
|
||||
user = [SOGoUser userWithLogin: [event objectAtIndex: eventOwnerIndex]
|
||||
roles: nil];
|
||||
while (state == iCalPersonPartStatOther && count < max)
|
||||
{
|
||||
user = [SOGoUser userWithLogin: [event objectAtIndex: eventOwnerIndex]
|
||||
roles: nil];
|
||||
if ([user hasEmail: [participants objectAtIndex: count]])
|
||||
state = [[states objectAtIndex: count] intValue];
|
||||
else
|
||||
@@ -933,7 +946,7 @@ static inline iCalPersonPartStat _userStateInEvent (NSArray *event)
|
||||
eventStart = eventEnd;
|
||||
eventEnd = swap;
|
||||
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
|
||||
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
|
||||
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
|
||||
}
|
||||
|
||||
startSecs = (unsigned int) [startDate timeIntervalSince1970];
|
||||
@@ -986,21 +999,21 @@ static inline iCalPersonPartStat _userStateInEvent (NSArray *event)
|
||||
currentDay = [blocks objectAtIndex: offset];
|
||||
}
|
||||
|
||||
computedEventEnd = eventEnd;
|
||||
computedEventEnd = eventEnd;
|
||||
|
||||
// We add 5 mins to the end date of an event if the end date
|
||||
// is equal or smaller than the event's start date.
|
||||
if (eventEnd <= currentStart)
|
||||
// We add 5 mins to the end date of an event if the end date
|
||||
// is equal or smaller than the event's start date.
|
||||
if (eventEnd <= currentStart)
|
||||
computedEventEnd = currentStart + (5*60);
|
||||
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
end: computedEventEnd
|
||||
number: number
|
||||
onDay: currentDayStart
|
||||
recurrenceTime: recurrenceTime
|
||||
userState: userState];
|
||||
[currentDay addObject: eventBlock];
|
||||
}
|
||||
[currentDay addObject: eventBlock];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1217,7 +1230,7 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSMutableArray *selectedCalendars;
|
||||
NSArray *folders;
|
||||
NSString *fUID;
|
||||
NSString *fUID, *fName;
|
||||
NSNumber *isActive;
|
||||
unsigned int count, foldersCount;
|
||||
|
||||
@@ -1231,7 +1244,11 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
isActive = [NSNumber numberWithBool: [folder isActive]];
|
||||
if ([isActive intValue] != 0) {
|
||||
fUID = [folder nameInContainer];
|
||||
[selectedCalendars addObject: fUID];
|
||||
fName = [folder displayName];
|
||||
[selectedCalendars addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
fUID, @"id",
|
||||
fName, @"name",
|
||||
nil]];
|
||||
}
|
||||
}
|
||||
return selectedCalendars;
|
||||
@@ -1289,9 +1306,10 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
{
|
||||
int count, max;
|
||||
NSArray *events, *event, *calendars;
|
||||
NSDictionary *eventsBlocks;
|
||||
NSMutableArray *allDayBlocks, *blocks, *currentDay, *eventsByCalendars, *eventsForCalendar;
|
||||
NSDictionary *eventsBlocks, *calendar;
|
||||
NSMutableArray *allDayBlocks, *blocks, *currentDay, *eventsForCalendar, *eventsByCalendars;
|
||||
NSNumber *eventNbr;
|
||||
NSString *calendarName, *calendarId;
|
||||
BOOL isAllDay;
|
||||
int i, j;
|
||||
|
||||
@@ -1301,20 +1319,25 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
|
||||
if ([currentView isEqualToString: @"multicolumndayview"])
|
||||
{
|
||||
calendars = [self _selectedCalendars];
|
||||
calendars = (NSMutableArray *)[self _selectedCalendars];
|
||||
eventsByCalendars = [NSMutableArray arrayWithCapacity:[calendars count]];
|
||||
for (i = 0; i < [calendars count]; i++) // For each calendar
|
||||
{
|
||||
calendar = [calendars objectAtIndex:i];
|
||||
calendarName = [calendar objectForKey: @"name"];
|
||||
calendarId = [calendar objectForKey: @"id"];
|
||||
eventsForCalendar = [NSMutableArray array];
|
||||
[self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks];
|
||||
for (j = 0; j < [events count]; j++) {
|
||||
if ([[[events objectAtIndex:j] objectAtIndex:eventFolderIndex] isEqualToString:[calendars objectAtIndex:i]]) {
|
||||
if ([[[events objectAtIndex:j] objectAtIndex:eventFolderIndex] isEqualToString: calendarId]) {
|
||||
// Event is in current calendar
|
||||
[eventsForCalendar addObject: [events objectAtIndex:j]];
|
||||
}
|
||||
}
|
||||
eventsBlocks = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
eventsFields, @"eventsFields",
|
||||
calendarId , @"id",
|
||||
calendarName, @"calendarName",
|
||||
eventsFields, @"eventsFields",
|
||||
eventsForCalendar, @"events",
|
||||
allDayBlocks, @"allDayBlocks",
|
||||
blocks, @"blocks", nil];
|
||||
@@ -1336,8 +1359,7 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
[currentDay sortUsingSelector: @selector (compareEventByStart:)];
|
||||
[self _addBlocksWidth: currentDay];
|
||||
}
|
||||
|
||||
[eventsByCalendars insertObject:eventsBlocks atIndex:i];
|
||||
[eventsByCalendars addObject: eventsBlocks];
|
||||
}
|
||||
return [self _responseWithData: eventsByCalendars];
|
||||
}
|
||||
@@ -1373,7 +1395,7 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
[currentDay sortUsingSelector: @selector (compareEventByStart:)];
|
||||
[self _addBlocksWidth: currentDay];
|
||||
}
|
||||
return [self _responseWithData: eventsBlocks];
|
||||
return [self _responseWithData: [NSArray arrayWithObject: eventsBlocks]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@
|
||||
|
||||
@implementation UIxCalMainView
|
||||
|
||||
- (NSString *) modulePath
|
||||
{
|
||||
return @"Calendar";
|
||||
}
|
||||
|
||||
- (void) checkDefaultModulePreference
|
||||
{
|
||||
SOGoUserDefaults *ud;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* UIxCalMonthView.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2009 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
|
||||
@@ -69,7 +67,6 @@
|
||||
|
||||
- (void) setCurrentTableDay: (NSCalendarDate *) newCurrentTableDay;
|
||||
- (NSCalendarDate *) currentTableDay;
|
||||
- (NSString *) labelForCurrentDayCell;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* UIxCalMonthView.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006, 2007 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
|
||||
@@ -235,27 +233,6 @@
|
||||
return currentWeek;
|
||||
}
|
||||
|
||||
- (NSString *) labelForCurrentDayCell
|
||||
{
|
||||
NSCalendarDate *lastDayOfMonth;
|
||||
NSString *label, *monthOfYear;
|
||||
int dayOfMonth;
|
||||
|
||||
dayOfMonth = [currentTableDay dayOfMonth];
|
||||
lastDayOfMonth = [currentTableDay lastDayOfMonth];
|
||||
if (dayOfMonth == 1
|
||||
|| [currentTableDay isDateOnSameDay: lastDayOfMonth])
|
||||
{
|
||||
monthOfYear
|
||||
= [monthNames objectAtIndex: [currentTableDay monthOfYear]];
|
||||
label = [NSString stringWithFormat: @"%d %@", dayOfMonth, monthOfYear];
|
||||
}
|
||||
else
|
||||
label = [NSString stringWithFormat: @"%d", dayOfMonth];
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
- (NSString *) headerDayCellClasses
|
||||
{
|
||||
unsigned int dayOfWeek;
|
||||
@@ -265,24 +242,19 @@
|
||||
return [NSString stringWithFormat: @"headerDay day%d", dayOfWeek];
|
||||
}
|
||||
|
||||
- (NSString *) dayHeaderNumber
|
||||
- (NSString *) dayHeaderMonth
|
||||
{
|
||||
NSString *nameOfMonth, *dayHeaderNumber;
|
||||
NSString *nameOfMonth = nil;
|
||||
unsigned int dayOfMonth;
|
||||
|
||||
dayOfMonth = [currentTableDay dayOfMonth];
|
||||
if (dayOfMonth == 1
|
||||
|| [currentTableDay isDateOnSameDay: [currentTableDay lastDayOfMonth]])
|
||||
{
|
||||
nameOfMonth
|
||||
= [self localizedNameForMonthOfYear: [currentTableDay monthOfYear]];
|
||||
dayHeaderNumber = [NSString stringWithFormat: @"%d %@", dayOfMonth,
|
||||
nameOfMonth];
|
||||
nameOfMonth = [self localizedNameForMonthOfYear: [currentTableDay monthOfYear]];
|
||||
}
|
||||
else
|
||||
dayHeaderNumber = [NSString stringWithFormat: @"%d", dayOfMonth];
|
||||
|
||||
return dayHeaderNumber;
|
||||
return nameOfMonth;
|
||||
}
|
||||
|
||||
- (NSString *) dayCellClasses
|
||||
@@ -299,7 +271,7 @@
|
||||
|
||||
[classes appendFormat: @"day weekOf%d week%dof%d day%d",
|
||||
numberOfWeeks,
|
||||
[weeksToDisplay indexOfObject: currentWeek],
|
||||
(int)[weeksToDisplay indexOfObject: currentWeek],
|
||||
numberOfWeeks, dayOfWeek];
|
||||
if (realDayOfWeek == 0 || realDayOfWeek == 6)
|
||||
[classes appendString: @" weekEndDay"];
|
||||
|
||||
@@ -49,6 +49,7 @@ static NSArray *layoutItems = nil;
|
||||
- (void) dealloc
|
||||
{
|
||||
[item release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setItem: (NSString *) newItem
|
||||
@@ -68,7 +69,7 @@ static NSArray *layoutItems = nil;
|
||||
|
||||
- (NSString *) itemPrintLayoutText
|
||||
{
|
||||
return [self labelForKey: [NSString stringWithFormat: item]];
|
||||
return [self labelForKey: [NSString stringWithFormat: @"%@", item]];
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
* @apiParam {Number} includeInFreeBusy 1 if calendar must be include in freebusy
|
||||
* @apiParam {Number} showCalendarAlarms 1 if alarms must be enabled
|
||||
* @apiParam {Number} showCalendarTasks 1 if tasks must be enabled
|
||||
* @apiParam {Number} synchronize 1 if we enable EAS synchronization for this calendar
|
||||
* @apiParam {Number} reloadOnLogin 1 if calendar is a Web calendar that must be reload when user logins
|
||||
* @apiParam {Object} [notifications] Notification (if active user is the calendar's owner)
|
||||
* @apiParam {Number} notifications.notifyOnPersonalModifications 1 if a mail is sent for each modification made by the owner
|
||||
@@ -108,6 +109,10 @@
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[calendar setShowCalendarTasks: [o boolValue]];
|
||||
|
||||
o = [params objectForKey: @"synchronize"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[calendar setSynchronize: [o boolValue]];
|
||||
|
||||
values = [params objectForKey: @"notifications"];
|
||||
if ([values isKindOfClass: [NSDictionary class]])
|
||||
{
|
||||
|
||||
@@ -99,7 +99,7 @@ _intValueFromHex (NSString *hexString)
|
||||
NSNumber *isActive, *fActiveTasks;
|
||||
SOGoAppointmentFolders *co;
|
||||
SOGoAppointmentFolder *folder;
|
||||
BOOL reloadOnLogin;
|
||||
BOOL reloadOnLogin, synchronize;
|
||||
|
||||
if (!calendars)
|
||||
{
|
||||
@@ -133,6 +133,16 @@ _intValueFromHex (NSString *hexString)
|
||||
[calendar setObject: [NSNumber numberWithBool: [folder showCalendarAlarms]] forKey: @"showCalendarAlarms"];
|
||||
[calendar setObject: [NSNumber numberWithBool: [folder showCalendarTasks]] forKey: @"showCalendarTasks"];
|
||||
|
||||
if ([folder isKindOfClass: [SOGoWebAppointmentFolder class]])
|
||||
synchronize = NO;
|
||||
else
|
||||
synchronize = [folder synchronize];
|
||||
|
||||
if ([[folder nameInContainer] isEqualToString: @"personal"])
|
||||
synchronize = YES;
|
||||
|
||||
[calendar setObject: [NSNumber numberWithBool: synchronize] forKey: @"synchronize"];
|
||||
|
||||
if ([folder isWebCalendar])
|
||||
{
|
||||
urls = [NSMutableDictionary dictionaryWithObject: [folder folderPropertyValueInCategory: @"WebCalendars"]
|
||||
|
||||
@@ -896,7 +896,7 @@ static NSArray *reminderValues = nil;
|
||||
content = [NSMutableString string];
|
||||
response = [context response];
|
||||
|
||||
[content appendFormat: [[self clientObject] contentAsString]];
|
||||
[content appendFormat: @"%@", [[self clientObject] contentAsString]];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
[response appendContentString: content];
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
[shortWeekDaysList retain];
|
||||
}
|
||||
|
||||
id = [NSString stringWithFormat: @"weekDay%i", [shortWeekDaysList indexOfObject: item]];
|
||||
id = [NSString stringWithFormat: @"weekDay%i", (int)[shortWeekDaysList indexOfObject: item]];
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,10 @@
|
||||
actionClass = "UIxCalFolderActions";
|
||||
actionName = "import";
|
||||
};
|
||||
UIxCalUserRightsEditor = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxCalUserRightsEditor";
|
||||
};
|
||||
userRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxCalUserRightsEditor";
|
||||
|
||||
@@ -1,40 +1,133 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE var:component>
|
||||
<var:component xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:toolbar="UIxAdministration.toolbar"
|
||||
const:jsFiles="dtree.js">
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:jsFiles="Common.js, Administration.js,
|
||||
Administration.services.js, Preferences.services.js,
|
||||
Contacts.services.js, Scheduler.services.js">
|
||||
|
||||
<div id="helpDialog" style="display: none" class="dialog left">
|
||||
<div>
|
||||
<h3><!-- module title --></h3>
|
||||
<div><!-- module description --></div>
|
||||
<a href="#" class="button" id="helpDialogClose"><span><var:string label:value="Close"/></span></a>
|
||||
<main class="view layout-fill" ui-view="administration" layout="row" ng-controller="navController">
|
||||
<!-- administration -->
|
||||
</main>
|
||||
|
||||
<script type="text/ng-template" id="administration.html">
|
||||
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="$mdMedia('gt-md')" layout="column">
|
||||
<var:component className="UIxSidenavToolbarTemplate" />
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex md-hue-2">
|
||||
<md-list>
|
||||
<md-list-item ng-click="app.go('rights')"
|
||||
ui-sref="administration.rights"
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>security</md-icon>
|
||||
<p class="sg-item-name"><var:string label:value="Rights"/></p>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</md-content>
|
||||
</md-sidenav>
|
||||
|
||||
<section layout="column" class="sg-app-content layout-fill" ui-view="module"><!-- admin module --></section>
|
||||
|
||||
</script>
|
||||
|
||||
<!--
|
||||
RIGHTS ADMINISTRATION PANEL
|
||||
-->
|
||||
<script type="text/ng-template" id="rights.html">
|
||||
<!-- TOP RIGHT TOOLBAR -->
|
||||
<md-toolbar layout="row" layout-align="space-between center" class="toolbar-main">
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
</md-toolbar>
|
||||
|
||||
<div layout="row" class="md-flex">
|
||||
|
||||
<div class="view-list" layout="column">
|
||||
<md-toolbar>
|
||||
<!-- search toolbar -->
|
||||
<div class="md-toolbar-tools sg-toolbar-secondary"
|
||||
sg-search="app.filter(searchText)">
|
||||
<md-icon>search</md-icon>
|
||||
<md-input-container md-no-float="md-no-float">
|
||||
<input name="folderSearch" type="search" ng-minlength="3"
|
||||
label:placeholder="Search Users"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content id="usersList" layout="column" class="md-flex">
|
||||
<md-subheader ng-show="app.service.$query">
|
||||
<span ng-switch="app.users.length">
|
||||
<span ng-switch-when="0"><var:string label:value="No matching user"/></span>
|
||||
<span ng-switch-default="true">{{app.users.length}} <var:string label:value="users found"/></span>
|
||||
</span>
|
||||
</md-subheader>
|
||||
<md-subheader ng-hide="app.service.$query">
|
||||
<var:string label:value="Start a search to edit the rights"/>
|
||||
</md-subheader>
|
||||
<md-list class="sg-section-list">
|
||||
<div ng-repeat="user in app.users">
|
||||
<md-list-item ng-class="{ 'sg-collapsed': user.uid != app.selectedUser.uid,
|
||||
'sg-expanded': user.uid == app.selectedUser.uid }"
|
||||
ng-click="app.selectUser($index)">
|
||||
<sg-avatar-image class="md-avatar"
|
||||
ng-if="::user.isGroup === 0"
|
||||
sg-email="::user.c_email"
|
||||
size="40">
|
||||
<!-- contact avatar -->
|
||||
</sg-avatar-image>
|
||||
<div class="sg-list-avatar"
|
||||
ng-show="::user.isGroup">
|
||||
<!-- list avatar -->
|
||||
</div>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead">
|
||||
<div>{{::user.cn}}</div>
|
||||
</div>
|
||||
<div class="sg-md-body">
|
||||
<div>{{::user.c_email}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<md-button class="md-icon-button"><md-icon ng-class="{'md-rotate-180': user.uid == app.selectedUser.uid}">expand_more</md-icon></md-button>
|
||||
</md-list-item>
|
||||
<div ng-show="user == app.selectedUser">
|
||||
<!-- folders list -->
|
||||
<md-list-item ng-show="user.$$folders.length == 0">
|
||||
<md-icon>warning</md-icon>
|
||||
<var:string label:value="No resource"/>
|
||||
</md-list-item>
|
||||
<md-list-item class="sg-folder" ng-repeat="folder in user.$$folders">
|
||||
<md-button class=""
|
||||
aria-label="{{::folder.displayName}}" title="{{::folder.displayName}}"
|
||||
ng-click="app.selectFolder(folder)">
|
||||
<md-icon ng-class="{ 'icon-contacts': folder.type == 'Contact',
|
||||
'icon-event': folder.type == 'Appointment' }"><!--icon--></md-icon>
|
||||
{{::folder.displayName}}
|
||||
</md-button>
|
||||
</md-list-item>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</div>
|
||||
</div>
|
||||
</md-list>
|
||||
</md-content>
|
||||
</div>
|
||||
|
||||
<div id="detailView" class="view-detail" layout="column" layout-align="start center"
|
||||
ng-class="{ 'sg-close': !app.selectedUser.selectedFolder }"
|
||||
ui-view="acl">
|
||||
<md-toolbar class="md-whiteframe-z1 hide-sm"><!-- empty toolbar --></md-toolbar>
|
||||
<md-content class="hide-sm md-flex layout-fill md-hue-1"
|
||||
layout="column" layout-align="center center">
|
||||
<div class="md-default-theme md-background md-fg md-hue-3 sg-md-title">
|
||||
<var:string label:value="No resource selected"/>
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<div id="leftPanel">
|
||||
<div class="titlediv"><var:string label:value="Modules" /></div>
|
||||
<div id="administrationModules">
|
||||
<ul>
|
||||
<li id="ACLs" class="_selected"><var:string label:value="ACLs"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dragHandle" id="verticalDragHandle"><!-- space --></div>
|
||||
|
||||
<div id="rightPanel">
|
||||
<span><h1 id="moduleTitle"><var:string label:value="ACLs_title"/></h1>
|
||||
<div id="moduleDescription" style="display: none"><var:string label:value="ACLs_description" const:escapeHTML="NO"/></div></span>
|
||||
<var:component className="UIxAdministrationFilterPanel" qualifier="qualifier" />
|
||||
<div id="administrationContent"><!-- space --></div>
|
||||
</div>
|
||||
|
||||
<var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
|
||||
</var:component>
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
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"
|
||||
>
|
||||
<div layout="column" class="layout-fill">
|
||||
<md-toolbar class="hide show-sm">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Close"
|
||||
ng-click="acl.close()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="md-icon-button"
|
||||
ng-click="acl.save()">
|
||||
<md-icon>save</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-toolbar class="md-tall">
|
||||
<div layout="row">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
ng-show="acl.user.isGroup === 0"
|
||||
sg-email="::acl.user.c_email"
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
<div class="sg-list-avatar" ng-show="acl.user.isGroup"><!--list avatar--></div>
|
||||
<div class="msg-header-content">
|
||||
<h1 class="sg-md-display-2--thin">{{::acl.user.cn}}</h1>
|
||||
<h6 class="sg-md-display-2-subheader"><md-icon ng-class="{ 'icon-contacts': acl.folderType == 'AddressBook',
|
||||
'icon-event': acl.folderType == 'Calendar' }"><!--icon--></md-icon>
|
||||
{{::acl.folder.name}}
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
<!-- only show the fab button on large screens -->
|
||||
<md-button type="button" class="hide-sm md-fab md-fab-bottom-right md-fab-overlap-bottom"
|
||||
ng-click="acl.save()">
|
||||
<md-icon>save</md-icon>
|
||||
</md-button>
|
||||
</md-toolbar>
|
||||
<md-content class="md-flex md-static">
|
||||
<div class="viewer">
|
||||
<div layout="row">
|
||||
<md-icon>search</md-icon>
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-input-name="addUser"
|
||||
md-search-text="acl.searchText"
|
||||
md-selected-item="acl.userToAdd"
|
||||
md-selected-item-change="acl.addUser(user)"
|
||||
md-items="user in acl.userFilter(acl.searchText)"
|
||||
md-item-text="user.empty"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
label:md-floating-label="Add User">
|
||||
<md-item-template>
|
||||
<span class="md-contact-suggestion">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span>
|
||||
<span class="md-contact-email"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
</div>
|
||||
<md-card ng-repeat="user in acl.users | orderBy:['userClass', 'displayName']"
|
||||
class="sg-collapsed"
|
||||
ng-class="{ 'sg-expanded': user.uid == acl.selectedUid }">
|
||||
<md-button ng-click="acl.selectUser(user)">
|
||||
<div layout="row" layout-align="start center" class="md-flex">
|
||||
<span class="card-picture" ng-switch="user.userClass">
|
||||
<div ng-switch-when="normal-user">
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="user.c_email"
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div ng-switch-when="normal-group" class="md-avatar sg-avatar-list"><!-- normal-group --></div>
|
||||
<div ng-switch-when="public-user" class="md-avatar sg-avatar-list"><!-- public-user --></div>
|
||||
</span>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead"><div>{{user.cn}}</div></div>
|
||||
<div class="sg-md-body"><div>{{user.c_email}}</div></div>
|
||||
</div>
|
||||
<md-button class="md-icon-button md-secondary" type="button"
|
||||
ng-click="acl.removeUser(user)"
|
||||
ng-hide="user.uid != acl.selectedUid || user.$isSpecial()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-button>
|
||||
<md-card-content id="AccessRightList" ng-show="user.uid == acl.selectedUid">
|
||||
<var:if condition="canSubscribeUsers">
|
||||
<md-checkbox ng-model="user.isSubscribed"
|
||||
label:arial-label="Subscribe User"
|
||||
ng-disabled="user.wasSubscribed"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
ng-hide="user.$isSpecial()">
|
||||
<var:string label:value="Subscribe User"/>
|
||||
</md-checkbox>
|
||||
</var:if>
|
||||
<div ng-include="acl.getTemplate()"></div>
|
||||
|
||||
<!-- <script type="text/ng-template" id="UIxContactsUserRightsEditor">
|
||||
<var:component className="UIxContactsUserRightsEditor" />
|
||||
</script>
|
||||
|
||||
<script type="text/ng-template" id="UIxCalUserRightsEditor">
|
||||
<var:component className="UIxCalUserRightsEditor" />
|
||||
</script> -->
|
||||
|
||||
</md-card-content>
|
||||
</md-card>
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
||||
</container>
|
||||
@@ -5,11 +5,32 @@
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<md-content md-scroll-y="md-scroll-y" class="viewer md-padding md-whiteframe-z1 bg-sogoPaper-50">
|
||||
<!-- <div class="editor md-padding">-->
|
||||
<div layout="column" class="layout-fill">
|
||||
<md-toolbar class="md-whiteframe-z1">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Cancel"
|
||||
ng-click="editor.cancel()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Reset"
|
||||
ng-click="editor.reset()">
|
||||
<md-icon>undo</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Save"
|
||||
ng-click="editor.save(editor.card.$isCard()?cardForm:listForm)">
|
||||
<md-icon>save</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-content class="md-flex md-static">
|
||||
<div layout="column" class="viewer md-padding">
|
||||
<hgroup class="header">
|
||||
<h1 class="sg-md-display-2--light" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
|
||||
<h6 class="sg-md-display-2-subheader">{{editor.card.$description()}}</h6>
|
||||
<h1 class="sg-md-display-2--thin" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
|
||||
<h6 class="sg-md-display-2-subheader--thin">{{editor.card.$description()}}</h6>
|
||||
</hgroup>
|
||||
|
||||
<!-- contact editor -->
|
||||
@@ -21,7 +42,7 @@
|
||||
</label>
|
||||
<input type="text" ng-maxlength="30" ng-model="editor.card.c_cn"/>
|
||||
</md-input-container>
|
||||
<!-- todo: look for better reset/normalization. Semanticaly this should be a fieldset, but content doesn't flex properly du to browser styles-->
|
||||
<!-- todo: look for better reset/normalization. Semanticaly this should be a fieldset, but content doesn't flex properly du to browser styles -->
|
||||
<div id="contact-identification" class="sg-fieldset" layout="row" layout-sm="column">
|
||||
<md-input-container flex="40">
|
||||
<label>
|
||||
@@ -43,19 +64,25 @@
|
||||
</md-input-container>
|
||||
</div>
|
||||
|
||||
<div class="sg-fieldset" layout="row" layout-sm="column">
|
||||
<md-input-container>
|
||||
<div id="contact-identification" class="sg-fieldset" layout="row" layout-sm="column">
|
||||
<md-input-container flex="40">
|
||||
<label>
|
||||
<var:string label:value="Organization"/>
|
||||
</label>
|
||||
<input type="text" ng-model="editor.card.c_org"/>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<md-input-container flex="40">
|
||||
<label>
|
||||
<var:string label:value="Title"/>
|
||||
</label>
|
||||
<input type="text" ng-model="editor.card.title"/>
|
||||
</md-input-container>
|
||||
<md-input-container flex="20">
|
||||
<label>
|
||||
<var:string label:value="Role"/>
|
||||
</label>
|
||||
<input type="text" ng-model="editor.card.role"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
|
||||
<!-- org units -->
|
||||
@@ -101,9 +128,11 @@
|
||||
<div class="section">
|
||||
<div class="attr" ng-repeat="email in editor.card.emails">
|
||||
<div class="md-layout-margin" layout="row" layout-align="space-between end">
|
||||
<md-select ng-model="email.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allEmailTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
<md-input-container flex="20">
|
||||
<md-select ng-model="email.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allEmailTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="Email Address"/>
|
||||
@@ -126,13 +155,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div layout="row" layout-align="space-between end" ng-show="editor.card.c_screenname != null">
|
||||
<md-input-container>
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Screen Name"/>
|
||||
</label>
|
||||
<input type="text" ng-model="editor.card.c_screenname"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.card.$delete('c_screenname', -1)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="md-layout-margin" layout="row" layout-align="start center" ng-show="editor.card.c_screenname == null">
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.addScreenName($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label">
|
||||
<var:string label:value="Add Screen Name"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- birthday -->
|
||||
<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>
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Birthday"/>
|
||||
</label>
|
||||
<md-datepicker class="pseudo-input-field"
|
||||
ng-model="editor.card.birthday"><!-- birthday --></md-datepicker>
|
||||
</div>
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.card.$delete('birthday', -1)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
@@ -151,9 +205,11 @@
|
||||
<div class="section">
|
||||
<div class="attr" ng-repeat="phone in editor.card.phones">
|
||||
<div class="md-layout-margin" layout="row" layout-align="space-between end">
|
||||
<md-select ng-model="phone.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allTelTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
<md-input-container flex="20">
|
||||
<md-select ng-model="phone.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allTelTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="Phone Number"/>
|
||||
@@ -181,9 +237,11 @@
|
||||
<div class="section">
|
||||
<div class="attr" ng-repeat="url in editor.card.urls">
|
||||
<div class="md-layout-margin" layout="row" layout-align="space-between end">
|
||||
<md-select ng-model="url.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allUrlTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
<md-input-container flex="20">
|
||||
<md-select ng-model="url.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allUrlTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="URL"/>
|
||||
@@ -209,9 +267,11 @@
|
||||
<div class="section">
|
||||
<div class="attr" ng-repeat="address in editor.card.addresses">
|
||||
<div layout="row" layout-align="center end">
|
||||
<md-select ng-model="address.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allAddressTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
<md-input-container flex="20">
|
||||
<md-select ng-model="address.type" label:placeholder="Type">
|
||||
<md-option ng-repeat="type in ::editor.allAddressTypes" ng-value="type">{{ type }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="street"/>
|
||||
@@ -287,22 +347,10 @@
|
||||
</label>
|
||||
<textarea ng-model="editor.card.note"><!-- note --></textarea>
|
||||
</md-input-container>
|
||||
|
||||
<div class="fieldset md-layout-margin" layout="row" layout-align="end center">
|
||||
<md-button type="button" ng-click="editor.cancel()">
|
||||
<var:string label:value="Cancel"/>
|
||||
</md-button>
|
||||
<md-button type="button" ng-click="editor.reset()">
|
||||
<var:string label:value="Reset"/>
|
||||
</md-button>
|
||||
<md-button class="md-primary md-hue-3" type="submit">
|
||||
<var:string label:value="Save"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- list editor -->
|
||||
<form name="listForm" ng-if="editor.card.$isList()" ng-submit="editor.save(listForm)">
|
||||
<form name="listForm" ng-show="editor.card.$isList()" ng-submit="editor.save(listForm)">
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="Display"/>
|
||||
@@ -339,22 +387,8 @@
|
||||
filter-selected="false"
|
||||
label:placeholder="Add Member"><!-- members --></md-contact-chips>
|
||||
</div>
|
||||
|
||||
<div class="fieldset md-layout-margin" layout="row" layout-align="end center">
|
||||
<md-button type="button" ng-click="editor.cancel()">
|
||||
<var:string label:value="Cancel"/>
|
||||
</md-button>
|
||||
<md-button type="button" ng-click="editor.reset()">
|
||||
<var:string label:value="Reset"/>
|
||||
</md-button>
|
||||
<var:if condition="canCreateOrModify">
|
||||
<md-button class="md-primary md-hue-3" type="submit">
|
||||
<var:string label:value="Save"/>
|
||||
</md-button>
|
||||
</var:if>
|
||||
</div>
|
||||
</form>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</md-content>
|
||||
|
||||
</div>
|
||||
</container>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
>
|
||||
<md-dialog flex="60" flex-sm="100">
|
||||
<md-toolbar class="sg-padded">
|
||||
<md-toolbar>
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">link</md-icon>
|
||||
<div class="md-toolbar-tools">
|
||||
<div class="pseudo-input-container md-flex">
|
||||
@@ -20,8 +20,8 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-dialog-content>
|
||||
<div layout="column" layout-padding="layout-padding">
|
||||
<md-dialog-content class="md-padding">
|
||||
<div layout="column">
|
||||
<div class="sg-md-title"><var:string label:value="Authenticated User Access"/></div>
|
||||
<md-input-container>
|
||||
<label><var:string label:value="CardDAV URL"/></label>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
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-dialog flex="40" flex-md="60" flex-sm="90">
|
||||
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<!-- name -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Name"/></label>
|
||||
<input type="text"
|
||||
class="md-title"
|
||||
ng-model="properties.addressbook.name"/>
|
||||
</md-input-container>
|
||||
<md-button class="md-icon-button" ng-click="properties.close()">
|
||||
<md-icon aria-label="Close dialog">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-dialog-content class="md-dialog-content" layout="column">
|
||||
<md-checkbox
|
||||
ng-model="properties.addressbook.synchronize"
|
||||
ng-disabled="properties.addressbook.id == 'personal'"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0">
|
||||
<var:string label:value="Synchronize"/>
|
||||
</md-checkbox>
|
||||
</md-dialog-content>
|
||||
|
||||
<md-dialog-actions>
|
||||
<md-button type="button" ng-click="properties.close()"><var:string label:value="Cancel"/></md-button>
|
||||
<md-button ng-click="properties.saveProperties()"><var:string label:value="Save"/></md-button>
|
||||
</md-dialog-actions>
|
||||
|
||||
</md-dialog>
|
||||
</container>
|
||||
@@ -9,7 +9,7 @@
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:userDefaultsKeys="SOGoContactsCategories"
|
||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.js, Contacts.services.js, vendor/angular-file-upload.min.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>
|
||||
@@ -20,13 +20,15 @@
|
||||
<script type="text/ng-template" id="UIxContactFoldersView">
|
||||
|
||||
<!-- Sidenav -->
|
||||
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
|
||||
<md-sidenav class="md-sidenav-left md-whiteframe-z1" layout="column"
|
||||
md-component-id="left" md-is-locked-open="isGtMedium"
|
||||
ng-class="{ 'sg-closed': leftIsClose }">
|
||||
<var:component className="UIxSidenavToolbarTemplate" />
|
||||
<!-- <div style="position: relative; display: flex;"> -->
|
||||
<md-content md-scroll-y="md-scroll-y">
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex md-hue-2">
|
||||
<!-- User's addressbooks -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<md-subheader class="sg-md-subheader md-hue-2">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Address Books"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
@@ -38,16 +40,16 @@
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="folder in app.service.$addressbooks track by folder.id"
|
||||
ng-click="app.select(folder)"
|
||||
ng-click="app.select($event, folder)"
|
||||
ng-dblclick="app.edit(folder)"
|
||||
ui-sref="app.addressbook({addressbookId: folder.id})"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>contacts</md-icon>
|
||||
<p class="sg-item-name"
|
||||
ng-show="app.editMode!=folder.id">{{folder.name}}</p>
|
||||
<md-input-container class="md-flex md-tile-content"
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == folder.id">
|
||||
<input class="folder-name" type="text"
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Address Book"
|
||||
ng-model="folder.name"
|
||||
ng-cloak="ng-cloak"
|
||||
@@ -67,7 +69,7 @@
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-menu-item ng-show="folder.id != 'personal'">
|
||||
<md-button type="button" ng-click="app.confirmDelete()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
@@ -94,6 +96,11 @@
|
||||
<var:string label:value="Sharing..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button" ng-click="app.showProperties(folder)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</md-list-item>
|
||||
@@ -101,7 +108,7 @@
|
||||
</section>
|
||||
<!-- Subscriptions -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<md-subheader class="sg-md-subheader md-hue-2">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Subscriptions"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
@@ -114,16 +121,16 @@
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="folder in app.service.$subscriptions track by folder.id"
|
||||
ng-click="app.select(folder)"
|
||||
ng-click="app.select($event, folder)"
|
||||
ng-dblclick="app.edit(folder)"
|
||||
ui-sref="app.addressbook({addressbookId: folder.id})"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>contacts</md-icon>
|
||||
<p class="sg-item-name"
|
||||
ng-show="editMode!=folder.id">{{folder.name}}</p>
|
||||
<md-input-container class="md-flex md-tile-content"
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode==folder.id">
|
||||
<input class="folder-name" type="text"
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Address Book"
|
||||
ng-model="folder.name"
|
||||
ng-cloak="ng-cloak"
|
||||
@@ -148,6 +155,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.showProperties(folder)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</md-list-item>
|
||||
@@ -155,14 +168,14 @@
|
||||
</section>
|
||||
<!-- Remote/domain addressbooks -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader md-padding">
|
||||
<md-subheader class="sg-md-subheader md-hue-2">
|
||||
<var:string label:value="Global Addressbooks"/>
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="folder in app.service.$remotes track by folder.id"
|
||||
ng-click="app.select(folder)"
|
||||
ng-click="app.select($event, folder)"
|
||||
ui-sref="app.addressbook({addressbookId: folder.id})"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>public</md-icon>
|
||||
<p class="sg-item-name">{{folder.name}}</p>
|
||||
</md-list-item>
|
||||
@@ -176,22 +189,24 @@
|
||||
</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">
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
</div>
|
||||
<div class="md-toolbar-tools" layout="row" layout-align="space-between center"
|
||||
ng-show="addressbook.selectedFolder.$selectedCount() == 0">
|
||||
<md-toolbar layout="row" layout-align="space-between center" class="toolbar-main">
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
</md-toolbar>
|
||||
|
||||
<div class="view-list" layout="row" layout-align="space-between center"
|
||||
ng-hide="addressbook.mode.search">
|
||||
<div class="sg-toolbar-group">
|
||||
<div layout="row" class="md-flex">
|
||||
|
||||
<div class="view-list" layout="column">
|
||||
|
||||
<!-- single-selection toolbar -->
|
||||
<md-toolbar class="md-whiteframe-z1"
|
||||
ng-show="addressbook.selectedFolder.$selectedCount() == 0">
|
||||
<!-- sort mode (default) -->
|
||||
<div class="md-toolbar-tools" ng-hide="addressbook.mode.search">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search"
|
||||
ng-click="addressbook.mode.search = true">
|
||||
<md-icon>search</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="sg-toolbar-group-last">
|
||||
<div class="sg-folder-name">{{addressbook.selectedFolder.name}}</div>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Sort"
|
||||
ng-click="$mdOpenMenu()">
|
||||
@@ -204,6 +219,18 @@
|
||||
<!-- selected --></md-icon> <var:string label:value="Name"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.sort('c_sn')">
|
||||
<md-icon ng-class="{ 'icon-check': addressbook.sortedBy('c_sn') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Lastname"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.sort('c_givenname')">
|
||||
<md-icon ng-class="{ 'icon-check': addressbook.sortedBy('c_givenname') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Firstname"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.sort('c_mail')">
|
||||
<md-icon ng-class="{ 'icon-check': addressbook.sortedBy('c_mail') }">
|
||||
@@ -233,8 +260,9 @@
|
||||
</md-menu-item>
|
||||
<md-menu-divider> <!-- divider --></md-menu-divider>
|
||||
<md-menu-item >
|
||||
<md-button ng-click="addressbook.sort(addressbook.selectedFolder.constructor.$query.sort)">
|
||||
<md-button ng-href="#">
|
||||
<md-checkbox
|
||||
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>
|
||||
@@ -246,122 +274,153 @@
|
||||
<md-icon>refresh</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- search mode -->
|
||||
<div class="view-list sg-padded--right sg-toolbar-search" layout="row" layout-align="space-between center"
|
||||
ng-show="addressbook.mode.search"
|
||||
sg-search="addressbook.selectedFolder.$filter(searchText, { search: searchField })">
|
||||
<md-button class="sg-icon-button"
|
||||
sg-search-cancel="addressbook.cancelSearch()"
|
||||
label:aria-label="Back">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<md-input-container>
|
||||
<input name="folderSearch" type="search" />
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<md-select>
|
||||
<md-option value="name_or_address" selected="selected"><var:string label:value="Name or Email"/></md-option>
|
||||
<md-option value="category"><var:string label:value="Category"/></md-option>
|
||||
<md-option value="organization"><var:string label:value="Organization"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</div>
|
||||
<!-- search mode -->
|
||||
<div class="md-toolbar-tools sg-toolbar-secondary"
|
||||
ng-show="addressbook.mode.search"
|
||||
sg-search="addressbook.selectedFolder.$filter(searchText, { search: searchField })">
|
||||
<md-button class="sg-icon-button"
|
||||
sg-search-cancel="addressbook.cancelSearch()"
|
||||
label:aria-label="Back">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<md-input-container md-no-float="md-no-float">
|
||||
<input name="folderSearch" type="search" label:placeholder="Search"/>
|
||||
</md-input-container>
|
||||
<md-input-container flex="25">
|
||||
<md-select>
|
||||
<md-option value="name_or_address" selected="selected"><var:string label:value="Name or Email"/></md-option>
|
||||
<md-option value="category"><var:string label:value="Category"/></md-option>
|
||||
<md-option value="organization"><var:string label:value="Organization"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<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>
|
||||
<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-show="addressbook.selectedFolder.acls.objectEraser"
|
||||
ng-click="addressbook.confirmDeleteSelectedCards()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Copy contacts" ng-click="$mdOpenMenu()">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Copy To"/></md-tooltip>
|
||||
<md-icon>content_copy</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Address Books"/></md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-repeat="folder in app.service.$addressbooks track by folder.id"
|
||||
ng-hide="addressbook.selectedFolder.id == folder.id">
|
||||
<md-button ng-click="addressbook.copySelectedCards(folder.id)">
|
||||
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
|
||||
<!-- multiple selection mode -->
|
||||
<md-toolbar class="md-whiteframe-z1 md-hue-1 sg-toolbar-secondary"
|
||||
ng-show="addressbook.selectedFolder.$selectedCount() > 0">
|
||||
<div class="md-toolbar-tools">
|
||||
<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 class="md-flex"><!-- spacer --></div>
|
||||
<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-show="addressbook.selectedFolder.acls.objectEraser"
|
||||
ng-click="addressbook.confirmDeleteSelectedCards()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Copy contacts" ng-click="$mdOpenMenu()">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Copy To"/></md-tooltip>
|
||||
<md-icon>content_copy</md-icon>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="More messages options" ng-click="$mdOpenMenu()">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button>
|
||||
<var:string label:value="Write"/>
|
||||
<md-menu-content width="4">
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Copy To"/></md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-repeat="folder in app.service.$addressbooks track by folder.id"
|
||||
ng-hide="addressbook.selectedFolder.id == folder.id">
|
||||
<md-button ng-click="addressbook.copySelectedCards(folder.id)">
|
||||
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="More messages options" ng-click="$mdOpenMenu()">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.saveSelectedCards()">
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<div layout="row" class="md-flex">
|
||||
<div class="view-list" layout="column">
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.newMessageWithSelectedCards($event)">
|
||||
<var:string label:value="Write"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="addressbook.saveSelectedCards()">
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content id="contactsList" layout="column" class="md-flex">
|
||||
<header class="sg-md-subheader sg-md-subheader--fixed">
|
||||
<h2 class="md-default-theme sg-md-subhead-solo fg-sogoBlue-700">
|
||||
<span ng-show="addressbook.selectedFolder.cards.length > 0">{{addressbook.selectedFolder.cards.length}} <var:string label:value="contacts"/></span>
|
||||
<span ng-show="addressbook.selectedFolder.cards.length == 0"><var:string label:value="No contact"/></span>
|
||||
</h2>
|
||||
</header>
|
||||
<md-subheader ng-show="addressbook.service.$query.value">
|
||||
<md-button class="md-icon-button hide show-gt-sm" ng-click="toggleLeft()">
|
||||
<md-icon ng-class="{'md-rotate-180': leftIsClose }">keyboard_arrow_left</md-icon>
|
||||
</md-button>
|
||||
<span ng-switch="addressbook.selectedFolder.cards.length">
|
||||
<span ng-switch-when="0"><var:string label:value="No matching contact"/></span>
|
||||
<span ng-switch-default="true">{{addressbook.selectedFolder.cards.length}} <var:string label:value="matching contacts"/></span>
|
||||
</span>
|
||||
</md-subheader>
|
||||
<md-subheader ng-hide="addressbook.service.$query.value">
|
||||
<md-button class="md-icon-button hide show-gt-sm" ng-click="toggleLeft()">
|
||||
<md-icon ng-class="{'md-rotate-180': leftIsClose }">keyboard_arrow_left</md-icon>
|
||||
</md-button>
|
||||
<span ng-switch="addressbook.selectedFolder.isRemote">
|
||||
<span ng-switch-when="1">
|
||||
<var:string label:value="Start a search to browse this address book"/>
|
||||
</span>
|
||||
<span ng-switch-default="true">
|
||||
<span ng-switch="addressbook.selectedFolder.cards.length">
|
||||
<span ng-switch-when="0"><var:string label:value="No contact"/></span>
|
||||
<span ng-switch-default="true">{{addressbook.selectedFolder.cards.length}} <var:string label:value="contacts"/></span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</md-subheader>
|
||||
<md-virtual-repeat-container class="md-flex">
|
||||
<md-list class="sg-section-list">
|
||||
<div md-virtual-repeat="currentCard in addressbook.selectedFolder.cards" md-item-size="72">
|
||||
<div md-virtual-repeat="currentCard in addressbook.selectedFolder.cards" md-item-size="56">
|
||||
<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})">
|
||||
<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="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>
|
||||
ui-sref="app.addressbook.card.view({addressbookId: addressbook.selectedFolder.id, cardId: currentCard.id})"
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<div class="md-avatar sg-avatar-selected"
|
||||
ng-if="currentCard.selected"
|
||||
ng-click="addressbook.toggleCardSelection($event, currentCard)">
|
||||
<!-- selected avatar -->
|
||||
</div>
|
||||
<sg-avatar-image class="md-avatar"
|
||||
ng-if="addressbook.notSelectedComponent(currentCard, 'vcard')"
|
||||
ng-click="addressbook.toggleCardSelection($event, currentCard)"
|
||||
sg-email="currentCard.$preferredEmail(addressbook.selectedFolder.constructor.$query)"
|
||||
size="40">
|
||||
<!-- contact avatar -->
|
||||
</sg-avatar-image>
|
||||
<div class="md-avatar sg-avatar-list"
|
||||
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.constructor.$query)}}</div>
|
||||
<div class="sg-md-subhead">
|
||||
<div ng-bind-html="currentCard.$fullname()"><!-- cn --></div>
|
||||
</div>
|
||||
<div class="sg-md-body">
|
||||
<div>{{currentCard.$preferredEmail(addressbook.selectedFolder.constructor.$query)}}</div>
|
||||
</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"
|
||||
@@ -371,10 +430,16 @@
|
||||
</md-content>
|
||||
</div>
|
||||
|
||||
<div id="detailView" class="view-detail ng-cloak" layout="column">
|
||||
<md-card class="viewer" ui-view="card"><!-- card view --></md-card>
|
||||
<div id="detailView" class="view-detail md-default-theme md-background md-bg md-hue-1"
|
||||
layout="column" layout-align="start center"
|
||||
ng-class="{ 'sg-close': !addressbook.selectedFolder.selectedCard }"
|
||||
ui-view="card">
|
||||
<md-toolbar class="md-whiteframe-z1 hide-sm"><!-- empty toolbar --></md-toolbar>
|
||||
<md-content class="hide-xs md-flex layout-fill md-hue-1"
|
||||
layout="column" layout-align="center center">
|
||||
<div class="md-default-theme md-background md-fg md-hue-3 sg-md-title"><var:string label:value="No contact selected"/></div>
|
||||
</md-content>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
@@ -383,6 +448,40 @@
|
||||
<var:component className="UIxContactsUserRightsEditor" />
|
||||
</script>
|
||||
|
||||
<!-- modal for cards import -->
|
||||
<script type="text/ng-template" id="UIxContactsImportDialog">
|
||||
<md-dialog flex="40" flex-sm="100" label:aria-label="Import Cards">
|
||||
<md-toolbar>
|
||||
<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"><var:string label:value="Import Cards"/></div>
|
||||
</div>
|
||||
<md-button class="md-icon-button" ng-click="$CardsImportDialogController.close()">
|
||||
<md-icon aria-label="Close dialog">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<p><var:string label:value="Select a vCard or LDIF file."/></p>
|
||||
</md-dialog-content>
|
||||
<md-dialog-actions>
|
||||
<md-progress-circular class="md-accent"
|
||||
md-mode="determinate"
|
||||
md-diameter="20px"
|
||||
ng-show="$CardsImportDialogController.uploader.isUploading"
|
||||
ng-value="$CardsImportDialogController.uploader.progress"><!-- progress --></md-progress-circular>
|
||||
<label class="md-button" for="file-input" ng-hide="$CardsImportDialogController.uploader.isUploading">
|
||||
<span><var:string label:value="Upload"/></span>
|
||||
</label>
|
||||
<input id="file-input" type="file" class="ng-hide"
|
||||
nv-file-select="nv-file-select"
|
||||
uploader="$CardsImportDialogController.uploader"/>
|
||||
<!-- <md-button ng-disabled="uploader.queue.length == 0" ng-click="upload()"><var:string label:value="Upload"/></md-button> -->
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</script>
|
||||
|
||||
<script type="text/ng-template" id="UIxContactViewTemplate">
|
||||
<var:component className="UIxContactViewTemplate" />
|
||||
</script>
|
||||
|
||||
@@ -3,52 +3,33 @@
|
||||
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-card-content>
|
||||
<header class="msg-header">
|
||||
<div ng-show="editor.card.tag == 'vcard'">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
sg-email="editor.card.$preferredEmail()"
|
||||
sg-src="editor.card.photoURL"
|
||||
size="48"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="sg-list-avatar" ng-show="editor.card.tag == 'vlist'">
|
||||
<!--list avatar-->
|
||||
</div>
|
||||
<div class="msg-header-content">
|
||||
<h1 class="sg-md-display-2--light" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
|
||||
<h6 class="sg-md-display-2-subheader">{{editor.card.$description()}}</h6>
|
||||
<md-chips ng-model="editor.card.categories"
|
||||
class="sg-readonly" readonly="true">
|
||||
<md-chip-template>
|
||||
{{$chip.value}}
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
<div class="sg-icon-bar--vertical">
|
||||
<md-button class="sg-icon-button show-sm"
|
||||
label:aria-label="Close"
|
||||
ng-click="toggleDetailView()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Edit"
|
||||
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>
|
||||
</md-button>
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<div layout="column" class="layout-fill">
|
||||
<md-toolbar class="md-whiteframe-z1">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button hide show-sm"
|
||||
label:aria-label="Close"
|
||||
ng-click="editor.close()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Edit"
|
||||
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>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More contact options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-button label:aria-label="More options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
@@ -66,109 +47,143 @@
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
<section class="msg-body">
|
||||
|
||||
<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>
|
||||
</md-toolbar>
|
||||
<md-content class="md-flex md-static">
|
||||
<div layout="column" class="viewer md-padding">
|
||||
<header class="msg-header">
|
||||
<div ng-show="editor.card.c_component == 'vcard'">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
sg-email="editor.card.$preferredEmail()"
|
||||
sg-src="editor.card.photoURL"
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="pseudo-input-field">
|
||||
<span>{{editor.card.$birthday()}}</span>
|
||||
<div class="sg-list-avatar" ng-show="editor.card.c_component == 'vlist'">
|
||||
<!--list avatar-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="msg-header-content">
|
||||
<h1 class="sg-md-display-2--thin" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
|
||||
<h6 class="sg-md-display-2-subheader--thin">{{editor.card.$description()}}</h6>
|
||||
<md-chips ng-model="editor.card.categories"
|
||||
class="sg-readonly" readonly="true">
|
||||
<md-chip-template>
|
||||
{{$chip.value}}
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
</header>
|
||||
<section class="msg-body">
|
||||
|
||||
<!-- list members -->
|
||||
<div class="section" ng-show="editor.card.refs.length > 0">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Members"/>
|
||||
</label>
|
||||
<md-list>
|
||||
<md-list-item class="md-3-line" ng-repeat="ref in editor.card.refs track by ref.reference">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
sg-email="ref.$preferredEmail()"
|
||||
size="48">
|
||||
<!-- contact avatar -->
|
||||
</sg-avatar-image>
|
||||
<div class="md-list-item-text">
|
||||
<h3>
|
||||
<a ui-sref="app.addressbook.card.view({addressbookId: editor.currentFolder.id, cardId: ref.reference})">
|
||||
{{ ref.$fullname() }}
|
||||
</a>
|
||||
</h3>
|
||||
<h4 ng-show="ref.email">
|
||||
<a ui-sref="mailto:{{ref.email}}" ng-class="ng-scope">
|
||||
{{ ref.email }}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</div>
|
||||
|
||||
<div class="section" ng-show="editor.card.emails.length > 0">
|
||||
<div class="pseudo-input-container" ng-repeat="email in editor.card.emails">
|
||||
<div class="pseudo-input-container" ng-show="editor.card.$birthday().length">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label"><var:entity const:name="nbsp"/>{{email.type}}</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="mailto:{{email.value}}">{{email.value}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" ng-show="editor.card.phones.length > 0">
|
||||
<div class="pseudo-input-container" ng-repeat="phone in editor.card.phones">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label">{{phone.type}}</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="tel:{{phone.value}}">{{phone.value}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" ng-show="editor.card.urls">
|
||||
<div class="pseudo-input-container" ng-repeat="url in editor.card.urls">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label"><var:entity const:name="nbsp"/>{{url.type}}
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Birthday"/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="#" ng-href="{{url.value}}">{{url.value}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" ng-show="editor.card.addresses">
|
||||
<div class="pseudo-input-container" ng-repeat="address in editor.card.addresses">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label">{{address.type}}</label>
|
||||
</div>
|
||||
<div class="pseudo-input-field">
|
||||
<div sg-address="address"><!-- address --></div>
|
||||
<span>{{editor.card.$birthday()}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pseudo-input-container" ng-show="editor.card.note">
|
||||
<div class="key">
|
||||
|
||||
<!-- list members -->
|
||||
<div class="section" ng-show="editor.card.refs.length > 0">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Note"/>
|
||||
<var:string label:value="Members"/>
|
||||
</label>
|
||||
<md-list>
|
||||
<md-list-item class="md-3-line" ng-repeat="ref in editor.card.refs track by ref.reference">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
sg-email="ref.$preferredEmail()"
|
||||
size="48">
|
||||
<!-- contact avatar -->
|
||||
</sg-avatar-image>
|
||||
<div class="md-list-item-text">
|
||||
<h3>
|
||||
<a ui-sref="app.addressbook.card.view({addressbookId: editor.currentFolder.id, cardId: ref.reference})">
|
||||
{{ ref.$fullname() }}
|
||||
</a>
|
||||
</h3>
|
||||
<h4 ng-show="ref.email">
|
||||
<a ui-sref="mailto:{{ref.email}}" ng-class="ng-scope">
|
||||
{{ ref.email }}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</div>
|
||||
<div class="pseudo-input-field">
|
||||
<div ng-bind-html="editor.card.note"><!-- note --></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</md-card-content>
|
||||
|
||||
<div class="section" ng-show="editor.card.emails.length > 0">
|
||||
<div class="pseudo-input-container" ng-repeat="email in editor.card.emails">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label"><var:entity const:name="nbsp"/>{{email.type}}</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="#" ng-bind="email.value"
|
||||
ng-click="addressbook.newMessageWithRecipient($event, email.value, editor.card.$fullname())"><!-- recipient --></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" ng-show="editor.card.c_screenname">
|
||||
<div class="pseudo-input-container">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label"><var:string label:value="Screen Name"/></label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">{{editor.card.c_screenname}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" ng-show="editor.card.phones.length > 0">
|
||||
<div class="pseudo-input-container" ng-repeat="phone in editor.card.phones">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label">{{phone.type}}</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="tel:{{phone.value}}">{{phone.value}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" ng-show="editor.card.urls">
|
||||
<div class="pseudo-input-container" ng-repeat="url in editor.card.urls">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label"><var:entity const:name="nbsp"/>{{url.type}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="pseudo-input-field">
|
||||
<a href="#" target="_new" ng-href="{{url.value}}">{{url.value}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" ng-show="editor.card.addresses">
|
||||
<div class="pseudo-input-container" ng-repeat="address in editor.card.addresses">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label">{{address.type}}</label>
|
||||
</div>
|
||||
<div class="pseudo-input-field">
|
||||
<div sg-address="address"><!-- address --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pseudo-input-container" ng-show="editor.card.note">
|
||||
<div class="key">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="Note"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="pseudo-input-field">
|
||||
<div ng-bind-html="editor.card.note"><!-- note --></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
||||
</container>
|
||||
|
||||
@@ -7,8 +7,15 @@
|
||||
xmlns:label="OGo:label"
|
||||
xmlns:uix="OGo:uix">
|
||||
<md-dialog flex="50" flex-sm="100">
|
||||
<md-dialog-content>
|
||||
<h2 class="md-title"><var:string label:value="Subscribe to a shared folder"/></h2>
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<div class="sg-md-title md-flex"><var:string label:value="Subscribe to a shared folder"/></div>
|
||||
<md-button class="md-icon-button" ng-click="subscribe.close()">
|
||||
<md-icon label:aria-label="Close">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<md-input-container>
|
||||
<label><md-icon>search</md-icon><var:string label:value="Search User"/></label>
|
||||
<input type="input"
|
||||
@@ -23,18 +30,17 @@
|
||||
<div layout="row" layout-align="start center" class="md-flex">
|
||||
<span class="card-picture" ng-switch="user.isGroup">
|
||||
<div ng-switch-when="0">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="user.c_email"
|
||||
size="48"><!-- avatar --></sg-avatar-image>
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div ng-switch-when="1" class="sg-list-avatar"><!-- normal-group --></div>
|
||||
</span>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead-multi">{{user.cn}} {{user.userClass}}</div>
|
||||
<div class="sg-md-body-multi">{{user.c_email}}</div>
|
||||
<div class="sg-md-subhead"><div>{{user.cn}}</div></div>
|
||||
<div class="sg-md-body"><div>{{user.c_email}}</div></div>
|
||||
</div>
|
||||
<md-icon ng-class="{ 'icon-expand-more': user.uid != subscribe.selectedUser.uid,
|
||||
'icon-expand-less': user.uid == subscribe.selectedUser.uid }"><!--icon--></md-icon>
|
||||
<md-icon ng-class="{'md-rotate-180': user.uid == subscribe.selectedUser.uid}">expand_more</md-icon>
|
||||
</div>
|
||||
</md-button>
|
||||
<md-card-content ng-show="user == subscribe.selectedUser">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
xmlns:uix="OGo:uix">
|
||||
<div class="addressbookUserRights" layout="column">
|
||||
<div layout="column">
|
||||
|
||||
<md-checkbox name="canViewObjects"
|
||||
ng-model="acl.selectedUser.rights.canViewObjects"
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<var:string label:value="Delegate ..." />
|
||||
</md-button>
|
||||
|
||||
<div class="md-actions" layout="row"
|
||||
<md-dialog-actions layout="row"
|
||||
layout-align="start center"
|
||||
ng-show="delegateInvitation == true">
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
<md-button class="md-primitive"
|
||||
ng-click="iCalendarAction('delegate')"
|
||||
ng-disabled="!delegatedTo || delegatedTo.length == 0"><var:string label:value="OK"/></md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</var:if>
|
||||
<!-- TODO - should we re-enable this? It never
|
||||
worked in v2!
|
||||
@@ -251,13 +251,15 @@
|
||||
<!-- md-contact-chips don't support "readonly", so we build them using md-chips
|
||||
in readonly mode and a template similar to the one of md-contact-chips -->
|
||||
<md-chips class="md-contact-chips sg-readonly"
|
||||
ng-model="part.participants"
|
||||
ng-model="::part.participants"
|
||||
readonly="true">
|
||||
<md-chip-template>
|
||||
<div class="md-contact-avatar"><img src="#" ng-src="{{$chip.image}}" alt="{{$chip.name}}"/></div>
|
||||
<div class="md-contact-avatar">
|
||||
<sg-avatar-image sg-email="$chip.email" size="32"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="md-contact-name">{{$chip.name}}</div>
|
||||
<md-icon ng-class="'icon-' + $chip.status"><!-- partstat --></md-icon>
|
||||
</md-chip-template>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
</md-list>
|
||||
|
||||
@@ -11,16 +11,18 @@
|
||||
var:title="filenameForDisplay"
|
||||
class="md-card-image"></img>
|
||||
<md-card-content>
|
||||
<p class="md-caption">
|
||||
<var:string value="filenameForDisplay" /><br/>
|
||||
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
|
||||
<p class="md-caption" var:title="filenameForDisplay">
|
||||
<var:string value="filenameForDisplay" />
|
||||
</p>
|
||||
</md-card-content>
|
||||
<div class="md-actions" layout="row" layout-align="end center">
|
||||
<md-dialog-actions layout="row" layout-align="start center">
|
||||
<div class="md-flex sg-attachment-size">
|
||||
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
|
||||
</div>
|
||||
<md-button class="sg-icon-button" var:href="pathForDownload">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Save Attachment"/></md-tooltip>
|
||||
<md-icon>save</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-card>
|
||||
</container>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE div>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
<container 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-card>
|
||||
<md-card-content>
|
||||
<img var:src="mimeImageURL"/>
|
||||
<p class="md-caption">
|
||||
<var:string value="filenameForDisplay"/><br/>
|
||||
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
|
||||
</p>
|
||||
</md-card-content>
|
||||
<div class="md-actions" layout="row" layout-align="end center">
|
||||
<md-card-content>
|
||||
<img var:src="mimeImageURL"/>
|
||||
<p class="md-caption">
|
||||
<var:string value="filenameForDisplay"/>
|
||||
</p>
|
||||
</md-card-content>
|
||||
<md-dialog-actions layout="row" layout-align="end center">
|
||||
<div class="md-flex sg-attachment-size">
|
||||
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
|
||||
</div>
|
||||
<md-button class="sg-icon-button" var:href="pathToAttachment" target="_blank">
|
||||
<md-tooltip md-direction="left"><var:string label:value="View Attachment"/></md-tooltip>
|
||||
<md-icon>open_in_browser</md-icon>
|
||||
@@ -21,7 +23,7 @@
|
||||
<md-tooltip md-direction="left"><var:string label:value="Save Attachment"/></md-tooltip>
|
||||
<md-icon>save</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
|
||||
<!-- DEBUG
|
||||
<pre><var:string value="bodyInfo"/></pre>
|
||||
@@ -43,4 +45,4 @@
|
||||
-->
|
||||
|
||||
</md-card>
|
||||
</div>
|
||||
</container>
|
||||
|
||||
@@ -5,201 +5,234 @@
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<md-dialog flex="80" flex-sm="100">
|
||||
<md-toolbar class="md-padding">
|
||||
<md-dialog class="sg-mail-editor" flex="80" flex-sm="100">
|
||||
<md-toolbar>
|
||||
<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>
|
||||
<md-icon class="sg-icon-toolbar-bg">edit</md-icon>
|
||||
<!-- from -->
|
||||
<sg-avatar-image 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>
|
||||
<div flex-gt-sm="flex-gt-sm"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button" ng-click="editor.send()">
|
||||
<md-button class="sg-icon-button" ng-click="editor.send()"
|
||||
ng-disabled="!(editor.message.editable.to.length > 0 || editor.message.editable.cc.length > 0 || editor.message.editable.bcc.length > 0)">
|
||||
<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">
|
||||
<md-dialog-content class="md-padding">
|
||||
<header>
|
||||
<div class="msg-header-content">
|
||||
|
||||
<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-autocomplete
|
||||
md-selected-item="editor.autocomplete.to.selected"
|
||||
md-search-text="editor.autocomplete.to.searchText"
|
||||
md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)"
|
||||
label:placeholder="Add a recipient">
|
||||
<span md-highlight-text="editor.autocomplete.to.searchText"
|
||||
md-highlight-flags="^i">{{user}}</span>
|
||||
</md-autocomplete>
|
||||
<md-chip-template>{{$chip}}</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
|
||||
<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-autocomplete
|
||||
md-selected-item="editor.autocomplete.cc.selected"
|
||||
md-search-text="editor.autocomplete.cc.searchText"
|
||||
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-autocomplete>
|
||||
<md-chip-template>{{$chip}}</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
|
||||
<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-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-autocomplete>
|
||||
<md-chip-template>{{$chip}}</md-chip-template>
|
||||
</md-chips>
|
||||
</div>
|
||||
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="Subject"/>
|
||||
</label>
|
||||
<input type="text" name="subject" ng-model="editor.message.editable.subject"/>
|
||||
</md-input-container>
|
||||
<!-- 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-transform-chip="editor.addRecipient($chip)">
|
||||
<md-autocomplete
|
||||
class="sg-chips-autocomplete"
|
||||
md-autofocus="true"
|
||||
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">
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<md-menu-item>
|
||||
<md-button>
|
||||
<md-checkbox ng-model="editor.message.editable.receipt">
|
||||
<var:string label:value="Return Receipt"/>
|
||||
</md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Priority"/></md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 1">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 1}"><!-- highest --></md-icon>
|
||||
<var:string label:value="highest"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 2">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 2}"><!-- high --></md-icon>
|
||||
<var:string label:value="high"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 3">
|
||||
<md-icon ng-class="{ 'icon-check':
|
||||
!editor.message.editable.priority
|
||||
|| editor.message.editable.priority == 3}"><!-- normal --></md-icon>
|
||||
<var:string label:value="normal"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 4">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 4}"><!-- low --></md-icon>
|
||||
<var:string label:value="low"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 5">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 5}"><!-- lowest --></md-icon>
|
||||
<var:string label:value="lowest"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
|
||||
<!-- 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-transform-chip="editor.addRecipient($chip)">
|
||||
<md-autocomplete
|
||||
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)"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
label:placeholder="Add a recipient">
|
||||
<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>
|
||||
</header>
|
||||
|
||||
<!-- MESSAGE CONTENT -->
|
||||
<textarea name="content" var:class="editorClass"
|
||||
ck-locale="editor.localeCode"
|
||||
ng-model="editor.message.editable.text"/>
|
||||
<!-- 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-transform-chip="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)"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
label:placeholder="Add a recipient">
|
||||
<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"/>
|
||||
</label>
|
||||
<input type="text" name="subject" ng-model="editor.message.editable.subject"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
|
||||
<!-- toolbar to show cc/bcc/attachment fields -->
|
||||
<div layout="column" layout-align="end 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>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<md-menu-item>
|
||||
<md-button ng-href="#">
|
||||
<md-checkbox ng-model="editor.message.editable.receipt">
|
||||
<var:string label:value="Return Receipt"/>
|
||||
</md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Priority"/></md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 1">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 1}"><!-- highest --></md-icon>
|
||||
<var:string label:value="highest"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 2">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 2}"><!-- high --></md-icon>
|
||||
<var:string label:value="high"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 3">
|
||||
<md-icon ng-class="{ 'icon-check':
|
||||
!editor.message.editable.priority
|
||||
|| editor.message.editable.priority == 3}"><!-- normal --></md-icon>
|
||||
<var:string label:value="normal"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 4">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 4}"><!-- low --></md-icon>
|
||||
<var:string label:value="low"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="editor.message.editable.priority = 5">
|
||||
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 5}"><!-- lowest --></md-icon>
|
||||
<var:string label:value="lowest"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- MESSAGE CONTENT -->
|
||||
<textarea name="content" var:class="editorClass"
|
||||
ck-locale="editor.localeCode"
|
||||
ng-model="editor.message.editable.text"/>
|
||||
</md-dialog-content>
|
||||
|
||||
<!-- TOOLBAR BUTTONS -->
|
||||
<div class="md-actions">
|
||||
<md-dialog-actions>
|
||||
<div layout="row" layout-align="space-between center" layout-fill="layout-fill">
|
||||
<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>
|
||||
<!-- Attachments -->
|
||||
<md-chips ng-model="editor.uploader.queue"
|
||||
class="md-flex sg-readonly" readonly="true">
|
||||
<md-chip-template>
|
||||
<span class="sg-chip-progress" ng-show="$chip.isUploading">
|
||||
<span class="md-default-theme md-warn md-bg"
|
||||
ng-style="{ width: $chip.progress + '%'}"><!-- progress --></span>
|
||||
</span>
|
||||
<a ng-href="{{$chip.inlineUrl}}" target="_new">{{$chip.file.name}}</a>
|
||||
<md-icon ng-class="{ 'md-warn': $chip.isUploading }"
|
||||
ng-click="editor.removeAttachment($chip)">close</md-icon>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
<label class="md-button md-icon-button" for="file-input">
|
||||
<md-icon>attach_file</md-icon>
|
||||
<!-- <span><var:string label:value="Attach"/></span> -->
|
||||
</label>
|
||||
<input id="file-input" type="file"
|
||||
<input id="file-input" name="file-input" type="file" class="ng-hide"
|
||||
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 -->
|
||||
<md-chips ng-model="editor.message.editable.attachmentAttrs"
|
||||
class="sg-readonly" readonly="true">
|
||||
<md-chip-template>
|
||||
<span>{{$chip.filename}}</span>
|
||||
<md-icon ng-click="editor.message.$deleteAttachment($chip.filename);">close</md-icon>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
<!-- FILE BEING ATTACHED TO A MAIL -->
|
||||
<md-chips ng-model="editor.uploader.queue"
|
||||
class="sg-readonly" readonly="true">
|
||||
<md-chip-template>
|
||||
<span>{{$chip.file.name}}</span>
|
||||
<md-icon ng-show="!$chip.isUploading"
|
||||
ng-click="editor.message.$deleteAttachment($chip.file.name);
|
||||
$chip.remove();">close</md-icon>
|
||||
<md-icon ng-show="$chip.isUploading"
|
||||
ng-click="editor.uploader.cancelItem($chip)"
|
||||
ng-style="{ 'color': '#F00' }">cancel</md-icon>
|
||||
<span ng-show="$chip.isUploading">{{$chip.progress}} %</span>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
uploader="editor.uploader"/>
|
||||
<!--
|
||||
Disable multiple until this issue is resolved:
|
||||
https://github.com/nervgh/angular-file-upload/issues/525
|
||||
-->
|
||||
<!-- multiple="multiple" -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</md-dialog>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -4,49 +4,262 @@
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:label="OGo:label">
|
||||
<div class="view-list" layout="column">
|
||||
|
||||
<!-- in virtual mailbox mode -->
|
||||
<md-toolbar class="md-whiteframe-z1"
|
||||
ng-hide="!app.showingAdvancedSearch || mailbox.selectedFolder.$selectedCount() > 0">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Search messages in"/></label>
|
||||
<md-select ng-model="app.search.mailbox">
|
||||
<md-option ng-value="">
|
||||
<span>{{app.accounts[0].name}}</span>
|
||||
</md-option>
|
||||
<md-option ng-repeat="folder in
|
||||
app.accounts[0].$flattenMailboxes()
|
||||
track by folder.path"
|
||||
ng-value="folder.path">
|
||||
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
|
||||
</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="More search options" ng-click="$mdOpenMenu()">
|
||||
<md-icon>settings</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-href="#">
|
||||
<md-checkbox ng-model="app.search.subfolders"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0">
|
||||
<var:string label:value="Search subfolders"/>
|
||||
</md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.search.match='AND'">
|
||||
<md-icon ng-class="{ 'icon-check': app.search.match == 'AND'}">
|
||||
<!-- all --></md-icon><var:string label:value="Match all of the following"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.search.match='OR'">
|
||||
<md-icon ng-class="{ 'icon-check': app.search.match == 'OR'}">
|
||||
<!-- any --></md-icon><var:string label:value="Match any of the following"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="sg-icon-button"
|
||||
ng-click="app.toggleAdvancedSearch()"
|
||||
ng-disabled="app.search.params.length == 0">
|
||||
<md-icon ng-class="{'icon-stop': app.service.selectedFolder.$isLoading,
|
||||
'icon-search': !app.service.selectedFolder.$isLoading}"><!-- icon --></md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<!-- single-selection toolbars -->
|
||||
<md-toolbar class="md-whiteframe-z1"
|
||||
ng-hide="app.showingAdvancedSearch || mailbox.selectedFolder.$selectedCount() > 0">
|
||||
<!-- sort mode (default) -->
|
||||
<div class="md-toolbar-tools" ng-hide="mailbox.mode.search">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search"
|
||||
ng-click="mailbox.mode.search = true">
|
||||
<md-icon>search</md-icon>
|
||||
</md-button>
|
||||
<div class="sg-folder-name">{{mailbox.selectedFolder.name}}</div>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Sort"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>sort</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('subject')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('subject') }">
|
||||
<!-- subject --></md-icon> <var:string label:value="Subject"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('from')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('from') }">
|
||||
<!-- from --></md-icon> <var:string label:value="From"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('date')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('date') }">
|
||||
<!-- date --></md-icon> <var:string label:value="Date"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('size')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('size') }">
|
||||
<!-- size --></md-icon> <var:string label:value="Size"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider> <!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.selectedFolder.$filter()">
|
||||
<md-checkbox
|
||||
ng-model="mailbox.service.$query.asc"
|
||||
ng-true-value="0"
|
||||
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="sg-icon-button" aria-label="Refresh" ng-click="mailbox.selectedFolder.$filter()" >
|
||||
<md-icon>refresh</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<!-- search mode -->
|
||||
<div class="md-toolbar-tools sg-toolbar-secondary"
|
||||
ng-show="mailbox.mode.search"
|
||||
sg-search="mailbox.selectedFolder.$filter({ sort: 'date', asc: false }, [{ searchBy: searchField, searchInput: searchText }])">
|
||||
<md-button class="sg-icon-button"
|
||||
sg-search-cancel="mailbox.cancelSearch()"
|
||||
label:aria-label="Back">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<md-input-container md-no-float="md-no-float">
|
||||
<input name="folderSearch" type="search" ng-minlength="3" label:placeholder="Search"/>
|
||||
</md-input-container>
|
||||
<md-input-container flex="25">
|
||||
<md-select>
|
||||
<md-option value="subject" selected="selected"><var:string label:value="Subject"/></md-option>
|
||||
<md-option value="from"><var:string label:value="Sender"/></md-option>
|
||||
<md-option value="subject_or_from"><var:string label:value="Subject or Sender"/></md-option>
|
||||
<md-option value="to_or_cc"><var:string label:value="To or Cc"/></md-option>
|
||||
<md-option value="body"><var:string label:value="Entire Message"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<!-- multiple-selection mode -->
|
||||
<md-toolbar class="md-hue-1 sg-toolbar-secondary" ng-show="mailbox.selectedFolder.$selectedCount() > 0">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button" ng-click="mailbox.unselectMessages()">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<label>{{mailbox.service.selectedFolder.$selectedCount()}} <var:string label:value="selected"/></label>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button" ng-click="mailbox.selectAll()">
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Select All"/></md-tooltip>
|
||||
<md-icon>select_all</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button" ng-click="mailbox.confirmDeleteSelectedMessages()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Copy messages" ng-click="$mdOpenMenu()">
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Copy To"/></md-tooltip>
|
||||
<md-icon>content_copy</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<div ng-repeat="account in mailbox.accounts track by account.id">
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true">{{account.name}}</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-repeat="folder in
|
||||
account.$flattenMailboxes()
|
||||
track by folder.path"
|
||||
ng-hide="mailbox.id == folder.id">
|
||||
<md-button ng-click="mailbox.copySelectedMessages(folder.id)">
|
||||
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</div>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="More messages options" ng-click="$mdOpenMenu()">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.markSelectedMessagesAsFlagged()">
|
||||
<var:string label:value="Flag"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.markSelectedMessagesAsUnread()">
|
||||
<var:string label:value="Mark as Unread"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.saveSelectedMessages()">
|
||||
<var:string label:value="Save As..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<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>
|
||||
<span ng-show="mailbox.selectedFolder.$messages.length == 0"><var:string label:value="No message"/></span>
|
||||
</h2>
|
||||
</header>
|
||||
<md-subheader>
|
||||
<!-- toggle sidenav -->
|
||||
<md-button class="md-icon-button hide show-gt-sm" ng-click="toggleLeft()">
|
||||
<md-icon ng-class="{'md-rotate-180': leftIsClose }">keyboard_arrow_left</md-icon>
|
||||
</md-button>
|
||||
<!-- message count -->
|
||||
<span ng-switch="mailbox.service.selectedFolder.getLength()">
|
||||
<span ng-switch-when="0"><var:string label:value="No message"/></span>
|
||||
<span ng-switch-default="true">{{mailbox.service.selectedFolder.getLength()}} <var:string label:value="messages"/></span>
|
||||
</span>
|
||||
</md-subheader>
|
||||
<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>
|
||||
<md-list-item
|
||||
class="md-default-theme md-background md-hue-1"
|
||||
md-virtual-repeat="currentMessage in mailbox.service.selectedFolder"
|
||||
md-on-demand="md-on-demand"
|
||||
ng-class="{'md-bg': mailbox.selectedFolder.isSelectedMessage(currentMessage.uid, currentMessage.$mailbox.path),
|
||||
unread: !currentMessage.isread}"
|
||||
ng-click="mailbox.selectMessage(currentMessage)">
|
||||
<sg-avatar-image class="md-avatar"
|
||||
ng-if="!currentMessage.selected"
|
||||
ng-click="mailbox.toggleMessageSelection($event, currentMessage)"
|
||||
sg-email="::currentMessage.from[0].email"
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
<div class="md-avatar sg-avatar-selected"
|
||||
ng-if="currentMessage.selected"
|
||||
ng-click="mailbox.toggleMessageSelection($event, currentMessage)"><!-- selected avatar --></div>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead">
|
||||
<div>
|
||||
<span class="sg-label-outline"
|
||||
ng-show="mailbox.service.$virtualMode">{{currentMessage.$mailbox.name}}</span>
|
||||
<md-icon ng-show="currentMessage.priority.level == 1 ||
|
||||
currentMessage.priority.level == 2"
|
||||
ng-class="{'md-warn': currentMessage.priority.level == 1}">error</md-icon>
|
||||
{{currentMessage.$shortAddress('from')}}
|
||||
</div>
|
||||
<div class="sg-tile-date" ng-bind="currentMessage.relativedate"><!-- date --></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 class="sg-md-body">
|
||||
<div>{{currentMessage.subject}}</div>
|
||||
</div>
|
||||
</md-list-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sg-tile-icons">
|
||||
<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.service.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 +268,15 @@
|
||||
</md-content>
|
||||
</div>
|
||||
|
||||
<div id="detailView" class="view-detail ng-cloak" layout="column" ui-view="message"
|
||||
ng-show="mailbox.selectedFolder.selectedMessage"><!-- message view --></div>
|
||||
<div id="detailView" class="view-detail md-default-theme md-background md-bg md-hue-1"
|
||||
layout="column" layout-align="start center"
|
||||
ng-class="{ 'sg-close': !mailbox.service.selectedFolder.selectedMessage }"
|
||||
ui-view="message">
|
||||
<md-toolbar class="md-whiteframe-z1 hide-sm"><!-- empty toolbar --></md-toolbar>
|
||||
<md-content class="hide-sm md-flex layout-fill md-hue-1"
|
||||
layout="column" layout-align="center center">
|
||||
<div class="md-default-theme md-background md-fg md-hue-3 sg-md-title"><var:string label:value="No message selected"/></div>
|
||||
</md-content>
|
||||
</div>
|
||||
|
||||
</container>
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:jsFiles="Common.js, Contacts.services.js, Mailer.services.js, Preferences.services.js, Mailer.js, Mailer.services.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/angular-file-upload.min.js">
|
||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.services.js, Mailer.js, Mailer.services.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/angular-file-upload.min.js">
|
||||
<script type="text/javascript">
|
||||
var mailAccounts =<var:string value="mailAccounts" const:escapeHTML="NO" />;
|
||||
var userNames =<var:string value="userNames" const:escapeHTML="NO" />;
|
||||
var unseenCountFolders =<var:string value="unseenCountFolders" const:escapeHTML="NO" />;
|
||||
var mailAccounts = <var:string value="mailAccounts" const:escapeHTML="NO" />;
|
||||
var userNames = <var:string value="userNames" const:escapeHTML="NO" />;
|
||||
var unseenCountFolders = <var:string value="unseenCountFolders" const:escapeHTML="NO" />;
|
||||
</script>
|
||||
<style type="text/css">
|
||||
<var:foreach list="availableLabels" item="currentLabel">
|
||||
@@ -223,30 +223,30 @@
|
||||
-->
|
||||
<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 layout-fill" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
|
||||
<md-sidenav class="md-sidenav-left md-whiteframe-z1 layout-fill" layout="column"
|
||||
md-component-id="left" md-is-locked-open="isGtMedium"
|
||||
ng-class="{ 'sg-closed': leftIsClose }">
|
||||
<var:component className="UIxSidenavToolbarTemplate" />
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex">
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex md-hue-2">
|
||||
<section ng-repeat="account in app.accounts track by account.id">
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<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>
|
||||
</div>
|
||||
<md-subheader class="md-hue-2">
|
||||
<div layout="row" layout-align="start center">
|
||||
<div class="sg-no-wrap">{{account.name}}</div>
|
||||
<div class="md-flex"><!-- spacer --></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>
|
||||
</div>
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
@@ -254,16 +254,23 @@
|
||||
ng-click="app.selectFolder(account, folder)"
|
||||
ng-dblclick="app.editFolder(folder)"
|
||||
ui-sref="mail.account.mailbox({accountId: account.id, mailboxId: (folder.path | encodeUri)})"
|
||||
ui-sref-active="sg-active">
|
||||
<md-icon ng-class="'sg-child-level-' + folder.level">{{app.metadataForFolder(folder).icon}}</md-icon>
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<div ng-class="'sg-child-level-' + folder.level">
|
||||
<md-icon ng-hide="folder.children.length">{{app.metadataForFolder(folder).icon}}</md-icon>
|
||||
<md-checkbox class="sg-folder"
|
||||
label:aria-label="Expanded"
|
||||
ng-show="folder.children.length"
|
||||
ng-model="folder.$expanded"
|
||||
ng-change="account.$flattenMailboxes({ reload: true, saveState: true })"><!-- expanded --></md-checkbox>
|
||||
</div>
|
||||
<p class="sg-item-name"
|
||||
ng-show="app.editMode != folder.path">
|
||||
{{app.metadataForFolder(folder).name}}
|
||||
<span ng-show="folder.unseenCount"> ({{folder.unseenCount}})</span>
|
||||
<span class="sg-counter-badge" ng-show="folder.unseenCount">{{folder.unseenCount}}</span>
|
||||
</p>
|
||||
<md-input-container class="md-flex md-tile-content"
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == folder.path">
|
||||
<input class="folder-name" type="text"
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Enter the new name of your folder"
|
||||
ng-model="folder.name"
|
||||
ng-blur="app.saveFolder(folder)"
|
||||
@@ -312,6 +319,12 @@
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button"
|
||||
ng-click="app.showAdvancedSearch(folder.path)">
|
||||
<var:string label:value="Search"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider ng-show="folder.type == 'folder'"><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-show="folder.type == 'folder'">
|
||||
<md-button type="button" ng-click="app.setFolderAs(folder, 'Drafts')">
|
||||
@@ -346,151 +359,58 @@
|
||||
</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">
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
<md-toolbar layout="row" layout-align="space-between center" class="toolbar-main"
|
||||
ng-hide="app.showingAdvancedSearch">
|
||||
<var:component className="UIxTopnavToolbarTemplate"/>
|
||||
</md-toolbar>
|
||||
|
||||
<!-- Advanced search toolbar -->
|
||||
<md-toolbar layout="column" class="md-tall toolbar-main"
|
||||
ng-show="app.showingAdvancedSearch">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-chips class="md-flex"
|
||||
ng-model="app.search.params"
|
||||
md-on-append="app.newSearchParam($chip)">
|
||||
<input sg-focus-on="advancedSearch" type="text"
|
||||
ng-disabled="app.currentSearchParam.length == 0"
|
||||
sg-placeholder="app.search.options[app.currentSearchParam]"/>
|
||||
<md-chip-template>
|
||||
<span class="md-caption" ng-show="$chip.negative == 0">(match</span>
|
||||
<span class="md-caption" ng-show="$chip.negative == 1">(does not match</span>
|
||||
<span class="md-caption">{{$chip.searchBy}})</span>
|
||||
<span>{{$chip.searchInput}}</span>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
<md-button type="button" class="sg-icon-button" ng-click="app.hideAdvancedSearch()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="md-toolbar-tools" layout="row" layout-align="space-between center"
|
||||
ng-show="mailbox.selectedFolder.$selectedCount() == 0">
|
||||
<!-- sort mode -->
|
||||
<div class="view-list" layout="row" layout-align="space-between center"
|
||||
ng-hide="mailbox.mode.search">
|
||||
<div class="sg-toolbar-group">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search"
|
||||
ng-click="mailbox.mode.search = true">
|
||||
<md-icon>search</md-icon>
|
||||
</md-button>
|
||||
<div class="md-toolbar-tools">
|
||||
<div layout="column">
|
||||
<div class="pseudo-input-container--compact">
|
||||
<label class="pseudo-input-label"><var:string label:value="Add a Criteria"/></label>
|
||||
</div>
|
||||
<div class="sg-toolbar-group-last">
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Sort"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>sort</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('subject')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('subject') }">
|
||||
<!-- subject --></md-icon> <var:string label:value="Subject"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('from')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('from') }">
|
||||
<!-- from --></md-icon> <var:string label:value="From"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('date')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('date') }">
|
||||
<!-- date --></md-icon> <var:string label:value="Date"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.sort('size')">
|
||||
<md-icon ng-class="{ 'icon-check': mailbox.sortedBy('size') }">
|
||||
<!-- size --></md-icon> <var:string label:value="Size"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider> <!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.selectedFolder.$filter()">
|
||||
<md-checkbox
|
||||
ng-model="mailbox.service.$query.asc"
|
||||
ng-true-value="0"
|
||||
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="sg-icon-button" aria-label="Refresh" ng-click="mailbox.selectedFolder.$filter()" >
|
||||
<md-icon>refresh</md-icon>
|
||||
</md-button>
|
||||
<div layout="row">
|
||||
<span class="md-button sg-outline-button" ng-click="app.addSearchParam('subject')">
|
||||
<var:string label:value="Subject"/>
|
||||
</span>
|
||||
<span class="md-button sg-outline-button" ng-click="app.addSearchParam('from')">
|
||||
<var:string label:value="From"/>
|
||||
</span>
|
||||
<span class="md-button sg-outline-button" ng-click="app.addSearchParam('to')">
|
||||
<var:string label:value="To"/>
|
||||
</span>
|
||||
<span class="md-button sg-outline-button" ng-click="app.addSearchParam('cc')">
|
||||
<var:string label:value="Cc"/>
|
||||
</span>
|
||||
<span class="md-button sg-outline-button" ng-click="app.addSearchParam('body')">
|
||||
<var:string label:value="Body"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- search mode -->
|
||||
<div class="view-list sg-padded--right sg-toolbar-search" layout="row" layout-align="space-between center"
|
||||
ng-show="mailbox.mode.search"
|
||||
sg-search="mailbox.selectedFolder.$filter({ sort: 'date', asc: false }, [{ searchBy: searchField, searchInput: searchText }])">
|
||||
<md-button class="sg-icon-button"
|
||||
sg-search-cancel="mailbox.cancelSearch()"
|
||||
label:aria-label="Back">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<md-input-container>
|
||||
<input name="folderSearch" type="search" />
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<md-select>
|
||||
<md-option value="subject" selected="selected"><var:string label:value="Subject"/></md-option>
|
||||
<md-option value="from"><var:string label:value="Sender"/></md-option>
|
||||
<md-option value="subject_or_from"><var:string label:value="Subject or Sender"/></md-option>
|
||||
<md-option value="to_or_cc"><var:string label:value="To or Cc"/></md-option>
|
||||
<md-option value="body"><var:string label:value="Entire Message"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div layout="row" layout-align="start center" ng-show="mailbox.selectedFolder.$selectedCount() > 0">
|
||||
<md-button class="sg-icon-button" ng-click="mailbox.unselectMessages()">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<label>{{mailbox.selectedFolder.$selectedCount()}} selected</label>
|
||||
<md-button class="sg-icon-button" ng-click="mailbox.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="mailbox.confirmDeleteSelectedMessages()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Copy messages" ng-click="$mdOpenMenu()">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Copy To"/></md-tooltip>
|
||||
<md-icon>content_copy</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<div ng-repeat="account in mailbox.accounts track by account.id">
|
||||
<md-menu-item>
|
||||
<md-button class="md-primary" ng-disabled="true">{{account.name}}</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-repeat="folder in
|
||||
account.$flattenMailboxes()
|
||||
track by folder.path"
|
||||
ng-hide="mailbox.id == folder.id">
|
||||
<md-button ng-click="mailbox.copySelectedMessages(folder.id)">
|
||||
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</div>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="More messages options" ng-click="$mdOpenMenu()">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.markSelectedMessagesAsFlagged()">
|
||||
<var:string label:value="Flag"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.markSelectedMessagesAsUnread()">
|
||||
<var:string label:value="Mark as Unread"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="mailbox.saveSelectedMessages()">
|
||||
<var:string label:value="Save As..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<div layout="row" class="md-flex">
|
||||
<var:component className="UIxMailFolderTemplate" />
|
||||
</div>
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<var:component xmlns="http://www.w3.org/1999/xhtml"
|
||||
<!DOCTYPE var:component>
|
||||
<var:component
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:uix="OGo:uix"
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:jsFiles="SOGoAutoCompletion.js"
|
||||
const:userDefaultsKeys="SOGoMailDisplayRemoteInlineImages"
|
||||
const:popup="YES">
|
||||
<script type="text/javascript">
|
||||
var messageName = '<var:string value="clientObject.relativeImap4Name"/>';
|
||||
var mailboxName = '/<var:string value="clientObject.container.container.nameInContainer"/>/<var:string value="clientObject.container.nameInContainer"/>';
|
||||
</script>
|
||||
<var:component className="UIxMailView" />
|
||||
<div class="menu" id="addressMenu">
|
||||
<ul>
|
||||
<li id="add_to_addressbook"><var:string label:value="Add to Address Book..."/></li>
|
||||
<li id="compose_mailto"><var:string label:value="Compose Mail To"/></li>
|
||||
<li id="create_filter"><var:string label:value="Create Filter From Message..."/></li>
|
||||
</ul>
|
||||
const:popup="YES"
|
||||
const:jsFiles="Common.js, Contacts.services.js, Preferences.services.js, Mailer.app.popup.js, Mailer.services.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/angular-file-upload.min.js">
|
||||
|
||||
<main class="layout-fill" ng-controller="navController">
|
||||
<div id="detailView" class="view-detail" layout="column" layout-align="start center"
|
||||
ui-view="message">
|
||||
<div class="sg-progress-circular-floating">
|
||||
<md-progress-circular class="md-accent ng-cloak"
|
||||
md-mode="indeterminate"
|
||||
md-diameter="32"><!-- progress --></md-progress-circular>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu" id="imageMenu">
|
||||
<ul>
|
||||
<li id="save_image"><var:string label:value="Save Image"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
</var:component>
|
||||
</main>
|
||||
|
||||
<script type="text/ng-template" id="UIxMailViewTemplate">
|
||||
<var:component className="UIxMailViewTemplate" />
|
||||
</script>
|
||||
|
||||
<script type="text/ng-template" id="UIxMailEditor">
|
||||
<var:component className="UIxMailEditor" />
|
||||
</script>
|
||||
</var:component>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
>
|
||||
<md-dialog flex="30" flex-sm="100">
|
||||
<md-toolbar class="sg-padded">
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">folder_shared</md-icon>
|
||||
<div class="pseudo-input-container md-flex">
|
||||
@@ -20,16 +20,38 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-dialog-content>
|
||||
<md-dialog-content class="md-padding">
|
||||
<div>
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-input-name="addUser"
|
||||
md-search-text="delegate.searchText"
|
||||
md-selected-item="delegate.userToAdd"
|
||||
md-selected-item-change="delegate.addUser(user)"
|
||||
md-items="user in delegate.userFilter(delegate.searchText)"
|
||||
md-item-text="user.empty"
|
||||
md-min-length="3"
|
||||
md-no-cache="true"
|
||||
label:md-floating-label="Add User">
|
||||
<span class="md-contact-suggestion" layout="row" layout-align="space-between center">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="delegate.searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span> <span class="md-contact-email"
|
||||
md-highlight-text="delegate.searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-autocomplete>
|
||||
</div>
|
||||
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="user in delegate.users | orderBy:['userClass', 'displayName']">
|
||||
<div layout="row" layout-align="start center" class="md-flex">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
<div layout="row" layout-align="start center" class="md-flex card-picture">
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="user.c_email"
|
||||
size="48"><!-- avatar --></sg-avatar-image>
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead-multi">{{user.cn}}</div>
|
||||
<div class="sg-md-body-multi">{{user.c_email}}</div>
|
||||
<div class="sg-md-subhead"><div>{{user.cn}}</div></div>
|
||||
<div class="sg-md-body"><div>{{user.c_email}}</div></div>
|
||||
</div>
|
||||
<md-button class="sg-icon-button" ng-click="delegate.removeUser(user)">
|
||||
<md-icon>delete</md-icon>
|
||||
@@ -38,27 +60,5 @@
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</md-dialog-content>
|
||||
|
||||
<div class="md-actions">
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-input-name="addUser"
|
||||
md-search-text="delegate.searchText"
|
||||
md-selected-item="delegate.userToAdd"
|
||||
md-selected-item-change="delegate.addUser(user)"
|
||||
md-items="user in delegate.userFilter(delegate.searchText)"
|
||||
md-item-text="user.empty"
|
||||
md-min-length="3"
|
||||
md-no-cache="true"
|
||||
label:md-floating-label="Add User">
|
||||
<span class="md-contact-suggestion" layout="row" layout-align="space-between center">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="delegate.searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span> <span class="md-contact-email"
|
||||
md-highlight-text="delegate.searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-autocomplete>
|
||||
</div>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -1,105 +1,51 @@
|
||||
<?xml version='1.0' standalone='yes'?>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
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:uix="OGo:uix">
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
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:uix="OGo:uix">
|
||||
|
||||
<md-content md-scroll-y="md-scroll-y" class="viewer md-padding md-flex bg-sogoPaper-50 md-whiteframe-z1">
|
||||
<header class="msg-header">
|
||||
<div class="msg-header-content">
|
||||
<div layout="row" layout-align="start center">
|
||||
<md-button class="sg-icon-button sg-msg-flag" label:aria-label="flagged" ng-click="viewer.message.toggleFlag()">
|
||||
<md-icon ng-class="{'flagged': viewer.message.isflagged}">star</md-icon>
|
||||
</md-button>
|
||||
<h3 class="sg-md-title-msg" ng-bind="viewer.message.subject"><!-- subject --></h3>
|
||||
</div>
|
||||
<div class="pseudo-input-container--compact">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="From"/>
|
||||
</label>
|
||||
<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>
|
||||
|
||||
<div class="pseudo-input-container--compact">
|
||||
<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">
|
||||
<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>
|
||||
|
||||
<md-chips class="sg-readonly" ng-model="viewer.message.flags" ng-change="viewer.changeFlags()">
|
||||
<md-chip-template>{{viewer.service.$tags[$chip][0]}}</md-chip-template>
|
||||
<md-autocomplete
|
||||
md-selected-item="viewer.tags.selected"
|
||||
md-selected-item-change="viewer.message.addTag(viewer.tags.selected)"
|
||||
md-search-text="viewer.tags.searchText"
|
||||
md-items="tag in viewer.service.filterTags(viewer.tags.searchText)"
|
||||
label:placeholder="Add a tag">
|
||||
<span md-highlight-text="viewer.tags.searchText">{{viewer.service.$tags[tag][0]}}</span>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <p class="flags">
|
||||
<!– Todo: change the text for an icon (conditional ?) The read/unread flag doesn't make sense at his place–>
|
||||
<span class="pseudo-input-label" ng-repeat="flag in message.flags">{{flag}}</span>
|
||||
</p>
|
||||
-->
|
||||
|
||||
<div class="sg-icon-bar--vertical">
|
||||
<md-button class="sg-icon-button show-sm"
|
||||
<div layout="column" class="layout-fill">
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button"
|
||||
ng-if="isPopup"
|
||||
label:aria-label="Close"
|
||||
ng-click="toggleDetailView()">
|
||||
ng-click="viewer.closePopup()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
<!-- todo: Replace md-tooltip values by localizable string variable -->
|
||||
<md-button class="sg-icon-button hide show-sm"
|
||||
ng-hide="isPopup"
|
||||
label:aria-label="Close"
|
||||
ng-click="viewer.close()">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex hide show-sm"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button" label:aria-label="flagged" ng-click="viewer.message.toggleFlag()">
|
||||
<md-icon ng-class="{'icon-star': viewer.message.isflagged,
|
||||
'icon-star-border': !viewer.message.isflagged}"><!-- flag --></md-icon>
|
||||
</md-button>
|
||||
<div class="md-flex hide-sm"><!-- spacer --></div>
|
||||
<md-button class="sg-icon-button"
|
||||
ng-hide="viewer.message.isDraft"
|
||||
ng-click="viewer.reply($event)"
|
||||
label:aria-label="reply">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Reply to Sender Only"/></md-tooltip>
|
||||
label:aria-label="Reply">
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Reply to Sender Only"/></md-tooltip>
|
||||
<md-icon>reply</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button"
|
||||
ng-show="viewer.message.allowReplyAll()"
|
||||
ng-click="viewer.replyAll($event)"
|
||||
label:aria-label="Reply All">
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Reply to sender and all recipients"/></md-tooltip>
|
||||
<md-icon>reply_all</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button" label:aria-label="Forward"
|
||||
ng-hide="viewer.message.isDraft"
|
||||
ng-click="viewer.forward($event)">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Forward selected message"/></md-tooltip>
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Forward selected message"/></md-tooltip>
|
||||
<md-icon>forward</md-icon>
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button" label:aria-label="Edit"
|
||||
@@ -109,25 +55,24 @@
|
||||
</md-button>
|
||||
<md-button class="sg-icon-button" label:aria-label="Delete"
|
||||
ng-click="viewer.doDelete()">
|
||||
<md-tooltip md-direction="left"><var:string label:value="Delete selected message or folder"/></md-tooltip>
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Delete selected message or folder"/></md-tooltip>
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
|
||||
<md-button class="sg-icon-button hide-sm" label:aria-label="Open in New Mail Window"
|
||||
ng-hide="isPopup"
|
||||
ng-click="viewer.openPopup()">
|
||||
<md-tooltip md-direction="bottom"><var:string label:value="Open in New Mail Window"/></md-tooltip>
|
||||
<md-icon>open_in_new</md-icon>
|
||||
</md-button>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="4">
|
||||
<md-menu-item ng-hide="viewer.message.isDraft">
|
||||
<md-button label:aria-label="Reply All"
|
||||
ng-click="viewer.replyAll($event)">
|
||||
<var:string label:value="Reply All"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="viewer.message.$hasUnsafeContent">
|
||||
<md-button label:aria-label="Load Images"
|
||||
ng-click="viewer.message.loadUnsafeContent()">
|
||||
<var:string label:value="Load Images"/>
|
||||
<md-menu-item ng-hide="viewer.showFlags">
|
||||
<md-button label:aria-label="Add a tag"
|
||||
ng-click="viewer.showFlags = true">
|
||||
<var:string label:value="Add a tag"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
@@ -144,38 +89,128 @@
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-toolbar>
|
||||
<md-content class="md-flex md-static">
|
||||
<div class="viewer">
|
||||
<md-toolbar class="sg-padded">
|
||||
<h3 class="sg-md-title-msg">{{viewer.message.subject}}</h3>
|
||||
<time class="msg-date" datetime="viewer.message.date" ng-bind="viewer.message.date"><!-- date --></time>
|
||||
</md-toolbar>
|
||||
<md-toolbar class="sg-padded">
|
||||
|
||||
<div ng-show="viewer.message.shouldAskReceipt == 1"
|
||||
layout-padding="layout-padding">
|
||||
<md-whiteframe class="md-whiteframe-z2" layout="column"
|
||||
layout-align="center start">
|
||||
<md-icon>warning</md-icon>
|
||||
<span><var:string label:value="The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?"/></span>
|
||||
<div class="md-actions" layout="row">
|
||||
<md-button label:aria-label="Yes"
|
||||
type="button" class="md-primary"
|
||||
ng-click="viewer.message.$sendMDN()"><var:string label:value="Yes"/></md-button>
|
||||
<md-button label:aria-label="No"
|
||||
type="button"
|
||||
ng-click="viewer.message.shouldAskReceipt = 0"><var:string label:value="No"/></md-button>
|
||||
</div>
|
||||
</md-whiteframe>
|
||||
</div>
|
||||
<div class="pseudo-input-container--compact">
|
||||
<label class="pseudo-input-label">
|
||||
<var:string label:value="From"/>
|
||||
</label>
|
||||
<div layout="row" layout-align="start center">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
sg-email="viewer.message.from[0].email"
|
||||
size="40">
|
||||
<!-- 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>
|
||||
<div class="pseudo-input-container--compact">
|
||||
<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">
|
||||
<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>
|
||||
<md-chips class="sg-readonly hide-sm"
|
||||
ng-show="viewer.showFlags"
|
||||
ng-model="viewer.message.flags"
|
||||
md-on-append="$chip.name"
|
||||
md-on-remove="viewer.message.removeTag($chip)">
|
||||
<md-chip-template>{{viewer.service.$tags[$chip][0]}}</md-chip-template>
|
||||
<md-autocomplete
|
||||
md-selected-item="viewer.tags.selected"
|
||||
md-selected-item-change="viewer.message.addTag(viewer.tags.selected.name)"
|
||||
md-search-text="viewer.tags.searchText"
|
||||
md-items="tag in viewer.service.filterTags(viewer.tags.searchText)"
|
||||
md-autoselect="true"
|
||||
label:placeholder="Add a tag">
|
||||
<md-item-template>
|
||||
<span md-highlight-text="viewer.tags.searchText"
|
||||
md-highlight-flags="^i">{{tag.description}}</span>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
</md-toolbar>
|
||||
<md-content md-scroll-x="md-scroll-x" class="md-padding md-whiteframe-z1">
|
||||
|
||||
<div class="msg-body">
|
||||
<div class="msg-date sg-md-body-multi">
|
||||
<time datetime="viewer.message.date" ng-bind="viewer.message.date"><!-- date --></time>
|
||||
<!-- Load external images -->
|
||||
<md-whiteframe class="md-whiteframe-z2" layout="row" layout-align="space-between center"
|
||||
ng-show="viewer.message.$hasUnsafeContent">
|
||||
<div layout="row" layout-align="start center" class="layout-fill">
|
||||
<div class="md-tile-left">
|
||||
<md-icon>collections</md-icon>
|
||||
</div>
|
||||
<p class="hide show-gt-md"><var:string label:value="This message contains external images."/></p>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button label:aria-label="Load Images"
|
||||
ng-click="viewer.message.loadUnsafeContent()">
|
||||
<var:string label:value="Load Images"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-whiteframe>
|
||||
|
||||
<!-- Send MDN -->
|
||||
<md-whiteframe class="md-whiteframe-z2" layout="column" layout-align="center start"
|
||||
ng-show="viewer.message.shouldAskReceipt == 1">
|
||||
<div layout="row" layout-align="start center">
|
||||
<div class="md-tile-left">
|
||||
<md-icon>message</md-icon>
|
||||
</div>
|
||||
<p class="sg-padded--right"><var:string label:value="The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?"/></p>
|
||||
</div>
|
||||
<div class="layout-fill" layout="row" layout-align="end center">
|
||||
<md-button label:aria-label="No"
|
||||
type="button"
|
||||
ng-click="viewer.message.shouldAskReceipt = 0"><var:string label:value="No"/></md-button>
|
||||
<md-button label:aria-label="Yes"
|
||||
type="submit"
|
||||
ng-click="viewer.message.$sendMDN()"><var:string label:value="Yes"/></md-button>
|
||||
</div>
|
||||
</md-whiteframe>
|
||||
|
||||
<div class="msg-body">
|
||||
<div layout="row" layout-wrap="layout-wrap">
|
||||
<div class="mailer_mailcontent" layout="row" layout-wrap="layout-wrap"
|
||||
ng-repeat="part in viewer.message.$content()"
|
||||
ng-class="part.msgclass">
|
||||
<div ng-if="part.html" ng-bind-html="part.content | ensureTarget"><!-- msg --></div>
|
||||
<div ng-if="part.compile" sg-compile="part.content" sg-zoomable-image="sg-zoomable-image"><!-- msg --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
||||
<div layout="row" layout-wrap="layout-wrap">
|
||||
<div ng-class="part.msgclass" layout="row" layout-wrap="layout-wrap" class="mailer_mailcontent" ng-repeat="part in viewer.message.$content()">
|
||||
<div ng-if="part.html" ng-bind-html="part.content"><!-- msg --></div>
|
||||
<div ng-if="part.compile" sg-compile="part.content"><!-- msg --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</md-content>
|
||||
</md-content>
|
||||
</div>
|
||||
</container>
|
||||
|
||||
@@ -15,17 +15,23 @@
|
||||
MUST be the first html element after body
|
||||
SHOULD be a main tag (with role="main")
|
||||
-->
|
||||
<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">
|
||||
|
||||
<main class="view layout-fill layout-padding md-default-theme md-background md-hue-1 md-bg"
|
||||
ui-view="login"
|
||||
layout="row" layout-align="center start"
|
||||
ng-controller="LoginController as app">
|
||||
<md-content class="ng-cloak md-whiteframe-z1"
|
||||
layout="row" layout-align="center center"
|
||||
layout-xs="column" layout-align-xs="space-between center"
|
||||
md-scroll-y="true"
|
||||
ng-show="app.showLogin">
|
||||
<div id="logo" class="md-padding">
|
||||
<img const:alt="*" id="splash" rsrc:src="img/sogo-full.svg"/>
|
||||
</div>
|
||||
<div class="sg-login md-padding md-default-theme md-bg md-accent layout-fill">
|
||||
<script type="text/javascript">
|
||||
var cookieUsername = '<var:string var:value="cookieUsername" const:escapeHTML="NO"/>';
|
||||
</script>
|
||||
<div id="login">
|
||||
<div id="logo">
|
||||
<img const:alt="*" id="splash" rsrc:src="img/sogo-full.svg"/>
|
||||
</div>
|
||||
|
||||
<form name="loginForm" layout="column"
|
||||
ng-cloak="ng-cloak"
|
||||
@@ -44,10 +50,8 @@
|
||||
|
||||
<!-- CONNECT BUTTON -->
|
||||
<div layout="row" layout-align="end center">
|
||||
<md-button class="md-raised" type="submit" ng-disabled='app.loginForm.$invalid'>
|
||||
<span>
|
||||
<var:string label:value="Connect"/>
|
||||
</span>
|
||||
<md-button class="md-primary md-hue-1" type="submit" ng-disabled='app.loginForm.$invalid'>
|
||||
<var:string label:value="Connect"/>
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
@@ -84,10 +88,10 @@
|
||||
</div>
|
||||
</form>
|
||||
<div layout="row" layout-align="end end" ng-cloak="ng-cloak">
|
||||
<md-button class="sg-icon-button fg-sogoPaper-500"
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="About"
|
||||
ng-click="app.showAbout()">
|
||||
<md-icon class="material-icons fg-sogoPaper-500">info</md-icon>
|
||||
<md-icon class="md-fg">info</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,17 +100,17 @@
|
||||
</main>
|
||||
|
||||
<script type="text/ng-template" id="aboutBox.html">
|
||||
<md-dialog flex="50">
|
||||
<md-dialog-content>
|
||||
<md-dialog flex="50" sm-flex="100">
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<p><a href="http://sogo.nu/" target="_new">sogo.nu</a></p>
|
||||
<p>Version <var:string value="version"/> (<var:string value="buildDate" />)</p>
|
||||
<br/>
|
||||
<p><var:string label:value="AboutBox" const:escapeHTML="NO"/></p>
|
||||
<!--<img class="full-image" const:alt="Inverse" rsrc:src="img/inverse.png"/>-->
|
||||
</md-dialog-content>
|
||||
<div class="md-actions">
|
||||
<md-dialog-actions>
|
||||
<md-button ng-click="about.closeDialog()"><var:string label:value="Close"/></md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
className="UIxPageFrame"
|
||||
>
|
||||
<md-dialog flex="50" flex-sm="100">
|
||||
<md-toolbar class="md-padding">
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">account_box</md-icon>
|
||||
<md-input-container>
|
||||
@@ -24,7 +24,7 @@
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
|
||||
<form id="mainForm" name="accountForm" var:href="ownPath">
|
||||
|
||||
@@ -136,8 +136,8 @@
|
||||
|
||||
</form>
|
||||
</md-dialog-content>
|
||||
<div class="md-actions">
|
||||
<md-dialog-actions>
|
||||
<md-button ng-disabled="$AccountDialogController.accountForm.$invalid" ng-click="$AccountDialogController.save()"><var:string label:value="Save"/></md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</var:component>
|
||||
|
||||
@@ -8,20 +8,20 @@
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:uix="OGo:uix"><var:string var:value="doctype" const:escapeHTML="NO" />
|
||||
<md-dialog flex="50" flex-sm="100">
|
||||
<form id="mainForm" var:href="ownPath">
|
||||
<md-toolbar class="md-padding">
|
||||
<form name="mainForm" ng-submit="filterEditor.save(mainForm)">
|
||||
<md-toolbar>
|
||||
<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"/>
|
||||
<input class="md-title" type="text" ng-model="filterEditor.filter.name" required="required"/>
|
||||
</md-input-container>
|
||||
<md-button type="button" class="sg-icon-button " ng-click="cancel()">
|
||||
<md-button type="button" class="sg-icon-button " ng-click="filterEditor.cancel()">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<script type="text/javascript">
|
||||
var filterId = '<var:string value="filterId"/>';
|
||||
var sieveFolderEncoding = '<var:string value="sieveFolderEncoding"/>';
|
||||
@@ -29,9 +29,9 @@
|
||||
</script>
|
||||
|
||||
<div layout="row" layout-align="start center">
|
||||
<div><var:string label:value="For incoming messages that"/></div>
|
||||
<var:string label:value="For incoming messages that"/>
|
||||
<md-input-container class="md-flex">
|
||||
<md-select ng-model="filter.match" required="required">
|
||||
<md-select ng-model="filterEditor.filter.match" required="required">
|
||||
<md-option const:value="all">
|
||||
<var:string label:value="match all of the following rules"/>
|
||||
</md-option>
|
||||
@@ -49,10 +49,10 @@
|
||||
<div layout="column">
|
||||
<div id="filterRules"><!-- empty -->
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="rule in filter.rules">
|
||||
<md-list-item ng-repeat="rule in filterEditor.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-option ng-value="key" ng-repeat="(key, value) in filterEditor.fieldLabels">{{ value }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
<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">
|
||||
<md-option ng-value="key" ng-repeat="(key, value) in filterEditor.numberOperatorLabels">
|
||||
{{ value }}
|
||||
</md-option>
|
||||
</md-select>
|
||||
@@ -70,18 +70,18 @@
|
||||
|
||||
<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">
|
||||
<md-option ng-value="key" ng-repeat="(key, value) in filterEditor.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 class="md-flex" md-no-float="md-no-float">
|
||||
<input type="text" label:placeholder="Value" ng-model="rule.value"/>
|
||||
</md-input-container>
|
||||
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
ng-click="removeMailFilterRule($index)">
|
||||
ng-click="filterEditor.removeMailFilterRule($index)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
<div layout="row" layout-align="end center">
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
ng-click="addMailFilterRule($event)">
|
||||
ng-click="filterEditor.addMailFilterRule($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
@@ -104,10 +104,10 @@
|
||||
|
||||
<md-list>
|
||||
<md-list-item layout="row" layout-align="space-between center"
|
||||
ng-repeat="action in filter.actions">
|
||||
ng-repeat="action in filterEditor.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-option ng-value="key" ng-repeat="(key, value) in filterEditor.methodLabels">{{ value }}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
@@ -130,8 +130,10 @@
|
||||
<!-- 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 ng-value="item.path" ng-repeat="item in filterEditor.mailboxes">
|
||||
<div ng-class="'sg-child-level-' + item.level">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
@@ -153,7 +155,7 @@
|
||||
<!-- nada -->
|
||||
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
ng-click="removeMailFilterAction($index)">
|
||||
ng-click="filterEditor.removeMailFilterAction($index)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
|
||||
@@ -162,15 +164,15 @@
|
||||
|
||||
<div layout="row" layout-align="end center">
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
ng-click="addMailFilterAction($event)">
|
||||
ng-click="filterEditor.addMailFilterAction($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
<div class="md-actions">
|
||||
<md-button type="button" ng-click="save()"><var:string label:value="Save"/></md-button>
|
||||
</div>
|
||||
<md-dialog-actions>
|
||||
<md-button type="submit"><var:string label:value="Save"/></md-button>
|
||||
</md-dialog-actions>
|
||||
</form>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -24,29 +24,33 @@
|
||||
<script type="text/ng-template" id="preferences.html">
|
||||
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="$mdMedia('gt-md')" layout="column">
|
||||
<var:component className="UIxSidenavToolbarTemplate" />
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex">
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex md-hue-2">
|
||||
<md-list>
|
||||
<md-list-item ng-click="app.go('general')"
|
||||
ui-sref="preferences.general"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>settings</md-icon>
|
||||
<p class="sg-item-name"><var:string label:value="General"/></p>
|
||||
</md-list-item>
|
||||
<var:if condition="userHasCalendarAccess">
|
||||
<md-list-item ng-click="app.go('calendars')"
|
||||
ui-sref="preferences.calendars"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>event</md-icon>
|
||||
<p class="sg-item-name"><var:string label:value="Calendar"/></p>
|
||||
</md-list-item>
|
||||
</var:if>
|
||||
<md-list-item ng-click="app.go('addressbooks')"
|
||||
ui-sref="preferences.addressbooks"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>contacts</md-icon>
|
||||
<p class="sg-item-name"><var:string label:value="Contacts"/></p>
|
||||
</md-list-item>
|
||||
<var:if condition="userHasMailAccess">
|
||||
<md-list-item ng-click="app.go('mailer')"
|
||||
ui-sref="preferences.mailer"
|
||||
ui-sref-active="sg-active">
|
||||
ui-sref-active="md-default-theme md-background md-bg md-hue-1">
|
||||
<md-icon>email</md-icon>
|
||||
<p class="sg-item-name"><var:string label:value="Mail"/></p>
|
||||
</md-list-item>
|
||||
</var:if>
|
||||
@@ -58,7 +62,7 @@
|
||||
|
||||
<!-- TOP RIGHT TOOLBAR -->
|
||||
<md-toolbar layout="row" layout-align="space-between start" class="md-tall">
|
||||
<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>
|
||||
<md-button type="button" class="md-fab md-fab-bottom-right md-fab-overlap-bottom"
|
||||
@@ -96,7 +100,8 @@
|
||||
<div flex="50">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Language"/></label>
|
||||
<md-select ng-model="app.preferences.defaults.SOGoLanguage">
|
||||
<md-select ng-model="app.preferences.defaults.SOGoLanguage"
|
||||
ng-change="app.onLanguageChange()">
|
||||
<var:foreach list="languages" item="item">
|
||||
<md-option var:value="item">
|
||||
<var:string value="languageText"/>
|
||||
@@ -180,6 +185,17 @@
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Alternate Avatar"/></label>
|
||||
<md-select ng-model="app.preferences.defaults.SOGoAlternateAvatar">
|
||||
<var:foreach list="alternateAvatar" item="item">
|
||||
<md-option var:value="item">
|
||||
<var:string value="itemAlternateAvatarText"/>
|
||||
</md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</md-content>
|
||||
</md-tab>
|
||||
@@ -345,11 +361,10 @@
|
||||
ng-repeat="item in
|
||||
app.preferences.defaults.SOGoCalendarCategories
|
||||
track by $index">
|
||||
<i class="md-avatar" ng-style="{'background-color': app.preferences.defaults.SOGoCalendarCategoriesColors[item]}">
|
||||
<sg-color-picker sg-on-select="app.preferences.defaults.SOGoCalendarCategoriesColors[item] = color"><!-- color picker--></sg-color-picker>
|
||||
</i>
|
||||
<sg-color-picker ng-model="app.preferences.defaults.SOGoCalendarCategoriesColors[item]"><!-- color picker--></sg-color-picker>
|
||||
<md-input-container>
|
||||
<input type="text" label:aria-label="Calendar Category" ng-model="app.preferences.defaults.SOGoCalendarCategories[$index]"/>
|
||||
<input type="text" label:aria-label="Calendar Category"
|
||||
ng-model="app.preferences.defaults.SOGoCalendarCategories[$index]"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
layout="row" layout-align="end center"
|
||||
@@ -600,7 +615,7 @@
|
||||
<input type="text" ng-model="app.preferences.defaults.SOGoSieveFilters[$index].name"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
ng-click="app.editMailFilter($index)"
|
||||
ng-click="app.editMailFilter($event, $index)"
|
||||
layout="row" layout-align="end center"
|
||||
label:aria-label="Edit Filter">
|
||||
<md-icon>edit</md-icon>
|
||||
@@ -637,9 +652,7 @@
|
||||
<md-list-item flex="50"
|
||||
ng-repeat="(key, value) in
|
||||
app.preferences.defaults.SOGoMailLabelsColors">
|
||||
<i class="md-avatar" ng-style="{'background-color': value[1]}">
|
||||
<sg-color-picker sg-on-select="value[1] = color"><!-- color picker--></sg-color-picker>
|
||||
</i>
|
||||
<sg-color-picker ng-model="value[1]"><!-- color picker--></sg-color-picker>
|
||||
<md-input-container>
|
||||
<input type="text"
|
||||
label:aria-label="Label"
|
||||
@@ -668,7 +681,7 @@
|
||||
<!-- MAIL > ACCOUNTS -->
|
||||
<md-tab id="mailAccountsTab"
|
||||
aria-controls="mailAccountsTab-content"
|
||||
label:label="Accounts">
|
||||
label:label="IMAP Accounts">
|
||||
|
||||
<md-list class="sg-padded">
|
||||
<md-list-item ng-repeat="item in
|
||||
@@ -765,7 +778,7 @@
|
||||
<var:string label:value="Do not send responses to mailing lists" />
|
||||
</md-checkbox>
|
||||
|
||||
<div layout="row" layout-align="end center">
|
||||
<div layout="row" layout-align="start center">
|
||||
<md-checkbox
|
||||
ng-model="app.preferences.defaults.Vacation.endDateEnabled"
|
||||
ng-true-value="1"
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label">
|
||||
<md-dialog flex="60" flex-sm="100">
|
||||
<md-dialog flex="60" flex-md="80" flex-sm="100">
|
||||
<form name="eventForm" ng-submit="editor.save(eventForm)">
|
||||
<md-toolbar class="sg-padded" ng-class="editor.component.getClassName('bg')">
|
||||
<md-toolbar ng-class="editor.component.getClassName('bg')">
|
||||
<div class="md-toolbar-tools">
|
||||
<!-- summary -->
|
||||
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
|
||||
@@ -23,191 +23,212 @@
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<!-- location -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Location"/></label>
|
||||
<input type="text" ng-model="editor.component.location"/>
|
||||
</md-input-container>
|
||||
<!-- calendar -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar">
|
||||
<md-option ng-repeat="calendar in ::editor.calendars"
|
||||
ng-value="calendar.id">{{calendar.name}}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<!-- categories -->
|
||||
<md-chips ng-model="editor.component.categories">
|
||||
<md-autocomplete
|
||||
md-selected-item="editor.categories.selected"
|
||||
md-search-text="editor.categories.searchText"
|
||||
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
|
||||
label:placeholder="Add a category">
|
||||
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
<!-- classification -->
|
||||
<md-radio-group layout="row" layout-align="space-around center"
|
||||
ng-model="editor.component.classification">
|
||||
<md-radio-button value="public">
|
||||
<var:string label:value="label_Public"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="confidential">
|
||||
<var:string label:value="label_Confidential"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="private">
|
||||
<var:string label:value="label_Private"/>
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
<!-- priority -->
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Priority"/></label>
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.priority"
|
||||
step="1"
|
||||
min="0"
|
||||
max="9"
|
||||
label:aria-label="Priority"><!-- slider --></md-slider>
|
||||
</div>
|
||||
<!-- is all day -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.isAllDay"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="All day Event">
|
||||
<var:string label:value="All day Event"/>
|
||||
</md-checkbox>
|
||||
<!-- is transparent -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.isTransparent"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Show Time as Free">
|
||||
<var:string label:value="Show Time as Free"/>
|
||||
</md-checkbox>
|
||||
<!-- send appointment notifications -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.sendAppointmentNotifications"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Send Appointment Notifications">
|
||||
<var:string label:value="Send Appointment Notifications"/>
|
||||
</md-checkbox>
|
||||
<!-- start + end -->
|
||||
<div layout="row">
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<!-- location -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="From"/></label>
|
||||
<input type="text" ng-model="editor.component.startDate" required="required"/>
|
||||
<label><var:string label:value="Location"/></label>
|
||||
<input type="text" ng-model="editor.component.location"/>
|
||||
</md-input-container>
|
||||
<!-- calendar -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="To"/></label>
|
||||
<input type="text" ng-model="editor.component.endDate" required="required"/>
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar">
|
||||
<md-option ng-repeat="calendar in ::editor.calendars"
|
||||
ng-value="calendar.id">{{calendar.name}}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- attach urls -->
|
||||
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
|
||||
<div layout="row" layout-align="center end">
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="URL"/>
|
||||
</label>
|
||||
<input type="text" ng-model="attach.value"
|
||||
sg-focus-on="attachUrl_{{$index}}"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.component.deleteAttachUrl($index)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
<!-- categories -->
|
||||
<md-chips ng-model="editor.component.categories">
|
||||
<md-autocomplete
|
||||
md-selected-item="editor.categories.selected"
|
||||
md-search-text="editor.categories.searchText"
|
||||
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
|
||||
md-min-length="0"
|
||||
label:placeholder="Add a category">
|
||||
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
<!-- classification -->
|
||||
<md-radio-group layout="row" layout-align="space-around center"
|
||||
ng-model="editor.component.classification">
|
||||
<md-radio-button value="public">
|
||||
<var:string label:value="label_Public"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="confidential">
|
||||
<var:string label:value="label_Confidential"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="private">
|
||||
<var:string label:value="label_Private"/>
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
<!-- priority -->
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Priority"/></label>
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.priority"
|
||||
step="1"
|
||||
min="0"
|
||||
max="9"
|
||||
label:aria-label="Priority"><!-- slider --></md-slider>
|
||||
</div>
|
||||
<!-- is all day -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.isAllDay"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="All day Event">
|
||||
<var:string label:value="All day Event"/>
|
||||
</md-checkbox>
|
||||
<!-- is transparent -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.isTransparent"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Show Time as Free">
|
||||
<var:string label:value="Show Time as Free"/>
|
||||
</md-checkbox>
|
||||
<!-- send appointment notifications -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.sendAppointmentNotifications"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Send Appointment Notifications">
|
||||
<var:string label:value="Send Appointment Notifications"/>
|
||||
</md-checkbox>
|
||||
<!-- start + end -->
|
||||
<div layout="row">
|
||||
<div flex="50">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="From"/></label>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" layout-wrap="layout-wrap">
|
||||
<md-datepicker ng-model="editor.component.start"
|
||||
ng-change="editor.updateStartTime()"
|
||||
label:md-placeholder="From"><!-- date picker --></md-datepicker>
|
||||
<sg-timepicker ng-model="editor.component.start"
|
||||
ng-change="editor.adjustStartTime()"
|
||||
ng-hide="editor.component.isAllDay"><!-- time picker --></sg-timepicker>
|
||||
</div>
|
||||
</div>
|
||||
<div flex="50">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="To"/></label>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" layout-wrap="layout-wrap">
|
||||
<md-datepicker ng-model="editor.component.end"
|
||||
ng-change="editor.updateEndTime()"
|
||||
label:md-placeholder="To"><!-- date picker --></md-datepicker>
|
||||
<sg-timepicker ng-model="editor.component.end"
|
||||
ng-change="editor.adjustEndTime()"
|
||||
ng-hide="editor.component.isAllDay"><!-- time picker --></sg-timepicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- attach urls -->
|
||||
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
|
||||
<div layout="row" layout-align="center end">
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="URL"/>
|
||||
</label>
|
||||
<input type="text" ng-model="attach.value"
|
||||
sg-focus-on="attachUrl_{{$index}}"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.component.deleteAttachUrl($index)">
|
||||
<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.addAttachUrl($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label">
|
||||
<var:string label:value="Attach"/>
|
||||
</label>
|
||||
</div>
|
||||
<!-- comment -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Description"/></label>
|
||||
<textarea ng-model="editor.component.comment"><!-- comment --></textarea>
|
||||
</md-input-container>
|
||||
<!-- repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div class="md-flex">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Repeat"/></label>
|
||||
<md-select ng-model="editor.component.repeat.frequency" ng-disabled="editor.component.occurrenceId">
|
||||
<var:foreach list="repeatList" item="item">
|
||||
<md-option var:value="item"><var:string var:value="itemRepeatText"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<md-button type="button" class="sg-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-disabled="editor.component.occurrenceId"
|
||||
ng-show="editor.component.repeat.frequency != 'never'"
|
||||
ng-click="editor.toggleRecurrenceEditor()">
|
||||
<md-icon ng-class="{'md-rotate-45': editor.showRecurrenceEditor}">add</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.addAttachUrl($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label">
|
||||
<var:string label:value="Attach"/>
|
||||
</label>
|
||||
</div>
|
||||
<!-- comment -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Description"/></label>
|
||||
<textarea ng-model="editor.component.comment"><!-- comment --></textarea>
|
||||
</md-input-container>
|
||||
<!-- repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div class="md-flex">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Repeat"/></label>
|
||||
<md-select ng-model="editor.component.repeat.frequency" ng-disabled="editor.component.occurrenceId">
|
||||
<var:foreach list="repeatList" item="item">
|
||||
<md-option var:value="item"><var:string var:value="itemRepeatText"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
<div ng-show="editor.showRecurrenceEditor" class="sg-subcontent">
|
||||
<var:component className="UIxRecurrenceEditor" />
|
||||
</div>
|
||||
<!-- end repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div ng-show="editor.component.repeat.frequency != 'never'">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="End Repeat"/></label>
|
||||
<md-select ng-model="editor.component.repeat.end"
|
||||
ng-disabled="editor.component.occurrenceId">
|
||||
<md-option value="never"><var:string label:value="Never"/></md-option>
|
||||
<md-option value="count"><var:string label:value="After"/></md-option>
|
||||
<md-option value="until"><var:string label:value="On Date"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" ng-show="editor.component.repeat.end == 'count'">
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="times" ng-model="editor.component.repeat.count"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="times"/>
|
||||
</div>
|
||||
<md-input-container ng-show="editor.component.repeat.end == 'until'">
|
||||
<input type="date" label:aria-label="Repeat until" ng-model="editor.component.repeat.until"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<md-button type="button" class="sg-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-show="editor.component.repeat.frequency != 'never'"
|
||||
ng-click="editor.toggleRecurrenceEditor()">
|
||||
<md-icon ng-class="{'md-rotate-45': editor.showRecurrenceEditor}">add</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div ng-show="editor.showRecurrenceEditor" class="sg-subcontent">
|
||||
<var:component className="UIxRecurrenceEditor" />
|
||||
</div>
|
||||
<!-- end repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div ng-show="editor.component.repeat.frequency != 'never'">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="End Repeat"/></label>
|
||||
<md-select ng-model="editor.component.repeat.end">
|
||||
<md-option value="never"><var:string label:value="Never"/></md-option>
|
||||
<md-option value="count"><var:string label:value="After"/></md-option>
|
||||
<md-option value="until"><var:string label:value="On Date"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<!-- attendees -->
|
||||
<div layout="row" layout-align="start start">
|
||||
<md-autocomplete class="md-flex"
|
||||
label:md-floating-label="Invite Attendees"
|
||||
md-selected-item="attendeeToAdd"
|
||||
md-search-text="editor.searchText"
|
||||
md-selected-item-change="editor.addAttendee(card)"
|
||||
md-items="card in editor.cardFilter(editor.searchText)"
|
||||
md-item-text="card.empty"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
sg-enter="editor.addAttendee(editor.searchText)">
|
||||
<md-item-template>
|
||||
<div class="md-contact-suggestion">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="editor.searchText"
|
||||
md-highlight-flags="^i">{{card.$$fullname}}</span>
|
||||
<span class="md-contact-email"
|
||||
md-highlight-text="editor.searchText"
|
||||
md-highlight-flags="^i">{{card.$$email}}</span>
|
||||
</div>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
<md-button type="button" class="sg-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-click="editor.toggleAttendeesEditor()">
|
||||
<md-icon ng-class="{'md-rotate-180': editor.showAttendeesEditor}">expand_more</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" ng-show="editor.component.repeat.end == 'count'">
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="times" ng-model="editor.component.repeat.count"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="times"/>
|
||||
</div>
|
||||
<md-input-container ng-show="editor.component.repeat.end == 'until'">
|
||||
<input type="date" label:aria-label="Repeat until" ng-model="editor.component.repeat.until"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- attendees -->
|
||||
<div layout="row" layout-align="start start">
|
||||
<md-autocomplete class="md-flex"
|
||||
label:md-floating-label="Invite Attendees"
|
||||
md-selected-item="attendeeToAdd"
|
||||
md-search-text="editor.searchText"
|
||||
md-selected-item-change="editor.addAttendee(card)"
|
||||
md-items="card in editor.cardFilter(editor.searchText)"
|
||||
md-item-text="card.empty"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
sg-enter="editor.addAttendee(editor.searchText)">
|
||||
<md-item-template>
|
||||
<div class="md-contact-suggestion" layout="row" layout-align="space-between center">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="editor.searchText"
|
||||
md-highlight-flags="^i">{{card.$$fullname}}</span>
|
||||
<span class="md-contact-email"
|
||||
md-highlight-text="editor.searchText"
|
||||
md-highlight-flags="^i">{{card.$$email}}</span>
|
||||
</div>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
<md-button type="button" class="sg-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-click="editor.toggleAttendeesEditor()">
|
||||
<md-icon ng-class="{'md-rotate-180': editor.showAttendeesEditor}">expand_more</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<!-- md-contact-chips don't support "readonly", so we build them using md-chips
|
||||
in readonly mode and a template similar to the one of md-contact-chips -->
|
||||
<md-chips class="md-contact-chips sg-readonly"
|
||||
@@ -215,37 +236,42 @@
|
||||
ng-hide="editor.showAttendeesEditor"
|
||||
readonly="true">
|
||||
<md-chip-template>
|
||||
<div class="md-contact-avatar"><img src="#" ng-src="{{$chip.image}}" alt="{{$chip.name}}"/></div>
|
||||
<div class="md-contact-name">{{$chip.name}}</div>
|
||||
<div class="md-contact-avatar">
|
||||
<sg-avatar-image sg-email="$chip.email" size="32"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="md-contact-name">{{$chip.name || $chip.email}}</div>
|
||||
<md-icon ng-class="'icon-' + $chip.status"><!-- partstat --></md-icon>
|
||||
<md-icon class="sg-chip-remove"
|
||||
label:aria-label="Delete"
|
||||
ng-click="editor.component.deleteAttendee($chip)">close</md-icon>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
<div ng-show="editor.showAttendeesEditor" class="sg-subcontent attendees">
|
||||
<var:component className="UIxAttendeesEditor" />
|
||||
</div>
|
||||
<!-- reminder -->
|
||||
<md-checkbox ng-model="editor.component.$hasAlarm"
|
||||
label:aria-label="Reminder">
|
||||
<var:string label:value="Reminder"/>
|
||||
</md-checkbox>
|
||||
<div class="sg-subcontent"
|
||||
ng-show="editor.component.$hasAlarm">
|
||||
<var:component className="UIxReminderEditor" />
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
<div ng-show="editor.showAttendeesEditor" class="attendees">
|
||||
<var:component className="UIxAttendeesEditor" />
|
||||
</div>
|
||||
<!-- reminder -->
|
||||
<md-checkbox ng-model="editor.component.$hasAlarm"
|
||||
label:aria-label="Reminder">
|
||||
<var:string label:value="Reminder"/>
|
||||
</md-checkbox>
|
||||
<div class="sg-subcontent"
|
||||
ng-show="editor.component.$hasAlarm">
|
||||
<var:component className="UIxReminderEditor" />
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
<!-- cancel/reset/save -->
|
||||
<div class="md-actions">
|
||||
<md-dialog-actions>
|
||||
<md-button type="button" ng-click="editor.cancel()">
|
||||
<var:string label:value="Cancel"/>
|
||||
</md-button>
|
||||
<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" type="submit"
|
||||
ng-disabled="editor.eventForm.$invalid">
|
||||
<var:string label:value="Save"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</form>
|
||||
</md-dialog>
|
||||
</md-dialog-actions>
|
||||
</form>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -4,25 +4,38 @@
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label">
|
||||
<md-dialog flex="40" flex-md="60" flex-sm="100">
|
||||
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">event</md-icon>
|
||||
<div class="sg-md-title md-flex">
|
||||
<!-- classification -->
|
||||
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
|
||||
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
|
||||
<!-- summary -->
|
||||
{{::editor.component.summary}}
|
||||
<!-- priority -->
|
||||
<md-icon ng-repeat="i in ::editor.component.priority | range">star</md-icon>
|
||||
</div>
|
||||
<md-button class="md-icon-button" ng-click="editor.close()">
|
||||
<md-icon aria-label="Close dialog">close</md-icon>
|
||||
</md-button>
|
||||
<md-dialog flex="40" flex-md="80" flex-sm="100">
|
||||
<md-toolbar ng-class="editor.component.getClassName('bg')">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">event</md-icon>
|
||||
<div class="sg-md-title md-flex">
|
||||
<!-- classification -->
|
||||
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
|
||||
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
|
||||
<!-- summary -->
|
||||
{{::editor.component.summary}}
|
||||
<!-- priority -->
|
||||
<md-icon ng-repeat="i in ::editor.component.priority | range">star</md-icon>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<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>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="md-icon-button" ng-click="editor.close()">
|
||||
<md-icon label:aria-label="Close">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<md-list>
|
||||
<!-- categories -->
|
||||
<md-list-item ng-show="editor.component.categories.length > 0">
|
||||
@@ -45,17 +58,15 @@
|
||||
<!-- start/end dates -->
|
||||
<md-list-item ng-class="{ 'md-2-line': editor.component.isAllDay, 'md-3-line': !editor.component.isAllDay }">
|
||||
<md-icon>access_time</md-icon>
|
||||
<div layout="row" class="md-flex">
|
||||
<div class="md-list-item-text" ng-show="editor.component.startDate">
|
||||
<p><var:string label:value="Start"/></p>
|
||||
<h3>{{::editor.component.localizedStartDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay">{{::editor.component.localizedStartTime}}</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.endDate">
|
||||
<p><var:string label:value="End"/></p>
|
||||
<h3>{{::editor.component.localizedEndDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay">{{::editor.component.localizedEndTime}}</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.startDate">
|
||||
<p><var:string label:value="Start"/></p>
|
||||
<h3>{{::editor.component.localizedStartDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay">{{::editor.component.localizedStartTime}}</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.endDate">
|
||||
<p><var:string label:value="End"/></p>
|
||||
<h3>{{::editor.component.localizedEndDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay">{{::editor.component.localizedEndTime}}</h3>
|
||||
</div>
|
||||
</md-list-item>
|
||||
<!-- is transparent -->
|
||||
@@ -81,14 +92,14 @@
|
||||
<!-- repeat -->
|
||||
<md-list-item ng-show="editor.component.$isRecurrent">
|
||||
<md-icon>repeat</md-icon>
|
||||
<p><!-- editor.component.repeat.toString() --></p>
|
||||
<p>{{editor.component.repeatDescription()}}</p>
|
||||
</md-list-item>
|
||||
<!-- reminder -->
|
||||
<md-list-item ng-show="editor.component.$hasAlarm" ng-hide="editor.component.userHasRSVP">
|
||||
<md-list-item ng-hide="!editor.component.$hasAlarm || editor.component.userHasRSVP">
|
||||
<md-icon>alarm_on</md-icon>
|
||||
<p><!-- editor.component.alarm.toString() --></p>
|
||||
<p>{{editor.component.alarmDescription()}}</p>
|
||||
</md-list-item>
|
||||
<md-list-item class="md-2-line" ng-show="editor.component.organizer">
|
||||
<md-list-item layout-align="start start" ng-show="editor.component.organizer">
|
||||
<md-icon>people</md-icon>
|
||||
<div layout="column" layout-fill="layout-fill">
|
||||
<!-- organizer -->
|
||||
@@ -98,7 +109,9 @@
|
||||
ng-model="::editor.organizer"
|
||||
readonly="true">
|
||||
<md-chip-template>
|
||||
<div class="md-contact-avatar"><img src="#" ng-src="{{$chip.$image}}" alt="{{$chip.name}}"/></div>
|
||||
<div class="md-contact-avatar">
|
||||
<sg-avatar-image sg-email="$chip.email" size="32"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="md-contact-name">{{$chip.name}}</div>
|
||||
</md-chip-template>
|
||||
</md-chips>
|
||||
@@ -112,7 +125,9 @@
|
||||
ng-model="::editor.component.attendees"
|
||||
readonly="true">
|
||||
<md-chip-template>
|
||||
<div class="md-contact-avatar"><img src="#" ng-src="{{$chip.image}}" alt="{{$chip.name}}"/></div>
|
||||
<div class="md-contact-avatar">
|
||||
<sg-avatar-image sg-email="$chip.email" size="32"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div class="md-contact-name">{{$chip.name}}</div>
|
||||
<md-icon ng-class="'icon-' + $chip.status"><!-- partstat --></md-icon>
|
||||
</md-chip-template>
|
||||
@@ -123,7 +138,7 @@
|
||||
</md-list>
|
||||
<!-- invitation -->
|
||||
<md-list ng-show="editor.component.userHasRSVP">
|
||||
<md-divider><!-- dividerd --></md-divider>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
<md-subheader class="md-no-sticky sg-padded--top"><var:string label:value="You are invited to participate"/></md-subheader>
|
||||
<!-- participation status -->
|
||||
<md-list-item>
|
||||
@@ -170,32 +185,96 @@
|
||||
<span ng-show="editor.component.$hasAlarm"><var:component className="UIxReminderEditor" /></span>
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
|
||||
<!-- actions -->
|
||||
<div class="md-actions" ng-show="editor.component.isEditable()">
|
||||
|
||||
<!-- editable but not recurrent -->
|
||||
<md-dialog-actions ng-show="editor.component.isEditable()">
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" ng-click="editor.edit()">
|
||||
<var:string label:value="Edit"/>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="md-actions" ng-show="editor.component.isEditableOccurrence()">
|
||||
</md-dialog-actions>
|
||||
<!-- editable and recurrent -->
|
||||
<md-dialog-actions ng-show="editor.component.isEditableOccurrence()">
|
||||
<md-menu>
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<var:string label:value="Delete"/> <md-icon>arrow_drop_down</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteOccurrence()">
|
||||
<var:string label:value="Delete This Occurrence"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete All Occurrences"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" ng-click="editor.editAllOccurrences()">
|
||||
<var:string label:value="Edit All Occurrences"/>
|
||||
</md-button>
|
||||
<md-button type="button" ng-click="editor.edit()">
|
||||
<var:string label:value="Edit This Occurrence"/>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="md-actions" ng-show="editor.component.isInvitation()">
|
||||
</md-dialog-actions>
|
||||
<!-- invitation but not recurrent -->
|
||||
<md-dialog-actions ng-show="editor.component.isInvitation()">
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" ng-click="editor.reply()">
|
||||
<var:string label:value="Update"/>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="md-actions" ng-show="editor.component.isInvitationOccurrence()">
|
||||
</md-dialog-actions>
|
||||
<!-- invitation and recurrent -->
|
||||
<md-dialog-actions ng-show="editor.component.isInvitationOccurrence()">
|
||||
<md-menu>
|
||||
<md-button class="md-warn"
|
||||
label:aria-label="Delete Event"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteOccurrence()">
|
||||
<var:string label:value="Delete This Occurrence"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete All Occurrences"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" ng-click="editor.replyAllOccurrences()">
|
||||
<var:string label:value="Update All Occurrences"/>
|
||||
</md-button>
|
||||
<md-button type="button" ng-click="editor.reply()">
|
||||
<var:string label:value="Update This Occurrence"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -14,15 +14,21 @@
|
||||
<!-- attendees -->
|
||||
<md-list>
|
||||
<md-list-item>
|
||||
<div><!-- empty --></div>
|
||||
<div class="md-tile-left"><!-- empty --></div>
|
||||
</md-list-item>
|
||||
<md-list-item ng-repeat="currentAttendee in editor.component.attendees track by currentAttendee.email">
|
||||
<sg-avatar-image sg-email="currentAttendee.email"
|
||||
size="32"><!-- avatar --></sg-avatar-image>
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="currentAttendee.email"
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead-multi">{{currentAttendee.name}}</div>
|
||||
<div class="sg-md-body-multi">{{currentAttendee.email}}</div>
|
||||
<div class="sg-md-subhead"><div>{{currentAttendee.name}}</div></div>
|
||||
<div class="sg-md-body"><div>{{currentAttendee.email}}</div></div>
|
||||
</div>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Delete"
|
||||
ng-click="editor.component.deleteAttendee(currentAttendee)">
|
||||
<md-icon>close</md-icon>
|
||||
</md-button>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
<!-- freebusy -->
|
||||
|
||||
@@ -1,115 +1,125 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<div var:class="daysViewClasses">
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<md-toolbar class="daysView md-hue-1" var:sg-view="currentView">
|
||||
|
||||
<!-- MultiColumnView -->
|
||||
<!-- Display the name of the calendar -->
|
||||
<var:if condition="isMultiColumnView">
|
||||
<div class="calendarLabels">
|
||||
<var:foreach list="calendarsToDisplay" item="currentCalendar">
|
||||
<div class="calendarsToDisplay" var:folder="currentCalendar.folder">
|
||||
<var:string value="labelForCalendar"/>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
|
||||
<!-- Display today abreviation and date -->
|
||||
<div class="days dayLabels">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses">
|
||||
<var:string value="labelForDate"/><br/>
|
||||
<span class="dayOfWeek"><var:string value="labelForDay"/></span>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
|
||||
<!-- All day cells -->
|
||||
<div class="days">
|
||||
<var:foreach list="calendarsToDisplay" item="currentCalendar">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses" var:day="currentTableDay.shortDateString" var:id="currentAllDayId" var:calendar="currentCalendar.folder" hour="allday"><!-- space --></div>
|
||||
</var:foreach>
|
||||
</var:foreach>
|
||||
</div>
|
||||
</var:if>
|
||||
<!-- Display today abreviation and date -->
|
||||
<div class="days dayLabels">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses">
|
||||
<!-- Week view day header -->
|
||||
<var:if condition="isWeekView">
|
||||
<div class="sg-md-caption md-default-theme md-fg md-primary md-hue-1"><var:string value="labelForDay"/></div>
|
||||
<var:if condition="currentTableDay.isToday">
|
||||
<div class="sg-md-display-2 md-default-theme md-fg md-accent md-hue-2"><var:string value="currentTableDay.dayOfMonth"/></div>
|
||||
</var:if>
|
||||
<var:if condition="currentTableDay.isToday" const:negate="YES">
|
||||
<div class="sg-md-display-2--thin md-default-theme md-fg md-hue-2"><var:string value="currentTableDay.dayOfMonth"/></div>
|
||||
</var:if>
|
||||
<div class="md-default-theme md-fg md-primary md-hue-2"><var:string value="labelForMonth"/></div>
|
||||
</var:if>
|
||||
|
||||
<!-- DayView or WeekView -->
|
||||
<var:if condition="isNotMultiColumnView">
|
||||
<!-- Display today abreviation and date -->
|
||||
<div class="days dayLabels">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses">
|
||||
<var:string value="labelForDate"/><br/>
|
||||
<span class="dayOfWeek"><var:string value="labelForDay"/></span>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
|
||||
<!-- All day cells -->
|
||||
<div class="days">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses" var:day="currentTableDay.shortDateString" var:id="currentAllDayId" hour="allday"><!-- space --></div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
</var:if>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- The hours cells -->
|
||||
<div var:class="daysViewClasses">
|
||||
<div class="hours">
|
||||
<var:foreach list="hoursToDisplay" item="currentTableHour">
|
||||
<div class="hour" var:id="currentHourId">
|
||||
<var:string value="currentTableHour"/>
|
||||
<!-- Day view header -->
|
||||
<var:if condition="isWeekView" const:negate="YES">
|
||||
<var:if condition="currentTableDay.isToday">
|
||||
<div class="sg-md-display-4 md-default-theme md-fg md-accent md-hue-2"><var:string value="currentTableDay.dayOfMonth"/></div>
|
||||
</var:if>
|
||||
<var:if condition="currentTableDay.isToday" const:negate="YES">
|
||||
<div class="sg-md-display-4 md-default-theme md-fg md-hue-2"><var:string value="currentTableDay.dayOfMonth"/></div>
|
||||
</var:if>
|
||||
<div class="md-default-theme md-fg md-primary md-hue-2"><var:string value="labelForMonth"/></div>
|
||||
</var:if>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
<div class="days">
|
||||
<!-- MultiColumnView -->
|
||||
<var:if condition="isMultiColumnView">
|
||||
<var:foreach list="calendarsToDisplay" item="currentCalendar">
|
||||
|
||||
<var:if condition="isMultiColumnView">
|
||||
<!-- Calendars names in multicolumn day view -->
|
||||
<div class="days">
|
||||
<div class="day multicolumnDay"
|
||||
ng-repeat="view in calendar.views"
|
||||
ng-class="view.calendar.getClassName('bdr')">
|
||||
{{view.calendar.name}}
|
||||
</div>
|
||||
</div>
|
||||
</var:if>
|
||||
|
||||
<!-- All day cells -->
|
||||
<div class="allDaysView md-default-theme md-background md-bg">
|
||||
<div class="days" sg-calendar-scroll-view="multiday-allday">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<sg-calendar-day var:class="dayClasses"
|
||||
var:day="currentTableDay.shortDateString"
|
||||
var:id="currentAllDayId"
|
||||
hour="allday"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
var:sg-day="currentTableDay.shortDateString"
|
||||
var:sg-day-string="currentTableDay.iso8601DateString"
|
||||
ng-repeat="view in calendar.views">
|
||||
<sg-calendar-day-table
|
||||
sg-blocks="view.allDayBlocks"
|
||||
sg-click="list.openEvent(event, component)"
|
||||
var:sg-day="currentTableDay.shortDateString"><!-- blocks for current day --></sg-calendar-day-table>
|
||||
<sg-calendar-day-block
|
||||
sg-calendar-ghost="sg-calendar-ghost"
|
||||
sg-block="list.component.$ghost"><!-- drag ghost --></sg-calendar-day-block>
|
||||
</sg-calendar-day>
|
||||
</var:foreach>
|
||||
</div>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content class="md-flex" sg-calendar-scroll-view="multiday">
|
||||
<div class="calendarView">
|
||||
|
||||
<!-- The hours -->
|
||||
<div class="hours">
|
||||
<var:foreach list="hoursToDisplay" item="currentTableHour">
|
||||
<div class="hour" var:id="currentHourId">
|
||||
<var:string value="currentTableHour"/>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
|
||||
<!-- The quarters grid -->
|
||||
<div class="daysView">
|
||||
<div class="days">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses" var:id="currentDayId" var:day-number="currentDayNumber" var:calendar="currentCalendar.folder" var:day="currentTableDay.shortDateString">
|
||||
<sg-calendar-day var:class="dayClasses"
|
||||
var:id="currentDayId"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
var:sg-day="currentTableDay.shortDateString"
|
||||
var:sg-day-string="currentTableDay.iso8601DateString"
|
||||
ng-repeat="view in calendar.views">
|
||||
<div class="hourCells">
|
||||
<var:foreach list="hoursToDisplay" item="currentTableHour">
|
||||
<div var:class="clickableHourCellClass" var:day="currentTableDay.shortDateString" var:hour="currentAppointmentHour">
|
||||
<div var:class="clickableHourCellClass"
|
||||
sg-draggable-calendar-block="sg-draggable-calendar-block"
|
||||
var:sg-hour="currentAppointmentHour">
|
||||
<span class="minutes15"><!-- space --></span>
|
||||
<span class="minutes30"><!-- space --></span>
|
||||
<span class="minutes45"><!-- space --></span>
|
||||
</div>
|
||||
</var:foreach>
|
||||
<sg-calendar-day-table
|
||||
sg-click="list.openEvent(event, component)"
|
||||
sg-blocks="view.blocks"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
var:sg-day="currentTableDay.shortDateString"><!-- blocks for current day --></sg-calendar-day-table>
|
||||
<sg-calendar-day-block
|
||||
sg-calendar-ghost="sg-calendar-ghost"
|
||||
sg-block="list.component.$ghost"><!-- drag ghost --></sg-calendar-day-block>
|
||||
</div>
|
||||
<div class="events"><!-- space --></div>
|
||||
</div>
|
||||
</sg-calendar-day>
|
||||
</var:foreach>
|
||||
</var:foreach>
|
||||
</var:if>
|
||||
<var:if condition="isNotMultiColumnView">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<div var:class="dayClasses" var:id="currentDayId" var:day-number="currentDayNumber" var:day="currentTableDay.shortDateString">
|
||||
<div class="hourCells">
|
||||
<var:foreach list="hoursToDisplay" item="currentTableHour">
|
||||
<div var:class="clickableHourCellClass" var:day="currentTableDay.shortDateString" var:hour="currentAppointmentHour">
|
||||
<span class="minutes15"><!-- space --></span>
|
||||
<span class="minutes30"><!-- space --></span>
|
||||
<span class="minutes45"><!-- space --></span>
|
||||
</div>
|
||||
</var:foreach>
|
||||
<sg-calendar-day-table
|
||||
sg-blocks="calendar.blocks"
|
||||
sg-click="list.openEvent(event, component)"
|
||||
var:sg-day="currentTableDay.shortDateString" />
|
||||
</div>
|
||||
<div class="events"><!-- space --></div>
|
||||
</div>
|
||||
</var:foreach>
|
||||
</var:if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</md-content>
|
||||
</container>
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<!-- <div class="menu" id="currentViewMenu">
|
||||
<ul>
|
||||
<li><var:string label:value="New Event..."/></li>
|
||||
<li><var:string label:value="New Task..."/></li>
|
||||
<li>!- separator -</li>
|
||||
<li><var:string label:value="Previous Day"/></li>
|
||||
<li><var:string label:value="Next Day"/></li>
|
||||
<li>!- separator -</li>
|
||||
<li><var:string label:value="Delete Event"/></li>
|
||||
<li><var:string label:value="Copy event to my calendar"/></li>
|
||||
<li><var:string label:value="View Raw Source"/></li>
|
||||
</ul>
|
||||
</div>-->
|
||||
<md-content>
|
||||
<div layout="row" layout-align="center">
|
||||
<h5>
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Previous Day"
|
||||
var:date="prevDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<var:string value="currentDayName" />
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Next Day"
|
||||
var:date="nextDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="calendarContent">
|
||||
<var:component
|
||||
className="UIxCalDayTable"
|
||||
startDate="startDate"
|
||||
const:CSSClass="dayOverview"
|
||||
const:numberOfDays="1"
|
||||
const:currentView="dayview"/>
|
||||
</div>
|
||||
</md-content>
|
||||
</container>
|
||||
<md-toolbar hide-sm="hide-sm">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Day"
|
||||
var:date="prevDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<div><var:string value="currentDayName" /></div>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Day"
|
||||
var:date="nextDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()"><md-icon>today</md-icon></md-button>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Day"
|
||||
ng-disabled="true"
|
||||
href="#/calendar/day"><md-icon>view_day</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Week"
|
||||
href="#/calendar/week"><md-icon>view_week</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Month"
|
||||
href="#/calendar/month"><md-icon>view_module</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Multicolumn Day View"
|
||||
href="#/calendar/multicolumnday"><md-icon>view_array</md-icon></a>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<var:component
|
||||
className="UIxCalDayTable"
|
||||
startDate="startDate"
|
||||
const:CSSClass="dayOverview"
|
||||
const:numberOfDays="1"
|
||||
const:currentView="dayview"/>
|
||||
</container>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.services.js, Mailer.services.js, Scheduler.js, Scheduler.services.js">
|
||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.services.js, Mailer.services.js, vendor/angular-file-upload.min.js, Scheduler.js, Scheduler.services.js">
|
||||
<script type="text/javascript">
|
||||
var firstDayOfWeek = <var:string value="firstDayOfWeek"/>;
|
||||
var dayStartHour = <var:string value="dayStartHour"/>;
|
||||
@@ -106,101 +106,101 @@
|
||||
<p><span class="label"><var:string label:value="Created by" /></span> <span>!- space -</span></p>
|
||||
<p class="description">!- space -</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="uploadDialog" style="display: none" class="dialog left">
|
||||
<div>
|
||||
<h3><var:string label:value="Import Events"/></h3>
|
||||
<p class="prompt"><var:string label:value="Select an iCalendar file (.ics)."/></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="calendarFile" class="textField" id="calendarFile" />
|
||||
<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" style="display: none" class="dialog left">
|
||||
<div>
|
||||
<h3><var:string label:value="Import Events"/></h3>
|
||||
<p><span id="uploadResultsContent">!- empty -</span>
|
||||
<a href="#" class="button" const:id="uploadOK">
|
||||
<span><var:string label:value="Done" /></span></a></p>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
-->
|
||||
|
||||
<main class="view layout-fill" ui-view="calendars" layout="row" ng-controller="navController"><!-- calendars list --></main>
|
||||
|
||||
<script type = "text/ng-template" id="UIxCalMainFrame">
|
||||
<script type="text/ng-template" id="UIxCalMainView">
|
||||
<!-- 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-model="calendar"><!-- stylesheet --></div>
|
||||
<sg-folder-stylesheet
|
||||
ng-repeat="calendar in app.service.$findAll()"
|
||||
ng-model="calendar"><!-- stylesheet --></sg-folder-stylesheet>
|
||||
<!-- calendars colors -->
|
||||
<sg-category-stylesheet
|
||||
ng-repeat="category in app.categories"
|
||||
ng-model="category"><!-- stylesheet --></sg-category-stylesheet>
|
||||
<!-- Sidenav -->
|
||||
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
|
||||
<md-sidenav class="md-sidenav-left md-whiteframe-z1" layout="column"
|
||||
md-component-id="left" md-is-locked-open="isGtMedium"
|
||||
ng-class="{ 'sg-closed': leftIsClose }">
|
||||
<var:component className="UIxSidenavToolbarTemplate" />
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex">
|
||||
<md-content md-scroll-y="md-scroll-y" class="md-flex md-hue-2">
|
||||
<!-- User's calendars -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<section class="sg-section-list">
|
||||
<md-subheader class="md-hue-2">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Calendars"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="New Calendar..."
|
||||
ng-click="calendars.newCalendar()">
|
||||
ng-click="app.newCalendar()">
|
||||
<md-icon>add_circle_outline</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="calendar in calendars.service.$calendars">
|
||||
<md-list-item ng-repeat="calendar in app.service.$calendars"
|
||||
ng-dblclick="app.editFolder(calendar)">
|
||||
<md-checkbox ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('checkbox')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-checkbox>
|
||||
<p class="sg-item-name">{{calendar.name}}</p>
|
||||
<p class="sg-item-name" ng-show="app.editMode != calendar.id">
|
||||
{{calendar.name}}
|
||||
<span class="sg-counter-badge" ng-show="calendar.activeTasks">{{calendar.activeTasks}}</span>
|
||||
</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-menu class="md-secondary" label:aria-label="Options">
|
||||
<md-icon label:aria-label="Options"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">more_vert</md-icon>
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.confirmDelete(calendar)">
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="calendar.id != 'personal'">
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.exportCalendar()">
|
||||
<md-button ng-click="app.importCalendar($event, calendar)">
|
||||
<var:string label:value="Import"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.exportCalendar(calendar)">
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showLinks(calendar)">
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.share(calendar)">
|
||||
<md-button ng-click="app.share(calendar)">
|
||||
<var:string label:value="Sharing..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showProperties(calendar)">
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
@@ -210,45 +210,66 @@
|
||||
</md-list>
|
||||
</section>
|
||||
<!-- Subscriptions -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<section class="sg-section-list">
|
||||
<md-subheader class="md-hue-2">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Subscriptions"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Subscribe to a Calendar..."
|
||||
sg-subscribe="calendar"
|
||||
sg-subscribe-on-select="calendars.subscribeToFolder(folderData)">
|
||||
sg-subscribe-on-select="app.subscribeToFolder(folderData)">
|
||||
<md-icon>add_circle_outline</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="calendar in calendars.service.$subscriptions">
|
||||
<md-list-item ng-repeat="calendar in app.service.$subscriptions"
|
||||
ng-dblclick="app.editFolder(calendar)">
|
||||
<md-checkbox ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('checkbox')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-checkbox>
|
||||
<p class="sg-item-name">{{calendar.name}}</p>
|
||||
<md-menu class="md-secondary" label:aria-label="Options" ng-click="true">
|
||||
<md-icon label:aria-label="Options"
|
||||
<p class="sg-item-name" ng-show="app.editMode != calendar.id">
|
||||
{{calendar.name}}
|
||||
<span class="sg-counter-badge" ng-show="calendar.activeTasks">{{calendar.activeTasks}}</span>
|
||||
</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-menu class="md-secondary" label:aria-label="Options">
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">more_vert</md-icon>
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.confirmDelete(calendar)">
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Unsubscribe Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showLinks(calendar)">
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showProperties(calendar)">
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
@@ -258,44 +279,62 @@
|
||||
</md-list>
|
||||
</section>
|
||||
<!-- Web Calendars -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader">
|
||||
<section class="sg-section-list">
|
||||
<md-subheader class="md-hue-2">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Web Calendars"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
label:aria-label="Subscribe to a web calendar..."
|
||||
ng-click="calendars.addWebCalendar()">
|
||||
ng-click="app.addWebCalendar()">
|
||||
<md-icon>add_circle_outline</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-subheader>
|
||||
<md-list>
|
||||
<md-list-item ng-repeat="calendar in calendars.service.$webcalendars">
|
||||
<md-list-item ng-repeat="calendar in app.service.$webcalendars"
|
||||
ng-dblclick="app.editFolder(calendar)">
|
||||
<md-checkbox ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('checkbox')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-checkbox>
|
||||
<p class="sg-item-name">{{calendar.name}}</p>
|
||||
<md-menu class="md-secondary" label:aria-label="Options" ng-click="true">
|
||||
<md-icon label:aria-label="Options"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">more_vert</md-icon>
|
||||
<p class="sg-item-name" ng-show="app.editMode != calendar.id">{{calendar.name}}</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-menu class="md-secondary" label:aria-label="Options">
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.confirmDelete(calendar)">
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showLinks(calendar)">
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendars.showProperties(calendar)">
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
@@ -310,197 +349,196 @@
|
||||
<!-- Main section -->
|
||||
<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">
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
<!-- <div class="sg-toolbar-group-2">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search">
|
||||
<md-toolbar layout="row" layout-align="space-between center" class="toolbar-main" >
|
||||
<var:component className="UIxTopnavToolbarTemplate" />
|
||||
<!-- <div class="sg-toolbar-group-2">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search">
|
||||
<md-icon>search</md-icon>
|
||||
</md-button>
|
||||
</div> -->
|
||||
</md-toolbar>
|
||||
<div layout="row" class="md-flex">
|
||||
<div class="view-list" layout="column">
|
||||
|
||||
<md-toolbar class="md-whiteframe-z1"
|
||||
ng-show="list.component.$selectedCount() == 0">
|
||||
<!-- sort/filter mode (default) -->
|
||||
<div class="md-toolbar-tools" layout="row" ng-hide="list.mode.search">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search"
|
||||
ng-click="list.mode.search = true">
|
||||
<md-icon>search</md-icon>
|
||||
</md-button>
|
||||
</div> -->
|
||||
</div><!-- .md-toolbar-tools -->
|
||||
<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">
|
||||
<div class="sg-toolbar-group">
|
||||
<md-button class="sg-icon-button" label:aria-label="Search"
|
||||
ng-click="list.mode.search = true">
|
||||
<md-icon>search</md-icon>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Filter"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>filter_list</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<div class="sg-toolbar-group-last">
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Filter"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>filter_list</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_all')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_all') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_all"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_today')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_today') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_today"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next7')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next7') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_next7"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next14')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next14') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_next14"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next31')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next31') }">
|
||||
<!-- selected --></md-icon><var:string label:value="view_next31"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_thismonth')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_thismonth') }">
|
||||
<!-- selected --></md-icon><var:string label:value="view_thismonth"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.filter('view_future')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryEvents.filterpopup == 'view_future' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_future"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.filter('view_selectedday')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryEvents.filterpopup == 'view_selectedday' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_selectedday"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_not_started')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_not_started' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_not_started"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_overdue')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_overdue' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_overdue"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_incomplete')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_incomplete' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_incomplete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider ng-if="list.componentType == 'tasks'"><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.component.$filter(list.componentType)">
|
||||
<md-checkbox
|
||||
ng-model="list.component.$queryTasks.show_completed"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"> <var:string label:value="Show completed tasks"/></md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Sort"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>sort</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('title')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('title') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Title"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('location')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('location') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Location"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('calendarName')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('calendarName') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.sort('start')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('start') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Start"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.sort('end')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('end') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="End"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('end')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('end') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Due Date"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('priority')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('priority') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Priority"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('category')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('category') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Category"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('status')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('status') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Status"/>
|
||||
</md-button>
|
||||
</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-checkbox
|
||||
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-checkbox
|
||||
ng-model="list.component.$queryTasks.asc"
|
||||
ng-true-value="0"
|
||||
ng-false-value="1"><var:string label:value="Descending Order"/></md-checkbox>
|
||||
</md-button>
|
||||
</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-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_all')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_all') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_all"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_today')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_today') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_today"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next7')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next7') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_next7"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next14')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next14') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_next14"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_next31')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_next31') }">
|
||||
<!-- selected --></md-icon><var:string label:value="view_next31"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.filter('view_thismonth')">
|
||||
<md-icon ng-class="{ 'icon-check': list.filteredBy('view_thismonth') }">
|
||||
<!-- selected --></md-icon><var:string label:value="view_thismonth"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.filter('view_future')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryEvents.filterpopup == 'view_future' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_future"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.filter('view_selectedday')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryEvents.filterpopup == 'view_selectedday' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_selectedday"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_not_started')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_not_started' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_not_started"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_overdue')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_overdue' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_overdue"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.filter('view_incomplete')">
|
||||
<md-icon ng-class="{ 'icon-check': list.component.$queryTasks.filterpopup == 'view_incomplete' }">
|
||||
<!-- selected --></md-icon> <var:string label:value="view_incomplete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider ng-if="list.componentType == 'tasks'"><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.component.$filter(list.componentType)">
|
||||
<md-checkbox
|
||||
ng-model="list.component.$queryTasks.show_completed"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"> <var:string label:value="Show completed tasks"/></md-checkbox>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-menu>
|
||||
<md-button class="sg-icon-button" label:aria-label="Sort"
|
||||
ng-click="$mdOpenMenu()">
|
||||
<md-icon>sort</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('title')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('title') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Title"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('location')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('location') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Location"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="list.sort('calendarName')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('calendarName') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.sort('start')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('start') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Start"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<md-button ng-click="list.sort('end')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('end') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="End"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('end')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('end') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Due Date"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('priority')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('priority') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Priority"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('category')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('category') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Category"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-if="list.componentType == 'tasks'">
|
||||
<md-button ng-click="list.sort('status')">
|
||||
<md-icon ng-class="{ 'icon-check': list.sortedBy('status') }">
|
||||
<!-- selected --></md-icon> <var:string label:value="Status"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item ng-if="list.componentType == 'events'">
|
||||
<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-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>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="sg-icon-button" ng-click="list.reload()">
|
||||
<md-icon>refresh</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<!-- search mode -->
|
||||
<div class="view-list sg-padded--right sg-toolbar-search" layout="row" layout-align="space-between center"
|
||||
<div class="md-toolbar-tools sg-toolbar-secondary"
|
||||
ng-show="list.mode.search"
|
||||
sg-search="list.component.$filter(list.componentType, { value: searchText, search: searchField })">
|
||||
<md-button class="sg-icon-button"
|
||||
@@ -511,67 +549,73 @@
|
||||
<md-input-container>
|
||||
<input name="folderSearch" type="search" />
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<md-input-container flex="25">
|
||||
<md-select>
|
||||
<md-option value="title_Category_Location" selected="selected"><var:string label:value="Title, category or location"/></md-option>
|
||||
<md-option value="entireContent"><var:string label:value="Entire content"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- day/week/month views -->
|
||||
<div class="sg-padded">
|
||||
<a class="sg-icon-button md-button"
|
||||
label:aria-label="Day"
|
||||
href="#/calendar/day"><md-icon>view_day</md-icon></a>
|
||||
<a class="sg-icon-button md-button"
|
||||
label:aria-label="Week"
|
||||
href="#/calendar/week"><md-icon>view_week</md-icon></a>
|
||||
<a class="sg-icon-button md-button"
|
||||
label:aria-label="Month"
|
||||
href="#/calendar/month"><md-icon>view_module</md-icon></a>
|
||||
</md-toolbar>
|
||||
|
||||
<!-- multiple-selection mode -->
|
||||
<md-toolbar class="md-whiteframe-z1 md-hue-1 sg-toolbar-secondary" ng-show="list.component.$selectedCount() > 0">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="sg-icon-button" ng-click="list.unselectComponents()">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</md-button>
|
||||
<label>{{list.component.$selectedCount()}} <var:string label:value="selected"/></label>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<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>
|
||||
</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">
|
||||
</md-toolbar>
|
||||
|
||||
<md-content layout="column" class="view-list">
|
||||
<md-tabs md-dynamic-height="true"
|
||||
md-selected="list.selectedList">
|
||||
<!-- Events list -->
|
||||
<md-tab label:label="Events"
|
||||
md-on-select="list.selectComponentType('events')">
|
||||
<md-subheader>
|
||||
<md-button class="md-icon-button hide show-gt-sm" ng-click="toggleLeft()">
|
||||
<md-icon ng-class="{'md-rotate-180': leftIsClose }">keyboard_arrow_left</md-icon>
|
||||
</md-button>
|
||||
<span>{{list.component.$queryEvents.filterpopup | loc}}</span>
|
||||
</md-subheader>
|
||||
<md-list class="sg-section-list">
|
||||
<md-list-item class="md-2-line"
|
||||
ng-repeat="event in list.component.$events"
|
||||
<md-list-item ng-repeat="event in list.component.$events"
|
||||
ng-click="list.openEvent($event, event)">
|
||||
<div class="sg-selected-avatar" ng-show="event.selected"
|
||||
ng-click="event.selected = !event.selected">
|
||||
<div class="md-avatar sg-avatar-selected" ng-show="event.selected"
|
||||
ng-click="list.toggleComponentSelection($event, event)">
|
||||
<!-- 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>
|
||||
<p class="md-secondary" layout="row">
|
||||
{{event.formatted_startdate}}
|
||||
<i class="sg-tile-icons">
|
||||
<md-icon ng-show="event.c_iscycle">repeat</md-icon>
|
||||
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
|
||||
</i>
|
||||
</p>
|
||||
<div class="sg-color-chip" ng-class="event.getClassName('bg')"
|
||||
ng-show="!event.selected"
|
||||
ng-click="list.toggleComponentSelection($event, event)"><!-- calendar color --></div>
|
||||
<div class="sg-category"
|
||||
ng-repeat="category in event.categories | limitTo:5"
|
||||
ng-class="'bg-category' + category"
|
||||
ng-style="{ left: ($index * 3) + 'px' }"><!-- calendar color --></div>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead">
|
||||
<div>{{event.c_title}}</div>
|
||||
</div>
|
||||
<div class="sg-md-body">
|
||||
<div>{{event.c_location}}</div>
|
||||
<div class="sg-tile-date" ng-bind="event.formatted_startdate"><!-- start --></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sg-tile-icons">
|
||||
<md-icon ng-show="event.c_iscycle">repeat</md-icon>
|
||||
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
|
||||
</div>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
<md-list-item disabled="disabled" ng-if="list.component.$events.length == 0">
|
||||
<p class="sg-md-caption"><var:string label:value="No events for selected criteria"/></p>
|
||||
@@ -581,25 +625,40 @@
|
||||
<!-- Tasks list -->
|
||||
<md-tab label:label="Tasks"
|
||||
md-on-select="list.selectComponentType('tasks')">
|
||||
<md-subheader>
|
||||
<md-button class="md-icon-button hide show-gt-sm" ng-click="toggleLeft()">
|
||||
<md-icon ng-class="{'md-rotate-180': leftIsClose }">keyboard_arrow_left</md-icon>
|
||||
</md-button>
|
||||
<span>{{list.component.$queryTasks.filterpopup | loc}}</span>
|
||||
</md-subheader>
|
||||
<md-list class="sg-section-list">
|
||||
<md-list-item class="md-2-line"
|
||||
ng-repeat="task in list.component.$tasks"
|
||||
<md-list-item ng-repeat="task in list.component.$tasks"
|
||||
ng-click="list.openTask($event, task)">
|
||||
<div class="sg-selected-avatar" ng-show="task.selected"
|
||||
ng-click="task.selected = !task.selected">
|
||||
<div class="md-avatar sg-avatar-selected" ng-show="task.selected"
|
||||
ng-click="list.toggleComponentSelection($event, task)">
|
||||
<!-- 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">
|
||||
{{task.formatted_enddate}}
|
||||
<span class="sg-tile-icons">
|
||||
<md-icon ng-show="task.c_iscycle">repeat</md-icon>
|
||||
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
|
||||
</span>
|
||||
</p>
|
||||
<div class="sg-color-chip" ng-class="task.getClassName('bg')"
|
||||
ng-show="!task.selected"
|
||||
ng-click="list.toggleComponentSelection($event, task)"><!-- calendar color --></div>
|
||||
<div class="sg-category"
|
||||
ng-repeat="category in task.categories | limitTo:5"
|
||||
ng-class="'bg-category' + category"
|
||||
ng-style="{ left: ($index * 3) + 'px' }"><!-- calendar color --></div>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead">
|
||||
<div>{{task.c_title}}</div>
|
||||
</div>
|
||||
<div class="sg-md-body">
|
||||
<div><!-- spacer --></div>
|
||||
<div>{{task.formatted_enddate}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sg-tile-icons">
|
||||
<md-icon ng-show="task.c_iscycle">repeat</md-icon>
|
||||
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
|
||||
</div>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
<md-list-item disabled="disabled" ng-if="list.component.$tasks.length == 0">
|
||||
<p class="sg-md-caption"><var:string label:value="No tasks for selected criteria"/></p>
|
||||
@@ -608,17 +667,61 @@
|
||||
</md-tab>
|
||||
</md-tabs>
|
||||
<md-button class="md-fab md-fab-bottom-right"
|
||||
label:aria-label="New Appointment"
|
||||
ng-click="list.newComponent($event)">
|
||||
<md-icon>add</md-icon>
|
||||
label:aria-label="Create a new event"
|
||||
ng-click="list.newComponent($event)"
|
||||
ng-if="list.componentType == 'events'">
|
||||
<md-icon >event</md-icon>
|
||||
</md-button>
|
||||
<md-button class="md-fab md-fab-bottom-right"
|
||||
label:aria-label="Create a new task"
|
||||
ng-click="list.newComponent($event)"
|
||||
ng-if="list.componentType == 'tasks'">
|
||||
<md-icon>assignment_turned_in</md-icon>
|
||||
</md-button>
|
||||
</md-content>
|
||||
<div id="detailView" hide-sm="hide-sm" class="view-detail" layout="column" ui-view="calendarView"><!-- calendar view --></div>
|
||||
</md-content>
|
||||
</div>
|
||||
<div id="detailView" class="view-detail" hide-xs="hide-xs" layout="column" ui-view="calendarView">
|
||||
<!-- calendar view -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</script>
|
||||
|
||||
<script type="text/ng-template" id="UIxUserRightsEditor">
|
||||
<var:component className="UIxCalUserRightsEditor" />
|
||||
</script>
|
||||
|
||||
<!-- modal for calendar import -->
|
||||
<script type="text/ng-template" id="UIxCalendarImportDialog">
|
||||
<md-dialog flex="40" flex-sm="100" label:aria-label="Import Calendar">
|
||||
<md-toolbar>
|
||||
<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"><var:string label:value="Import Calendar"/></div>
|
||||
</div>
|
||||
<md-button class="md-icon-button" ng-click="$CalendarImportDialogController.close()">
|
||||
<md-icon aria-label="Close dialog">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<p><var:string label:value="Select an ICS file."/></p>
|
||||
</md-dialog-content>
|
||||
<md-dialog-actions>
|
||||
<md-progress-circular class="md-accent"
|
||||
md-mode="determinate"
|
||||
md-diameter="20px"
|
||||
ng-show="$CalendarImportDialogController.uploader.isUploading"
|
||||
ng-value="$CalendarImportDialogController.uploader.progress"><!-- progress --></md-progress-circular>
|
||||
<label class="md-button" for="file-input" ng-hide="$CalendarImportDialogController.uploader.isUploading">
|
||||
<span><var:string label:value="Upload"/></span>
|
||||
</label>
|
||||
<input id="file-input" type="file" class="ng-hide"
|
||||
nv-file-select="nv-file-select"
|
||||
uploader="$CalendarImportDialogController.uploader"/>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</script>
|
||||
|
||||
</var:component>
|
||||
|
||||
@@ -1,71 +1,103 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<div class="menu" id="currentViewMenu" ng-hide="true">
|
||||
<ul>
|
||||
<li><var:string label:value="New Event..."/></li>
|
||||
<li><var:string label:value="New Task..."/></li>
|
||||
<li><!-- separator --></li>
|
||||
<li><var:string label:value="Previous Month"/></li>
|
||||
<li><var:string label:value="Next Month"/></li>
|
||||
<li><!-- separator --></li>
|
||||
<li><var:string label:value="Delete Event"/></li>
|
||||
<li><var:string label:value="Copy event to my calendar"/></li>
|
||||
<li><var:string label:value="View Raw Source"/></li>
|
||||
</ul>
|
||||
<md-toolbar class="md-whiteframe-z1" hide-sm="hide-sm">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Month"
|
||||
var:date="prevMonthQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<md-input-container>
|
||||
<md-select ng-model="calendar.nav.month">
|
||||
<md-option><var:string value="monthNameOfThisMonth" /></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<md-select ng-model="calendar.nav.year">
|
||||
<md-option><var:string value="selectedDate.yearOfCommonEra" /></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Month"
|
||||
var:date="nextMonthQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()"><md-icon>today</md-icon></md-button>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Day"
|
||||
href="#/calendar/day"><md-icon>view_day</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Week"
|
||||
href="#/calendar/week"><md-icon>view_week</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Month"
|
||||
ng-disabled="true"
|
||||
href="#/calendar/month"><md-icon>view_module</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Multicolumn Day View"
|
||||
href="#/calendar/multicolumnday"><md-icon>view_array</md-icon></a>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content>
|
||||
<div layout="row" layout-align="center">
|
||||
<h5>
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Previous Month"
|
||||
var:date="prevMonthQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<var:string value="monthNameOfThisMonth" />
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Next Month"
|
||||
var:date="nextMonthQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="monthView">
|
||||
<div layout="row" layout-align="center center">
|
||||
<var:foreach list="headerDaysToDisplay" item="currentTableDay">
|
||||
<div class="md-flex-fix dayLabels"><var:string value="labelForCurrentDayToDisplay"/></div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
<md-grid-list
|
||||
md-cols="7"
|
||||
md-row-height="1:1">
|
||||
<var:foreach list="weeksToDisplay" item="currentWeek">
|
||||
<var:foreach list="currentWeek" item="currentTableDay">
|
||||
<md-grid-tile
|
||||
md-rowspan="1"
|
||||
md-colspan="1"
|
||||
class="day"
|
||||
var:day="currentTableDay.shortDateString"
|
||||
var:day-number="currentDayNumber"
|
||||
var:id="currentDayId">
|
||||
<div layout="column" layout-fill="true">
|
||||
<div class="sg-calendar-tile-header"><var:string value="dayHeaderNumber"/></div>
|
||||
<md-toolbar md-scroll-shrink="true" class="monthView md-hue-1">
|
||||
<div layout="row" layout-align="center center"
|
||||
class="md-flex md-default-theme md-fg md-hue-1">
|
||||
<var:foreach list="headerDaysToDisplay" item="currentTableDay">
|
||||
<div class="dayLabels"><var:string value="labelForCurrentDayToDisplay"/></div>
|
||||
</var:foreach>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content class="md-flex" sg-calendar-scroll-view="monthly">
|
||||
<div class="calendarView monthView">
|
||||
<md-grid-list
|
||||
md-cols="7"
|
||||
md-row-height="1:1"
|
||||
md-gutter="0">
|
||||
<var:foreach list="weeksToDisplay" item="currentWeek">
|
||||
<var:foreach list="currentWeek" item="currentTableDay">
|
||||
<md-grid-tile
|
||||
md-rowspan="1"
|
||||
md-colspan="1"
|
||||
var:class="dayCellClasses"
|
||||
var:id="currentDayId"
|
||||
>
|
||||
<sg-calendar-day layout="column" layout-fill="true"
|
||||
var:sg-day="currentTableDay.shortDateString"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
var:sg-day-string="currentTableDay.iso8601DateString">
|
||||
<div class="sg-calendar-tile-header md-default-theme md-fg md-hue-2">
|
||||
<var:if condition="currentTableDay.isToday">
|
||||
<span class="md-default-theme md-bg md-accent md-hue-2"><var:string value="currentTableDay.dayOfMonth"/></span> <var:string value="dayHeaderMonth"/>
|
||||
</var:if>
|
||||
<var:if condition="currentTableDay.isToday" const:negate="YES">
|
||||
<span class=""><var:string value="currentTableDay.dayOfMonth"/></span> <var:string value="dayHeaderMonth"/>
|
||||
</var:if>
|
||||
</div>
|
||||
<md-content
|
||||
sg-draggable-calendar-block="sg-draggable-calendar-block"
|
||||
class="clickableDayCell">
|
||||
<sg-calendar-month-day
|
||||
sg-blocks="calendar.blocks"
|
||||
sg-blocks="calendar.views[0].blocks"
|
||||
sg-click="list.openEvent(event, component)"
|
||||
var:sg-day="currentTableDay.shortDateString"><!-- day's events --></sg-calendar-month-day>
|
||||
</div>
|
||||
</md-grid-tile>
|
||||
</var:foreach>
|
||||
</md-content>
|
||||
<sg-calendar-month-event
|
||||
sg-calendar-ghost="sg-calendar-ghost"
|
||||
sg-block="list.component.$ghost"><!-- drag ghost --></sg-calendar-month-event>
|
||||
</sg-calendar-day>
|
||||
</md-grid-tile>
|
||||
</var:foreach>
|
||||
</md-grid-list>
|
||||
</div>
|
||||
</md-content>
|
||||
</container>
|
||||
</var:foreach>
|
||||
</md-grid-list>
|
||||
</div>
|
||||
</md-content>
|
||||
</container>
|
||||
|
||||
@@ -1,56 +1,46 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<container
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<div class="menu" id="currentViewMenu">
|
||||
<ul>
|
||||
<li><var:string label:value="New Event..."/></li>
|
||||
<li><var:string label:value="New Task..."/></li>
|
||||
<li><!-- separator --></li>
|
||||
<li><var:string label:value="Previous Day"/></li>
|
||||
<li><var:string label:value="Next Day"/></li>
|
||||
<li><!-- separator --></li>
|
||||
<li><var:string label:value="Delete Event"/></li>
|
||||
<li><var:string label:value="Copy event to my calendar"/></li>
|
||||
<li><var:string label:value="View Raw Source"/></li>
|
||||
</ul>
|
||||
<md-toolbar hide-sm="hide-sm">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Day"
|
||||
var:date="prevDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<div><var:string value="currentDayName" /></div>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Day"
|
||||
var:date="nextDayQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()"><md-icon>today</md-icon></md-button>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Day"
|
||||
href="#/calendar/day"><md-icon>view_day</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Week"
|
||||
href="#/calendar/week"><md-icon>view_week</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Month"
|
||||
href="#/calendar/month"><md-icon>view_module</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Multicolumn Day View"
|
||||
ng-disabled="true"
|
||||
href="#/calendar/multicolumnday"><md-icon>view_array</md-icon></a>
|
||||
</div>
|
||||
<!-- Navigation header -->
|
||||
<span class="daysHeader">
|
||||
<span class="day1">
|
||||
<a href="#" id="leftNavigationArrow" var:date="prevDayQueryParameters.day" onclick="return onCalendarGotoDay(this);">
|
||||
<img rsrc:src="arrow-left.png"/></a></span>
|
||||
<span class="day0"><var:string value="currentDayName" /></span>
|
||||
<span class="day1">
|
||||
<a href="#" id="rightNavigationArrow" var:date="nextDayQueryParameters.day" onclick="return onCalendarGotoDay(this);">
|
||||
<img rsrc:src="arrow-right.png"/></a></span>
|
||||
<a href="#" id="listCollapse"><img var:class="collapseBtnClass" rsrc:src="collapse.png"/></a>
|
||||
</span>
|
||||
</md-toolbar>
|
||||
|
||||
<!-- TODO : Move this inside the schedulerUI.css -->
|
||||
<style type="text/css">
|
||||
DIV.day
|
||||
{
|
||||
width: <var:string value="dayWidthPercentage" />% !important;
|
||||
}
|
||||
<var:foreach list="subscriptionUsers" item="currentTableUser">
|
||||
DIV[class~='day'].appointmentsOf<var:string value="currentTableUser" />
|
||||
{
|
||||
left: <var:string value="currentTableUserDayLeftPercentage" />% !important;
|
||||
}
|
||||
</var:foreach>
|
||||
</style>
|
||||
|
||||
<!-- Display the calendar header and the table view -->
|
||||
<div id="calendarContent">
|
||||
<var:component
|
||||
<var:component
|
||||
className="UIxCalDayTable"
|
||||
startDate="startDate"
|
||||
const:CSSClass="dayOverview"
|
||||
const:numberOfDays="1"
|
||||
const:currentView="multicolumndayview"/>
|
||||
</div>
|
||||
</container>
|
||||
</container>
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE var:component>
|
||||
<var:component xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:uix="OGo:uix"
|
||||
xmlns:label="OGo:label"
|
||||
xmlns:rsrc="OGo:url"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:toolbar="none"
|
||||
const:popup="YES">
|
||||
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
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:uix="OGo:uix">
|
||||
<div layout="column">
|
||||
|
||||
<md-input-container>
|
||||
@@ -74,4 +70,4 @@
|
||||
|
||||
</div>
|
||||
|
||||
</var:component>
|
||||
</container>
|
||||
|
||||
@@ -1,34 +1,47 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<!DOCTYPE container>
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
|
||||
<md-content>
|
||||
<div layout="row" layout-align="center">
|
||||
<h5>
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Previous Week"
|
||||
var:date="prevWeekQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<var:string value="currentWeekName" />
|
||||
<md-button
|
||||
class="sg-icon-button"
|
||||
label:aria-label="Next Week"
|
||||
var:date="nextWeekQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="calendarContent">
|
||||
<var:component
|
||||
className="UIxCalDayTable"
|
||||
startDate="startDate"
|
||||
const:CSSClass="weekOverview"
|
||||
const:numberOfDays="7"
|
||||
const:currentView="weekview"/>
|
||||
</div>
|
||||
</md-content>
|
||||
</container>
|
||||
<md-toolbar hide-sm="hide-sm">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Week"
|
||||
var:date="prevWeekQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<div><var:string value="currentWeekName" /></div>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Week"
|
||||
var:date="nextWeekQueryParameters.day"
|
||||
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()"><md-icon>today</md-icon></md-button>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Day"
|
||||
href="#/calendar/day"><md-icon>view_day</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Week"
|
||||
ng-disabled="true"
|
||||
href="#/calendar/week"><md-icon>view_week</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Month"
|
||||
href="#/calendar/month"><md-icon>view_module</md-icon></a>
|
||||
<a class="md-icon-button md-button"
|
||||
label:aria-label="Multicolumn Day View"
|
||||
href="#/calendar/multicolumnday"><md-icon>view_array</md-icon></a>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<var:component
|
||||
className="UIxCalDayTable"
|
||||
startDate="startDate"
|
||||
const:CSSClass="weekOverview"
|
||||
const:numberOfDays="7"
|
||||
const:currentView="weekview"/>
|
||||
</container>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>
|
||||
|
||||
<md-dialog flex="60" flex-sm="100">
|
||||
<md-toolbar class="sg-padded">
|
||||
<md-toolbar>
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">link</md-icon>
|
||||
<div class="md-toolbar-tools">
|
||||
<div class="pseudo-input-container md-flex">
|
||||
@@ -21,8 +21,8 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-dialog-content>
|
||||
<div layout="column" layout-padding="layout-padding">
|
||||
<md-dialog-content class="md-padding">
|
||||
<div layout="column">
|
||||
|
||||
<div layout="column" layout-padding="layout-padding">
|
||||
<md-input-container ng-show="links.calendar.isWebCalendar">
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
>
|
||||
<md-dialog flex-sm="100">
|
||||
|
||||
<md-toolbar ng-style="{ 'background-color': properties.calendar.color }">
|
||||
<div class="md-toolbar-tools sg-padded--right">
|
||||
<md-toolbar ng-class="properties.calendar.getClassName('bg')">
|
||||
<div class="md-toolbar-tools">
|
||||
<!-- color -->
|
||||
<sg-color-picker sg-on-select="properties.calendar.color = color"><!-- color picker --></sg-color-picker>
|
||||
<sg-color-picker ng-model="properties.calendar.color"><!-- color picker --></sg-color-picker>
|
||||
<!-- name -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Name"/></label>
|
||||
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-dialog-content>
|
||||
<md-dialog-content class="md-dialog-content" layout="column">
|
||||
<md-checkbox
|
||||
ng-model="properties.calendar.includeInFreeBusy"
|
||||
ng-true-value="1"
|
||||
@@ -44,6 +44,14 @@
|
||||
ng-false-value="0">
|
||||
<var:string label:value="Show tasks"/>
|
||||
</md-checkbox>
|
||||
<md-checkbox
|
||||
ng-model="properties.calendar.synchronize"
|
||||
ng-show="!properties.calendar.isWebCalendar"
|
||||
ng-disabled="properties.calendar.id == 'personal'"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0">
|
||||
<var:string label:value="Synchronize"/>
|
||||
</md-checkbox>
|
||||
<md-checkbox
|
||||
ng-model="properties.calendar.reloadOnLogin"
|
||||
ng-show="properties.calendar.isWebCalendar"
|
||||
@@ -51,7 +59,7 @@
|
||||
ng-false-value="0">
|
||||
<var:string label:value="Reload on login"/>
|
||||
</md-checkbox>
|
||||
<div ng-hide="properties.calendar.isWebCalendar || !properties.calendar.isOwned">
|
||||
<div ng-hide="properties.calendar.isWebCalendar || !properties.calendar.isOwned" layout="column">
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
<md-checkbox
|
||||
ng-model="properties.calendar.notifications.notifyOnPersonalModifications"
|
||||
@@ -80,10 +88,10 @@
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
|
||||
<div class="md-actions">
|
||||
<md-dialog-actions>
|
||||
<md-button type="button" ng-click="properties.close()"><var:string label:value="Cancel"/></md-button>
|
||||
<md-button ng-click="properties.saveProperties()"><var:string label:value="Save"/></md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<md-dialog flex="60" flex-sm="100">
|
||||
<form name="eventForm" ng-submit="editor.save(eventForm)">
|
||||
<md-toolbar ng-class="editor.component.getClassName('bg')">
|
||||
<div class="md-toolbar-tools sg-padded">
|
||||
<div class="md-toolbar-tools">
|
||||
<!-- summary -->
|
||||
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
|
||||
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
|
||||
@@ -23,130 +23,155 @@
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<!-- location -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Location"/></label>
|
||||
<input type="text" ng-model="editor.component.location"/>
|
||||
</md-input-container>
|
||||
<!-- categories -->
|
||||
<md-chips ng-model="editor.component.categories">
|
||||
<md-autocomplete
|
||||
md-selected-item="editor.categories.selected"
|
||||
md-search-text="editor.categories.searchText"
|
||||
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
|
||||
label:placeholder="Add a category">
|
||||
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
<!-- calendar -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar">
|
||||
<md-option ng-repeat="calendar in ::editor.calendars"
|
||||
ng-value="calendar.id">{{calendar.name}}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<!-- classification -->
|
||||
<md-radio-group layout="row" layout-align="space-around center"
|
||||
ng-model="editor.component.classification">
|
||||
<md-radio-button value="public">
|
||||
<var:string label:value="label_Public"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="confidential">
|
||||
<var:string label:value="label_Confidential"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="private">
|
||||
<var:string label:value="label_Private"/>
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
<!-- priority -->
|
||||
<div layout="row" layout-align="center center">
|
||||
<div flex="20"><var:string label:value="Priority"/></div>
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.priority"
|
||||
step="1"
|
||||
min="0"
|
||||
max="9"
|
||||
label:aria-label="Priority"><!-- slider --></md-slider>
|
||||
</div>
|
||||
<!-- is all day -->
|
||||
<md-checkbox
|
||||
ng-model="editor.component.isAllDay"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="All day Event">
|
||||
<var:string label:value="All day Event"/>
|
||||
</md-checkbox>
|
||||
<!-- start + end -->
|
||||
<div layout="row">
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
<!-- location -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Start"/></label>
|
||||
<input type="text" ng-model="editor.component.startDate"/>
|
||||
<label><var:string label:value="Location"/></label>
|
||||
<input type="text" ng-model="editor.component.location"/>
|
||||
</md-input-container>
|
||||
<!-- categories -->
|
||||
<md-chips ng-model="editor.component.categories">
|
||||
<md-autocomplete
|
||||
md-selected-item="editor.categories.selected"
|
||||
md-search-text="editor.categories.searchText"
|
||||
md-items="category in editor.component.constructor.filterCategories(editor.categories.searchText)"
|
||||
md-min-length="0"
|
||||
label:placeholder="Add a category">
|
||||
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
|
||||
</md-autocomplete>
|
||||
</md-chips>
|
||||
<!-- calendar -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Due"/></label>
|
||||
<input type="text" ng-model="editor.component.dueDate"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- status -->
|
||||
<div layout="row">
|
||||
<md-input-container flex="50">
|
||||
<label><var:string label:value="Status"/></label>
|
||||
<md-select ng-model="editor.component.status">
|
||||
<var:foreach list="statusList" item="item">
|
||||
<md-option var:value="item"><var:string value="itemStatusText"/></md-option>
|
||||
</var:foreach>
|
||||
<label><var:string label:value="Calendar"/></label>
|
||||
<md-select ng-model="editor.component.destinationCalendar">
|
||||
<md-option ng-repeat="calendar in ::editor.calendars"
|
||||
ng-value="calendar.id">{{calendar.name}}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container ng-show="editor.component.status == 'completed'">
|
||||
<label><var:string label:value="status_COMPLETED"/></label>
|
||||
<input type="text" ng-model="editor.component.completedDate"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="center center"
|
||||
ng-show="editor.component.enablePercentComplete()">
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.percentComplete"
|
||||
step="5"
|
||||
min="0"
|
||||
max="100"
|
||||
label:aria-label="% complete"><!-- slider --></md-slider>
|
||||
<div flex="30">{{editor.component.percentComplete}} <var:string label:value="% complete"/></div>
|
||||
</div>
|
||||
<!-- attach urls -->
|
||||
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
|
||||
<div layout="row" layout-align="center end">
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="URL"/>
|
||||
</label>
|
||||
<input type="text" ng-model="attach.value"
|
||||
sg-focus-on="attachUrl_{{$index}}"/>
|
||||
</md-input-container>
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.component.deleteAttachUrl($index)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
<!-- classification -->
|
||||
<md-radio-group layout="row" layout-align="space-around center"
|
||||
ng-model="editor.component.classification">
|
||||
<md-radio-button value="public">
|
||||
<var:string label:value="label_Public"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="confidential">
|
||||
<var:string label:value="label_Confidential"/>
|
||||
</md-radio-button>
|
||||
<md-radio-button value="private">
|
||||
<var:string label:value="label_Private"/>
|
||||
</md-radio-button>
|
||||
</md-radio-group>
|
||||
<!-- priority -->
|
||||
<div layout="row" layout-align="center center">
|
||||
<div flex="20"><var:string label:value="Priority"/></div>
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.priority"
|
||||
step="1"
|
||||
min="0"
|
||||
max="9"
|
||||
label:aria-label="Priority"><!-- slider --></md-slider>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-layout-margin" layout="row" layout-align="start center">
|
||||
<md-button class="sg-icon-button" type="button" ng-click="editor.addAttachUrl($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label">
|
||||
<var:string label:value="Attach"/>
|
||||
</label>
|
||||
</div>
|
||||
<!-- comment -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Description"/></label>
|
||||
<textarea ng-model="editor.component.comment"><!-- comment --></textarea>
|
||||
</md-input-container>
|
||||
<!-- repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div class="md-flex">
|
||||
<!-- start -->
|
||||
<div ng-show="editor.component.start">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="From"/></label>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" layout-wrap="layout-wrap">
|
||||
<md-datepicker ng-model="editor.component.start"
|
||||
ng-change="editor.updateStartTime()"
|
||||
label:md-placeholder="From"> <!-- date picker--></md-datepicker>
|
||||
<sg-timepicker ng-model="editor.component.start"
|
||||
ng-change="editor.adjustStartTime()"><!-- time picker --></sg-timepicker>
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.component.$deleteStartDate()">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-layout-margin" layout="row" layout-align="start center" ng-hide="editor.component.start">
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.addStartDate()">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label"><var:string label:value="Add From"/></label>
|
||||
</div>
|
||||
<!-- due -->
|
||||
<div ng-show="editor.component.due">
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="Due"/></label>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" layout-wrap="layout-wrap">
|
||||
<md-datepicker ng-model="editor.component.due"
|
||||
ng-change="editor.updateDueTime()"
|
||||
label:md-placeholder="Due"> <!-- date picker--></md-datepicker>
|
||||
<sg-timepicker ng-model="editor.component.due"
|
||||
ng-change="editor.adjustDueTime()"><!-- time picker --></sg-timepicker>
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.component.$deleteDueDate()">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-layout-margin" layout="row" layout-align="start center" ng-hide="editor.component.due">
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.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">
|
||||
<md-input-container flex="50">
|
||||
<label><var:string label:value="Status"/></label>
|
||||
<md-select ng-model="editor.component.status">
|
||||
<var:foreach list="statusList" item="item">
|
||||
<md-option var:value="item"><var:string value="itemStatusText"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<md-input-container ng-show="editor.component.status == 'completed'">
|
||||
<label><var:string label:value="status_COMPLETED"/></label>
|
||||
<input type="text" ng-model="editor.component.completedDate"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="center center"
|
||||
ng-show="editor.component.enablePercentComplete()">
|
||||
<md-slider class="md-flex"
|
||||
md-discrete="true"
|
||||
ng-model="editor.component.percentComplete"
|
||||
step="5"
|
||||
min="0"
|
||||
max="100"
|
||||
label:aria-label="% complete"><!-- slider --></md-slider>
|
||||
<div flex="30">{{editor.component.percentComplete}} <var:string label:value="% complete"/></div>
|
||||
</div>
|
||||
<!-- attach urls -->
|
||||
<div class="attr" ng-repeat="attach in editor.component.attachUrls">
|
||||
<div layout="row" layout-align="center end">
|
||||
<md-input-container>
|
||||
<label>
|
||||
<var:string label:value="URL"/>
|
||||
</label>
|
||||
<input type="text" ng-model="attach.value"
|
||||
sg-focus-on="attachUrl_{{$index}}"/>
|
||||
</md-input-container>
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.component.deleteAttachUrl($index)">
|
||||
<md-icon>remove_circle</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-layout-margin" layout="row" layout-align="start center">
|
||||
<md-button class="md-icon-button" type="button" ng-click="editor.addAttachUrl($event)">
|
||||
<md-icon>add_circle</md-icon>
|
||||
</md-button>
|
||||
<label class="button-label">
|
||||
<var:string label:value="Attach"/>
|
||||
</label>
|
||||
</div>
|
||||
<!-- comment -->
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Description"/></label>
|
||||
<textarea ng-model="editor.component.comment"><!-- comment --></textarea>
|
||||
</md-input-container>
|
||||
<!-- repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="Repeat"/></label>
|
||||
<md-select class="pseudo-input-field" ng-model="editor.component.repeat.frequency">
|
||||
@@ -155,63 +180,62 @@
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button type="button" class="md-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-show="editor.component.repeat.frequency != 'never'"
|
||||
ng-click="editor.toggleRecurrenceEditor()">
|
||||
<md-icon ng-class="{'md-rotate-45': editor.showRecurrenceEditor}">add</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
<md-button type="button" class="sg-icon-button"
|
||||
label:aria-label="repeat_CUSTOM"
|
||||
ng-show="editor.component.repeat.frequency != 'never'"
|
||||
ng-click="editor.toggleRecurrenceEditor()">
|
||||
<md-icon ng-class="{'icon-more-horiz': !editor.showRecurrenceEditor,
|
||||
'icon-clear': editor.showRecurrenceEditor}"><!-- toggle custom rule --></md-icon>
|
||||
<div ng-show="editor.showRecurrenceEditor" class="sg-subcontent">
|
||||
<var:component className="UIxRecurrenceEditor" />
|
||||
</div>
|
||||
<!-- end repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div ng-show="editor.component.repeat.frequency != 'never'">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="End Repeat"/></label>
|
||||
<md-select class="pseudo-input-field" ng-model="editor.component.repeat.end">
|
||||
<md-option value="never"><var:string label:value="Never"/></md-option>
|
||||
<md-option value="count"><var:string label:value="After"/></md-option>
|
||||
<md-option value="until"><var:string label:value="On Date"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" ng-show="editor.component.repeat.end == 'count'">
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="times" ng-model="editor.component.repeat.count"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="times"/>
|
||||
</div>
|
||||
<md-input-container ng-show="editor.component.repeat.end == 'until'">
|
||||
<input type="date" label:aria-label="Repeat until" ng-model="editor.component.repeat.until"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- reminder -->
|
||||
<md-checkbox ng-model="editor.component.$hasAlarm"
|
||||
label:aria-label="Reminder">
|
||||
<var:string label:value="Reminder"/>
|
||||
</md-checkbox>
|
||||
<div class="sg-subcontent"
|
||||
ng-show="editor.component.$hasAlarm">
|
||||
<var:component className="UIxReminderEditor" />
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
<!-- cancel/reset/save -->
|
||||
<md-dialog-actions>
|
||||
<md-button type="button" ng-click="editor.cancel()">
|
||||
<var:string label:value="Cancel"/>
|
||||
</md-button>
|
||||
</div>
|
||||
<div ng-show="editor.showRecurrenceEditor" class="sg-subcontent">
|
||||
<var:component className="UIxRecurrenceEditor" />
|
||||
</div>
|
||||
<!-- end repeat -->
|
||||
<div layout="row" layout-align="start end">
|
||||
<div ng-show="editor.component.repeat.frequency != 'never'">
|
||||
<md-input-container>
|
||||
<label><var:string label:value="End Repeat"/></label>
|
||||
<md-select class="pseudo-input-field" ng-model="editor.component.repeat.end">
|
||||
<md-option value="never"><var:string label:value="Never"/></md-option>
|
||||
<md-option value="count"><var:string label:value="After"/></md-option>
|
||||
<md-option value="until"><var:string label:value="On Date"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="start center" ng-show="editor.component.repeat.end == 'count'">
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="times" ng-model="editor.component.repeat.count"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="times"/>
|
||||
</div>
|
||||
<md-input-container ng-show="editor.component.repeat.end == 'until'">
|
||||
<input type="date" label:aria-label="Repeat until" ng-model="editor.component.repeat.until"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- reminder -->
|
||||
<md-checkbox ng-model="editor.component.$hasAlarm"
|
||||
label:aria-label="Reminder">
|
||||
<var:string label:value="Reminder"/>
|
||||
</md-checkbox>
|
||||
<div class="sg-subcontent"
|
||||
ng-show="editor.component.$hasAlarm">
|
||||
<var:component className="UIxReminderEditor" />
|
||||
</div>
|
||||
</md-dialog-content>
|
||||
<!-- cancel/reset/save -->
|
||||
<div class="md-actions">
|
||||
<md-button type="button" ng-click="editor.cancel()">
|
||||
<var:string label:value="Cancel"/>
|
||||
</md-button>
|
||||
<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"
|
||||
ng-disabled="editor.eventForm.$invalid">
|
||||
<var:string label:value="Save"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</form>
|
||||
</md-dialog>
|
||||
<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"
|
||||
ng-disabled="editor.eventForm.$invalid">
|
||||
<var:string label:value="Save"/>
|
||||
</md-button>
|
||||
</md-dialog-actions>
|
||||
</form>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label">
|
||||
<md-dialog flex="40" flex-md="60" flex-sm="100">
|
||||
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
|
||||
<md-toolbar ng-class="editor.component.getClassName('bg')">
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">assignment_turned_in</md-icon>
|
||||
<div class="sg-md-title md-flex">
|
||||
@@ -13,12 +13,25 @@
|
||||
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
|
||||
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
|
||||
<!-- summary -->
|
||||
{{editor.component.summary}}
|
||||
{{::editor.component.summary}}
|
||||
<!-- priority -->
|
||||
<md-icon ng-repeat="i in editor.component.priority | range">star</md-icon>
|
||||
<md-icon ng-repeat="i in ::editor.component.priority | range">star</md-icon>
|
||||
</div>
|
||||
<md-button class="md-icon-button" ng-click="editor.close()">
|
||||
<md-icon aria-label="Close dialog">close</md-icon>
|
||||
<md-menu>
|
||||
<md-button label:aria-label="More options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<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>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-button class="sg-icon-button" ng-click="editor.close()">
|
||||
<md-icon label:aria-label="Close">close</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
@@ -26,7 +39,7 @@
|
||||
<md-list>
|
||||
<!-- categories -->
|
||||
<md-list-item ng-show="editor.component.categories.length > 0">
|
||||
<md-chips class="sg-readonly" ng-model="editor.component.categories" readonly="true">
|
||||
<md-chips class="sg-readonly" ng-model="::editor.component.categories" readonly="true">
|
||||
<md-chip-template>
|
||||
<span>{{$chip}}</span>
|
||||
</md-chip-template>
|
||||
@@ -35,7 +48,7 @@
|
||||
<!-- location -->
|
||||
<md-list-item ng-show="editor.component.location">
|
||||
<md-icon>place</md-icon>
|
||||
<p>{{editor.component.location}}</p>
|
||||
<p>{{::editor.component.location}}</p>
|
||||
</md-list-item>
|
||||
<!-- calendar -->
|
||||
<md-list-item>
|
||||
@@ -43,23 +56,18 @@
|
||||
<p>{{editor.component.calendar}}</p>
|
||||
</md-list-item>
|
||||
<!-- start/due dates -->
|
||||
<md-list-item class="md-2-line">
|
||||
<md-list-item ng-class="{ 'md-2-line': editor.component.isAllDay, 'md-3-line': !editor.component.isAllDay }"
|
||||
ng-show="editor.component.startDate || editor.component.dueDate">
|
||||
<md-icon>access_time</md-icon>
|
||||
<div layout="row" class="md-flex">
|
||||
<div class="md-list-item-text" ng-show="editor.component.startDate">
|
||||
<p><var:string label:value="Start"/></p>
|
||||
<h3>
|
||||
{{editor.component.localizedStartDate}}
|
||||
<span ng-hide="editor.component.isAllDay"> {{editor.component.localizedStartTime}}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.dueDate">
|
||||
<p><var:string label:value="Due Date"/></p>
|
||||
<h3>
|
||||
{{editor.component.localizedDueDate}}
|
||||
<span ng-hide="editor.component.isAllDay">{{editor.component.localizedDueTime}}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.startDate">
|
||||
<p><var:string label:value="Start"/></p>
|
||||
<h3>{{::editor.component.localizedStartDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay"> {{::editor.component.localizedStartTime}}</h3>
|
||||
</div>
|
||||
<div class="md-list-item-text" ng-show="editor.component.dueDate">
|
||||
<p><var:string label:value="Due Date"/></p>
|
||||
<h3>{{::editor.component.localizedDueDate}}</h3>
|
||||
<h3 ng-hide="editor.component.isAllDay">{{::editor.component.localizedDueTime}}</h3>
|
||||
</div>
|
||||
</md-list-item>
|
||||
<!-- status -->
|
||||
@@ -72,32 +80,59 @@
|
||||
<p>{{editor.component.percentComplete}} %</p>
|
||||
</md-list-item>
|
||||
<!-- attach urls -->
|
||||
<md-list-item ng-repeat="url in editor.component.attachUrls">
|
||||
<md-list-item ng-repeat="url in ::editor.component.attachUrls">
|
||||
<md-icon>link</md-icon>
|
||||
<p><a ng-href="url.value">{{url.value}}</a></p>
|
||||
</md-list-item>
|
||||
<!-- comment -->
|
||||
<md-list-item ng-show="editor.component.comment">
|
||||
<md-icon>mode_comment</md-icon>
|
||||
<p>{{editor.component.comment}}</p>
|
||||
<p>{{::editor.component.comment}}</p>
|
||||
</md-list-item>
|
||||
<!-- repeat -->
|
||||
<md-list-item ng-show="editor.component.repeat">
|
||||
<md-list-item ng-show="editor.component.$isRecurrent">
|
||||
<md-icon>repeat</md-icon>
|
||||
<p><!-- editor.component.repeat.toString() --></p>
|
||||
<p>{{editor.component.repeatDescription()}}</p>
|
||||
</md-list-item>
|
||||
<!-- reminder -->
|
||||
<md-list-item ng-show="editor.component.$hasAlarm">
|
||||
<md-icon>alarm</md-icon>
|
||||
<p><!-- editor.component.alarm.toString() --></p>
|
||||
<md-icon>alarm_on</md-icon>
|
||||
<p>{{editor.component.alarmDescription()}}</p>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</md-dialog-content>
|
||||
<!-- edit -->
|
||||
<div class="md-actions" ng-show="editor.component.isEditable()">
|
||||
<md-dialog-actions ng-show="editor.component.isEditable()">
|
||||
<md-button class="md-warn" label:aria-label="Delete Task"
|
||||
ng-show="editor.component.isEditable() || editor.component.isInvitation()"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
<md-menu ng-show="editor.component.isEditableOccurrence() || editor.component.isInvitationOccurrence()">
|
||||
<md-button class="md-warn" label:aria-label="Delete Task"
|
||||
ng-click="$mdOpenMenu()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<var:string label:value="Delete"/><md-icon>arrow_drop_down</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteOccurrence()">
|
||||
<var:string label:value="Delete This Occurrence"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button class="md-warn"
|
||||
ng-click="editor.deleteAllOccurrences()">
|
||||
<var:string label:value="Delete All Occurrences"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<div class="md-flex"><!-- spacer --></div>
|
||||
<md-button ng-click="editor.edit()">
|
||||
<var:string label:value="Edit"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
</container>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
>
|
||||
<md-dialog flex="50" flex-sm="100">
|
||||
<md-toolbar class="sg-padded">
|
||||
<md-toolbar>
|
||||
<div class="md-toolbar-tools">
|
||||
<md-icon class="material-icons sg-icon-toolbar-bg">folder_shared</md-icon>
|
||||
<div class="pseudo-input-container md-flex">
|
||||
@@ -19,32 +19,59 @@
|
||||
</md-button>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content>
|
||||
<md-dialog-content class="md-padding">
|
||||
<div layout="row">
|
||||
<md-icon>search</md-icon>
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-input-name="addUser"
|
||||
md-search-text="acl.searchText"
|
||||
md-selected-item="acl.userToAdd"
|
||||
md-selected-item-change="acl.addUser(user)"
|
||||
md-items="user in acl.userFilter(acl.searchText)"
|
||||
md-item-text="user.empty"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
label:md-floating-label="Add User">
|
||||
<md-item-template>
|
||||
<span class="md-contact-suggestion">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span>
|
||||
<span class="md-contact-email"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
</div>
|
||||
<md-card ng-repeat="user in acl.users | orderBy:['userClass', 'displayName']"
|
||||
ng-class="{ 'sg-collapsed': user.uid != acl.selectedUser.uid, 'sg-expanded': user.uid == acl.selectedUser.uid }">
|
||||
class="sg-collapsed"
|
||||
ng-class="{ 'sg-expanded': user.uid == acl.selectedUid }">
|
||||
<md-button ng-click="acl.selectUser(user)">
|
||||
<div layout="row" layout-align="start center" class="md-flex">
|
||||
<span class="card-picture" ng-switch="user.userClass">
|
||||
<div ng-switch-when="normal-user">
|
||||
<sg-avatar-image class="md-tile-left"
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="user.c_email"
|
||||
size="48"><!-- avatar --></sg-avatar-image>
|
||||
size="40"><!-- avatar --></sg-avatar-image>
|
||||
</div>
|
||||
<div ng-switch-when="normal-group" class="sg-list-avatar"><!-- normal-group --></div>
|
||||
<div ng-switch-when="public-user" class="sg-list-avatar"><!-- public-user --></div>
|
||||
<div ng-switch-when="normal-group" class="md-avatar sg-avatar-list"><!-- normal-group --></div>
|
||||
<div ng-switch-when="public-user" class="md-avatar sg-avatar-list"><!-- public-user --></div>
|
||||
</span>
|
||||
<div class="sg-tile-content">
|
||||
<div class="sg-md-subhead-multi">{{user.cn}}</div>
|
||||
<div class="sg-md-body-multi">{{user.c_email}}</div>
|
||||
<div class="sg-md-subhead"><div>{{user.cn}}</div></div>
|
||||
<div class="sg-md-body"><div>{{user.c_email}}</div></div>
|
||||
</div>
|
||||
<md-button class="sg-icon-button" type="button"
|
||||
<md-button class="md-icon-button" type="button"
|
||||
ng-click="acl.removeUser(user)"
|
||||
ng-hide="user.uid != acl.selectedUser.uid || user.$isSpecial()">
|
||||
ng-hide="user.uid != acl.selectedUid || user.$isSpecial()">
|
||||
<md-icon>delete</md-icon>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-button>
|
||||
<md-card-content id="AccessRightList" ng-show="user.uid == acl.selectedUser.uid">
|
||||
<md-card-content id="AccessRightList" ng-show="user.uid == acl.selectedUid">
|
||||
<var:if condition="canSubscribeUsers">
|
||||
<md-checkbox ng-model="user.isSubscribed"
|
||||
label:arial-label="Subscribe User"
|
||||
@@ -67,33 +94,10 @@
|
||||
</md-card>
|
||||
</md-dialog-content>
|
||||
|
||||
<div ng-hide="acl.confirmation.showing" class="md-actions">
|
||||
<md-autocomplete
|
||||
class="md-flex"
|
||||
md-input-name="addUser"
|
||||
md-search-text="acl.searchText"
|
||||
md-selected-item="acl.userToAdd"
|
||||
md-selected-item-change="acl.addUser(user)"
|
||||
md-items="user in acl.userFilter(acl.searchText)"
|
||||
md-item-text="user.empty"
|
||||
md-min-length="3"
|
||||
md-delay="300"
|
||||
md-no-cache="true"
|
||||
label:md-floating-label="Add User">
|
||||
<md-item-template>
|
||||
<span class="md-contact-suggestion">
|
||||
<span class="md-contact-name"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.cn}}</span>
|
||||
<span class="md-contact-email"
|
||||
md-highlight-text="acl.searchText"
|
||||
md-highlight-flags="^i">{{user.c_email}}</span>
|
||||
</span>
|
||||
</md-item-template>
|
||||
</md-autocomplete>
|
||||
<md-button ng-click="acl.saveModal()"><var:string label:value="Save"/></md-button>
|
||||
</div>
|
||||
<div class="md-actions" ng-show="acl.confirmation.showing">
|
||||
<md-dialog-actions ng-hide="acl.confirmation.showing">
|
||||
<md-button class="md-primary" ng-click="acl.saveModal()"><var:string label:value="Save"/></md-button>
|
||||
</md-dialog-actions>
|
||||
<md-dialog-actions ng-show="acl.confirmation.showing">
|
||||
<span>{{acl.confirmation.message}}</span>
|
||||
<md-button ng-click="acl.selectedUser.$resetRights(true); acl.confirmation.showing = false">
|
||||
<var:string label:value="Cancel"/>
|
||||
@@ -101,7 +105,7 @@
|
||||
<md-button class="md-warn" ng-click="acl.confirmation.showing = false">
|
||||
<var:string label:value="OK"/>
|
||||
</md-button>
|
||||
</div>
|
||||
</md-dialog-actions>
|
||||
</md-dialog>
|
||||
|
||||
</container>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user