Compare commits

...

17 Commits
7.3.2 ... 7.3.3

Author SHA1 Message Date
Yuri Kuznetsov
846b57842f 7.3.3 2023-02-07 09:16:25 +02:00
Yuri Kuznetsov
3fa7ddf9f8 fix upgrade 2023-02-06 17:39:36 +02:00
Yuri Kuznetsov
5b8ccb4513 fisable group tabs for portal 2023-02-06 17:10:41 +02:00
Yuri Kuznetsov
fe3ab8b8a0 fix invalid null 2023-01-30 21:07:43 +02:00
Yuri Kuznetsov
5cace584f1 Merge branch 'update-async' into fix 2023-01-30 14:16:15 +02:00
Yuri Kuznetsov
b6e7f5113f prevent shortcut pagination if focused of form element 2023-01-29 10:17:38 +02:00
Yuri Kuznetsov
5d48dd090c group email account use from name 2023-01-27 21:40:19 +02:00
Yuri Kuznetsov
785bc0ed6e update async 2023-01-27 16:47:37 +02:00
Eymen Elkum
80cce0b1ba fix convert lead map fields (#2574)
* fix convert lead map fields

* fix convert lead map fields

Co-authored-by: Eymen Elkum <eymen@eblasoft.com.tr>
2023-01-20 14:46:52 +02:00
Yuri Kuznetsov
b477c3420b varchar optionsPath 2023-01-19 17:24:20 +02:00
Yuri Kuznetsov
72a1d73848 fix dropdown menu hidden 2023-01-19 17:20:22 +02:00
Yuri Kuznetsov
0559e21baf currency field customization limitatinos 2023-01-18 10:45:48 +02:00
Yuri Kuznetsov
22e68e8fdf no fallback login for portal 2023-01-17 14:15:23 +02:00
Yuri Kuznetsov
ad89d65a48 fix login data 2023-01-17 14:07:20 +02:00
Yuri Kuznetsov
0a92ed8f39 header adjust buttons fix 2023-01-17 13:46:57 +02:00
Yuri Kuznetsov
d5d19f2974 main merge select style 2023-01-16 10:02:39 +02:00
Yuri Kuznetsov
6e3c765ba3 attachment focus fix 2023-01-16 09:54:21 +02:00
23 changed files with 190 additions and 123 deletions

View File

@@ -152,7 +152,7 @@ class Saver implements SaverInterface
$key = strtolower($emailAddressValue);
if ($key && isset($hash->$key)) {
$hash->{$key}['optOut'] = $entity->get('emailAddressIsOptedOut');
$hash->{$key}['optOut'] = (bool) $entity->get('emailAddressIsOptedOut');
}
}
@@ -170,7 +170,7 @@ class Saver implements SaverInterface
$key = strtolower($emailAddressValue);
if ($key && isset($hash->$key)) {
$hash->{$key}['invalid'] = $entity->get('emailAddressIsInvalid');
$hash->{$key}['invalid'] = (bool) $entity->get('emailAddressIsInvalid');
}
}

View File

@@ -163,7 +163,7 @@ class Saver implements SaverInterface
$key = $phoneNumberValue;
if (isset($hash->$key)) {
$hash->{$key}['optOut'] = $entity->get('phoneNumberIsOptedOut');
$hash->{$key}['optOut'] = (bool) $entity->get('phoneNumberIsOptedOut');
}
}
@@ -180,7 +180,7 @@ class Saver implements SaverInterface
$key = $phoneNumberValue;
if (isset($hash->$key)) {
$hash->{$key}['invalid'] = $entity->get('phoneNumberIsInvalid');
$hash->{$key}['invalid'] = (bool) $entity->get('phoneNumberIsInvalid');
}
}

View File

@@ -267,6 +267,10 @@ class Account implements AccountInterface
->withAuthMechanism($this->entity->getSmtpAuthMechanism());
}
if ($this->entity->getFromName()) {
$smtpParams = $smtpParams->withFromName($this->entity->getFromName());
}
$handlerClassName = $this->entity->getSmtpHandlerClassName();
if (!$handlerClassName) {

View File

@@ -232,7 +232,7 @@ class ConvertService
->find();
foreach ($meetings as $meeting) {
if ($contact && $contact->hasId()) {
if ($contact && $contact->hasId()) {
$this->entityManager
->getRDBRepository(Meeting::ENTITY_TYPE)
->relate($meeting, 'contacts', $contact);
@@ -379,7 +379,7 @@ class ConvertService
$fieldList = array_keys($this->metadata->get('entityDefs.Lead.fields', []));
foreach ($fieldList as $field) {
if (!$this->metadata->get('entityDefs.'.$entityType.'.fields.' . $field)) {
if (!$this->metadata->get('entityDefs.' . $entityType . '.fields.' . $field)) {
continue;
}
@@ -401,10 +401,10 @@ class ConvertService
}
foreach ($fieldMap as $field => $leadField) {
$type = $this->metadata->get(['entityDefs', 'Lead', 'fields', $field, 'type']);
$type = $this->metadata->get(['entityDefs', $entityType, 'fields', $field, 'type']);
if (in_array($type, ['file', 'image'])) {
$attachment = $lead->get($field);
$attachment = $lead->get($leadField);
if ($attachment) {
$attachment = $this->getAttachmentRepository()->getCopiedAttachment($attachment);
@@ -419,7 +419,7 @@ class ConvertService
continue;
}
else if ($type === 'attachmentMultiple') {
$attachmentList = $lead->get($field);
$attachmentList = $lead->get($leadField);
if (count($attachmentList)) {
$idList = [];

View File

@@ -55,13 +55,16 @@
"customizationDisplayAsLabelDisabled": true,
"customizationAuditedDisabled": true,
"customizationReadOnlyDisabled": true,
"customizationInlineEditDisabledDisabled": true,
"customizationDefaultView": "views/admin/field-manager/fields/currency-default",
"customizationTooltipTextDisabled": true,
"maxLength": 6
},
"converted": {
"type": "currencyConverted",
"readOnly": true,
"importDisabled": true
"importDisabled": true,
"customizationInlineEditDisabledDisabled": true
}
},
"validationList": [

View File

@@ -162,7 +162,9 @@ class SettingsService
}
/** @var ?bool $fallback */
$fallback = $mData['fallback'] ?? null;
$fallback = !$this->applicationState->isPortal() ?
($mData['fallback'] ?? null) :
false;
if ($fallback === null) {
/** @var ?string $fallbackConfigParam */
@@ -172,7 +174,7 @@ class SettingsService
}
/** @var stdClass $data */
$data = (object) ($mData['fallbackConfigParam'] ?? []);
$data = (object) ($mData['data'] ?? []);
return [
'handler' => $handler,

View File

@@ -1,10 +1,11 @@
<div class="cell">
<div class="field" data-name="link">
<select class="form-control">
{{#each linkList}}
<option value="{{./this}}">{{translate this category='links' scope='TargetList'}}</option>
{{/each}}
</select>
<div class="row">
<div class="cell col-md-6">
<div class="field" data-name="link">
<select class="form-control" data-name="link">
{{#each linkList}}
<option value="{{./this}}">{{translate this category='links' scope='TargetList'}}</option>
{{/each}}
</select>
</div>
</div>
</div>

View File

@@ -26,7 +26,8 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
define('crm:views/campaign/modals/mail-merge-pdf', ['views/modal', 'model'], function (Dep, Model) {
define('crm:views/campaign/modals/mail-merge-pdf', ['views/modal', 'ui/select'],
function (Dep, /** module:ui/select */ Select) {
return Dep.extend({
@@ -51,7 +52,8 @@ define('crm:views/campaign/modals/mail-merge-pdf', ['views/modal', 'model'], fun
return;
}
var targetEntityType = this.getMetadata().get(['entityDefs', 'TargetList', 'links', link, 'entity']);
let targetEntityType = this.getMetadata()
.get(['entityDefs', 'TargetList', 'links', link, 'entity']);
if (!this.getAcl().checkScope(targetEntityType)) {
return;
@@ -72,8 +74,13 @@ define('crm:views/campaign/modals/mail-merge-pdf', ['views/modal', 'model'], fun
});
},
afterRender: function () {
Select.init(this.$el.find('.field[data-name="link"] select'));
},
actionProceed: function () {
var link = this.$el.find('.field[data-name="link"] select').val();
let link = this.$el.find('.field[data-name="link"] select').val();
this.trigger('proceed', link);
},
});

View File

@@ -104,7 +104,7 @@ define('crm:views/meeting/detail', ['views/detail', 'lib!moment'], function (Dep
text = this.translate('Acceptance', 'labels', 'Meeting');
}
this.removeMenuItem('setAcceptanceStatus');
this.removeMenuItem('setAcceptanceStatus', true);
let iconHtml = '';

View File

@@ -575,7 +575,16 @@ function (Dep, FileUpload) {
this.isUploading = false;
setTimeout(() => this.focusOnUploadButton(), 50);
setTimeout(() => {
if (
document.activeElement &&
document.activeElement.tagName !== 'BODY'
) {
return;
}
this.focusOnUploadButton();
}, 50);
}
})
.catch(() => {

View File

@@ -156,6 +156,7 @@ define('views/fields/email', ['views/fields/varchar'], function (Dep) {
if (this.isReadMode()) {
data.isOptedOut = this.model.get(this.isOptedOutFieldName);
data.isInvalid = this.model.get(this.isInvalidFieldName);
if (this.model.get(this.name)) {
data.isErased = this.model.get(this.name).indexOf(this.erasedPlaceholder) === 0
@@ -509,6 +510,7 @@ define('views/fields/email', ['views/fields/varchar'], function (Dep) {
setup: function () {
this.dataFieldName = this.name + 'Data';
this.isOptedOutFieldName = this.name + 'IsOptedOut';
this.isInvalidFieldName = this.name + 'IsInvalid';
this.erasedPlaceholder = 'ERASED:';
@@ -555,6 +557,7 @@ define('views/fields/email', ['views/fields/varchar'], function (Dep) {
data[this.dataFieldName] = addressData;
data[this.name] = null;
data[this.isOptedOutFieldName] = false;
data[this.isInvalidFieldName] = false;
let primaryIndex = 0;
@@ -565,6 +568,10 @@ define('views/fields/email', ['views/fields/varchar'], function (Dep) {
if (item.optOut) {
data[this.isOptedOutFieldName] = true;
}
if (item.invalid) {
data[this.isInvalidFieldName] = true;
}
}
});
@@ -579,6 +586,7 @@ define('views/fields/email', ['views/fields/varchar'], function (Dep) {
data[this.name] = addressData[0].emailAddress;
} else {
data[this.isOptedOutFieldName] = null;
data[this.isInvalidFieldName] = null;
}
return data;

View File

@@ -604,6 +604,13 @@ define('views/fields/file', ['views/fields/link', 'helpers/file-upload'], functi
this.isUploading = false;
setTimeout(() => {
if (
document.activeElement &&
document.activeElement.tagName !== 'BODY'
) {
return;
}
let $a = this.$el.find('.preview a');
$a.focus();
}, 50);

View File

@@ -176,6 +176,7 @@ function (Dep, /** module:ui/select*/Select) {
if (this.isReadMode()) {
data.isOptedOut = this.model.get(this.isOptedOutFieldName);
data.isInvalid = this.model.get(this.isInvalidFieldName);
if (this.model.get(this.name)) {
data.isErased = this.model.get(this.name).indexOf(this.erasedPlaceholder) === 0;
@@ -409,6 +410,7 @@ function (Dep, /** module:ui/select*/Select) {
.get('entityDefs.' + this.model.name + '.fields.' + this.name + '.defaultType');
this.isOptedOutFieldName = this.name + 'IsOptedOut';
this.isInvalidFieldName = this.name + 'IsInvalid';
this.phoneNumberOptedOutByDefault = this.getConfig().get('phoneNumberIsOptedOutByDefault');
@@ -468,6 +470,7 @@ function (Dep, /** module:ui/select*/Select) {
data[this.dataFieldName] = addressData;
data[this.name] = null;
data[this.isOptedOutFieldName] = false;
data[this.isInvalidFieldName] = false;
let primaryIndex = 0;
@@ -478,6 +481,10 @@ function (Dep, /** module:ui/select*/Select) {
if (item.optOut) {
data[this.isOptedOutFieldName] = true;
}
if (item.invalid) {
data[this.isInvalidFieldName] = true;
}
}
});
@@ -492,6 +499,7 @@ function (Dep, /** module:ui/select*/Select) {
data[this.name] = addressData[0].phoneNumber;
} else {
data[this.isOptedOutFieldName] = null;
data[this.isInvalidFieldName] = null;
}
return data;

View File

@@ -88,6 +88,11 @@ define('views/fields/varchar', ['views/fields/base', 'helpers/reg-exp-pattern'],
this.noSpellCheck = this.noSpellCheck || this.params.noSpellCheck;
if (this.params.optionsPath) {
this.params.options = Espo.Utils.clone(
this.getMetadata().get(this.params.optionsPath) || []);
}
if (this.options.customOptionList) {
this.setOptionList(this.options.customOptionList);
}

View File

@@ -179,6 +179,8 @@ define('views/main', ['view'], function (Dep) {
this.on('header-rendered', () => {
this.$headerActionsContainer = this.$el.find('.page-header .header-buttons');
this.adjustButtons();
});
this.on('after:render', () => this.adjustButtons());
@@ -411,8 +413,7 @@ define('views/main', ['view'], function (Dep) {
if (!doNotReRender && this.isRendered()) {
this.getHeaderView()
.reRender()
.then(() => this.adjustButtons());
.reRender();
return;
}
@@ -420,8 +421,7 @@ define('views/main', ['view'], function (Dep) {
if (!doNotReRender && this.isBeingRendered()) {
this.once('after:render', () => {
this.getHeaderView()
.reRender()
.then(() => this.adjustButtons());
.reRender();
});
}
},
@@ -453,8 +453,7 @@ define('views/main', ['view'], function (Dep) {
if (!doNotReRender && this.isRendered()) {
this.getHeaderView()
.reRender()
.then(() => this.adjustButtons());
.reRender();
return;
}
@@ -462,8 +461,7 @@ define('views/main', ['view'], function (Dep) {
if (!doNotReRender && this.isBeingRendered()) {
this.once('after:render', () => {
this.getHeaderView()
.reRender()
.then(() => this.adjustButtons());
.reRender();
});

View File

@@ -715,6 +715,10 @@ define('views/modals/detail', ['views/modal', 'helpers/action-item-setup'], func
return;
}
if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'INPUT') {
return;
}
e.preventDefault();
e.stopPropagation();
@@ -734,6 +738,10 @@ define('views/modals/detail', ['views/modal', 'helpers/action-item-setup'], func
return;
}
if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'INPUT') {
return;
}
e.preventDefault();
e.stopPropagation();

View File

@@ -26,21 +26,24 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('views/portal/fields/tab-list', 'views/settings/fields/tab-list', function (Dep) {
define('views/portal/fields/tab-list', ['views/settings/fields/tab-list'], function (Dep) {
return Dep.extend({
noGroups: true,
setupOptions: function () {
Dep.prototype.setupOptions.call(this);
this.params.options = this.params.options.filter(function (tab) {
if (tab === '_delimiter_') return true;
this.params.options = this.params.options.filter(tab => {
if (tab === '_delimiter_') {
return true;
}
if (!!this.getMetadata().get('scopes.' + tab + '.aclPortal')) {
return true;
}
}, this);
}
});
},
});
});

View File

@@ -935,7 +935,7 @@ function (Dep, ViewRecordHelper, ActionItemSetup) {
}
if (!this.isDropdownEditItemListEmpty()) {
this.$dropdownItemListButton.removeClass('hidden');
this.$dropdownEditItemListButton.removeClass('hidden');
}
this.adjustButtons();
@@ -3965,6 +3965,10 @@ function (Dep, ViewRecordHelper, ActionItemSetup) {
return;
}
if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'INPUT') {
return;
}
let $button = this.$el.find('button[data-action="previous"]');
if (!$button.length || $button.hasClass('disabled')) {
@@ -3994,6 +3998,10 @@ function (Dep, ViewRecordHelper, ActionItemSetup) {
return;
}
if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'INPUT') {
return;
}
let $button = this.$el.find('button[data-action="next"]');
if (!$button.length || $button.hasClass('disabled')) {

View File

@@ -29,7 +29,7 @@
"yzalis/identicon": "*",
"zordius/lightncandy": "dev-espo#v1.2.5e",
"composer/semver": "^3",
"spatie/async": "1.5.3",
"spatie/async": "1.5.5",
"tecnickcom/tcpdf": "6.3.5",
"symfony/process": "4.4.*",
"symfony/http-foundation": "4.4.*",

151
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b8579baeb6ecd7fa882bd35e9a2d85de",
"content-hash": "9e7630c5c6bca8d8d99ca27b546df824",
"packages": [
{
"name": "async-aws/core",
@@ -1635,6 +1635,66 @@
],
"time": "2022-11-14T08:50:44+00:00"
},
{
"name": "laravel/serializable-closure",
"version": "v1.2.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
"reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/47afb7fae28ed29057fdca37e16a84f90cc62fae",
"reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae",
"shasum": ""
},
"require": {
"php": "^7.3|^8.0"
},
"require-dev": {
"nesbot/carbon": "^2.61",
"pestphp/pest": "^1.21.3",
"phpstan/phpstan": "^1.8.2",
"symfony/var-dumper": "^5.4.11"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Laravel\\SerializableClosure\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
},
{
"name": "Nuno Maduro",
"email": "nuno@laravel.com"
}
],
"description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.",
"keywords": [
"closure",
"laravel",
"serializable"
],
"support": {
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
"time": "2022-09-08T13:45:54+00:00"
},
{
"name": "league/flysystem",
"version": "2.1.1",
@@ -2450,71 +2510,6 @@
},
"time": "2018-02-13T20:26:39+00:00"
},
{
"name": "opis/closure",
"version": "3.6.1",
"source": {
"type": "git",
"url": "https://github.com/opis/closure.git",
"reference": "943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opis/closure/zipball/943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5",
"reference": "943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5",
"shasum": ""
},
"require": {
"php": "^5.4 || ^7.0 || ^8.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.6.x-dev"
}
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": [
"functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca@gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin@hotmail.com"
}
],
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"homepage": "https://opis.io/closure",
"keywords": [
"anonymous functions",
"closure",
"function",
"serializable",
"serialization",
"serialize"
],
"support": {
"issues": "https://github.com/opis/closure/issues",
"source": "https://github.com/opis/closure/tree/3.6.1"
},
"time": "2020-11-07T02:01:34+00:00"
},
{
"name": "paragonie/constant_time_encoding",
"version": "v2.6.3",
@@ -4057,27 +4052,27 @@
},
{
"name": "spatie/async",
"version": "1.5.3",
"version": "1.5.5",
"source": {
"type": "git",
"url": "https://github.com/spatie/async.git",
"reference": "d371b76ff876530c4906596490fd977720477e48"
"reference": "742708736b1e6d606dd1cd0f60acb7e354211e41"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/async/zipball/d371b76ff876530c4906596490fd977720477e48",
"reference": "d371b76ff876530c4906596490fd977720477e48",
"url": "https://api.github.com/repos/spatie/async/zipball/742708736b1e6d606dd1cd0f60acb7e354211e41",
"reference": "742708736b1e6d606dd1cd0f60acb7e354211e41",
"shasum": ""
},
"require": {
"opis/closure": "^3.4.2",
"php": "^7.1 || ^8.0",
"symfony/process": "^3.3 || ^4.0 || ^5.0"
"laravel/serializable-closure": "^1.0",
"php": "^7.4|^8.0",
"symfony/process": "^3.3 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
"larapack/dd": "^1.1",
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.0",
"symfony/stopwatch": "^4.0 || ^5.0"
"phpunit/phpunit": "^7.5 || ^8.5.21 || ^9.0",
"symfony/stopwatch": "^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"ext-pcntl": "Required to use async processes",
@@ -4112,7 +4107,7 @@
],
"support": {
"issues": "https://github.com/spatie/async/issues",
"source": "https://github.com/spatie/async/tree/1.5.3"
"source": "https://github.com/spatie/async/tree/1.5.5"
},
"funding": [
{
@@ -4120,7 +4115,7 @@
"type": "github"
}
],
"time": "2020-12-29T22:19:12+00:00"
"time": "2022-06-21T06:40:45+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -7702,5 +7697,5 @@
"ext-pdo": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.3.0"
}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "espocrm",
"version": "7.3.2",
"version": "7.3.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "espocrm",
"version": "7.3.2",
"version": "7.3.3",
"hasInstallScript": true,
"license": "GPL-3.0",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "7.3.2",
"version": "7.3.3",
"description": "Open-source CRM.",
"repository": {
"type": "git",

View File

@@ -102,6 +102,7 @@ class BeforeUpgrade
'assignedUserId' => $user->getId(),
'name' => $emailAddress . ' (auto-created)',
'emailAddress' => $emailAddress,
'useImap' => false,
'useSmtp' => true,
'status' => 'Active',
'smtpHost' => $smtpServer,