From 7552ffe241557635cb9dad6ec68abf9be89381cd Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Tue, 29 Apr 2014 15:49:30 +0400 Subject: [PATCH] Added export contacts (csv) Interface optimizations --- dev/Styles/Contacts.less | 4 +- dev/Styles/Layout.less | 74 +++++--- dev/Styles/Scroll.less | 6 +- .../RainLoop/Providers/AddressBook.php | 10 ++ .../Providers/AddressBook/Classes/Contact.php | 162 +++++++++++++++-- .../AddressBook/Classes/Property.php | 8 + .../Providers/AddressBook/PdoAddressBook.php | 11 +- .../app/templates/Views/PopupsContacts.html | 11 +- rainloop/v/0.0.0/static/css/app.css | 108 ++++++++---- rainloop/v/0.0.0/static/css/app.min.css | 2 +- .../v/0.0.0/static/css/fonts/rainloop.eot | Bin 17268 -> 17728 bytes .../v/0.0.0/static/css/fonts/rainloop.svg | 2 + .../v/0.0.0/static/css/fonts/rainloop.ttf | Bin 17100 -> 17560 bytes .../v/0.0.0/static/css/fonts/rainloop.woff | Bin 12148 -> 12448 bytes rainloop/v/0.0.0/static/js/admin.js | 104 +++++------ rainloop/v/0.0.0/static/js/admin.min.js | 6 +- rainloop/v/0.0.0/static/js/app.js | 164 +++++++++--------- rainloop/v/0.0.0/static/js/app.min.js | 16 +- rainloop/v/0.0.0/static/js/libs.js | 104 +++++------ vendors/fontastic/fonts/rainloop.eot | Bin 17268 -> 17728 bytes vendors/fontastic/fonts/rainloop.svg | 2 + vendors/fontastic/fonts/rainloop.ttf | Bin 17100 -> 17560 bytes vendors/fontastic/fonts/rainloop.woff | Bin 12148 -> 12448 bytes vendors/fontastic/icons-reference.html | 16 ++ vendors/fontastic/styles.css | 6 + 25 files changed, 526 insertions(+), 290 deletions(-) diff --git a/dev/Styles/Contacts.less b/dev/Styles/Contacts.less index 6ec8f1742..9de69d712 100644 --- a/dev/Styles/Contacts.less +++ b/dev/Styles/Contacts.less @@ -5,10 +5,10 @@ .control-group { .control-label.fix-width { - width: 90px; + width: 50px; } .controls.fix-width { - margin-left: 110px; + margin-left: 70px; } } diff --git a/dev/Styles/Layout.less b/dev/Styles/Layout.less index 6061fe55f..ea5e45079 100644 --- a/dev/Styles/Layout.less +++ b/dev/Styles/Layout.less @@ -106,40 +106,17 @@ html.ssm-state-desktop { #rl-sub-right { left: 400px; } -} - -html.ssm-state-tablet { - - #rl-left { - width: 160px; - } - - #rl-right { - left: 160px; - } - - #rl-sub-left { - width: 350px; - - .messageList .inputSearch { - width: 220px; - } - } - - #rl-sub-right { - left: 350px; - } .b-compose.modal { - width: 800px; + width: 1000px; } .b-contacts-content.modal { - width: 800px; + width: 1000px; } } -html.ssm-state-mobile { +html.ssm-state-tablet, html.ssm-state-mobile { #rl-left { width: 155px; @@ -162,11 +139,52 @@ html.ssm-state-mobile { } .b-compose.modal { - width: 800px; + width: 700px; } .b-contacts-content.modal { - width: 800px; + width: 600px; + } + + .b-contacts-content.modal { + .b-list-toopbar, .b-list-content, .b-list-footer-toopbar { + width: 150px; + } + .b-list-toopbar .e-search { + width: 125px; + } + .b-view-content { + left: 150px; + } + .contactValueInput { + width: 200px; + } + } +} + +html.ssm-state-tablet { + + .b-compose.modal { + width: 700px; + } + + .b-contacts-content.modal { + width: 700px; + } + + .b-contacts-content.modal { + .b-list-toopbar, .b-list-content, .b-list-footer-toopbar { + width: 200px; + } + .b-list-toopbar .e-search { + width: 175px; + } + .b-view-content { + left: 200px; + } + .contactValueInput { + width: 250px; + } } } diff --git a/dev/Styles/Scroll.less b/dev/Styles/Scroll.less index a85987e98..e1e09f553 100644 --- a/dev/Styles/Scroll.less +++ b/dev/Styles/Scroll.less @@ -6,9 +6,9 @@ width: 100%; height: 2px; z-index: 102; - -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.8); - -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.8); - box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.8); + -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); + box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); } .nano:before { diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php index 336522ba8..657133293 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php @@ -176,6 +176,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider 'Name' => PropertyType::FULLNAME, 'FullName' => PropertyType::FULLNAME, 'DisplayName' => PropertyType::FULLNAME, + 'GivenName' => PropertyType::FULLNAME, 'First' => PropertyType::FIRST_NAME, 'FirstName' => PropertyType::FIRST_NAME, 'Middle' => PropertyType::MIDDLE_NAME, @@ -183,9 +184,14 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider 'Last' => PropertyType::LAST_NAME, 'LastName' => PropertyType::LAST_NAME, 'Suffix' => PropertyType::NAME_SUFFIX, + 'NameSuffix' => PropertyType::NAME_SUFFIX, + 'Prefix' => PropertyType::NAME_PREFIX, + 'NamePrefix' => PropertyType::NAME_PREFIX, + 'ShortName' => PropertyType::NICK_NAME, 'NickName' => PropertyType::NICK_NAME, 'BusinessFax' => array(PropertyType::PHONE, 'Work,Fax'), 'BusinessFax2' => array(PropertyType::PHONE, 'Work,Fax'), + 'BusinessFax3' => array(PropertyType::PHONE, 'Work,Fax'), 'BusinessPhone' => array(PropertyType::PHONE, 'Work'), 'BusinessPhone2' => array(PropertyType::PHONE, 'Work'), 'BusinessPhone3' => array(PropertyType::PHONE, 'Work'), @@ -193,6 +199,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider 'CompanyMainPhone' => array(PropertyType::PHONE, 'Work'), 'HomeFax' => array(PropertyType::PHONE, 'Home,Fax'), 'HomeFax2' => array(PropertyType::PHONE, 'Home,Fax'), + 'HomeFax3' => array(PropertyType::PHONE, 'Home,Fax'), 'HomePhone' => array(PropertyType::PHONE, 'Home'), 'HomePhone2' => array(PropertyType::PHONE, 'Home'), 'HomePhone3' => array(PropertyType::PHONE, 'Home'), @@ -206,6 +213,9 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider 'Email' => array(PropertyType::EMAIl, 'Home'), 'Email2' => array(PropertyType::EMAIl, 'Home'), 'Email3' => array(PropertyType::EMAIl, 'Home'), + 'HomeEmail' => array(PropertyType::EMAIl, 'Home'), + 'HomeEmail2' => array(PropertyType::EMAIl, 'Home'), + 'HomeEmail3' => array(PropertyType::EMAIl, 'Home'), 'EmailAddress' => array(PropertyType::EMAIl, 'Home'), 'Email2Address' => array(PropertyType::EMAIl, 'Home'), 'Email3Address' => array(PropertyType::EMAIl, 'Home'), diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Contact.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Contact.php index 2ae191727..f4abd69df 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Contact.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Contact.php @@ -266,22 +266,162 @@ class Contact } /** - * @todo * @return string */ - public function ToCsvHeader() + public function ToCsv($bWithHeader = false) { - return ''; - } + $aData = array(); + if ($bWithHeader) + { + $aData[] = array( + 'Title', 'First Name', 'Middle Name', 'Last Name', 'Nick Name', 'Display Name', + 'Company', 'Department', 'Job Title', 'Office Location', + 'E-mail Address', 'Notes', 'Web Page', 'Birthday', + 'Other Email', 'Other Phone', 'Other Mobile', 'Mobile Phone', + 'Home Email', 'Home Phone', 'Home Fax', + 'Home Street', 'Home City', 'Home State', 'Home Postal Code', 'Home Country', + 'Business Email', 'Business Phone', 'Business Fax', + 'Business Street', 'Business City', 'Business State', 'Business Postal Code', 'Business Country' + ); + } + + $aValues = array( + '', // 0 'Title', + '', // 1 'First Name', + '', // 2 'Middle Name', + '', // 3 'Last Name', + '', // 4 'Nick Name', + '', // 5 'Display Name', + '', // 6 'Company', + '', // 7 'Department', + '', // 8 'Job Title', + '', // 9 'Office Location', + '', // 10 'E-mail Address', + '', // 11 'Notes', + '', // 12 'Web Page', + '', // 13 'Birthday', + '', // 14 'Other Email', + '', // 15 'Other Phone', + '', // 16 'Other Mobile', + '', // 17 'Mobile Phone', + '', // 18 'Home Email', + '', // 19 'Home Phone', + '', // 20 'Home Fax', + '', // 21 'Home Street', + '', // 22 'Home City', + '', // 23 'Home State', + '', // 24 'Home Postal Code', + '', // 25 'Home Country', + '', // 26 'Business Email', + '', // 27 'Business Phone', + '', // 28 'Business Fax', + '', // 29 'Business Street', + '', // 30 'Business City', + '', // 31 'Business State', + '', // 32 'Business Postal Code', + '' // 33 'Business Country' + ); - /** - * @todo - * @return string - */ - public function ToCsvLine() - { $this->UpdateDependentValues(); - return ''; + + foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty) + { + $iIndex = -1; + if ($oProperty) + { + $aUpperTypes = $oProperty->TypesUpperAsArray(); + switch ($oProperty->Type) + { + case PropertyType::FULLNAME: + $iIndex = 5; + break; + case PropertyType::NICK_NAME: + $iIndex = 4; + break; + case PropertyType::FIRST_NAME: + $iIndex = 1; + break; + case PropertyType::LAST_NAME: + $iIndex = 3; + break; + case PropertyType::MIDDLE_NAME: + $iIndex = 2; + break; + case PropertyType::EMAIl: + switch (true) + { + case \in_array('OTHER', $aUpperTypes): + $iIndex = 14; + break; + case \in_array('WORK', $aUpperTypes): + $iIndex = 26; + break; + default: + $iIndex = 18; + break; + } + break; + case PropertyType::PHONE: + switch (true) + { + case \in_array('OTHER', $aUpperTypes): + $iIndex = 15; + break; + case \in_array('WORK', $aUpperTypes): + $iIndex = 27; + break; + case \in_array('MOBILE', $aUpperTypes): + $iIndex = 17; + break; + default: + $iIndex = 19; + break; + } + break; + case PropertyType::WEB_PAGE: + $iIndex = 12; + break; + case PropertyType::NOTE: + $iIndex = 11; + break; + } + + if (-1 < $iIndex) + { + $aValues[$iIndex] = $oProperty->Value; + } + } + } + + // subfix + if (empty($aValues[10])) // 'E-mail Address' + { + if (!empty($aValues[18])) + { + $aValues[10] = $aValues[18]; + } + else if (!empty($aValues[26])) + { + $aValues[10] = $aValues[26]; + } + else if (!empty($aValues[14])) + { + $aValues[10] = $aValues[14]; + } + } + + $aData[] = \array_map(function ($sValue) { + $sValue = \trim($sValue); + return \preg_match('/[\r\n,"]/', $sValue) ? '"'.\str_replace('"', '""', $sValue).'"' : $sValue; + }, $aValues); + + $sResult = ''; + foreach ($aData as $aSubData) + { + $sResult .= \implode(',', $aSubData)."\r\n"; + } + + return $sResult; } /** diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php index f93e204b6..3c99f0b65 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php @@ -90,6 +90,14 @@ class Property return $aResult; } + /** + * @return array + */ + public function TypesUpperAsArray() + { + return \array_map('strtoupper', $this->TypesAsArray()); + } + public function UpdateDependentValues() { $this->Value = \trim($this->Value); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php index e753f9ae1..53a125206 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php @@ -379,7 +379,7 @@ class PdoAddressBook } $bVcf = 'vcf' === $sType; - $bCsvHeader = false; + $bCsvHeader = true; $aDatabaseSyncData = $this->prepearDatabaseSyncData($iUserID); if (\is_array($aDatabaseSyncData) && 0 < \count($aDatabaseSyncData)) @@ -397,13 +397,8 @@ class PdoAddressBook } else { - if (!$bCsvHeader) - { - $bCsvHeader = true; - echo $oContact->ToCsvHeader(); - } - - echo $oContact->ToCsvLine(); + echo $oContact->ToCsv($bCsvHeader); + $bCsvHeader = false; } } } diff --git a/rainloop/v/0.0.0/app/templates/Views/PopupsContacts.html b/rainloop/v/0.0.0/app/templates/Views/PopupsContacts.html index 8f49c8f49..3762438af 100644 --- a/rainloop/v/0.0.0/app/templates/Views/PopupsContacts.html +++ b/rainloop/v/0.0.0/app/templates/Views/PopupsContacts.html @@ -20,21 +20,22 @@