Improve handling of contact lists
parent
61c48d37e4
commit
3364263247
|
@ -81,7 +81,7 @@
|
|||
<span class="button"><i class="icon-hyperlink"><!-- links --></i></span>
|
||||
</li>
|
||||
<li data-ng-show="!addressbook.isRemote">
|
||||
<span class="button"><i class="icon-pencil" data-ng-click="edit()"><!-- rename --></i></span>
|
||||
<span class="button" data-ng-click="edit()"><i class="icon-pencil"><!-- rename --></i></span>
|
||||
</li>
|
||||
<li data-ng-show="!addressbook.isRemote">
|
||||
<span class="button" data-ng-click="share()"><i class="icon-earth"><!-- share --></i></span>
|
||||
|
@ -207,11 +207,14 @@
|
|||
<span>{{card.$birthday() | date}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" data-ng-show="card.refs.length > 0">
|
||||
<div class="section" data-ng-repeat="ref in card.refs">
|
||||
<!-- list members -->
|
||||
<div class="attr" data-ng-repeat="ref in card.refs">
|
||||
<div class="attr">
|
||||
<div class="value single">
|
||||
<a href="mailto:{{ref.email}}">{{ref.fn || ref.email}}</a>
|
||||
<a data-ui-sref="addressbook.card.view({addressbookId: addressbook.id, cardId: ref.reference})">{{ref.$fullname()}}</a>
|
||||
<span data-ng-show="ref.email">
|
||||
<a href="mailto:{{ref.email}}"><i class="icon-ion-ios7-email-outline"><!-- email --></i> {{ref.email}}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -314,32 +314,35 @@
|
|||
<ion-content padding="10">
|
||||
<div>
|
||||
<div class="subtitle">
|
||||
<var:string label:value="List display"/>
|
||||
<var:string label:value="List details"/>
|
||||
</div>
|
||||
<ion-list class="list-clear">
|
||||
<ion-item class="item-input">
|
||||
<input type="text" label:placeholder="Display" ng-model="card.fn"/>
|
||||
<input type="text" label:placeholder="List name:" ng-model="card.fn"/>
|
||||
</ion-item>
|
||||
<ion-item class="item-input">
|
||||
<input type="text" label:placeholder="Nickname" ng-model="card.nickname"/>
|
||||
<input type="text" label:placeholder="List nickname:" ng-model="card.nickname"/>
|
||||
</ion-item>
|
||||
<ion-item class="item-input">
|
||||
<input type="text" label:placeholder="List description:" ng-model="card.description"/>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
<var:string label:value="List of members"/>
|
||||
<var:string label:value="Members"/>
|
||||
</div>
|
||||
<div id="search-box" class="item-input-inset">
|
||||
<div class="item-input-wrapper">
|
||||
<i class="icon ion-search placeholder-icon"></i>
|
||||
<input type="text" label:placeholder="Search" data-ng-model="search.query" data-ng-keyup="showPopOver($event)" />
|
||||
<i ng-show="displayIcon()" class="clear-search icon ion-ios7-close-empty" ng-click="clearSearch()"><!-- spacer --></i>
|
||||
<i ng-show="search.query" class="clear-search icon ion-ios7-close-empty" ng-click="resetSearch()"><!-- spacer --></i>
|
||||
</div>
|
||||
</div>
|
||||
<ion-list class="list-clear">
|
||||
<ion-item ng-repeat="ref in card.refs" class="item-input">
|
||||
<button class="button button-small button-assertive button-icon icon ion-minus-circled"
|
||||
data-ng-click="card.$delete('refs', $index)"><!-- remove --></button>
|
||||
<span>{{shortFormat(ref)}}</span>
|
||||
<span>{{ref.$shortFormat()}}</span>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<button class="button button-block button-assertive" ng-hide="card.isNew"
|
||||
|
@ -352,9 +355,9 @@
|
|||
<script type="text/ng-template" id="searchFolderContacts.html">
|
||||
<ion-popover-view>
|
||||
<ion-content>
|
||||
<ion-list ng-repeat="card in addressbook.cards | orderBy:['sn'] | filter:searchCards">
|
||||
<ion-item ng-if="displayContact(card)" ng-click="addMember(card)">
|
||||
<span>{{card.$shortFormat()}}</span>
|
||||
<ion-list ng-repeat="card in addressbook.cards | orderBy:['sn'] | filter:cardsFilter">
|
||||
<ion-item ng-click="addMember(card)">
|
||||
<span>{{card.$shortFormat(search.query)}}</span>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
|
|
@ -340,8 +340,12 @@
|
|||
};
|
||||
|
||||
Card.prototype.$addMember = function(email) {
|
||||
var card = new Card({email: email, emails: [{value: email}]});
|
||||
if (angular.isUndefined(this.refs)) {
|
||||
this.refs = [{email: email}];
|
||||
this.refs = [card];
|
||||
}
|
||||
else if (email.length == 0) {
|
||||
this.refs.push(card);
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < this.refs.length; i++) {
|
||||
|
@ -350,7 +354,7 @@
|
|||
}
|
||||
}
|
||||
if (i == this.refs.length)
|
||||
this.refs.push({email: email});
|
||||
this.refs.push(card);
|
||||
}
|
||||
return this.refs.length - 1;
|
||||
};
|
||||
|
@ -368,6 +372,11 @@
|
|||
}
|
||||
});
|
||||
angular.extend(this, this.$shadowData);
|
||||
// Reinstanciate Card objects for list members
|
||||
angular.forEach(this.refs, function(o, i) {
|
||||
if (o.email) o.emails = [{value: o.email}];
|
||||
_this.refs[i] = new Card(o);
|
||||
});
|
||||
this.$shadowData = this.$omit(true);
|
||||
};
|
||||
|
||||
|
@ -384,8 +393,11 @@
|
|||
* @param {Card} card
|
||||
*/
|
||||
Card.prototype.$updateMember = function(index, email, card) {
|
||||
var ref = {email: email, reference: card.c_name, fn: card.$fullname()};
|
||||
this.refs[index] = ref;
|
||||
var ref = {email: email,
|
||||
emails: [{value: email}],
|
||||
reference: card.c_name,
|
||||
fn: card.$fullname()};
|
||||
this.refs[index] = new Card(ref);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -405,6 +417,11 @@
|
|||
// Calling $timeout will force Angular to refresh the view
|
||||
Card.$timeout(function() {
|
||||
angular.extend(_this, data);
|
||||
// Instanciate Card objects for list members
|
||||
angular.forEach(_this.refs, function(o, i) {
|
||||
if (o.email) o.emails = [{value: o.email}];
|
||||
_this.refs[i] = new Card(o);
|
||||
});
|
||||
// Make a copy of the data in order for an eventual reset.
|
||||
_this.$shadowData = _this.$omit(true);
|
||||
});
|
||||
|
@ -421,7 +438,12 @@
|
|||
Card.prototype.$omit = function(deep) {
|
||||
var card = {};
|
||||
angular.forEach(this, function(value, key) {
|
||||
if (key != 'constructor' && key[0] != '$') {
|
||||
if (key == 'refs') {
|
||||
card.refs = _.map(value, function(o) {
|
||||
return o.$omit(deep);
|
||||
});
|
||||
}
|
||||
else if (key != 'constructor' && key[0] != '$') {
|
||||
if (deep)
|
||||
card[key] = angular.copy(value);
|
||||
else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* JavaScript for SOGoContacts (mobile) */
|
||||
/* JavaScript for SOGo.ContactsUI (mobile) module */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
@ -140,7 +140,6 @@
|
|||
};
|
||||
$scope.edit = function(addressbook) {
|
||||
$ionicActionSheet.show({
|
||||
titleText: l('Modify your addressbook %{0}', addressbook.name),
|
||||
buttons: [
|
||||
{ text: l('Rename') }
|
||||
],
|
||||
|
@ -183,17 +182,17 @@
|
|||
|
||||
$scope.addCard = function() {
|
||||
$ionicActionSheet.show({
|
||||
titleText: l('Create a new card or a new list'),
|
||||
//titleText: l('Create a new card or a new list'),
|
||||
buttons: [
|
||||
{ text: l('New Card')},
|
||||
{ text: l('New List')}
|
||||
],
|
||||
canceltext: l('Cancel'),
|
||||
buttonClicked: function(index) {
|
||||
if(index == 0){
|
||||
if (index == 0){
|
||||
$state.go('app.newCard', { addressbookId: stateAddressbook.id, contactType: 'card' });
|
||||
}
|
||||
else if(index == 1){
|
||||
else if (index == 1){
|
||||
$state.go('app.newCard', { addressbookId: stateAddressbook.id, contactType: 'list' });
|
||||
}
|
||||
return true;
|
||||
|
@ -224,8 +223,7 @@
|
|||
};
|
||||
}])
|
||||
|
||||
.controller('CardCtrl', ['$scope', '$rootScope', '$state', '$stateParams', '$ionicModal', '$ionicPopover', 'sgDialog', 'sgAddressBook', 'sgCard', 'stateCard',
|
||||
function($scope, $rootScope, $state, $stateParams, $ionicModal, $ionicPopover, Dialog, AddressBook, Card, stateCard) {
|
||||
.controller('CardCtrl', ['$scope', '$rootScope', '$state', '$stateParams', '$ionicModal', '$ionicPopover', 'sgDialog', 'sgAddressBook', 'sgCard', 'stateCard', function($scope, $rootScope, $state, $stateParams, $ionicModal, $ionicPopover, Dialog, AddressBook, Card, stateCard) {
|
||||
$scope.card = stateCard;
|
||||
|
||||
$scope.UserFolderURL = UserFolderURL;
|
||||
|
@ -234,63 +232,47 @@
|
|||
$scope.allUrlTypes = Card.$URL_TYPES;
|
||||
$scope.allAddressTypes = Card.$ADDRESS_TYPES;
|
||||
|
||||
$scope.search = {query: ""};
|
||||
$scope.cardsFilter = function(item) {
|
||||
var query, id = false;
|
||||
if (item.tag == "vcard" && $scope.search.query) {
|
||||
query = $scope.search.query.toLowerCase();
|
||||
if (item.emails && item.emails.length > 0) {
|
||||
// Is one of the email addresses match the query string?
|
||||
if (_.find(item.emails, function(email) {
|
||||
return (email.value.toLowerCase().indexOf(query) >= 0);
|
||||
}))
|
||||
id = item.id;
|
||||
}
|
||||
if (!id && item.fn)
|
||||
// Is the fn attribute matches the query string?
|
||||
if (item.fn.toLowerCase().indexOf(query) >= 0)
|
||||
id = item.id;
|
||||
if (id) {
|
||||
// Is the card already part of the members? If so, ignore it.
|
||||
if (_.find($scope.card.refs, function(ref) {
|
||||
return ref.reference == id;
|
||||
}))
|
||||
id = false;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
};
|
||||
$scope.resetSearch = function() {
|
||||
$scope.search.query = null;
|
||||
};
|
||||
$scope.addMember = function(member) {
|
||||
var i = $scope.card.$addMember(''),
|
||||
email = member.$preferredEmail($scope.search.query);
|
||||
$scope.card.$updateMember(i, email, member);
|
||||
$scope.popover.hide();
|
||||
};
|
||||
$ionicPopover.fromTemplateUrl('searchFolderContacts.html', {
|
||||
scope: $scope,
|
||||
}).then(function(popover) {
|
||||
$scope.popover = popover;
|
||||
});
|
||||
|
||||
$scope.search = {query: ""};
|
||||
|
||||
|
||||
$scope.shortFormat = function(ref) {
|
||||
var fullname = ref.fn,
|
||||
email = ref.email;
|
||||
if (email && fullname)
|
||||
fullname += ' (' + email + ')';
|
||||
return fullname;
|
||||
};
|
||||
|
||||
$scope.searchCards = function(item) {
|
||||
if (item.tag == "vcard" && $scope.search.query) {
|
||||
var displayCard = false;
|
||||
if(item.emails.length > 0) {
|
||||
angular.forEach(item.emails, function(email) {
|
||||
var mail = email.value.toLowerCase();
|
||||
if(mail.indexOf($scope.search.query.toLowerCase()) != -1) {
|
||||
displayCard = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
if (item.fn) {
|
||||
var fullName = item.fn.toLowerCase();
|
||||
if(fullName.indexOf($scope.search.query.toLowerCase())!=-1)
|
||||
displayCard = true;
|
||||
}
|
||||
return displayCard;
|
||||
}
|
||||
};
|
||||
$scope.clearSearch = function() {
|
||||
$scope.search.query = null;
|
||||
};
|
||||
$scope.displayIcon = function() {
|
||||
if ($scope.search.query) {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
};
|
||||
$scope.displayContact = function(card) {
|
||||
var contact = true;
|
||||
if(card.tag == "vcard" && card.c_mail){
|
||||
angular.forEach($scope.card.refs, function(ref) {
|
||||
if( card.c_mail == ref.email)
|
||||
contact = false;
|
||||
})
|
||||
}
|
||||
return contact;
|
||||
};
|
||||
|
||||
$scope.edit = function() {
|
||||
// Build modal editor
|
||||
$ionicModal.fromTemplateUrl('cardEditor.html', {
|
||||
|
@ -342,20 +324,6 @@
|
|||
var i = $scope.card.$addAddress('', '', '', '', '', '', '', '');
|
||||
focus('address_' + i);
|
||||
};
|
||||
$scope.addMember = function(member) {
|
||||
var isAlreadyInList = false;
|
||||
angular.forEach($scope.card.refs, function(ref) {
|
||||
if (member.c_mail == ref.email)
|
||||
isAlreadyInList = true;
|
||||
else
|
||||
isAlreadyInList = false;
|
||||
});
|
||||
if (member.c_mail && !isAlreadyInList) {
|
||||
var i = $scope.card.$addMember('');
|
||||
$scope.card.$updateMember(i, member.c_mail, member);
|
||||
$scope.popover.hide();
|
||||
}
|
||||
};
|
||||
$scope.showPopOver = function(keyEvent) {
|
||||
$scope.popover.show(keyEvent);
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
//$topbar-bg-color: $primary-color;
|
||||
$module-color: #75B4BF;
|
||||
$module-color: #C6C543;
|
||||
$module-color: #6F5A73;
|
||||
$module-color: #6F5A73; // purple
|
||||
$module-secondary-color: #8EC588; // light green
|
||||
$module-secondary-color: #3D792A; // green
|
||||
$module-secondary-color: #B996BF;
|
||||
$module-secondary-color: #B59BB9; // SOGo green
|
||||
$module-secondary-color: #B59BB9; // light purple
|
||||
$module-light-color: #F7ECFF;
|
||||
$topbar-bg-color: $module-color;
|
||||
$topbar-link-bg-active-hover: scale-color($module-secondary-color, $lightness: -14%);
|
||||
|
@ -293,6 +293,16 @@ $column-gutter: 0;
|
|||
&.single {
|
||||
@include grid-column($offset: 4, $columns:9);
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
a {
|
||||
color: #666;
|
||||
margin-left: 0.2em;
|
||||
&:hover {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.buttonsToolbar {
|
||||
|
|
Loading…
Reference in New Issue