Merge branch 'master' into version/8.4

This commit is contained in:
Yuri Kuznetsov
2024-06-10 09:49:37 +03:00
11 changed files with 97 additions and 44 deletions
@@ -60,7 +60,9 @@
"layout": "listForContact",
"createAttributeMap": {
"accountId": "accountId",
"accountName": "accountName"
"accountName": "accountName",
"id": "contactId",
"name": "contactName"
},
"selectHandler": "handlers/select-related/same-account"
},
+3 -3
View File
@@ -86,7 +86,7 @@ class BaseEntity implements Entity
$this->entityType = $entityType;
$this->entityManager = $entityManager;
$this->attributes = $defs['attributes'] /*?? $defs['fields']*/ ?? $this->attributes;
$this->attributes = $defs['attributes'] ?? $this->attributes;
$this->relations = $defs['relations'] ?? $this->relations;
if ($valueAccessorFactory) {
@@ -247,7 +247,7 @@ class BaseEntity implements Entity
);
}
// @todo Remove support in v9.0.
// @todo Remove support in v10.0.
if ($this->hasRelation($attribute) && $this->id && $this->entityManager) {
trigger_error(
"Accessing related records with Entity::get is deprecated. " .
@@ -337,7 +337,7 @@ class BaseEntity implements Entity
$value = $this->fetchedValuesContainer[$attribute] ?? null;
if ($value === null) {
return $value;
return null;
}
$type = $this->getAttributeType($attribute);
@@ -116,6 +116,7 @@ class Service
$recordService = $this->recordServiceContainer->get($entityType);
$recordService->loadAdditionalFields($e);
$recordService->prepareEntityForOutput($e);
$ignoreTypeList = [
+1 -1
View File
@@ -120,7 +120,7 @@ class ArrayFieldView extends BaseFieldView {
const itemHtmlList = [];
(this.selected || []).forEach(value => {
itemHtmlList.push(this.getItemHtml(value));
itemHtmlList.push(this.getItemHtml(value || ''));
});
// noinspection JSValidateTypes
@@ -41,7 +41,7 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
primaryLink
getAttributeList() {
let list = super.getAttributeList();
const list = super.getAttributeList();
list.push(this.primaryIdAttribute);
list.push(this.primaryNameAttribute);
@@ -58,10 +58,10 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
super.setup();
this.events['click [data-action="switchPrimary"]'] = e => {
let $target = $(e.currentTarget);
let id = $target.data('id');
const $target = $(e.currentTarget);
const id = $target.data('id');
LinkMultipleWithPrimaryFieldView.prototype.switchPrimary.call(this, id);
this.switchPrimary(id);
};
this.primaryId = this.model.get(this.primaryIdAttribute);
@@ -78,8 +78,23 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
this.primaryName = id ?
this.nameHash[id] : null;
}
this.trigger('change');
switchPrimary(id) {
const $switch = this.$el.find(`[data-id="${id}"][data-action="switchPrimary"]`);
if (!$switch.hasClass('active')) {
this.$el.find('button[data-action="switchPrimary"]')
.removeClass('active')
.children()
.addClass('text-muted');
$switch.addClass('active').children().removeClass('text-muted');
this.setPrimaryId(id);
this.trigger('change');
}
}
renderLinks() {
@@ -96,7 +111,7 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
getValueForDisplay() {
if (this.isDetailMode() || this.isListMode()) {
let itemList = [];
const itemList = [];
if (this.primaryId) {
itemList.push(
@@ -147,15 +162,15 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
return LinkMultipleWithPrimaryFieldView.prototype.addLinkHtml.call(this, id, name);
}
let $el = super.addLinkHtml(id, name);
const $el = super.addLinkHtml(id, name);
let isPrimary = (id === this.primaryId);
const isPrimary = (id === this.primaryId);
let $star = $('<span>')
const $star = $('<span>')
.addClass('fas fa-star fa-sm')
.addClass(!isPrimary ? 'text-muted' : '')
.addClass(!isPrimary ? 'text-muted' : '');
let $button = $('<button>')
const $button = $('<button>')
.attr('type', 'button')
.addClass('btn btn-link btn-sm pull-right hidden')
.attr('title', this.translate('Primary'))
@@ -171,7 +186,7 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
}
managePrimaryButton() {
let $primary = this.$el.find('button[data-action="switchPrimary"]');
const $primary = this.$el.find('button[data-action="switchPrimary"]');
if ($primary.length > 1) {
$primary.removeClass('hidden');
@@ -180,11 +195,18 @@ class LinkMultipleWithColumnsWithPrimaryFieldView extends LinkMultipleWithColumn
}
if ($primary.filter('.active').length === 0) {
let $first = $primary.first();
const $first = $primary.first();
if ($first.length) {
$first.addClass('active').children().removeClass('text-muted');
this.setPrimaryId($first.data('id'));
const id = $first.data('id');
this.setPrimaryId(id);
if (id !== this.primaryId) {
this.trigger('change');
}
}
}
}
@@ -40,7 +40,7 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
primaryLink
switchPrimary(id) {
let $switch = this.$el.find(`[data-id="${id}"][data-action="switchPrimary"]`);
const $switch = this.$el.find(`[data-id="${id}"][data-action="switchPrimary"]`);
if (!$switch.hasClass('active')) {
this.$el.find('button[data-action="switchPrimary"]')
@@ -51,6 +51,8 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
$switch.addClass('active').children().removeClass('text-muted');
this.setPrimaryId(id);
this.trigger('change');
}
}
@@ -84,8 +86,8 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
});
this.events['click [data-action="switchPrimary"]'] = e => {
let $target = $(e.currentTarget);
let id = $target.data('id');
const $target = $(e.currentTarget);
const id = $target.data('id');
this.switchPrimary(id);
};
@@ -100,8 +102,6 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
this.primaryName = id ?
this.nameHash[id] : null;
this.trigger('change');
}
/**
@@ -124,7 +124,7 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
*/
getValueForDisplay() {
if (this.isDetailMode() || this.isListMode()) {
let itemList = [];
const itemList = [];
if (this.primaryId) {
itemList.push(this.getDetailLinkHtml(this.primaryId, this.primaryName));
@@ -178,17 +178,17 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
return super.addLinkHtml(id, name);
}
let $container = this.$el.find('.link-container');
const $container = this.$el.find('.link-container');
let $el = $('<div>')
const $el = $('<div>')
.addClass('form-inline clearfix ')
.addClass('list-group-item link-with-role link-group-item-with-primary')
.addClass('link-' + id)
.attr('data-id', id);
let $name = $('<div>').text(name).append('&nbsp;');
const $name = $('<div>').text(name).append('&nbsp;');
let $remove = $('<a>')
const $remove = $('<a>')
.attr('role', 'button')
.attr('tabindex', '0')
.attr('data-id', id)
@@ -198,8 +198,8 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
$('<span>').addClass('fas fa-times')
);
let $left = $('<div>');
let $right = $('<div>');
const $left = $('<div>');
const $right = $('<div>');
$left.append($name);
$right.append($remove);
@@ -207,13 +207,13 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
$el.append($left);
$el.append($right);
let isPrimary = (id === this.primaryId);
const isPrimary = (id === this.primaryId);
let $star = $('<span>')
const $star = $('<span>')
.addClass('fas fa-star fa-sm')
.addClass(!isPrimary ? 'text-muted' : '')
.addClass(!isPrimary ? 'text-muted' : '');
let $button = $('<button>')
const $button = $('<button>')
.attr('type', 'button')
.addClass('btn btn-link btn-sm pull-right hidden')
.attr('title', this.translate('Primary'))
@@ -234,7 +234,7 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
* @protected
*/
managePrimaryButton() {
let $primary = this.$el.find('button[data-action="switchPrimary"]');
const $primary = this.$el.find('button[data-action="switchPrimary"]');
if ($primary.length > 1) {
$primary.removeClass('hidden');
@@ -244,12 +244,18 @@ class LinkMultipleWithPrimaryFieldView extends LinkMultipleFieldView {
}
if ($primary.filter('.active').length === 0) {
let $first = $primary.first();
const $first = $primary.first();
if ($first.length) {
$first.addClass('active').children().removeClass('text-muted');
this.setPrimaryId($first.data('id'));
const id = $first.data('id');
this.setPrimaryId(id);
if (id !== this.primaryId) {
this.trigger('change');
}
}
}
}
+5
View File
@@ -112,6 +112,11 @@ class SearchView extends View {
this.filtersLayoutName = this.options.filtersLayoutName || this.filtersLayoutName;
this.primaryFiltersDisabled = this.options.primaryFiltersDisabled || this.primaryFiltersDisabled;
this.viewModeIconClassMap = {
...this.viewModeIconClassMap,
...this.getMetadata().get(`clientDefs.${this.scope}.viewModeIconClassMap`),
};
/** @type {module:search-manager} */
this.searchManager = this.options.searchManager;
+3 -3
View File
@@ -60,14 +60,14 @@
@navbar-link-icon-color-value: @gray-dark-value;
@navbar-inverse-color-value: #d2d5da;
@navbar-inverse-bg-value: #677a99;
@navbar-inverse-bg-value: #5d759e;
@navbar-inverse-border-value: @default-border-color-value;
@navbar-inverse-link-color-value: #fff;
@navbar-inverse-link-hover-color-value: #fff;
@navbar-inverse-link-hover-bg-value: #62728d;
@navbar-inverse-link-hover-bg-value: #596e93;
@navbar-inverse-link-disabled-color-value: #444;
@navbar-inverse-link-disabled-bg-value: transparent;
@navbar-inverse-link-active-bg-value: #54647f;
@navbar-inverse-link-active-bg-value: #4a6086;
@navbar-inverse-link-icon-color-value: @navbar-inverse-link-color-value;
@navbar-inverse-link-icon-hover-color-value: @navbar-inverse-link-icon-color-value;
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "espocrm",
"version": "8.2.4",
"version": "8.2.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "espocrm",
"version": "8.2.4",
"version": "8.2.5",
"hasInstallScript": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "8.2.4",
"version": "8.2.5",
"description": "Open-source CRM.",
"repository": {
"type": "git",
+17
View File
@@ -70,6 +70,23 @@
"type": "string"
}
},
"listViewModeList": {
"type": "array",
"items": {
"anyOf": [
{"type": "string"},
{"enum": ["__APPEND__", "list", "kanban"]}
]
},
"description": "A list view mode list."
},
"viewModeIconClassMap": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "View mode icon classes. mode => class map."
},
"saveErrorHandlers": {
"description": "Save error handlers. https://docs.espocrm.com/development/frontend/save-error-handlers/",
"type": "object",