Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56f8e68599 | |||
| e8d75808ef | |||
| bc8bf89d6e | |||
| 91385cc3f0 | |||
| ad21511c72 | |||
| 938a24f102 | |||
| 43b041ed6c | |||
| 5e3f048795 | |||
| 3aec3ef6d2 | |||
| 712a450734 | |||
| 5675b6721b | |||
| a4e23b8adb | |||
| 9d49f418c8 | |||
| ea9f70dffa | |||
| b624accbe8 | |||
| 12f974635e | |||
| cfce68eb7e | |||
| db8fbd1ed3 |
@@ -48,6 +48,6 @@ class ContainsType extends \Espo\Core\Formula\Functions\Base
|
||||
return false;
|
||||
}
|
||||
|
||||
return strpos($string, $needle) !== false;
|
||||
return mb_strpos($string, $needle) !== false;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,6 @@ class LowerCaseType extends \Espo\Core\Formula\Functions\Base
|
||||
$value = strval($value);
|
||||
}
|
||||
|
||||
return strtolower($value);
|
||||
return mb_strtolower($value);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
@@ -52,9 +52,9 @@ class SubstringType extends \Espo\Core\Formula\Functions\Base
|
||||
|
||||
if (count($item->value) > 2) {
|
||||
$length = $this->evaluate($item->value[2]);
|
||||
return substr($string, $start, $length);
|
||||
return mb_substr($string, $start, $length);
|
||||
} else {
|
||||
return substr($string, $start);
|
||||
return mb_substr($string, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,6 @@ class UpperCaseType extends \Espo\Core\Formula\Functions\Base
|
||||
$value = strval($value);
|
||||
}
|
||||
|
||||
return strtoupper($value);
|
||||
return mb_strtoupper($value);
|
||||
}
|
||||
}
|
||||
@@ -176,6 +176,8 @@ class Parser
|
||||
|
||||
$this->processStrings($expression, $modifiedExpression, $splitterIndexList, true);
|
||||
|
||||
$expressionOutOfBraceList = [];
|
||||
|
||||
for ($i = 0; $i < strlen($modifiedExpression); $i++) {
|
||||
if ($modifiedExpression[$i] === '(') {
|
||||
$braceCounter++;
|
||||
@@ -186,6 +188,11 @@ class Parser
|
||||
if ($braceCounter === 0 && $i < strlen($modifiedExpression) - 1) {
|
||||
$hasExcessBraces = false;
|
||||
}
|
||||
if ($braceCounter === 0) {
|
||||
$expressionOutOfBraceList[] = true;
|
||||
} else {
|
||||
$expressionOutOfBraceList[] = false;
|
||||
}
|
||||
}
|
||||
if ($braceCounter !== 0) {
|
||||
throw new Error('Incorrect round brackets in expression ' . $expression . '.');
|
||||
@@ -226,7 +233,13 @@ class Parser
|
||||
|
||||
foreach ($this->priorityList as $operationList) {
|
||||
foreach ($operationList as $operator) {
|
||||
$index = strpos($expression, $operator, 1);
|
||||
$startFrom = 1;
|
||||
while (true) {
|
||||
$index = strpos($expression, $operator, $startFrom);
|
||||
if ($index === false) break;
|
||||
if ($expressionOutOfBraceList[$index]) break;
|
||||
$startFrom = $index + 1;
|
||||
}
|
||||
if ($index !== false) {
|
||||
$possibleRightOperator = null;
|
||||
if (strlen($operator) === 1) {
|
||||
|
||||
@@ -161,6 +161,9 @@ class Base
|
||||
if ($desc) {
|
||||
$list = array_reverse($list);
|
||||
}
|
||||
foreach ($list as $i => $listItem) {
|
||||
$list[$i] = str_replace(',', '_COMMA_', $listItem);
|
||||
}
|
||||
$result['orderBy'] = 'LIST:' . $sortBy . ':' . implode(',', $list);
|
||||
return;
|
||||
}
|
||||
@@ -1636,18 +1639,31 @@ class Base
|
||||
$textFilterForFullTextSearch = $textFilter;
|
||||
|
||||
$skipWidlcards = false;
|
||||
if (!$useFullTextSearch) {
|
||||
if (mb_strpos($textFilter, '*') !== false) {
|
||||
$skipWidlcards = true;
|
||||
$textFilter = str_replace('*', '%', $textFilter);
|
||||
} else {
|
||||
|
||||
if (mb_strpos($textFilter, '*') !== false) {
|
||||
$skipWidlcards = true;
|
||||
$textFilter = str_replace('*', '%', $textFilter);
|
||||
} else {
|
||||
if (!$useFullTextSearch) {
|
||||
$textFilterForFullTextSearch .= '*';
|
||||
}
|
||||
|
||||
$textFilterForFullTextSearch = str_replace('%', '*', $textFilterForFullTextSearch);
|
||||
}
|
||||
|
||||
$fullTextSearchData = $this->getFullTextSearchDataForTextFilter($textFilterForFullTextSearch, !$useFullTextSearch);
|
||||
$textFilterForFullTextSearch = str_replace('%', '*', $textFilterForFullTextSearch);
|
||||
|
||||
$skipFullTextSearch = false;
|
||||
if (!$forceFullTextSearch) {
|
||||
if (mb_strpos($textFilterForFullTextSearch, '*') === 0) {
|
||||
$skipFullTextSearch = true;
|
||||
} else if (mb_strpos($textFilterForFullTextSearch, ' *') !== false) {
|
||||
$skipFullTextSearch = true;
|
||||
}
|
||||
}
|
||||
|
||||
$fullTextSearchData = null;
|
||||
if (!$skipFullTextSearch) {
|
||||
$fullTextSearchData = $this->getFullTextSearchDataForTextFilter($textFilterForFullTextSearch, !$useFullTextSearch);
|
||||
}
|
||||
|
||||
$fullTextGroup = [];
|
||||
|
||||
|
||||
@@ -58,18 +58,32 @@ class AssignmentEmailNotification extends \Espo\Core\Hooks\Base
|
||||
|
||||
foreach ($userIdList as $userId) {
|
||||
if (in_array($userId, $fetchedAssignedUserIdList)) continue;
|
||||
if ($this->getUser()->id === $userId) continue;
|
||||
if (!$this->isNotSelfAssignment($entity, $userId)) continue;
|
||||
$this->createJob($entity, $userId);
|
||||
}
|
||||
} else {
|
||||
$userId = $entity->get('assignedUserId');
|
||||
if (!empty($userId) && $userId != $this->getUser()->id && $entity->isAttributeChanged('assignedUserId')) {
|
||||
if (!empty($userId) && $entity->isAttributeChanged('assignedUserId') && $this->isNotSelfAssignment($entity, $userId)) {
|
||||
$this->createJob($entity, $userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function isNotSelfAssignment(Entity $entity, $assignedUserId)
|
||||
{
|
||||
if ($entity->hasAttribute('createdById') && $entity->hasAttribute('modifiedById')) {
|
||||
if ($entity->isNew()) {
|
||||
$isNotSelfAssignment = $assignedUserId !== $entity->get('createdById');
|
||||
} else {
|
||||
$isNotSelfAssignment = $assignedUserId !== $entity->get('modifiedById');
|
||||
}
|
||||
} else {
|
||||
$isNotSelfAssignment = $assignedUserId !== $this->getUser()->id;
|
||||
}
|
||||
return $isNotSelfAssignment;
|
||||
}
|
||||
|
||||
protected function createJob(Entity $entity, $userId)
|
||||
{
|
||||
$job = $this->getEntityManager()->getEntity('Job');
|
||||
|
||||
@@ -576,7 +576,13 @@ abstract class Base
|
||||
if (strpos($orderBy, 'LIST:') === 0) {
|
||||
list($l, $field, $list) = explode(':', $orderBy);
|
||||
$fieldPath = $this->getFieldPathForOrderBy($entity, $field);
|
||||
$part = "FIELD(" . $fieldPath . ", '" . implode("', '", array_reverse(explode(",", $list))) . "') DESC";
|
||||
$listQuoted = [];
|
||||
$list = array_reverse(explode(',', $list));
|
||||
foreach ($list as $i => $listItem) {
|
||||
$listItem = str_replace('_COMMA_', ',', $listItem);
|
||||
$listQuoted[] = $this->quote($listItem);
|
||||
}
|
||||
$part = "FIELD(" . $fieldPath . ", " . implode(", ", $listQuoted) . ") DESC";
|
||||
return $part;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
"personStringData": {
|
||||
"type": "varchar",
|
||||
"notStorable": true,
|
||||
"disabled": true
|
||||
"disabled": true,
|
||||
"view": "views/email/fields/person-string-data"
|
||||
},
|
||||
"isRead": {
|
||||
"type": "bool",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<span class="list-icon-container pull-right"{{#unless isReplied}} style="visibility: hidden;"{{/unless}}>
|
||||
<span class="glyphicon glyphicon-share-alt small text-muted icon-flip-horizontal" title="{{translate 'isReplied' category='fields' scope='Email'}}"></span>
|
||||
</span>
|
||||
<span title="{{value}}">{{value}}</span>
|
||||
@@ -1,5 +1,7 @@
|
||||
{{#if hasAttachment}}
|
||||
<span class="glyphicon glyphicon-paperclip small text-muted pull-right"></span>
|
||||
<span class="list-icon-container pull-right">
|
||||
<span class="glyphicon glyphicon-paperclip small text-muted" title="{{translate 'hasAttachment' category='fields' scope='Email'}}"></span>
|
||||
</span>
|
||||
{{/if}}
|
||||
{{#unless isRead}}<strong>{{/unless}}
|
||||
<a href="#{{model.name}}/view/{{model.id}}" class="link{{#if isImportant}} text-warning{{/if}}" data-id="{{model.id}}" title="{{value}}">{{value}}</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{{#unless isPlain}}
|
||||
{{#if useIframe}}
|
||||
<iframe frameborder="0" style="width: 100%;" class="hidden" scrolling="no"></iframe>
|
||||
<iframe frameborder="0" style="width: 100%; overflow-x: hidden; overflow-y: hidden;" class="hidden"></iframe>
|
||||
{{else}}
|
||||
<div class="html-container">{{{value}}}</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -1 +1 @@
|
||||
<input type="checkbox" class="record-checkbox" data-id="{{model.id}}">
|
||||
<span class="record-checkbox-container"><input type="checkbox" class="record-checkbox" data-id="{{model.id}}"></span>
|
||||
@@ -1,3 +1,4 @@
|
||||
{{#if fieldList.length}}
|
||||
<div class="row">
|
||||
{{#each fieldList}}
|
||||
<div class="cell form-group col-sm-6 col-md-12{{#if hidden}} hidden-cell{{/if}}" data-name="{{name}}">
|
||||
@@ -8,21 +9,26 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless complexDateFieldsDisabled}}
|
||||
<div class="row">
|
||||
{{#if hasComplexCreated}}
|
||||
<div class="cell form-group col-sm-6 col-md-12" data-name="complexCreated">
|
||||
<label class="control-label" data-name="complexCreated"><span class="label-text">{{translate 'Created'}}</span></label>
|
||||
<div class="field" data-name="complexCreated">
|
||||
<span data-name="createdAt" class="field">{{{createdAtField}}}</span> <span class="text-muted">»</span> <span data-name="createdBy" class="field">{{{createdByField}}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if hasComplexModified}}
|
||||
<div class="cell form-group col-sm-6 col-md-12" data-name="complexModified">
|
||||
<label class="control-label" data-name="complexModified"><span class="label-text">{{translate 'Modified'}}</span></label>
|
||||
<div class="field" data-name="complexModified">
|
||||
<span data-name="modifiedAt" class="field">{{{modifiedAtField}}}</span> <span class="text-muted">»</span> <span data-name="modifiedBy" class="field">{{{modifiedByField}}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{#if fieldList.length}}
|
||||
<div class="row">
|
||||
{{#each fieldList}}
|
||||
<div class="cell form-group col-sm-6 col-md-12{{#if hidden}} hidden-cell{{/if}}" data-name="{{name}}">
|
||||
@@ -8,3 +9,4 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -35,7 +35,8 @@ Espo.define('views/admin/entity-manager/record/edit-formula', 'views/record/base
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
this.createField('beforeSaveCustomScript', 'views/fields/formula', {
|
||||
targetEntityType: this.options.targetEntityType
|
||||
targetEntityType: this.options.targetEntityType,
|
||||
height: 500
|
||||
}, 'edit');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
Espo.define('views/email/fields/person-string-data', 'views/fields/varchar', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
listTemplate: 'email/fields/person-string-data/list',
|
||||
|
||||
data: function () {
|
||||
var data = Dep.prototype.data.call(this);
|
||||
data.isReplied = this.model.get('isReplied');
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
@@ -37,6 +37,7 @@ Espo.define('views/email/fields/subject', 'views/fields/varchar', function (Dep)
|
||||
data.isRead = (this.model.get('sentById') === this.getUser().id) || this.model.get('isRead');
|
||||
data.isImportant = this.model.get('isImportant');
|
||||
data.hasAttachment = this.model.get('hasAttachment');
|
||||
data.isReplied = this.model.get('isReplied');
|
||||
|
||||
if (!data.isNotEmpty) {
|
||||
if (
|
||||
|
||||
@@ -208,10 +208,23 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
documentElement.write(body);
|
||||
documentElement.close();
|
||||
|
||||
var $body = $iframe.contents().find('html body');
|
||||
|
||||
var $document = $(documentElement);
|
||||
|
||||
var processWidth = function () {
|
||||
var bodyElement = $body.get(0);
|
||||
if (bodyElement) {
|
||||
if (bodyElement.clientWidth !== iframeElement.scrollWidth) {
|
||||
iframeElement.style.height = (iframeElement.scrollHeight + 20) + 'px';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var increaseHeightStep = 10;
|
||||
var processIncreaseHeight = function (iteration, previousDiff) {
|
||||
$body.css('height', '');
|
||||
|
||||
iteration = iteration || 0;
|
||||
|
||||
if (iteration > 200) {
|
||||
@@ -224,6 +237,8 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
|
||||
if (typeof previousDiff !== 'undefined') {
|
||||
if (diff === previousDiff) {
|
||||
$body.css('height', (iframeElement.clientHeight - increaseHeightStep) + 'px');
|
||||
processWidth();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -232,6 +247,8 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
var height = iframeElement.scrollHeight + increaseHeightStep;
|
||||
iframeElement.style.height = height + 'px';
|
||||
processIncreaseHeight(iteration, diff);
|
||||
} else {
|
||||
processWidth();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -241,7 +258,6 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
overflowY: 'hidden',
|
||||
overflowX: 'hidden'
|
||||
});
|
||||
$iframe.attr('scrolling', 'no');
|
||||
|
||||
iframeElement.style.height = '0px';
|
||||
} else {
|
||||
@@ -265,7 +281,6 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
|
||||
overflowY: 'hidden',
|
||||
overflowX: 'scroll'
|
||||
});
|
||||
$iframe.attr('scrolling', 'yes');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -92,15 +92,17 @@ Espo.define('views/global-search/global-search', 'view', function (Dep) {
|
||||
$document = $(document);
|
||||
$document.on('mouseup.global-search', function (e) {
|
||||
if (e.which !== 1) return;
|
||||
if (!$container.is(e.target) && $container.has(e.target).length === 0) {
|
||||
this.closePanel();
|
||||
}
|
||||
}.bind(this));
|
||||
$document.on('click.global-search', function (e) {
|
||||
if (e.target.tagName == 'A' && $(e.target).data('action') != 'showMore') {
|
||||
setTimeout(function () {
|
||||
this.closePanel();
|
||||
}.bind(this), 100);
|
||||
return;
|
||||
}
|
||||
if (!$container.is(e.target) && $container.has(e.target).length === 0) {
|
||||
this.closePanel();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
@@ -112,11 +114,10 @@ Espo.define('views/global-search/global-search', 'view', function (Dep) {
|
||||
if (this.hasView('panel')) {
|
||||
this.getView('panel').remove();
|
||||
};
|
||||
$document.off('mouseup.global-search');
|
||||
$container.remove();
|
||||
},
|
||||
$document.off('mouseup.global-search');
|
||||
$document.off('click.global-search');
|
||||
$container.remove();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -1013,7 +1013,7 @@ Espo.define('views/record/list', 'view', function (Dep) {
|
||||
layout.push({
|
||||
name: 'r-checkboxField',
|
||||
columnName: 'r-checkbox',
|
||||
template: 'record.list-checkbox'
|
||||
template: 'record/list-checkbox'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -34,28 +34,44 @@ Espo.define('views/record/panels/default-side', 'views/record/panels/side', func
|
||||
|
||||
data: function () {
|
||||
var data = Dep.prototype.data.call(this);
|
||||
if (this.complexCreatedDisabled && this.complexModifiedDisabled) {
|
||||
if (this.complexCreatedDisabled && this.complexModifiedDisabled || (!this.hasComplexCreated && !this.hasComplexModified)) {
|
||||
data.complexDateFieldsDisabled = true;
|
||||
}
|
||||
data.hasComplexCreated = this.hasComplexCreated;
|
||||
data.hasComplexModified = this.hasComplexModified;
|
||||
return data;
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
|
||||
this.hasComplexCreated =
|
||||
!!this.getMetadata().get(['entityDefs', this.model.name, 'fields', 'createdAt'])
|
||||
&&
|
||||
!!this.getMetadata().get(['entityDefs', this.model.name, 'fields', 'createdBy']);
|
||||
|
||||
this.hasComplexModified =
|
||||
!!this.getMetadata().get(['entityDefs', this.model.name, 'fields', 'modifiedAt'])
|
||||
&&
|
||||
!!this.getMetadata().get(['entityDefs', this.model.name, 'fields', 'modifiedBy']);
|
||||
|
||||
if (!this.complexCreatedDisabled) {
|
||||
this.createField('createdBy', null, null, null, true);
|
||||
this.createField('createdAt', null, null, null, true);
|
||||
if (!this.model.get('createdById')) {
|
||||
this.recordViewObject.hideField('complexCreated');
|
||||
if (this.hasComplexCreated) {
|
||||
this.createField('createdBy', null, null, null, true);
|
||||
this.createField('createdAt', null, null, null, true);
|
||||
if (!this.model.get('createdById')) {
|
||||
this.recordViewObject.hideField('complexCreated');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.recordViewObject.hideField('complexCreated');
|
||||
}
|
||||
|
||||
if (!this.complexModifiedDisabled) {
|
||||
this.createField('modifiedBy', null, null, null, true);
|
||||
this.createField('modifiedAt', null, null, null, true);
|
||||
if (this.hasComplexModified) {
|
||||
this.createField('modifiedBy', null, null, null, true);
|
||||
this.createField('modifiedAt', null, null, null, true);
|
||||
}
|
||||
if (!this.model.get('modifiedById')) {
|
||||
this.recordViewObject.hideField('complexModified');
|
||||
}
|
||||
@@ -63,13 +79,13 @@ Espo.define('views/record/panels/default-side', 'views/record/panels/side', func
|
||||
this.recordViewObject.hideField('complexModified');
|
||||
}
|
||||
|
||||
if (!this.complexCreatedDisabled) {
|
||||
if (!this.complexCreatedDisabled && this.hasComplexCreated) {
|
||||
this.listenTo(this.model, 'change:createdById', function () {
|
||||
if (!this.model.get('createdById')) return;
|
||||
this.recordViewObject.showField('complexCreated');
|
||||
}, this);
|
||||
}
|
||||
if (!this.complexModifiedDisabled) {
|
||||
if (!this.complexModifiedDisabled && this.hasComplexModified) {
|
||||
this.listenTo(this.model, 'change:modifiedById', function () {
|
||||
if (!this.model.get('modifiedById')) return;
|
||||
this.recordViewObject.showField('complexModified');
|
||||
|
||||
@@ -120,6 +120,12 @@ Espo.define('views/record/panels/side', 'view', function (Dep) {
|
||||
this.createFields();
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
if (this.$el.children().size() === 0) {
|
||||
this.$el.parent().addClass('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
setupFields: function () {
|
||||
},
|
||||
|
||||
|
||||
@@ -132,7 +132,14 @@ div.list-expanded > ul > li > div.expanded-row > .cell:first-child {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.list > table.table td > span.glyphicon.pull-right,
|
||||
.list > table.table td > span.list-icon-container.pull-right {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.list > table.table td > span.list-icon-container.pull-left {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.list > ul.list-group > li.list-row .cell > span.glyphicon.pull-right {
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
@@ -375,6 +382,10 @@ ul.dropdown-menu > li.checkbox {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.dropdown-menu > li > a {
|
||||
line-height: @line-height-computed;
|
||||
}
|
||||
|
||||
ul.dropdown-menu > li > a.active {
|
||||
background-color: @gray-lighter;
|
||||
text-decoration: none;
|
||||
@@ -961,8 +972,8 @@ table.list th {
|
||||
.list > table th[data-name="r-checkbox"] {
|
||||
white-space: nowrap;
|
||||
.select-all-container {
|
||||
line-height: @line-height-base;
|
||||
height: unit(@line-height-base, em);
|
||||
line-height: @line-height-computed;
|
||||
height: @line-height-computed;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
@@ -977,6 +988,11 @@ table.list th {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.list .record-checkbox-container {
|
||||
height: @line-height-computed;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.list > table td > div.field {
|
||||
white-space: normal;
|
||||
}
|
||||
@@ -1274,6 +1290,15 @@ label.attach-file-label {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.icon-flip-horizontal {
|
||||
-moz-transform: scaleX(-1);
|
||||
-webkit-transform: scaleX(-1);
|
||||
-o-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
-ms-filter: fliph;
|
||||
filter: fliph;
|
||||
}
|
||||
|
||||
.post-container > textarea.note,
|
||||
textarea.auto-height {
|
||||
overflow-x: hidden;
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
.clearfix();
|
||||
}
|
||||
|
||||
@line-height-small-computed: floor((@font-size-base * @line-height-small));
|
||||
|
||||
@table-cell-padding: 8px;
|
||||
|
||||
@table-cell-less-padding: 3px;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "espocrm",
|
||||
"version": "5.3.3",
|
||||
"version": "5.3.4",
|
||||
"description": "",
|
||||
"main": "index.php",
|
||||
"repository": {
|
||||
|
||||
@@ -77,4 +77,29 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase
|
||||
$actual = $this->evaluator->process($expression);
|
||||
$this->assertTrue($actual);
|
||||
}
|
||||
|
||||
function testSummationOfMultipleIfThenElse()
|
||||
{
|
||||
$expression = "
|
||||
ifThenElse(
|
||||
true,
|
||||
(1 + 0 + 1) - 1 * 0.5,
|
||||
0
|
||||
)
|
||||
+
|
||||
ifThenElse(
|
||||
true,
|
||||
(1 - 0) * 0.5,
|
||||
0
|
||||
)
|
||||
+
|
||||
ifThenElse(
|
||||
true,
|
||||
(1 - 0) * 0.5,
|
||||
0
|
||||
)
|
||||
";
|
||||
$actual = $this->evaluator->process($expression);
|
||||
$this->assertEquals(2.5, $actual);
|
||||
}
|
||||
}
|
||||
@@ -305,6 +305,7 @@ class ParserTest extends \PHPUnit\Framework\TestCase
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$expression = "!value * 10";
|
||||
|
||||
Reference in New Issue
Block a user