(feat) initial support for contact import in the address book module
This commit is contained in:
parent
0a8834193f
commit
85c8aebbd4
|
@ -112,15 +112,11 @@
|
||||||
|
|
||||||
request = [context request];
|
request = [context request];
|
||||||
rc = [NSMutableDictionary dictionary];
|
rc = [NSMutableDictionary dictionary];
|
||||||
data = [request formValueForKey: @"contactsFile"];
|
data = [[[[[request httpRequest] body] parts] lastObject] body];
|
||||||
if ([data respondsToSelector: @selector(isEqualToString:)])
|
|
||||||
fileContent = (NSString *) data;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
fileContent = [[NSString alloc] initWithData: (NSData *) data
|
||||||
encoding: NSUTF8StringEncoding];
|
encoding: NSUTF8StringEncoding];
|
||||||
[fileContent autorelease];
|
[fileContent autorelease];
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContent && [fileContent length])
|
if (fileContent && [fileContent length])
|
||||||
{
|
{
|
||||||
|
@ -132,12 +128,10 @@
|
||||||
imported = 0;
|
imported = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[rc setObject: [NSNumber numberWithInt: imported]
|
[rc setObject: [NSNumber numberWithInt: imported] forKey: @"imported"];
|
||||||
forKey: @"imported"];
|
|
||||||
|
|
||||||
response = [self responseWithStatus: 200];
|
response = [self responseWithStatus: 200];
|
||||||
[response setHeader: @"text/html"
|
[response setHeader: @"text/html" forKey: @"content-type"];
|
||||||
forKey: @"content-type"];
|
|
||||||
[(WOResponse*)response appendContentString: [rc jsonRepresentation]];
|
[(WOResponse*)response appendContentString: [rc jsonRepresentation]];
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -9,64 +9,11 @@
|
||||||
className="UIxPageFrame"
|
className="UIxPageFrame"
|
||||||
title="title"
|
title="title"
|
||||||
const:userDefaultsKeys="SOGoContactsCategories"
|
const:userDefaultsKeys="SOGoContactsCategories"
|
||||||
const:jsFiles="Common.js, Preferences.services.js, Contacts.js, Contacts.services.js">
|
const:jsFiles="Common.js, Preferences.services.js, Contacts.js, Contacts.services.js, vendor/angular-file-upload.min.js">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var contactFolders = <var:string value="contactFolders" const:escapeHTML="NO" />;
|
var contactFolders = <var:string value="contactFolders" const:escapeHTML="NO" />;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div id="uploadDialog" style="display: none" class="dialog left">
|
|
||||||
<div>
|
|
||||||
<h3><var:string label:value="Import Cards"/></h3>
|
|
||||||
<p class="prompt"><var:string label:value="Select a vCard or LDIF file."/></p>
|
|
||||||
<form const:href="" name="uploadForm" id="uploadForm" method="post"
|
|
||||||
enctype="multipart/form-data"
|
|
||||||
onsubmit="return AIM.submit(this, {'onStart' : validateUploadForm,
|
|
||||||
'onComplete' : uploadCompleted})">
|
|
||||||
<p class="prompt"><input type="file" name="contactsFile" id="contactsFile" class="textField" required="required" />
|
|
||||||
<a href="#" class="button actionButton" id="uploadSubmit"
|
|
||||||
onclick="if($('uploadForm').onsubmit()) $('uploadForm').submit()">
|
|
||||||
<span><var:string label:value="Upload" /></span></a>
|
|
||||||
<a href="#" class="button" const:id="uploadCancel">
|
|
||||||
<span><var:string label:value="Cancel" /></span></a></p>
|
|
||||||
</form>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="uploadResults" dropdown-content="dropdown-content" class="f-dropdown">
|
|
||||||
<div>
|
|
||||||
<h3><var:string label:value="Import Cards"/></h3>
|
|
||||||
<p id="uploadResultsContent">!- empty -</p>
|
|
||||||
<p><a href="#" class="button" const:id="uploadOK">
|
|
||||||
<span><var:string label:value="Done" /></span></a></p>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="f-dropdown" dropdown-content="dropdown-content" id="contactMenu">
|
|
||||||
<li><var:string label:value="Properties" /></li>
|
|
||||||
<li><var:string label:value="Categories" /></li>
|
|
||||||
<li>!- separator -</li>
|
|
||||||
<li><var:string label:value="Write" /></li>
|
|
||||||
<li><var:string label:value="Instant Message" /></li>
|
|
||||||
<li>!- separator -</li>
|
|
||||||
<li><var:string label:value="Delete" /></li>
|
|
||||||
<li>!- separator -</li>
|
|
||||||
<li><var:string label:value="Move To" /></li>
|
|
||||||
<li><var:string label:value="Copy To" /></li>
|
|
||||||
<li><var:string label:value="Export" /></li>
|
|
||||||
<li><var:string label:value="View Raw Source" /></li>
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
MAIN CONTENT ROW
|
|
||||||
Content of the application view injected injected in the element bellow
|
|
||||||
MUST be the first html element after body
|
|
||||||
SHOULD be a main tag (with role="main")
|
|
||||||
|
|
||||||
Templates script tag wrappers goes next
|
|
||||||
-->
|
|
||||||
<main class="view md-layout-fill" ui-view="addressbooks" layout="row" ng-controller="navController"><!-- addressbooks list --></main>
|
<main class="view md-layout-fill" ui-view="addressbooks" layout="row" ng-controller="navController"><!-- addressbooks list --></main>
|
||||||
|
|
||||||
<!-- TEMPLATE SCRIPT WRAPPER -->
|
<!-- TEMPLATE SCRIPT WRAPPER -->
|
||||||
|
@ -125,6 +72,12 @@
|
||||||
<var:string label:value="Delete"/>
|
<var:string label:value="Delete"/>
|
||||||
</md-button>
|
</md-button>
|
||||||
</md-menu-item>
|
</md-menu-item>
|
||||||
|
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||||
|
<md-menu-item>
|
||||||
|
<md-button type="button" ng-click="app.importCards($event, folder)">
|
||||||
|
<var:string label:value="Import"/>
|
||||||
|
</md-button>
|
||||||
|
</md-menu-item>
|
||||||
<md-menu-item>
|
<md-menu-item>
|
||||||
<md-button type="button" ng-click="app.exportCards()">
|
<md-button type="button" ng-click="app.exportCards()">
|
||||||
<var:string label:value="Export"/>
|
<var:string label:value="Export"/>
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
/**
|
/**
|
||||||
* @ngInject
|
* @ngInject
|
||||||
*/
|
*/
|
||||||
AddressBooksController.$inject = ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$mdDialog', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'User', 'stateAddressbooks'];
|
AddressBooksController.$inject = ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$mdDialog', '$mdToast', 'FileUploader', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'User', 'stateAddressbooks'];
|
||||||
function AddressBooksController($state, $scope, $rootScope, $stateParams, $timeout, $mdDialog, focus, Card, AddressBook, Dialog, Settings, User, stateAddressbooks) {
|
function AddressBooksController($state, $scope, $rootScope, $stateParams, $timeout, $mdDialog, $mdToast, FileUploader, focus, Card, AddressBook, Dialog, Settings, User, stateAddressbooks) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.activeUser = Settings.activeUser;
|
vm.activeUser = Settings.activeUser;
|
||||||
|
@ -101,8 +101,85 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function importCards() {
|
function importCards($event, folder) {
|
||||||
|
$mdDialog.show({
|
||||||
|
parent: angular.element(document.body),
|
||||||
|
targetEvent: $event,
|
||||||
|
clickOutsideToClose: true,
|
||||||
|
escapeToClose: true,
|
||||||
|
template: [
|
||||||
|
'<md-dialog flex="40" flex-sm="100" aria-label="' + l('Import Cards') + '">',
|
||||||
|
' <md-toolbar class="sg-padded">',
|
||||||
|
' <div class="md-toolbar-tools">',
|
||||||
|
' <md-icon class="material-icons sg-icon-toolbar-bg">import_export</md-icon>',
|
||||||
|
' <div class="md-flex">',
|
||||||
|
' <div class="sg-md-title">' + l('Import Cards') + '</div>',
|
||||||
|
' </div>',
|
||||||
|
' <md-button class="md-icon-button" ng-click="close()">',
|
||||||
|
' <md-icon aria-label="Close dialog">close</md-icon>',
|
||||||
|
' </md-button>',
|
||||||
|
' </div>',
|
||||||
|
' </md-toolbar>',
|
||||||
|
' <md-dialog-content>',
|
||||||
|
' <div layout="column">',
|
||||||
|
' <div layout="row" layout-align="start center">',
|
||||||
|
' <span>' + l('Select a vCard or LDIF file.') + '</span>',
|
||||||
|
' <label class="md-button" for="file-input">',
|
||||||
|
' <span>' + l('Choose File') + '</span>',
|
||||||
|
' </label>',
|
||||||
|
' <input id="file-input" type="file" nv-file-select="nv-file-select" uploader="uploader" ng-show="false"/>',
|
||||||
|
' </div>',
|
||||||
|
' <span ng-show="uploader.queue.length == 0">' + l('No file chosen') + '</span>',
|
||||||
|
' <span ng-show="uploader.queue.length > 0">{{ uploader.queue[0].file.name }}</span>',
|
||||||
|
' </div>',
|
||||||
|
' </md-dialog-content>',
|
||||||
|
' <div class="md-actions">',
|
||||||
|
' <md-button ng-disabled="uploader.queue.length == 0" ng-click="upload()">' + l('Upload') + '</md-button>',
|
||||||
|
' </div>',
|
||||||
|
'</md-dialog>'
|
||||||
|
].join(''),
|
||||||
|
controller: CardsImportDialogController,
|
||||||
|
locals: {
|
||||||
|
folder: folder
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngInject
|
||||||
|
*/
|
||||||
|
CardsImportDialogController.$inject = ['scope', '$mdDialog', 'folder'];
|
||||||
|
function CardsImportDialogController(scope, $mdDialog, folder) {
|
||||||
|
|
||||||
|
scope.uploader = new FileUploader({
|
||||||
|
url: ApplicationBaseURL + '/' + folder.id + '/import',
|
||||||
|
onProgressItem: function(item, progress) {
|
||||||
|
console.debug(item); console.debug(progress);
|
||||||
|
},
|
||||||
|
onSuccessItem: function(item, response, status, headers) {
|
||||||
|
console.debug(item); console.debug('success = ' + JSON.stringify(response, undefined, 2));
|
||||||
|
$mdDialog.hide();
|
||||||
|
$mdToast.show(
|
||||||
|
$mdToast.simple()
|
||||||
|
.content(l('A total of %{0} cards were imported in the addressbook.', response.imported))
|
||||||
|
.position('top right')
|
||||||
|
.hideDelay(3000));
|
||||||
|
AddressBook.selectedFolder.$reload();
|
||||||
|
},
|
||||||
|
onCancelItem: function(item, response, status, headers) {
|
||||||
|
console.debug(item); console.debug('cancel = ' + JSON.stringify(response, undefined, 2));
|
||||||
|
},
|
||||||
|
onErrorItem: function(item, response, status, headers) {
|
||||||
|
console.debug(item); console.debug('error = ' + JSON.stringify(response, undefined, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.close = function() {
|
||||||
|
$mdDialog.hide();
|
||||||
|
};
|
||||||
|
scope.upload = function() {
|
||||||
|
scope.uploader.uploadAll();
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportCards() {
|
function exportCards() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('SOGo.ContactsUI', ['ngSanitize', 'ui.router', 'SOGo.Common', 'SOGo.PreferencesUI'])
|
angular.module('SOGo.ContactsUI', ['ngSanitize', 'ui.router', 'angularFileUpload', 'SOGo.Common', 'SOGo.PreferencesUI'])
|
||||||
.config(configure)
|
.config(configure)
|
||||||
.run(runBlock);
|
.run(runBlock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue