diff --git a/application/Espo/Modules/Crm/Resources/layouts/Contact/listSelect.json b/application/Espo/Modules/Crm/Resources/layouts/Contact/listSelect.json
index 54d4fb3c2f..e0d4263ae7 100644
--- a/application/Espo/Modules/Crm/Resources/layouts/Contact/listSelect.json
+++ b/application/Espo/Modules/Crm/Resources/layouts/Contact/listSelect.json
@@ -1,5 +1,5 @@
[
- {"name":"name","link":true, "width": "40"},
+ {"name":"name", "link":true, "width": 40},
{"name":"account"},
{"name":"emailAddress", "notSortable": true}
]
diff --git a/application/Espo/Resources/layouts/ActionHistoryRecord/listSmall.json b/application/Espo/Resources/layouts/ActionHistoryRecord/listSmall.json
index bcadcb596e..1137059292 100644
--- a/application/Espo/Resources/layouts/ActionHistoryRecord/listSmall.json
+++ b/application/Espo/Resources/layouts/ActionHistoryRecord/listSmall.json
@@ -1,6 +1,6 @@
[
- {"name":"action", "width": "18", "notSortable": true},
- {"name":"targetType", "width": "20", "notSortable": true},
+ {"name":"action", "width": 18, "notSortable": true},
+ {"name":"targetType", "width": 20, "notSortable": true},
{"name":"target", "notSortable": true},
- {"name":"createdAt", "width": "18", "align": "right", "notSortable": true}
-]
\ No newline at end of file
+ {"name":"createdAt", "width": 18, "align": "right", "notSortable": true}
+]
diff --git a/application/Espo/Resources/layouts/AuthToken/list.json b/application/Espo/Resources/layouts/AuthToken/list.json
index e24851b115..de70a1b06d 100644
--- a/application/Espo/Resources/layouts/AuthToken/list.json
+++ b/application/Espo/Resources/layouts/AuthToken/list.json
@@ -1,7 +1,7 @@
[
{"name":"user"},
- {"name":"isActive", "widthPx": "100"},
- {"name":"ipAddress", "width": "17"},
- {"name":"createdAt", "width": "19"},
- {"name":"lastAccess", "width": "19"}
+ {"name":"isActive", "widthPx": 100},
+ {"name":"ipAddress", "width": 17},
+ {"name":"createdAt", "width": 19},
+ {"name":"lastAccess", "width": 19}
]
diff --git a/application/Espo/Resources/layouts/AuthToken/listSmall.json b/application/Espo/Resources/layouts/AuthToken/listSmall.json
index e24851b115..de70a1b06d 100644
--- a/application/Espo/Resources/layouts/AuthToken/listSmall.json
+++ b/application/Espo/Resources/layouts/AuthToken/listSmall.json
@@ -1,7 +1,7 @@
[
{"name":"user"},
- {"name":"isActive", "widthPx": "100"},
- {"name":"ipAddress", "width": "17"},
- {"name":"createdAt", "width": "19"},
- {"name":"lastAccess", "width": "19"}
+ {"name":"isActive", "widthPx": 100},
+ {"name":"ipAddress", "width": 17},
+ {"name":"createdAt", "width": 19},
+ {"name":"lastAccess", "width": 19}
]
diff --git a/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json b/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json
index 55ede72410..13222d6cb8 100644
--- a/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json
+++ b/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json
@@ -1,5 +1,5 @@
[
{"name":"target", "notSortable": true},
- {"name":"isCreated", "width": "25", "notSortable": true},
- {"name":"createdAt", "width": "30", "notSortable": true}
+ {"name":"isCreated", "width": 25, "notSortable": true},
+ {"name":"createdAt", "width": 30, "notSortable": true}
]
diff --git a/application/Espo/Tools/Stream/UserRecordService.php b/application/Espo/Tools/Stream/UserRecordService.php
index b347464891..22949f78ca 100644
--- a/application/Espo/Tools/Stream/UserRecordService.php
+++ b/application/Espo/Tools/Stream/UserRecordService.php
@@ -389,7 +389,7 @@ class UserRecordService
[
'entityType:' => 'parentType',
'entityId:' => 'parentId',
- 'subscription.userId' => $user->getId(),
+ 'subscriptionExclude.userId' => $user->getId(),
]
)
->where([
diff --git a/client/res/templates/record/search.tpl b/client/res/templates/record/search.tpl
index 9d3162e9e8..f936a3e8d0 100644
--- a/client/res/templates/record/search.tpl
+++ b/client/res/templates/record/search.tpl
@@ -34,7 +34,7 @@
data-action="selectPreset"
>
- {{#if label}}{{label}}{{else}}{{translate name category='presetFilters' scope=../entityType}}{{/if}}
+ {{~#if label}}{{label}}{{else}}{{translate name category='presetFilters' scope=../entityType}}{{/if~}}
diff --git a/client/src/collection.js b/client/src/collection.js
index 1f2bbbed24..8d3deed2af 100644
--- a/client/src/collection.js
+++ b/client/src/collection.js
@@ -174,7 +174,7 @@ class Collection {
parentModel
/**
- * @param {Model[]|null} [models] Models.
+ * @param {Model[]|Record[]|null} [models] Models.
* @param {{
* entityType?: string,
* model?: Model.prototype,
diff --git a/client/src/views/email/fields/email-address-varchar.js b/client/src/views/email/fields/email-address-varchar.js
index 8b952a1191..ba1b0a609c 100644
--- a/client/src/views/email/fields/email-address-varchar.js
+++ b/client/src/views/email/fields/email-address-varchar.js
@@ -420,7 +420,38 @@ class EmailAddressVarcharFieldView extends BaseFieldView {
return true;
}
+ /**
+ *
+ * @param {string} address
+ * @param {string} name
+ * @param {string} [type]
+ * @param {string} [id]
+ */
addAddress(address, name, type, id) {
+ if (name === '') {
+ const nameHash = this.model.attributes.nameHash ?? {};
+
+ if (address in nameHash) {
+ name = nameHash[address];
+ }
+ }
+
+ if (type === undefined) {
+ const typeHash = this.model.attributes.typeHash ?? {};
+
+ if (address in typeHash) {
+ type = typeHash[address];
+ }
+ }
+
+ if (id === undefined) {
+ const idHash = this.model.attributes.idHash ?? {};
+
+ if (address in idHash) {
+ id = idHash[address];
+ }
+ }
+
if (this.justAddedAddress) {
this.deleteAddress(this.justAddedAddress);
}
@@ -482,9 +513,9 @@ class EmailAddressVarcharFieldView extends BaseFieldView {
$text.append(
$('').text(name),
- ' ',
+ ' ',
$('').addClass('text-muted middle-dot'),
- ' '
+ ' '
);
}
diff --git a/client/src/views/fields/array.js b/client/src/views/fields/array.js
index fee07fe20e..432767bbbe 100644
--- a/client/src/views/fields/array.js
+++ b/client/src/views/fields/array.js
@@ -256,6 +256,10 @@ class ArrayFieldView extends BaseFieldView {
this.allowCustomOptions = true;
}
+ if (this.params.allowCustomOptions === false) {
+ this.allowCustomOptions = false;
+ }
+
if (this.type === 'array') {
this.validations.push('noInputValue')
}
diff --git a/client/src/views/fields/link.js b/client/src/views/fields/link.js
index ba583787f1..a0b72af4d4 100644
--- a/client/src/views/fields/link.js
+++ b/client/src/views/fields/link.js
@@ -217,6 +217,13 @@ class LinkFieldView extends BaseFieldView {
*/
linkClass
+ /**
+ * @protected
+ * @type {string}
+ * @since 9.2.5
+ */
+ foreignNameAttribute
+
/** @inheritDoc */
events = {
/** @this LinkFieldView */
@@ -364,6 +371,10 @@ class LinkFieldView extends BaseFieldView {
this.model.getFieldParam(this.name, 'entity') ||
this.model.getLinkParam(this.name, 'entity');
+ this.foreignNameAttribute = this.model.getLinkParam(this.name, 'foreignName') ??
+ this.getMetadata().get(`clientDefs.${this.foreignScope}.nameAttribute`) ??
+ 'name';
+
if ('createDisabled' in this.options) {
this.createDisabled = this.options.createDisabled;
}
@@ -407,12 +418,12 @@ class LinkFieldView extends BaseFieldView {
* @return {Promise|void}
*/
select(model) {
- this.$elementName.val(model.get('name') || model.id);
- this.$elementId.val(model.get('id'));
+ this.$elementName.val(model.get(this.foreignNameAttribute) || model.id);
+ this.$elementId.val(model.id);
if (this.mode === this.MODE_SEARCH) {
- this.searchData.idValue = model.get('id');
- this.searchData.nameValue = model.get('name') || model.id;
+ this.searchData.idValue = model.id;
+ this.searchData.nameValue = model.get(this.foreignNameAttribute) || model.id;
}
this.trigger('change');
@@ -611,7 +622,7 @@ class LinkFieldView extends BaseFieldView {
if (!this.forceSelectAllAttributes) {
const mandatorySelectAttributeList = this.getMandatorySelectAttributeList();
- let select = ['id', 'name'];
+ let select = ['id', this.foreignNameAttribute];
if (mandatorySelectAttributeList) {
select = select.concat(mandatorySelectAttributeList);
@@ -824,12 +835,20 @@ class LinkFieldView extends BaseFieldView {
const list = [];
response.list.forEach(item => {
+ const name = item[this.foreignNameAttribute] || item.name || item.id;
+
+ const attributes = item;
+
+ if (this.foreignNameAttribute !== 'name') {
+ attributes[this.foreignNameAttribute] = name;
+ }
+
list.push({
id: item.id,
- name: item.name || item.id,
+ name: name,
data: item.id,
- value: item.name || item.id,
- attributes: item,
+ value: name,
+ attributes: attributes,
});
});
@@ -1365,7 +1384,7 @@ class LinkFieldView extends BaseFieldView {
*/
selectOneOf(models) {
models.forEach(model => {
- this.addLinkOneOf(model.id, model.get('name'));
+ this.addLinkOneOf(model.id, model.get(this.foreignNameAttribute));
});
}
}
diff --git a/client/src/views/record/edit.js b/client/src/views/record/edit.js
index af561549c9..6497d588f6 100644
--- a/client/src/views/record/edit.js
+++ b/client/src/views/record/edit.js
@@ -148,7 +148,11 @@ class EditRecordView extends DetailRecordView {
this.wait(promise);
// @todo Revise. Possible race condition issues.
- promise.then(() => super.setupBeforeFinal());
+ promise.then(() => {
+ super.setupBeforeFinal();
+
+ this.processDynamicLogic();
+ });
}
if (this.model.isNew()) {
diff --git a/client/src/views/record/search.js b/client/src/views/record/search.js
index 2191791a1c..ffa2f69d6b 100644
--- a/client/src/views/record/search.js
+++ b/client/src/views/record/search.js
@@ -938,7 +938,7 @@ class SearchView extends View {
this.$el
.find('ul.filter-menu a.preset[data-name="'+presetName+'"]')
- .prepend('');
+ .prepend('');
}
manageBoolFilters() {
diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less
index eb2a271486..576ce8e477 100644
--- a/frontend/less/espo/custom.less
+++ b/frontend/less/espo/custom.less
@@ -112,7 +112,7 @@ img.image-preview {
.preset {
text-overflow: ellipsis;
- overflow: hidden !important;
+ //overflow: hidden !important;
}
.preset > div{
diff --git a/frontend/less/espo/elements/dropdown.less b/frontend/less/espo/elements/dropdown.less
index ea8e183178..2bf7935278 100644
--- a/frontend/less/espo/elements/dropdown.less
+++ b/frontend/less/espo/elements/dropdown.less
@@ -8,6 +8,8 @@
padding: var(--5px) 0;
user-select: none;
+ min-width: calc(var(--50px) + var(--10px));
+
.autocomplete-suggestion.autocomplete-selected {
background-color: var(--dropdown-link-hover-bg) !important;
color: var(--dropdown-link-hover-color) !important;
diff --git a/frontend/less/espo/elements/type.less b/frontend/less/espo/elements/type.less
index 3dab594ba0..d6cce12513 100644
--- a/frontend/less/espo/elements/type.less
+++ b/frontend/less/espo/elements/type.less
@@ -213,6 +213,10 @@ small,
top: var(--minus-1px);
}
+.no-select {
+ user-select: none;
+}
+
a[role="button"],
a[href="javascript:"] {
&:not(.selectable) {
diff --git a/package-lock.json b/package-lock.json
index 2b38137c87..7d0fb7558e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "espocrm",
- "version": "9.2.4",
+ "version": "9.2.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "espocrm",
- "version": "9.2.4",
+ "version": "9.2.5",
"hasInstallScript": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
diff --git a/package.json b/package.json
index 28be97c66f..d05fcfdd2a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "espocrm",
- "version": "9.2.4",
+ "version": "9.2.5",
"description": "Open-source CRM.",
"repository": {
"type": "git",
diff --git a/schema/metadata/app/webSocket.json b/schema/metadata/app/webSocket.json
index 17c0204051..d0e1443177 100644
--- a/schema/metadata/app/webSocket.json
+++ b/schema/metadata/app/webSocket.json
@@ -19,7 +19,7 @@
},
"accessCheckCommand": {
"type": "string",
- "description": "A console command that will be used to check whether a topic is allowed for a user when they attempting to subscribe. Patameter placeholders starts with the colon :. The userId parameter contains a user ID. If access checking is not needed, omit this parameter."
+ "description": "A console command that will be used to check whether a topic is allowed for a user when they attempting to subscribe. Parameter placeholders starts with the colon :. The userId parameter contains a user ID. If access checking is not needed, omit this parameter."
}
}
}