mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
parent
9cc791caba
commit
8c0276631b
36 changed files with 628 additions and 66 deletions
|
|
@ -58,6 +58,14 @@ LinkBuilder.prototype.upload = function ()
|
||||||
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
LinkBuilder.prototype.uploadContacts = function ()
|
||||||
|
{
|
||||||
|
return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,16 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable)
|
||||||
;
|
;
|
||||||
|
|
||||||
$(this.oContentVisible)
|
$(this.oContentVisible)
|
||||||
|
.on('selectstart', function (oEvent) {
|
||||||
|
if (oEvent && oEvent.preventDefault)
|
||||||
|
{
|
||||||
|
oEvent.preventDefault();
|
||||||
|
}
|
||||||
|
})
|
||||||
.on('click', this.sItemSelector, function (oEvent) {
|
.on('click', this.sItemSelector, function (oEvent) {
|
||||||
self.actionClick(ko.dataFor(this), oEvent);
|
self.actionClick(ko.dataFor(this), oEvent);
|
||||||
}).on('click', this.sItemCheckedSelector, function (oEvent) {
|
})
|
||||||
|
.on('click', this.sItemCheckedSelector, function (oEvent) {
|
||||||
var oItem = ko.dataFor(this);
|
var oItem = ko.dataFor(this);
|
||||||
if (oItem)
|
if (oItem)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@
|
||||||
.box-shadow(none);
|
.box-shadow(none);
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
width: 250px;
|
width: 300px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.075));
|
.box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.075));
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
|
|
||||||
.g-ui-user-select-none {
|
.g-ui-user-select-none {
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
-khtml-user-select: none;
|
-khtml-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
-o-user-select: none;
|
-o-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-touch-callout: none;
|
standard-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.g-ui-clearfix {
|
.g-ui-clearfix {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
margin-left: -2px;
|
margin-left: -1px;
|
||||||
|
width: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconsize24 {
|
.iconsize24 {
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,11 @@ function PopupsContactsViewModel()
|
||||||
this.contactsCount = ko.observable(0);
|
this.contactsCount = ko.observable(0);
|
||||||
this.contacts = ko.observableArray([]);
|
this.contacts = ko.observableArray([]);
|
||||||
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
|
||||||
this.currentContact = ko.observable(null);
|
this.currentContact = ko.observable(null);
|
||||||
|
|
||||||
|
this.importUploaderButton = ko.observable(null);
|
||||||
|
|
||||||
this.contactsSharingIsAllowed = !!RL.settingsGet('ContactsSharingIsAllowed');
|
this.contactsSharingIsAllowed = !!RL.settingsGet('ContactsSharingIsAllowed');
|
||||||
|
|
||||||
this.contactsPage = ko.observable(1);
|
this.contactsPage = ko.observable(1);
|
||||||
|
|
@ -336,6 +339,46 @@ PopupsContactsViewModel.prototype.addNewPhone = function ()
|
||||||
this.addNewProperty(Enums.ContactPropertyType.MobilePersonal);
|
this.addNewProperty(Enums.ContactPropertyType.MobilePersonal);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PopupsContactsViewModel.prototype.initUploader = function ()
|
||||||
|
{
|
||||||
|
if (this.importUploaderButton())
|
||||||
|
{
|
||||||
|
var
|
||||||
|
oJua = new Jua({
|
||||||
|
'action': RL.link().uploadContacts(),
|
||||||
|
'name': 'uploader',
|
||||||
|
'queueSize': 1,
|
||||||
|
'multipleSizeLimit': 1,
|
||||||
|
'disableFolderDragAndDrop': true,
|
||||||
|
'disableDragAndDrop': true,
|
||||||
|
'disableMultiple': true,
|
||||||
|
'disableDocumentDropPrevent': true,
|
||||||
|
'clickElement': this.importUploaderButton()
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
if (oJua)
|
||||||
|
{
|
||||||
|
oJua
|
||||||
|
.on('onStart', _.bind(function () {
|
||||||
|
this.contacts.importing(true);
|
||||||
|
}, this))
|
||||||
|
.on('onComplete', _.bind(function (sId, bResult, oData) {
|
||||||
|
|
||||||
|
this.contacts.importing(false);
|
||||||
|
this.reloadContactList();
|
||||||
|
|
||||||
|
if (!sId || !bResult || !oData || !oData.Result)
|
||||||
|
{
|
||||||
|
window.alert(Utils.i18n('CONTACTS/ERROR_IMPORT_FILE'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}, this))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
PopupsContactsViewModel.prototype.removeCheckedOrSelectedContactsFromList = function ()
|
PopupsContactsViewModel.prototype.removeCheckedOrSelectedContactsFromList = function ()
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
|
|
@ -575,6 +618,8 @@ PopupsContactsViewModel.prototype.onBuild = function (oDom)
|
||||||
|
|
||||||
return bResult;
|
return bResult;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.initUploader();
|
||||||
};
|
};
|
||||||
|
|
||||||
PopupsContactsViewModel.prototype.onShow = function ()
|
PopupsContactsViewModel.prototype.onShow = function ()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "RainLoop",
|
"name": "RainLoop",
|
||||||
"title": "RainLoop Webmail",
|
"title": "RainLoop Webmail",
|
||||||
"version": "1.6.1",
|
"version": "1.6.1",
|
||||||
"release": "630",
|
"release": "642",
|
||||||
"description": "Simple, modern & fast web-based email client",
|
"description": "Simple, modern & fast web-based email client",
|
||||||
"homepage": "http://rainloop.net",
|
"homepage": "http://rainloop.net",
|
||||||
"main": "Gruntfile.js",
|
"main": "Gruntfile.js",
|
||||||
|
|
|
||||||
|
|
@ -5122,6 +5122,235 @@ class Actions
|
||||||
return $this->DefaultResponse(__FUNCTION__, $aResponse);
|
return $this->DefaultResponse(__FUNCTION__, $aResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
|
* @param resource $rFile
|
||||||
|
* @param string $sFileStart
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function importContactsFromCsvFile($oAccount, $rFile, $sFileStart)
|
||||||
|
{
|
||||||
|
$this->Logger()->Write('Import Csv');
|
||||||
|
|
||||||
|
$iCount = 0;
|
||||||
|
$aHeaders = null;
|
||||||
|
$aData = array();
|
||||||
|
|
||||||
|
if ($oAccount && \is_resource($rFile))
|
||||||
|
{
|
||||||
|
$oPab = $this->PersonalAddressBookProvider($oAccount);
|
||||||
|
if ($oPab)
|
||||||
|
{
|
||||||
|
$sDelimiter = ((int) \strpos($sFileStart, ',') > (int) \strpos($sFileStart, ';')) ? ',' : ';';
|
||||||
|
|
||||||
|
@\setlocale(LC_CTYPE, 'en_US.UTF-8');
|
||||||
|
while (false !== ($mRow = \fgetcsv($rFile, 5000, $sDelimiter, '"')))
|
||||||
|
{
|
||||||
|
if (null === $aHeaders)
|
||||||
|
{
|
||||||
|
if (3 >= \count($mRow))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aHeaders = $mRow;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aNewItem = array();
|
||||||
|
foreach ($aHeaders as $iIndex => $sHeaderValue)
|
||||||
|
{
|
||||||
|
$aNewItem[@\iconv('utf-8', 'utf-8//IGNORE', $sHeaderValue)] =
|
||||||
|
isset($mRow[$iIndex]) ? $mRow[$iIndex] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$aData[] = $aNewItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_array($aData) && 0 < \count($aData))
|
||||||
|
{
|
||||||
|
$this->Logger()->Write('Start to import '.\count($aData).' contacts from csv file');
|
||||||
|
$oPab->ImportCsvArray($oAccount->ParentEmailHelper(), $aData);
|
||||||
|
|
||||||
|
$iCount = \count($aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $iCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
|
* @param resource $rFile
|
||||||
|
* @param string $sFileStart
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function importContactsFromVcfFile($oAccount, $rFile, $sFileStart)
|
||||||
|
{
|
||||||
|
$this->Logger()->Write('Import Vcf');
|
||||||
|
|
||||||
|
$iCount = 0;
|
||||||
|
if ($oAccount && \is_resource($rFile))
|
||||||
|
{
|
||||||
|
$oPab = $this->PersonalAddressBookProvider($oAccount);
|
||||||
|
if ($oPab)
|
||||||
|
{
|
||||||
|
$sFile = \stream_get_contents($rFile);
|
||||||
|
if (\is_resource($rFile))
|
||||||
|
{
|
||||||
|
@\fclose($rFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($sFile) && 5 < \strlen($sFile))
|
||||||
|
{
|
||||||
|
$sFile = \trim($sFile);
|
||||||
|
if ("\xef\xbb\xbf" === \substr($sFile, 0, 3))
|
||||||
|
{
|
||||||
|
$sFile = \substr($sFile, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oVCard = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$oVCardSplitter = new \Sabre\VObject\Splitter\VCard($sFile);
|
||||||
|
}
|
||||||
|
catch (\Exception $oExc)
|
||||||
|
{
|
||||||
|
$this->Logger()->WriteException($oExc);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($oVCardSplitter)
|
||||||
|
{
|
||||||
|
$oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact();
|
||||||
|
|
||||||
|
$oVCard = null;
|
||||||
|
$sEmail = $oAccount->ParentEmailHelper();
|
||||||
|
|
||||||
|
$this->Logger()->Write('Start to import contacts from vcf');
|
||||||
|
while ($oVCard = $oVCardSplitter->getNext())
|
||||||
|
{
|
||||||
|
if ($oVCard instanceof \Sabre\VObject\Component\VCard)
|
||||||
|
{
|
||||||
|
if (empty($oVCard->UID))
|
||||||
|
{
|
||||||
|
$oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
$oContact->ParseVCard($oVCard, $oVCard->serialize());
|
||||||
|
if ($oPab->ContactSave($sEmail, $oContact))
|
||||||
|
{
|
||||||
|
$iCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oContact->Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $iCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function UploadContacts()
|
||||||
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
$oConfig = $this->Config();
|
||||||
|
|
||||||
|
$sInputName = 'uploader';
|
||||||
|
$mResponse = false;
|
||||||
|
|
||||||
|
$iError = UploadError::UNKNOWN;
|
||||||
|
$iSizeLimit = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0)) * 1024 * 1024;
|
||||||
|
|
||||||
|
if ($oAccount)
|
||||||
|
{
|
||||||
|
$oPab = $this->PersonalAddressBookProvider($oAccount);
|
||||||
|
if ($oPab)
|
||||||
|
{
|
||||||
|
$iError = UPLOAD_ERR_OK;
|
||||||
|
$_FILES = isset($_FILES) ? $_FILES : null;
|
||||||
|
if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size']))
|
||||||
|
{
|
||||||
|
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;
|
||||||
|
|
||||||
|
if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size'])
|
||||||
|
{
|
||||||
|
$iError = UploadError::CONFIG_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sSavedName = 'upload-post-'.md5($_FILES[$sInputName]['name'].$_FILES[$sInputName]['tmp_name']);
|
||||||
|
|
||||||
|
if (UPLOAD_ERR_OK === $iError)
|
||||||
|
{
|
||||||
|
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $_FILES[$sInputName]['tmp_name']))
|
||||||
|
{
|
||||||
|
$iError = UploadError::ON_SAVING;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
|
||||||
|
if ($mData)
|
||||||
|
{
|
||||||
|
$sFileStart = @\fread($mData, 20);
|
||||||
|
\rewind($mData);
|
||||||
|
|
||||||
|
if (false !== $sFileStart)
|
||||||
|
{
|
||||||
|
$sFileStart = \trim($sFileStart);
|
||||||
|
if (false !== \strpos($sFileStart, 'BEGIN:VCARD'))
|
||||||
|
{
|
||||||
|
$mResponse = $this->importContactsFromVcfFile($oAccount, $mData, $sFileStart);
|
||||||
|
}
|
||||||
|
else if (false !== \strpos($sFileStart, ',') || false !== \strpos($sFileStart, ';'))
|
||||||
|
{
|
||||||
|
$mResponse = $this->importContactsFromCsvFile($oAccount, $mData, $sFileStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_resource($mData))
|
||||||
|
{
|
||||||
|
@\fclose($mData);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($mData);
|
||||||
|
$this->FilesProvider()->Clear($oAccount, $sSavedName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES))
|
||||||
|
{
|
||||||
|
$iError = UPLOAD_ERR_INI_SIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$iError = UploadError::EMPTY_FILES_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UPLOAD_ERR_OK !== $iError)
|
||||||
|
{
|
||||||
|
$iClientError = UploadClientError::NORMAL;
|
||||||
|
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
|
||||||
|
|
||||||
|
if (!empty($sError))
|
||||||
|
{
|
||||||
|
return $this->FalseResponse(__FUNCTION__, $iClientError, $sError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $mResponse);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|
@ -5200,7 +5429,7 @@ class Actions
|
||||||
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
|
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
|
||||||
if (!empty($sError))
|
if (!empty($sError))
|
||||||
{
|
{
|
||||||
return $this->FalseResponse($sSavedName, $iClientError, $sError);
|
return $this->FalseResponse(__FUNCTION__, $iClientError, $sError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace RainLoop\Providers;
|
namespace RainLoop\Providers;
|
||||||
|
|
||||||
|
use \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType as PropertyType;
|
||||||
|
|
||||||
class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
|
class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -181,4 +183,99 @@ class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
|
||||||
{
|
{
|
||||||
return $this->IsActive() ? $this->oDriver->IncFrec($sEmail, $aEmails, $bCreateAuto) : false;
|
return $this->IsActive() ? $this->oDriver->IncFrec($sEmail, $aEmails, $bCreateAuto) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sCsvName
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function csvNameToTypeConvertor($sCsvName)
|
||||||
|
{
|
||||||
|
static $aMap = null;
|
||||||
|
if (null === $aMap)
|
||||||
|
{
|
||||||
|
$aMap = array(
|
||||||
|
'Title' => PropertyType::FULLNAME,
|
||||||
|
'First Name' => PropertyType::FIRST_NAME,
|
||||||
|
'Middle Name' => PropertyType::MIDDLE_NAME,
|
||||||
|
'Last Name' => PropertyType::LAST_NAME,
|
||||||
|
'Suffix' => PropertyType::NAME_SUFFIX,
|
||||||
|
'Business Fax' => PropertyType::FAX_BUSSINES,
|
||||||
|
'Business Phone' => PropertyType::PHONE_BUSSINES,
|
||||||
|
'Business Phone 2' => PropertyType::PHONE_BUSSINES,
|
||||||
|
'Company Main Phone' => PropertyType::PHONE_BUSSINES,
|
||||||
|
'Home Fax' => PropertyType::FAX_PERSONAL,
|
||||||
|
'Home Phone' => PropertyType::PHONE_PERSONAL,
|
||||||
|
'Home Phone 2' => PropertyType::PHONE_PERSONAL,
|
||||||
|
'Mobile Phone' => PropertyType::MOBILE_PERSONAL,
|
||||||
|
'Other Fax' => PropertyType::FAX_OTHER,
|
||||||
|
'Other Phone' => PropertyType::PHONE_OTHER,
|
||||||
|
// 'Primary Phone' => PropertyType::PHONE_PERSONAL,
|
||||||
|
'E-mail Address' => PropertyType::EMAIl_PERSONAL,
|
||||||
|
'E-mail 2 Address' => PropertyType::EMAIl_OTHER,
|
||||||
|
'E-mail 3 Address' => PropertyType::EMAIl_OTHER,
|
||||||
|
'E-mail Display Name' => PropertyType::FULLNAME,
|
||||||
|
'E-mail 2 Display Name' => PropertyType::FULLNAME,
|
||||||
|
'E-mail 3 Display Name' => PropertyType::FULLNAME,
|
||||||
|
'Notes' => PropertyType::NOTE,
|
||||||
|
'Web Page' => PropertyType::WEB_PAGE_PERSONAL,
|
||||||
|
'WebPage' => PropertyType::WEB_PAGE_PERSONAL,
|
||||||
|
);
|
||||||
|
|
||||||
|
$aMap = array_change_key_case($aMap, CASE_LOWER);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sCsvNameLower = \MailSo\Base\Utils::IsAscii($sCsvName) ? \strtolower($sCsvName) : '';
|
||||||
|
return isset($aMap[$sCsvNameLower]) ? $aMap[$sCsvNameLower] : PropertyType::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sEmail
|
||||||
|
* @param array $aCsvData
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function ImportCsvArray($sEmail, $aCsvData)
|
||||||
|
{
|
||||||
|
$iCount = 0;
|
||||||
|
if ($this->IsActive() && \is_array($aCsvData) && 0 < \count($aCsvData))
|
||||||
|
{
|
||||||
|
$oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact();
|
||||||
|
foreach ($aCsvData as $aItem)
|
||||||
|
{
|
||||||
|
foreach ($aItem as $sItemName => $sItemValue)
|
||||||
|
{
|
||||||
|
$sItemName = \trim($sItemName);
|
||||||
|
$sItemValue = \trim($sItemValue);
|
||||||
|
|
||||||
|
if (!empty($sItemName) && !empty($sItemValue))
|
||||||
|
{
|
||||||
|
$iType = $this->csvNameToTypeConvertor($sItemName);
|
||||||
|
if (PropertyType::UNKNOWN !== $iType)
|
||||||
|
{
|
||||||
|
$oProp = new \RainLoop\Providers\PersonalAddressBook\Classes\Property();
|
||||||
|
$oProp->Type = $iType;
|
||||||
|
$oProp->Value = $sItemValue;
|
||||||
|
|
||||||
|
$oContact->Properties[] = $oProp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oContact && 0 < \count($oContact->Properties))
|
||||||
|
{
|
||||||
|
if ($this->ContactSave($sEmail, $oContact))
|
||||||
|
{
|
||||||
|
$iCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$oContact->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($oContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $iCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@ class Contact
|
||||||
$sFirstName = $oProperty->Value;
|
$sFirstName = $oProperty->Value;
|
||||||
}
|
}
|
||||||
else if (\in_array($oProperty->Type, array(PropertyType::FULLNAME,
|
else if (\in_array($oProperty->Type, array(PropertyType::FULLNAME,
|
||||||
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES,
|
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER,
|
||||||
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES,
|
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
$sOther = $oProperty->Value;
|
$sOther = $oProperty->Value;
|
||||||
|
|
@ -288,6 +288,21 @@ class Contact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($oVCard->URL))
|
||||||
|
{
|
||||||
|
foreach($oVCard->URL as $oUrl)
|
||||||
|
{
|
||||||
|
$oTypes = $oEmail ? $oEmail['TYPE'] : null;
|
||||||
|
$sUrl = $oTypes ? \trim((string) $oUrl) : '';
|
||||||
|
|
||||||
|
if ($oTypes && 0 < \strlen($sUrl))
|
||||||
|
{
|
||||||
|
$oProp = new Property($oTypes->has('WORK') ? PropertyType::WEB_PAGE_BUSSINES : PropertyType::WEB_PAGE_PERSONAL, $sEmail);
|
||||||
|
\array_push($aProperties, $oProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($oVCard->TEL))
|
if (isset($oVCard->TEL))
|
||||||
{
|
{
|
||||||
$bPref = false;
|
$bPref = false;
|
||||||
|
|
@ -402,6 +417,7 @@ class Contact
|
||||||
break;
|
break;
|
||||||
case PropertyType::EMAIl_PERSONAL:
|
case PropertyType::EMAIl_PERSONAL:
|
||||||
case PropertyType::EMAIl_BUSSINES:
|
case PropertyType::EMAIl_BUSSINES:
|
||||||
|
case PropertyType::EMAIl_OTHER:
|
||||||
$aParams = array('TYPE' => array('INTERNET'));
|
$aParams = array('TYPE' => array('INTERNET'));
|
||||||
$aParams['TYPE'][] = PropertyType::EMAIl_BUSSINES === $oProperty->Type ? 'WORK' : 'HOME';
|
$aParams['TYPE'][] = PropertyType::EMAIl_BUSSINES === $oProperty->Type ? 'WORK' : 'HOME';
|
||||||
|
|
||||||
|
|
@ -412,23 +428,33 @@ class Contact
|
||||||
}
|
}
|
||||||
$oVCard->add('EMAIL', $oProperty->Value, $aParams);
|
$oVCard->add('EMAIL', $oProperty->Value, $aParams);
|
||||||
break;
|
break;
|
||||||
|
case PropertyType::WEB_PAGE_PERSONAL:
|
||||||
|
case PropertyType::WEB_PAGE_BUSSINES:
|
||||||
|
case PropertyType::WEB_PAGE_OTHER:
|
||||||
|
$aParams = array('TYPE' => array());
|
||||||
|
$aParams['TYPE'][] = PropertyType::WEB_PAGE_BUSSINES === $oProperty->Type ? 'WORK' : 'HOME';
|
||||||
|
$oVCard->add('URL', $oProperty->Value, $aParams);
|
||||||
|
break;
|
||||||
case PropertyType::PHONE_PERSONAL:
|
case PropertyType::PHONE_PERSONAL:
|
||||||
case PropertyType::PHONE_BUSSINES:
|
case PropertyType::PHONE_BUSSINES:
|
||||||
|
case PropertyType::PHONE_OTHER:
|
||||||
case PropertyType::MOBILE_PERSONAL:
|
case PropertyType::MOBILE_PERSONAL:
|
||||||
case PropertyType::MOBILE_BUSSINES:
|
case PropertyType::MOBILE_BUSSINES:
|
||||||
|
case PropertyType::MOBILE_OTHER:
|
||||||
case PropertyType::FAX_PERSONAL:
|
case PropertyType::FAX_PERSONAL:
|
||||||
case PropertyType::FAX_BUSSINES:
|
case PropertyType::FAX_BUSSINES:
|
||||||
|
case PropertyType::FAX_OTHER:
|
||||||
$aParams = array('TYPE' => array());
|
$aParams = array('TYPE' => array());
|
||||||
$sType = '';
|
$sType = '';
|
||||||
if (\in_array($oProperty->Type, array(PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES)))
|
if (\in_array($oProperty->Type, array(PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER)))
|
||||||
{
|
{
|
||||||
$sType = 'VOICE';
|
$sType = 'VOICE';
|
||||||
}
|
}
|
||||||
else if (\in_array($oProperty->Type, array(PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES)))
|
else if (\in_array($oProperty->Type, array(PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER)))
|
||||||
{
|
{
|
||||||
$sType = 'CELL';
|
$sType = 'CELL';
|
||||||
}
|
}
|
||||||
else if (\in_array($oProperty->Type, array(PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES)))
|
else if (\in_array($oProperty->Type, array(PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES, PropertyType::FAX_OTHER)))
|
||||||
{
|
{
|
||||||
$sType = 'FAX';
|
$sType = 'FAX';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class Property
|
||||||
public function IsEmail()
|
public function IsEmail()
|
||||||
{
|
{
|
||||||
return \in_array($this->Type, array(
|
return \in_array($this->Type, array(
|
||||||
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES
|
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,9 +80,9 @@ class Property
|
||||||
public function IsPhone()
|
public function IsPhone()
|
||||||
{
|
{
|
||||||
return \in_array($this->Type, array(
|
return \in_array($this->Type, array(
|
||||||
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES,
|
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER,
|
||||||
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES,
|
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER,
|
||||||
PropertyType::FAX_BUSSINES
|
PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES, PropertyType::FAX_OTHER
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,19 @@ class PropertyType
|
||||||
|
|
||||||
const EMAIl_PERSONAL = 30;
|
const EMAIl_PERSONAL = 30;
|
||||||
const EMAIl_BUSSINES = 31;
|
const EMAIl_BUSSINES = 31;
|
||||||
|
const EMAIl_OTHER = 32;
|
||||||
|
|
||||||
const PHONE_PERSONAL = 50;
|
const PHONE_PERSONAL = 50;
|
||||||
const PHONE_BUSSINES = 51;
|
const PHONE_BUSSINES = 51;
|
||||||
|
const PHONE_OTHER = 52;
|
||||||
|
|
||||||
const MOBILE_PERSONAL = 60;
|
const MOBILE_PERSONAL = 60;
|
||||||
const MOBILE_BUSSINES = 61;
|
const MOBILE_BUSSINES = 61;
|
||||||
|
const MOBILE_OTHER = 62;
|
||||||
|
|
||||||
const FAX_PERSONAL = 70;
|
const FAX_PERSONAL = 70;
|
||||||
const FAX_BUSSINES = 71;
|
const FAX_BUSSINES = 71;
|
||||||
|
const FAX_OTHER = 72;
|
||||||
|
|
||||||
const FACEBOOK = 90;
|
const FACEBOOK = 90;
|
||||||
const SKYPE = 91;
|
const SKYPE = 91;
|
||||||
|
|
@ -34,5 +38,9 @@ class PropertyType
|
||||||
|
|
||||||
const NOTE = 110;
|
const NOTE = 110;
|
||||||
|
|
||||||
|
const WEB_PAGE_PERSONAL = 220;
|
||||||
|
const WEB_PAGE_BUSSINES = 221;
|
||||||
|
const WEB_PAGE_OTHER = 222;
|
||||||
|
|
||||||
const CUSTOM = 250;
|
const CUSTOM = 250;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -403,9 +403,9 @@ class PdoPersonalAddressBook
|
||||||
($this->bConsiderShare ? ' OR scope_type = :scope_type_share_all' : '').
|
($this->bConsiderShare ? ' OR scope_type = :scope_type_share_all' : '').
|
||||||
') AND (prop_value LIKE :search ESCAPE \'=\''.
|
') AND (prop_value LIKE :search ESCAPE \'=\''.
|
||||||
(0 < \strlen($sCustomSearch) ? ' OR (prop_type IN ('.\implode(',', array(
|
(0 < \strlen($sCustomSearch) ? ' OR (prop_type IN ('.\implode(',', array(
|
||||||
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES,
|
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER,
|
||||||
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES,
|
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER,
|
||||||
PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES
|
PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES, PropertyType::FAX_OTHER
|
||||||
)).') AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
)).') AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
||||||
') GROUP BY id_contact, id_prop';
|
') GROUP BY id_contact, id_prop';
|
||||||
|
|
||||||
|
|
@ -729,7 +729,7 @@ class PdoPersonalAddressBook
|
||||||
$iUserID = $this->getUserId($sEmail);
|
$iUserID = $this->getUserId($sEmail);
|
||||||
|
|
||||||
$sTypes = implode(',', array(
|
$sTypes = implode(',', array(
|
||||||
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::FIRST_NAME, PropertyType::LAST_NAME
|
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FIRST_NAME, PropertyType::LAST_NAME
|
||||||
));
|
));
|
||||||
|
|
||||||
$sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_pab_properties '.
|
$sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_pab_properties '.
|
||||||
|
|
@ -759,6 +759,7 @@ class PdoPersonalAddressBook
|
||||||
{
|
{
|
||||||
$aIdContacts = array();
|
$aIdContacts = array();
|
||||||
$aIdProps = array();
|
$aIdProps = array();
|
||||||
|
$aContactAllAccess = array();
|
||||||
|
|
||||||
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
if (\is_array($aFetch) && 0 < \count($aFetch))
|
if (\is_array($aFetch) && 0 < \count($aFetch))
|
||||||
|
|
@ -767,10 +768,17 @@ class PdoPersonalAddressBook
|
||||||
{
|
{
|
||||||
$iIdContact = $aItem && isset($aItem['id_contact']) ? (int) $aItem['id_contact'] : 0;
|
$iIdContact = $aItem && isset($aItem['id_contact']) ? (int) $aItem['id_contact'] : 0;
|
||||||
$iIdProp = $aItem && isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0;
|
$iIdProp = $aItem && isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0;
|
||||||
|
$iType = $aItem && isset($aItem['prop_type']) ? (int) $aItem['prop_type'] : 0;
|
||||||
|
|
||||||
if (0 < $iIdContact && 0 < $iIdProp)
|
if (0 < $iIdContact && 0 < $iIdProp)
|
||||||
{
|
{
|
||||||
$aIdContacts[$iIdContact] = $iIdContact;
|
$aIdContacts[$iIdContact] = $iIdContact;
|
||||||
$aIdProps[$iIdProp] = $iIdProp;
|
$aIdProps[$iIdProp] = $iIdProp;
|
||||||
|
|
||||||
|
if (\in_array($iType, array(PropertyType::LAST_NAME, PropertyType::FIRST_NAME)))
|
||||||
|
{
|
||||||
|
$aContactAllAccess[$iIdContact] = $iIdContact;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -783,7 +791,7 @@ class PdoPersonalAddressBook
|
||||||
$oStmt->closeCursor();
|
$oStmt->closeCursor();
|
||||||
|
|
||||||
$sTypes = \implode(',', array(
|
$sTypes = \implode(',', array(
|
||||||
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::FIRST_NAME, PropertyType::LAST_NAME
|
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FIRST_NAME, PropertyType::LAST_NAME
|
||||||
));
|
));
|
||||||
|
|
||||||
$sSql = 'SELECT id_prop, id_contact, prop_type, prop_value FROM rainloop_pab_properties '.
|
$sSql = 'SELECT id_prop, id_contact, prop_type, prop_value FROM rainloop_pab_properties '.
|
||||||
|
|
@ -815,7 +823,8 @@ class PdoPersonalAddressBook
|
||||||
|
|
||||||
$aNames[$iIdContact][PropertyType::LAST_NAME === $iType ? 0 : 1] = $aItem['prop_value'];
|
$aNames[$iIdContact][PropertyType::LAST_NAME === $iType ? 0 : 1] = $aItem['prop_value'];
|
||||||
}
|
}
|
||||||
else if (isset($aIdProps[$iIdProp]) && \in_array($iType, array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES)))
|
else if ((isset($aIdProps[$iIdProp]) || isset($aContactAllAccess[$iIdContact]))&&
|
||||||
|
\in_array($iType, array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES)))
|
||||||
{
|
{
|
||||||
if (!isset($aEmails[$iIdContact]))
|
if (!isset($aEmails[$iIdContact]))
|
||||||
{
|
{
|
||||||
|
|
@ -827,8 +836,8 @@ class PdoPersonalAddressBook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->writeLog($aNames);
|
// $this->writeLog($aNames);
|
||||||
$this->writeLog($aEmails);
|
// $this->writeLog($aEmails);
|
||||||
|
|
||||||
foreach ($aEmails as $iId => $aItems)
|
foreach ($aEmails as $iId => $aItems)
|
||||||
{
|
{
|
||||||
|
|
@ -886,7 +895,7 @@ class PdoPersonalAddressBook
|
||||||
$iUserID = $this->getUserId($sEmail);
|
$iUserID = $this->getUserId($sEmail);
|
||||||
|
|
||||||
$sTypes = \implode(',', array(
|
$sTypes = \implode(',', array(
|
||||||
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES
|
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER
|
||||||
));
|
));
|
||||||
|
|
||||||
$aExists = array();
|
$aExists = array();
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,12 @@ class CardDAV implements \Sabre\CardDAV\Backend\BackendInterface
|
||||||
$sEmail = $this->getAuthEmail('', $mAddressBookID);
|
$sEmail = $this->getAuthEmail('', $mAddressBookID);
|
||||||
if (!empty($sEmail))
|
if (!empty($sEmail))
|
||||||
{
|
{
|
||||||
|
if (empty($oVCard->UID))
|
||||||
|
{
|
||||||
|
$oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
|
||||||
|
$sCardData = $oVCard->serialize();
|
||||||
|
}
|
||||||
|
|
||||||
$oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact();
|
$oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact();
|
||||||
$oContact->ParseVCard($oVCard, $sCardData);
|
$oContact->ParseVCard($oVCard, $sCardData);
|
||||||
|
|
||||||
|
|
@ -358,6 +364,12 @@ class CardDAV implements \Sabre\CardDAV\Backend\BackendInterface
|
||||||
$oContact = $this->oPersonalAddressBook->GetContactByID($sEmail, \substr($sCardUri, 0, -4), true);
|
$oContact = $this->oPersonalAddressBook->GetContactByID($sEmail, \substr($sCardUri, 0, -4), true);
|
||||||
if ($oContact && (0 === $iRev || $oContact->Changed < $iRev))
|
if ($oContact && (0 === $iRev || $oContact->Changed < $iRev))
|
||||||
{
|
{
|
||||||
|
if (empty($oVCard->UID))
|
||||||
|
{
|
||||||
|
$oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
|
||||||
|
$sCardData = $oVCard->serialize();
|
||||||
|
}
|
||||||
|
|
||||||
$oContact->ParseVCard($oVCard, $sCardData);
|
$oContact->ParseVCard($oVCard, $sCardData);
|
||||||
if ($this->oPersonalAddressBook->ContactSave($sEmail, $oContact) && !empty($oContact->CardDavHash))
|
if ($this->oPersonalAddressBook->ContactSave($sEmail, $oContact) && !empty($oContact->CardDavHash))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,14 @@ class ServiceActions
|
||||||
return $this->privateUpload('Upload');
|
return $this->privateUpload('Upload');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function ServiceUploadContacts()
|
||||||
|
{
|
||||||
|
return $this->privateUpload('UploadContacts');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,45 @@
|
||||||
<div class="modal hide b-contacts-content" data-bind="modal: modalVisibility">
|
<div class="modal hide b-contacts-content" data-bind="modal: modalVisibility">
|
||||||
<div class="modal-header b-header-toolbar g-ui-user-select-none">
|
<div class="modal-header b-header-toolbar g-ui-user-select-none">
|
||||||
<button type="button" class="close" data-bind="command: cancelCommand">×</button>
|
<button type="button" class="close" data-bind="command: cancelCommand">×</button>
|
||||||
|
<div class="btn-toolbar">
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
<a class="btn button-create-contact" data-bind="command: newCommand">
|
<a class="btn button-create-contact" data-bind="command: newCommand">
|
||||||
<i class="icon-plus"></i>
|
<i class="icon-plus"></i>
|
||||||
|
|
||||||
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_ADD_CONTACT"></span>
|
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_ADD_CONTACT"></span>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="btn dropdown-toggle buttonMore" data-toggle="dropdown">
|
||||||
|
<i data-bind="css: {'icon-list': !contacts.importing(), 'icon-spinner animated': contacts.importing()}"></i>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu g-ui-menu">
|
||||||
|
<li class="e-item">
|
||||||
|
<a class="e-link" data-bind="initDom: importUploaderButton">
|
||||||
|
<i class="icon-list-add"></i>
|
||||||
|
|
||||||
|
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_IMPORT"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
<a class="btn btn-success button-new-message" data-bind="command: newMessageCommand">
|
<a class="btn btn-success button-new-message" data-bind="command: newMessageCommand">
|
||||||
<i class="icon-mail icon-white"></i>
|
<i class="icon-mail icon-white"></i>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
<a class="btn btn-danger button-delete" data-bind="command: deleteCommand">
|
<a class="btn btn-danger button-delete" data-bind="command: deleteCommand">
|
||||||
<i class="icon-trash icon-white"></i>
|
<i class="icon-trash icon-white"></i>
|
||||||
<span data-bind="text: 1 < contactsCheckedOrSelected().length ? ' (' + contactsCheckedOrSelected().length + ')' : ''"></span>
|
<span data-bind="text: 1 < contactsCheckedOrSelected().length ? ' (' + contactsCheckedOrSelected().length + ')' : ''"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="modal-body" style="position: relative">
|
<div class="modal-body" style="position: relative">
|
||||||
<div class="b-list-toopbar">
|
<div class="b-list-toopbar">
|
||||||
<input class="i18n span3 e-search" type="text" placeholder="Search" data-18n-placeholder="CONTACS/SEARCH_INPUT_PLACEHOLDER" data-bind="value: search" />
|
<input class="i18n span3 e-search" type="text" placeholder="Search" data-18n-placeholder="CONTACS/SEARCH_INPUT_PLACEHOLDER" data-bind="value: search" />
|
||||||
|
|
@ -58,7 +84,7 @@
|
||||||
<div class="listEmptySearchList" data-bind="visible: 0 === contacts().length && '' !== search() && !contacts.loading()">
|
<div class="listEmptySearchList" data-bind="visible: 0 === contacts().length && '' !== search() && !contacts.loading()">
|
||||||
<span class="i18n" data-i18n-text="CONTACTS/EMPTY_SEARCH"></span>
|
<span class="i18n" data-i18n-text="CONTACTS/EMPTY_SEARCH"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="e-contact-foreach" data-bind="foreach: contacts, visible: 0 < contacts().length">
|
<div class="e-contact-foreach g-ui-user-select-none" data-bind="foreach: contacts, visible: 0 < contacts().length">
|
||||||
<div class="e-contact-item g-ui-user-select-none" data-bind="css: lineAsCcc()">
|
<div class="e-contact-item g-ui-user-select-none" data-bind="css: lineAsCcc()">
|
||||||
<div class="sidebarParent">
|
<div class="sidebarParent">
|
||||||
|
|
||||||
|
|
@ -133,17 +159,6 @@
|
||||||
<a href="javascript:void(0);" class="g-ui-link add-link i18n" data-bind="visible: !viewReadOnly(), click: addNewPhone" data-i18n-text="CONTACTS/LINK_ADD_PHONE"></a>
|
<a href="javascript:void(0);" class="g-ui-link add-link i18n" data-bind="visible: !viewReadOnly(), click: addNewPhone" data-i18n-text="CONTACTS/LINK_ADD_PHONE"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="control-group" data-bind="foreach: viewPropertiesOther">
|
|
||||||
<label class="control-label remove-padding-top fix-width">
|
|
||||||
|
|
||||||
</label>
|
|
||||||
<div class="controls fix-width">
|
|
||||||
<div class="property-line">
|
|
||||||
<span class="contactValueStatic" data-bind="text: value" />
|
|
||||||
<input type="text" class="contactValueInput" data-bind="value: value, hasFocus: focused, valueUpdate: 'keyup'" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>-->
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="controls fix-width">
|
<div class="controls fix-width">
|
||||||
<br />
|
<br />
|
||||||
|
|
@ -152,10 +167,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="e-save-trigger">
|
|
||||||
<div data-bind="saveTrigger: viewSaveTrigger"></div>
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
<div class="e-read-only-sign">
|
<div class="e-read-only-sign">
|
||||||
<i class="icon-lock iconsize24" data-placement="left" data-bind="tooltip: 'CONTACTS/LABEL_READ_ONLY'"></i>
|
<i class="icon-lock iconsize24" data-placement="left" data-bind="tooltip: 'CONTACTS/LABEL_READ_ONLY'"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Suche"
|
||||||
BUTTON_ADD_CONTACT = "Kontakt hinzufügen"
|
BUTTON_ADD_CONTACT = "Kontakt hinzufügen"
|
||||||
BUTTON_CREATE_CONTACT = "Kontakt anlegen"
|
BUTTON_CREATE_CONTACT = "Kontakt anlegen"
|
||||||
BUTTON_UPDATE_CONTACT = "Kontakt aktualisieren"
|
BUTTON_UPDATE_CONTACT = "Kontakt aktualisieren"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "es wird geladen"
|
LIST_LOADING = "es wird geladen"
|
||||||
EMPTY_LIST = "Keine Kontakte"
|
EMPTY_LIST = "Keine Kontakte"
|
||||||
EMPTY_SEARCH = "Keine Kontakte gefunden"
|
EMPTY_SEARCH = "Keine Kontakte gefunden"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Search"
|
||||||
BUTTON_ADD_CONTACT = "Add Contact"
|
BUTTON_ADD_CONTACT = "Add Contact"
|
||||||
BUTTON_CREATE_CONTACT = "Create"
|
BUTTON_CREATE_CONTACT = "Create"
|
||||||
BUTTON_UPDATE_CONTACT = "Update"
|
BUTTON_UPDATE_CONTACT = "Update"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Loading"
|
LIST_LOADING = "Loading"
|
||||||
EMPTY_LIST = "No contacts here"
|
EMPTY_LIST = "No contacts here"
|
||||||
EMPTY_SEARCH = "No contacts found"
|
EMPTY_SEARCH = "No contacts found"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Buscar"
|
||||||
BUTTON_ADD_CONTACT = "Añadir Contacto"
|
BUTTON_ADD_CONTACT = "Añadir Contacto"
|
||||||
BUTTON_CREATE_CONTACT = "Crear"
|
BUTTON_CREATE_CONTACT = "Crear"
|
||||||
BUTTON_UPDATE_CONTACT = "Actualizar"
|
BUTTON_UPDATE_CONTACT = "Actualizar"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Cargando"
|
LIST_LOADING = "Cargando"
|
||||||
EMPTY_LIST = "No hay contactos aquí"
|
EMPTY_LIST = "No hay contactos aquí"
|
||||||
EMPTY_SEARCH = "No se encontraron contactos"
|
EMPTY_SEARCH = "No se encontraron contactos"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Recherche"
|
||||||
BUTTON_ADD_CONTACT = "Ajouter un contact"
|
BUTTON_ADD_CONTACT = "Ajouter un contact"
|
||||||
BUTTON_CREATE_CONTACT = "Créer"
|
BUTTON_CREATE_CONTACT = "Créer"
|
||||||
BUTTON_UPDATE_CONTACT = "Modifier"
|
BUTTON_UPDATE_CONTACT = "Modifier"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Chargement"
|
LIST_LOADING = "Chargement"
|
||||||
EMPTY_LIST = "Aucun contact"
|
EMPTY_LIST = "Aucun contact"
|
||||||
EMPTY_SEARCH = "Aucun contact trouvé"
|
EMPTY_SEARCH = "Aucun contact trouvé"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Leita"
|
||||||
BUTTON_ADD_CONTACT = "Bæta við tengilið"
|
BUTTON_ADD_CONTACT = "Bæta við tengilið"
|
||||||
BUTTON_CREATE_CONTACT = "Búa til"
|
BUTTON_CREATE_CONTACT = "Búa til"
|
||||||
BUTTON_UPDATE_CONTACT = "Uppfæra"
|
BUTTON_UPDATE_CONTACT = "Uppfæra"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Hleð"
|
LIST_LOADING = "Hleð"
|
||||||
EMPTY_LIST = "Engir tengiliðir hér"
|
EMPTY_LIST = "Engir tengiliðir hér"
|
||||||
EMPTY_SEARCH = "Engir tengiliðir fundust"
|
EMPTY_SEARCH = "Engir tengiliðir fundust"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "검색"
|
||||||
BUTTON_ADD_CONTACT = "연락처 추가"
|
BUTTON_ADD_CONTACT = "연락처 추가"
|
||||||
BUTTON_CREATE_CONTACT = "연락처 추가"
|
BUTTON_CREATE_CONTACT = "연락처 추가"
|
||||||
BUTTON_UPDATE_CONTACT = "연락처 갱신"
|
BUTTON_UPDATE_CONTACT = "연락처 갱신"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "여는중"
|
LIST_LOADING = "여는중"
|
||||||
EMPTY_LIST = "연락처가 없습니다."
|
EMPTY_LIST = "연락처가 없습니다."
|
||||||
EMPTY_SEARCH = "연락처를 찾을 수 없습니다."
|
EMPTY_SEARCH = "연락처를 찾을 수 없습니다."
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Meklēt"
|
||||||
BUTTON_ADD_CONTACT = "Pievienot kontaktu"
|
BUTTON_ADD_CONTACT = "Pievienot kontaktu"
|
||||||
BUTTON_CREATE_CONTACT = "Izveidot"
|
BUTTON_CREATE_CONTACT = "Izveidot"
|
||||||
BUTTON_UPDATE_CONTACT = "Atjaunot"
|
BUTTON_UPDATE_CONTACT = "Atjaunot"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Lādējās"
|
LIST_LOADING = "Lādējās"
|
||||||
EMPTY_LIST = "Nav kontaktu"
|
EMPTY_LIST = "Nav kontaktu"
|
||||||
EMPTY_SEARCH = "Kontakti nav atrasti"
|
EMPTY_SEARCH = "Kontakti nav atrasti"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Zoeken"
|
||||||
BUTTON_ADD_CONTACT = "Contact Toevoegen"
|
BUTTON_ADD_CONTACT = "Contact Toevoegen"
|
||||||
BUTTON_CREATE_CONTACT = "Nieuw"
|
BUTTON_CREATE_CONTACT = "Nieuw"
|
||||||
BUTTON_UPDATE_CONTACT = "Update"
|
BUTTON_UPDATE_CONTACT = "Update"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Laden"
|
LIST_LOADING = "Laden"
|
||||||
EMPTY_LIST = "Geen contacten hier"
|
EMPTY_LIST = "Geen contacten hier"
|
||||||
EMPTY_SEARCH = "Geen contacten gevonden"
|
EMPTY_SEARCH = "Geen contacten gevonden"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Søk"
|
||||||
BUTTON_ADD_CONTACT = "Legg til kontakt"
|
BUTTON_ADD_CONTACT = "Legg til kontakt"
|
||||||
BUTTON_CREATE_CONTACT = "Opprett"
|
BUTTON_CREATE_CONTACT = "Opprett"
|
||||||
BUTTON_UPDATE_CONTACT = "Oppdater"
|
BUTTON_UPDATE_CONTACT = "Oppdater"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Laster"
|
LIST_LOADING = "Laster"
|
||||||
EMPTY_LIST = "Ingen kontakter her"
|
EMPTY_LIST = "Ingen kontakter her"
|
||||||
EMPTY_SEARCH = "Ingen kontakter funnet"
|
EMPTY_SEARCH = "Ingen kontakter funnet"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Szukaj"
|
||||||
BUTTON_ADD_CONTACT = "Dodaj Kontakt"
|
BUTTON_ADD_CONTACT = "Dodaj Kontakt"
|
||||||
BUTTON_CREATE_CONTACT = "Utwórz"
|
BUTTON_CREATE_CONTACT = "Utwórz"
|
||||||
BUTTON_UPDATE_CONTACT = "Aktualizuj"
|
BUTTON_UPDATE_CONTACT = "Aktualizuj"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Ładowanie"
|
LIST_LOADING = "Ładowanie"
|
||||||
EMPTY_LIST = "Brak kontaktów"
|
EMPTY_LIST = "Brak kontaktów"
|
||||||
EMPTY_SEARCH = "Nie znaleziono żadnych kontaktów"
|
EMPTY_SEARCH = "Nie znaleziono żadnych kontaktów"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Procurar"
|
||||||
BUTTON_ADD_CONTACT = "Adicionar Contatos"
|
BUTTON_ADD_CONTACT = "Adicionar Contatos"
|
||||||
BUTTON_CREATE_CONTACT = "Criar"
|
BUTTON_CREATE_CONTACT = "Criar"
|
||||||
BUTTON_UPDATE_CONTACT = "Atualizar"
|
BUTTON_UPDATE_CONTACT = "Atualizar"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Carregando"
|
LIST_LOADING = "Carregando"
|
||||||
EMPTY_LIST = "Nenhum contato aqui"
|
EMPTY_LIST = "Nenhum contato aqui"
|
||||||
EMPTY_SEARCH = "Nenhum contato encontrado"
|
EMPTY_SEARCH = "Nenhum contato encontrado"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Procurar"
|
||||||
BUTTON_ADD_CONTACT = "Adicionar Contatos"
|
BUTTON_ADD_CONTACT = "Adicionar Contatos"
|
||||||
BUTTON_CREATE_CONTACT = "Criar"
|
BUTTON_CREATE_CONTACT = "Criar"
|
||||||
BUTTON_UPDATE_CONTACT = "Atualizar"
|
BUTTON_UPDATE_CONTACT = "Atualizar"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "Carregando"
|
LIST_LOADING = "Carregando"
|
||||||
EMPTY_LIST = "Nenhum contato aqui"
|
EMPTY_LIST = "Nenhum contato aqui"
|
||||||
EMPTY_SEARCH = "Nenhum contato encontrado"
|
EMPTY_SEARCH = "Nenhum contato encontrado"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "Поиск контактов"
|
||||||
BUTTON_ADD_CONTACT = "Добавить контакт"
|
BUTTON_ADD_CONTACT = "Добавить контакт"
|
||||||
BUTTON_CREATE_CONTACT = "Сохранить"
|
BUTTON_CREATE_CONTACT = "Сохранить"
|
||||||
BUTTON_UPDATE_CONTACT = "Обновить"
|
BUTTON_UPDATE_CONTACT = "Обновить"
|
||||||
|
BUTTON_IMPORT = "Импорт (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Ошибка импорта (Неправильный формат файла)"
|
||||||
LIST_LOADING = "Загрузка"
|
LIST_LOADING = "Загрузка"
|
||||||
EMPTY_LIST = "Нет контактов"
|
EMPTY_LIST = "Нет контактов"
|
||||||
EMPTY_SEARCH = "Контакты не найдены"
|
EMPTY_SEARCH = "Контакты не найдены"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ SEARCH_INPUT_PLACEHOLDER = "搜索"
|
||||||
BUTTON_ADD_CONTACT = "添加联系人"
|
BUTTON_ADD_CONTACT = "添加联系人"
|
||||||
BUTTON_CREATE_CONTACT = "新增联系人"
|
BUTTON_CREATE_CONTACT = "新增联系人"
|
||||||
BUTTON_UPDATE_CONTACT = "更新联系人"
|
BUTTON_UPDATE_CONTACT = "更新联系人"
|
||||||
|
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
|
||||||
|
ERROR_IMPORT_FILE = "Import error (invalid file format)"
|
||||||
LIST_LOADING = "加载中"
|
LIST_LOADING = "加载中"
|
||||||
EMPTY_LIST = "暂无联系人"
|
EMPTY_LIST = "暂无联系人"
|
||||||
EMPTY_SEARCH = "没找到联系人"
|
EMPTY_SEARCH = "没找到联系人"
|
||||||
|
|
|
||||||
|
|
@ -5267,7 +5267,8 @@ a.badge:hover {
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
margin-left: -2px;
|
margin-left: -1px;
|
||||||
|
width: 17px;
|
||||||
}
|
}
|
||||||
.iconsize24 {
|
.iconsize24 {
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
|
|
@ -5680,11 +5681,13 @@ html.no-rgba .modal {
|
||||||
}
|
}
|
||||||
.g-ui-user-select-none {
|
.g-ui-user-select-none {
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
-khtml-user-select: none;
|
-khtml-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
-o-user-select: none;
|
-o-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-touch-callout: none;
|
standard-user-select: none;
|
||||||
}
|
}
|
||||||
.g-ui-clearfix {
|
.g-ui-clearfix {
|
||||||
*zoom: 1;
|
*zoom: 1;
|
||||||
|
|
@ -7483,7 +7486,7 @@ html.rl-message-fullscreen .messageView .b-content .buttonFull {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
width: 250px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
.b-contacts-content.modal .b-view-content .contactValueInput:hover {
|
.b-contacts-content.modal .b-view-content .contactValueInput:hover {
|
||||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
|
|
||||||
2
rainloop/v/0.0.0/static/css/app.min.css
vendored
2
rainloop/v/0.0.0/static/css/app.min.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -3022,6 +3022,14 @@ LinkBuilder.prototype.upload = function ()
|
||||||
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
LinkBuilder.prototype.uploadContacts = function ()
|
||||||
|
{
|
||||||
|
return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
4
rainloop/v/0.0.0/static/js/admin.min.js
vendored
4
rainloop/v/0.0.0/static/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -3022,6 +3022,14 @@ LinkBuilder.prototype.upload = function ()
|
||||||
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
LinkBuilder.prototype.uploadContacts = function ()
|
||||||
|
{
|
||||||
|
return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
@ -4376,9 +4384,16 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable)
|
||||||
;
|
;
|
||||||
|
|
||||||
$(this.oContentVisible)
|
$(this.oContentVisible)
|
||||||
|
.on('selectstart', function (oEvent) {
|
||||||
|
if (oEvent && oEvent.preventDefault)
|
||||||
|
{
|
||||||
|
oEvent.preventDefault();
|
||||||
|
}
|
||||||
|
})
|
||||||
.on('click', this.sItemSelector, function (oEvent) {
|
.on('click', this.sItemSelector, function (oEvent) {
|
||||||
self.actionClick(ko.dataFor(this), oEvent);
|
self.actionClick(ko.dataFor(this), oEvent);
|
||||||
}).on('click', this.sItemCheckedSelector, function (oEvent) {
|
})
|
||||||
|
.on('click', this.sItemCheckedSelector, function (oEvent) {
|
||||||
var oItem = ko.dataFor(this);
|
var oItem = ko.dataFor(this);
|
||||||
if (oItem)
|
if (oItem)
|
||||||
{
|
{
|
||||||
|
|
@ -9429,8 +9444,11 @@ function PopupsContactsViewModel()
|
||||||
this.contactsCount = ko.observable(0);
|
this.contactsCount = ko.observable(0);
|
||||||
this.contacts = ko.observableArray([]);
|
this.contacts = ko.observableArray([]);
|
||||||
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
|
||||||
this.currentContact = ko.observable(null);
|
this.currentContact = ko.observable(null);
|
||||||
|
|
||||||
|
this.importUploaderButton = ko.observable(null);
|
||||||
|
|
||||||
this.contactsSharingIsAllowed = !!RL.settingsGet('ContactsSharingIsAllowed');
|
this.contactsSharingIsAllowed = !!RL.settingsGet('ContactsSharingIsAllowed');
|
||||||
|
|
||||||
this.contactsPage = ko.observable(1);
|
this.contactsPage = ko.observable(1);
|
||||||
|
|
@ -9733,6 +9751,46 @@ PopupsContactsViewModel.prototype.addNewPhone = function ()
|
||||||
this.addNewProperty(Enums.ContactPropertyType.MobilePersonal);
|
this.addNewProperty(Enums.ContactPropertyType.MobilePersonal);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PopupsContactsViewModel.prototype.initUploader = function ()
|
||||||
|
{
|
||||||
|
if (this.importUploaderButton())
|
||||||
|
{
|
||||||
|
var
|
||||||
|
oJua = new Jua({
|
||||||
|
'action': RL.link().uploadContacts(),
|
||||||
|
'name': 'uploader',
|
||||||
|
'queueSize': 1,
|
||||||
|
'multipleSizeLimit': 1,
|
||||||
|
'disableFolderDragAndDrop': true,
|
||||||
|
'disableDragAndDrop': true,
|
||||||
|
'disableMultiple': true,
|
||||||
|
'disableDocumentDropPrevent': true,
|
||||||
|
'clickElement': this.importUploaderButton()
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
if (oJua)
|
||||||
|
{
|
||||||
|
oJua
|
||||||
|
.on('onStart', _.bind(function () {
|
||||||
|
this.contacts.importing(true);
|
||||||
|
}, this))
|
||||||
|
.on('onComplete', _.bind(function (sId, bResult, oData) {
|
||||||
|
|
||||||
|
this.contacts.importing(false);
|
||||||
|
this.reloadContactList();
|
||||||
|
|
||||||
|
if (!sId || !bResult || !oData || !oData.Result)
|
||||||
|
{
|
||||||
|
window.alert(Utils.i18n('CONTACTS/ERROR_IMPORT_FILE'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}, this))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
PopupsContactsViewModel.prototype.removeCheckedOrSelectedContactsFromList = function ()
|
PopupsContactsViewModel.prototype.removeCheckedOrSelectedContactsFromList = function ()
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
|
|
@ -9972,6 +10030,8 @@ PopupsContactsViewModel.prototype.onBuild = function (oDom)
|
||||||
|
|
||||||
return bResult;
|
return bResult;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.initUploader();
|
||||||
};
|
};
|
||||||
|
|
||||||
PopupsContactsViewModel.prototype.onShow = function ()
|
PopupsContactsViewModel.prototype.onShow = function ()
|
||||||
|
|
|
||||||
14
rainloop/v/0.0.0/static/js/app.min.js
vendored
14
rainloop/v/0.0.0/static/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue