From 02ba68868fdce44f28ecadb0a1297a0137811ece Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Thu, 22 Jan 2015 00:15:40 +0400 Subject: [PATCH] Sieve filters (interface) --- dev/Model/Filter.js | 33 +++++++++++++++++ dev/Model/FilterCondition.js | 29 ++++++++++++++- dev/Settings/User/Filters.js | 37 +++++++++++++++---- dev/View/Admin/Settings/Pane.js | 2 - dev/View/Popup/Filter.js | 6 ++- .../0.0.0/app/libraries/RainLoop/Actions.php | 1 - .../Providers/Filters/Classes/Filter.php | 6 +-- .../Providers/Filters/SieveStorage.php | 8 +++- .../templates/Views/User/MailMessageView.html | 2 +- .../templates/Views/User/SettingsFilters.html | 10 +++++ .../User/SettingsFiltersActionVacation.html | 5 +-- .../User/SettingsFiltersConditionDefault.html | 20 +++++----- 12 files changed, 129 insertions(+), 30 deletions(-) diff --git a/dev/Model/Filter.js b/dev/Model/Filter.js index 664fc913d..58d43272f 100644 --- a/dev/Model/Filter.js +++ b/dev/Model/Filter.js @@ -146,6 +146,16 @@ return false; } + if (0 < this.conditions().length) + { + if (_.find(this.conditions(), function (oCond) { + return oCond && !oCond.verify(); + })) + { + return false; + } + } + if ('' === this.actionValue()) { if (-1 < Utils.inArray(this.actionType(), [ @@ -211,6 +221,29 @@ { this.id = Utils.pString(oItem['ID']); this.name(Utils.pString(oItem['Name'])); + this.enabled(!!oItem['Enabled']); + + this.conditionsType(Utils.pString(oItem['ConditionsType'])); + + this.conditions([]); + + if (Utils.isNonEmptyArray(oItem['Conditions'])) + { + this.conditions(_.compact(_.map(oItem['Conditions'], function (aData) { + var oFilterCondition = new FilterConditionModel(); + return oFilterCondition && oFilterCondition.parse(aData) ? + oFilterCondition : null; + }))); + } + + this.actionType(Utils.pString(oItem['ActionType'])); + + this.actionValue(Utils.pString(oItem['ActionValue'])); + this.actionValueSecond(Utils.pString(oItem['ActionValueSecond'])); + + this.actionMarkAsRead(!!oItem['MarkAsRead']); + this.keepForward(!!oItem['KeepForward']); + this.actionSkipOthers(!!oItem['SkipOthers']); bResult = true; } diff --git a/dev/Model/FilterCondition.js b/dev/Model/FilterCondition.js index b3239a309..9192ea059 100644 --- a/dev/Model/FilterCondition.js +++ b/dev/Model/FilterCondition.js @@ -8,6 +8,7 @@ ko = require('ko'), Enums = require('Common/Enums'), + Utils = require('Common/Utils'), AbstractModel = require('Knoin/AbstractModel') ; @@ -20,8 +21,9 @@ AbstractModel.call(this, 'FilterConditionModel'); this.field = ko.observable(Enums.FilterConditionField.From); - this.type = ko.observable(Enums.FilterConditionType.EqualTo); + this.type = ko.observable(Enums.FilterConditionType.Contains); this.value = ko.observable(''); + this.value.error = ko.observable(false); this.template = ko.computed(function () { @@ -42,6 +44,31 @@ _.extend(FilterConditionModel.prototype, AbstractModel.prototype); + FilterConditionModel.prototype.verify = function () + { + if ('' === this.value()) + { + this.value.error(true); + return false; + } + + return true; + }; + + FilterConditionModel.prototype.parse = function (oItem) + { + if (oItem && oItem['Field'] && oItem['Type']) + { + this.field(Utils.pString(oItem['Field'])); + this.type(Utils.pString(oItem['Type'])); + this.value(Utils.pString(oItem['Value'])); + + return true; + } + + return false; + }; + FilterConditionModel.prototype.toJson = function () { return { diff --git a/dev/Settings/User/Filters.js b/dev/Settings/User/Filters.js index 4a4cfb1a2..fa9e84cf8 100644 --- a/dev/Settings/User/Filters.js +++ b/dev/Settings/User/Filters.js @@ -5,6 +5,7 @@ var ko = require('ko'), + _ = require('_'), Enums = require('Common/Enums'), Utils = require('Common/Utils'), @@ -80,11 +81,33 @@ FiltersUserSettings.prototype.updateList = function () { - var self = this; + var + self = this, + FilterModel = require('Model/Filter') + ; this.filters.loading(true); + Remote.filtersGet(function (sResult, oData) { + self.filters.loading(false); + + if (Enums.StorageResultType.Success === sResult && oData && + oData.Result && Utils.isArray(oData.Result)) + { + var aResult = _.compact(_.map(oData.Result, function (aItem) { + var oNew = new FilterModel(); + return (oNew && oNew.parse(aItem)) ? oNew : null; + })); + + self.filters(aResult); + } + else + { + self.filters([]); + } + + self.haveChanges(false); }); }; @@ -121,16 +144,16 @@ require('View/Popup/Filter'), [oCloned, function () { var - oFilters = self.filters(), - iIndex = oFilters.indexOf(oEdit) + aFilters = self.filters(), + iIndex = aFilters.indexOf(oEdit) ; - if (-1 < iIndex && oFilters[iIndex]) + if (-1 < iIndex && aFilters[iIndex]) { - Utils.delegateRunOnDestroy(oFilters[iIndex]); - oFilters[iIndex] = oCloned; + Utils.delegateRunOnDestroy(aFilters[iIndex]); + aFilters[iIndex] = oCloned; - self.filters(oFilters); + self.filters(aFilters); self.haveChanges(true); } diff --git a/dev/View/Admin/Settings/Pane.js b/dev/View/Admin/Settings/Pane.js index 9e3c392ee..6e93c9e91 100644 --- a/dev/View/Admin/Settings/Pane.js +++ b/dev/View/Admin/Settings/Pane.js @@ -7,8 +7,6 @@ _ = require('_'), ko = require('ko'), - Utils = require('Common/Utils'), - Settings = require('Storage/Settings'), Data = require('Storage/Admin/Data'), Remote = require('Storage/Admin/Remote'), diff --git a/dev/View/Popup/Filter.js b/dev/View/Popup/Filter.js index 0f7f640d7..10c7bb634 100644 --- a/dev/View/Popup/Filter.js +++ b/dev/View/Popup/Filter.js @@ -7,7 +7,6 @@ _ = require('_'), ko = require('ko'), - Consts = require('Common/Consts'), Enums = require('Common/Enums'), Utils = require('Common/Utils'), @@ -119,6 +118,11 @@ this.fTrueCallback = fTrueCallback; this.filter(oFilter); + if (oFilter) + { + this.selectedFolderValue(oFilter.actionValue()); + } + this.isNew(!bEdit); if (!bEdit && oFilter) diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index ecc88def5..61abf59a4 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -2063,7 +2063,6 @@ class Actions */ public function DoFiltersSave() { - sleep(1); $aIncFilters = $this->GetActionParam('Filters', array()); $aFilters = array(); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/Filter.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/Filter.php index 0f95d8ec8..e21bf73fd 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/Filter.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/Filter.php @@ -217,9 +217,9 @@ class Filter $this->sActionValue = isset($aFilter['ActionValue']) ? $aFilter['ActionValue'] : ''; $this->sActionValueSecond = isset($aFilter['ActionValueSecond']) ? $aFilter['ActionValueSecond'] : ''; - $this->bMarkAsRead = isset($aFilter['MarkAsRead']) ? $aFilter['MarkAsRead'] : false; - $this->bSkipOthers = isset($aFilter['SkipOthers']) ? $aFilter['SkipOthers'] : false; - $this->bKeepForward = isset($aFilter['KeepForward']) ? $aFilter['KeepForward'] : true; + $this->bMarkAsRead = isset($aFilter['MarkAsRead']) ? '1' === (string) $aFilter['MarkAsRead'] : false; + $this->bSkipOthers = isset($aFilter['SkipOthers']) ? '1' === (string) $aFilter['SkipOthers'] : false; + $this->bKeepForward = isset($aFilter['KeepForward']) ? '1' === (string) $aFilter['KeepForward'] : true; $this->aConditions = \RainLoop\Providers\Filters\Classes\FilterCondition::CollectionFromJSON( isset($aFilter['Conditions']) ? $aFilter['Conditions'] : array()); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/SieveStorage.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/SieveStorage.php index c2f4b5bfc..a75a807fc 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/SieveStorage.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Filters/SieveStorage.php @@ -180,7 +180,11 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface $sTab = ''; } - if ($oFilter->MarkAsRead()) + if ($oFilter->MarkAsRead() && \in_array($oFilter->ActionType(), array( + \RainLoop\Providers\Filters\Enumerations\ActionType::NONE, + \RainLoop\Providers\Filters\Enumerations\ActionType::MOVE_TO, + \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD + ))) { $aCapa['imap4flags'] = true; $aResult[] = $sTab.'addflag "\\\\Seen";'; @@ -353,6 +357,6 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface */ private function quote($sValue) { - return \str_replace('"', '\\"', \trim($sValue)); + return \str_replace(array('\\', '"'), array('\\\\', '\\"'), \trim($sValue)); } } diff --git a/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html b/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html index be5f5bdb9..eafdcd8ac 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html @@ -280,7 +280,7 @@    -
+
   diff --git a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html index 9f879d5a7..01fa444de 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html @@ -19,6 +19,16 @@
+
+
+
+
+ +    + These changes need to be saved to the server. @i18n +
+
+
diff --git a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html index 8acee0fd2..976d889bf 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html @@ -1,10 +1,9 @@ -
-
+
-
+
diff --git a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html index 61f6978de..4ddd8c021 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html @@ -1,9 +1,11 @@ - -  - -  - -  - - - \ No newline at end of file +
+ +   + +   + +   + + + +
\ No newline at end of file