mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-11 00:14:50 +03:00
Sieve filters (interface)
This commit is contained in:
parent
68cc322bd5
commit
02ba68868f
12 changed files with 129 additions and 30 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -2063,7 +2063,6 @@ class Actions
|
|||
*/
|
||||
public function DoFiltersSave()
|
||||
{
|
||||
sleep(1);
|
||||
$aIncFilters = $this->GetActionParam('Filters', array());
|
||||
|
||||
$aFilters = array();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@
|
|||
|
||||
<span class="i18n text" data-i18n-text="MESSAGE/BUTTON_SHOW_IMAGES"></span>
|
||||
</div>
|
||||
<div class="readReceipt" data-bind="visible: message() && '' !== message().readReceipt() && !message().isReadReceipt(), click: function() { readReceipt(message()); }">
|
||||
<div class="readReceipt" data-bind="visible: message() && !isDraftOrSentFolder() && '' !== message().readReceipt() && !message().isReadReceipt(), click: function() { readReceipt(message()); }">
|
||||
<i class="icon-mail"></i>
|
||||
|
||||
<span class="i18n text" data-i18n-text="MESSAGE/BUTTON_NOTIFY_READ_RECEIPT"></span>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,16 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" data-bind="visible: haveChanges">
|
||||
<div class="span8">
|
||||
<br />
|
||||
<div class="alert g-ui-user-select-none" style="margin-bottom: 0">
|
||||
<i class="icon-warning"></i>
|
||||
|
||||
These changes need to be saved to the server. @i18n
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span8">
|
||||
<div class="process-place g-ui-user-select-none" data-bind="style: {'visibility': visibility }">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
<br />
|
||||
<div class="control-group">
|
||||
<div class="control-group" style="margin-bottom: 0">
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" data-bind="value: actionValueSecond" placeholder="Subject (optional) @i18n" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {'error': actionValue.error}">
|
||||
<div class="control-group" data-bind="css: {'error': actionValue.error}" style="margin-bottom: 0">
|
||||
<div class="controls">
|
||||
<textarea class="span5" data-bind="value: actionValue" style="height: 100px;" placeholder="Message @i18n"></textarea>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<select class="span3" data-bind="options: $root.fieldOptions, value: field, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
|
||||
<select class="span2" data-bind="options: $root.typeOptions, value: type, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="icon-trash"></i>
|
||||
</span>
|
||||
<div class="control-group" data-bind="css: {'error': value.error}" style="margin-bottom: 0">
|
||||
<select class="span3" data-bind="options: $root.fieldOptions, value: field, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
|
||||
<select class="span2" data-bind="options: $root.typeOptions, value: type, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="icon-trash"></i>
|
||||
</span>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue