mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-10 12:07:02 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d9f1a225f | ||
|
|
8518a44935 | ||
|
|
b4a5d28f53 | ||
|
|
aa5427d976 | ||
|
|
04218e0291 | ||
|
|
c7c6cfe27f | ||
|
|
98d457dae6 | ||
|
|
007cf8c2aa | ||
|
|
8b73912c3d | ||
|
|
1ac2f489ab | ||
|
|
773f929b01 | ||
|
|
f3da3e0fb3 | ||
|
|
0a57e538d5 | ||
|
|
e8dae0cfd1 | ||
|
|
e9c55bbd43 | ||
|
|
7a98325eae | ||
|
|
b0a811c51d | ||
|
|
a1d920f003 | ||
|
|
07443e54de | ||
|
|
717a678c9a | ||
|
|
73533080f6 | ||
|
|
1c7a6d9825 | ||
|
|
c553bc8d0a | ||
|
|
4f2ade5f7f | ||
|
|
b882aad4ab | ||
|
|
8541c12441 | ||
|
|
2a967261b3 | ||
|
|
12e40352fe | ||
|
|
2b0bde8c0b | ||
|
|
931e8b934c | ||
|
|
a07cb5ef38 |
@@ -162,6 +162,10 @@ class LinkCheck
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->metadata->get(['recordDefs', $entityType, 'relationships', $link, 'linkCheckDisabled'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$foreignEntityType = $defs->getForeignEntityType();
|
||||
|
||||
$foreignEntity = $this->entityManager->getEntityById($foreignEntityType, $id);
|
||||
|
||||
@@ -569,7 +569,10 @@ class Service implements Crud,
|
||||
$list = [];
|
||||
|
||||
foreach ($duplicateList as $e) {
|
||||
$list[] = $e->getValueMap();
|
||||
$list[] = (object) [
|
||||
'id' => $e->getId(),
|
||||
'name' => $e->get('name'),
|
||||
];
|
||||
}
|
||||
|
||||
throw ConflictSilent::createWithBody('duplicate', Json::encode($list));
|
||||
|
||||
@@ -512,7 +512,7 @@ class SearchParams
|
||||
|
||||
unset($where[$i]);
|
||||
}
|
||||
else if ($type == 'textFilter' && $value) {
|
||||
else if ($type === 'textFilter') {
|
||||
$params['textFilter'] = $value;
|
||||
|
||||
unset($where[$i]);
|
||||
|
||||
@@ -208,7 +208,7 @@ class SelectBuilder
|
||||
|
||||
$textFilter = $searchParams->getTextFilter();
|
||||
|
||||
if ($textFilter) {
|
||||
if ($textFilter !== null) {
|
||||
$this->withTextFilter($textFilter);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,19 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"reminders": {
|
||||
"visible": {
|
||||
"conditionGroup": [
|
||||
{
|
||||
"type": "isNotEmpty",
|
||||
"attribute": "assignedUserId",
|
||||
"data": {
|
||||
"field": "assignedUser"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
[
|
||||
{"name":"name", "width": 35,"link":"true", "view": "crm:views/contact/fields/name-for-account"},
|
||||
{"name":"accountRole", "width": 35, "notSortable": true},
|
||||
{"name":"emailAddress"}
|
||||
{
|
||||
"name": "name",
|
||||
"link": "true",
|
||||
"view": "crm:views/contact/fields/name-for-account"
|
||||
},
|
||||
{
|
||||
"name": "accountRole",
|
||||
"width": 28,
|
||||
"notSortable": true
|
||||
},
|
||||
{
|
||||
"name":"emailAddress",
|
||||
"width": 33
|
||||
}
|
||||
]
|
||||
|
||||
@@ -119,9 +119,12 @@ class ConvertService
|
||||
|
||||
if ($rDuplicateList) {
|
||||
foreach ($rDuplicateList as $e) {
|
||||
$item = $e->getValueMap();
|
||||
$item->_entityType = $e->getEntityType();
|
||||
$duplicateList[] = $item;
|
||||
$duplicateList[] = (object) [
|
||||
'id' => $e->getId(),
|
||||
'name' => $e->getName(),
|
||||
'_entityType' => $e->getEntityType(),
|
||||
];
|
||||
|
||||
$skipSave = true;
|
||||
}
|
||||
}
|
||||
@@ -151,10 +154,11 @@ class ConvertService
|
||||
|
||||
if ($rDuplicateList) {
|
||||
foreach ($rDuplicateList as $e) {
|
||||
$item = $e->getValueMap();
|
||||
$item->_entityType = $e->getEntityType();
|
||||
|
||||
$duplicateList[] = $item;
|
||||
$duplicateList[] = (object) [
|
||||
'id' => $e->getId(),
|
||||
'name' => $e->getName(),
|
||||
'_entityType' => $e->getEntityType(),
|
||||
];
|
||||
|
||||
$skipSave = true;
|
||||
}
|
||||
@@ -189,9 +193,11 @@ class ConvertService
|
||||
|
||||
if ($rDuplicateList) {
|
||||
foreach ($rDuplicateList as $e) {
|
||||
$item = $e->getValueMap();
|
||||
$item->_entityType = $e->getEntityType();
|
||||
$duplicateList[] = $item;
|
||||
$duplicateList[] = (object) [
|
||||
'id' => $e->getId(),
|
||||
'name' => $e->getName(),
|
||||
'_entityType' => $e->getEntityType(),
|
||||
];
|
||||
|
||||
$skipSave = true;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"ico": ["image/vnd.microsoft.icon"],
|
||||
"ics": ["text/calendar"],
|
||||
"jar": ["application/java-archive"],
|
||||
"jpeg ": ["image/jpeg"],
|
||||
"jpeg": ["image/jpeg"],
|
||||
"jpg": ["image/jpeg"],
|
||||
"js": ["text/javascript"],
|
||||
"json": ["application/json"],
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"controller": "controllers/record",
|
||||
"searchPanelDisabled": true,
|
||||
"massUpdateDisabled": true,
|
||||
"mergeDisabled": true,
|
||||
"massRemoveDisabled": true,
|
||||
"iconClass": "fas fa-calendar-week",
|
||||
"menu": {
|
||||
"list": {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
"viewSetupHandlers": {
|
||||
"record/edit": "handlers/working-time-range"
|
||||
},
|
||||
"mergeDisabled": true,
|
||||
"massUpdateDisabled": true,
|
||||
"menu": {
|
||||
"list": {
|
||||
"buttons": [
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
"hasSeconds": true
|
||||
},
|
||||
"user": {
|
||||
"type": "link"
|
||||
"type": "link",
|
||||
"view": "views/fields/user"
|
||||
},
|
||||
"userType": {
|
||||
"type": "foreign",
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
},
|
||||
"user": {
|
||||
"type": "link",
|
||||
"readOnly": true
|
||||
"readOnly": true,
|
||||
"view": "views/fields/user"
|
||||
},
|
||||
"portal": {
|
||||
"type": "link",
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
],
|
||||
"fields": {
|
||||
"from": {
|
||||
"type": "currency"
|
||||
"type": "currency",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
},
|
||||
"to": {
|
||||
"type": "currency"
|
||||
"type": "currency",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
}
|
||||
},
|
||||
"naming": "prefix",
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
],
|
||||
"fields": {
|
||||
"from": {
|
||||
"type": "float"
|
||||
"type": "float",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
},
|
||||
"to": {
|
||||
"type": "float"
|
||||
"type": "float",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
}
|
||||
},
|
||||
"naming": "prefix",
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
],
|
||||
"fields": {
|
||||
"from": {
|
||||
"type": "int"
|
||||
"type": "int",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
},
|
||||
"to": {
|
||||
"type": "int"
|
||||
"type": "int",
|
||||
"layoutAvailabilityList": [
|
||||
"filters",
|
||||
"massUpdate"
|
||||
]
|
||||
}
|
||||
},
|
||||
"naming": "prefix",
|
||||
|
||||
@@ -624,7 +624,7 @@ class EntityManager
|
||||
$this->fileManager->removeInDir("custom/Espo/Custom/Resources/layouts/{$normalizedName}");
|
||||
$this->fileManager->removeDir("custom/Espo/Custom/Resources/layouts/{$normalizedName}");
|
||||
|
||||
$languageList = $this->config->get('languageList', []);
|
||||
$languageList = $this->metadata->get(['app', 'language', 'list'], []);
|
||||
|
||||
foreach ($languageList as $language) {
|
||||
$filePath = 'custom/Espo/Custom/Resources/i18n/' . $language . '/' . $normalizedName . '.json';
|
||||
|
||||
@@ -52,7 +52,7 @@ class DompdfInitializer
|
||||
$pdf = new Dompdf($options);
|
||||
|
||||
$size = $template->getPageFormat() === Template::PAGE_FORMAT_CUSTOM ?
|
||||
[$template->getPageWidth(), $template->getPageHeight()] :
|
||||
[0.0, 0.0, $template->getPageWidth(), $template->getPageHeight()] :
|
||||
$template->getPageFormat();
|
||||
|
||||
$orientation = $template->getPageOrientation() === Template::PAGE_ORIENTATION_PORTRAIT ?
|
||||
|
||||
@@ -1 +1 @@
|
||||
{{#if accountIsInactive}}<del>{{/if}}{{value}}{{#if accountIsInactive}}</del>{{/if}}
|
||||
{{#if accountIsInactive}}<del>{{/if}}<span title="{{value}}">{{value}}</span>{{#if accountIsInactive}}</del>{{/if}}
|
||||
|
||||
@@ -28,31 +28,48 @@
|
||||
|
||||
define('crm:view-setup-handlers/document/record-list-drag-n-drop', [], function () {
|
||||
|
||||
var Handler = function (view) {
|
||||
let Handler = function (view) {
|
||||
this.view = view;
|
||||
};
|
||||
|
||||
_.extend(Handler.prototype, {
|
||||
|
||||
process: function () {
|
||||
this.listenTo(this.view, 'after:render', function () {
|
||||
this.initDragDrop();
|
||||
}, this);
|
||||
this.listenTo(this.view, 'after:render', () => this.initDragDrop());
|
||||
this.listenTo(this.view, 'remove', () => this.disable());
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
let $el = this.view.$el.parent();
|
||||
/** @type {Element} */
|
||||
let el = $el.get(0);
|
||||
|
||||
$el.off('drop');
|
||||
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.onDragoverBind) {
|
||||
return;
|
||||
}
|
||||
|
||||
el.removeEventListener('dragover', this.onDragoverBind);
|
||||
el.removeEventListener('dragenter', this.onDragenterBind);
|
||||
el.removeEventListener('dragleave', this.onDragleaveBind);
|
||||
},
|
||||
|
||||
initDragDrop: function () {
|
||||
var $el = this.view.$el.parent();
|
||||
this.disable();
|
||||
|
||||
$el.off('drop');
|
||||
$el.off('dragover');
|
||||
$el.off('dragleave');
|
||||
let $el = this.view.$el.parent();
|
||||
let el = $el.get(0);
|
||||
|
||||
$el.on('drop', function (e) {
|
||||
$el.on('drop', e => {
|
||||
e.preventDefault();
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
var e = e.originalEvent;
|
||||
e = e.originalEvent;
|
||||
|
||||
if (
|
||||
e.dataTransfer &&
|
||||
@@ -68,65 +85,31 @@ define('crm:view-setup-handlers/document/record-list-drag-n-drop', [], function
|
||||
}
|
||||
|
||||
this.removeDrop($el);
|
||||
}.bind(this));
|
||||
|
||||
$el.get(0).addEventListener('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
this.dropEntered = false;
|
||||
|
||||
$el.get(0).addEventListener('dragenter', function (e) {
|
||||
e.preventDefault();
|
||||
this.onDragoverBind = this.onDragover.bind(this);
|
||||
this.onDragenterBind = this.onDragenter.bind(this);
|
||||
this.onDragleaveBind = this.onDragleave.bind(this);
|
||||
|
||||
if (!e.dataTransfer.types || !e.dataTransfer.types.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!~e.dataTransfer.types.indexOf('Files')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dropEntered) {
|
||||
this.renderDrop();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$el.get(0).addEventListener('dragleave', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.dropEntered) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fromElement = e.fromElement || e.relatedTarget;
|
||||
|
||||
if (fromElement && $.contains($el.get(0), fromElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
fromElement &&
|
||||
fromElement.parentNode &&
|
||||
fromElement.parentNode.toString() === '[object ShadowRoot]'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeDrop();
|
||||
|
||||
}.bind(this));
|
||||
el.addEventListener('dragover', this.onDragoverBind);
|
||||
el.addEventListener('dragenter', this.onDragenterBind);
|
||||
el.addEventListener('dragleave', this.onDragleaveBind);
|
||||
},
|
||||
|
||||
renderDrop: function () {
|
||||
this.dropEntered = true;
|
||||
|
||||
let $backdrop =
|
||||
$('<div class="dd-backdrop" />')
|
||||
$('<div class="dd-backdrop">')
|
||||
.css('pointer-events', 'none')
|
||||
.html(
|
||||
'<span class="fas fa-paperclip"></span> ' +
|
||||
this.view.getLanguage().translate('Create Document', 'labels', 'Document')
|
||||
.append('<span class="fas fa-paperclip"></span>')
|
||||
.append(' ')
|
||||
.append(
|
||||
$('<span>')
|
||||
.text(this.view.getLanguage().translate('Create Document', 'labels', 'Document'))
|
||||
);
|
||||
|
||||
this.view.$el.append($backdrop);
|
||||
@@ -141,31 +124,84 @@ define('crm:view-setup-handlers/document/record-list-drag-n-drop', [], function
|
||||
create: function (file) {
|
||||
this.view
|
||||
.actionQuickCreate()
|
||||
.then(
|
||||
function (view) {
|
||||
var fileView = view.getRecordView().getFieldView('file');
|
||||
.then(view => {
|
||||
let fileView = view.getRecordView().getFieldView('file');
|
||||
|
||||
if (!fileView) {
|
||||
var msg = "No 'file' field on the layout.";
|
||||
if (!fileView) {
|
||||
let msg = "No 'file' field on the layout.";
|
||||
|
||||
Espo.Ui.error(msg);
|
||||
console.error(msg);
|
||||
Espo.Ui.error(msg);
|
||||
console.error(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileView.isRendered()) {
|
||||
fileView.uploadFile(file);
|
||||
if (fileView.isRendered()) {
|
||||
fileView.uploadFile(file);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.listenToOnce(fileView, 'after:render', function () {
|
||||
fileView.uploadFile(file);
|
||||
});
|
||||
}.bind(this)
|
||||
);
|
||||
this.listenToOnce(fileView, 'after:render', () => {
|
||||
fileView.uploadFile(file);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragover: function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragenter: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!e.dataTransfer.types || !e.dataTransfer.types.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!~e.dataTransfer.types.indexOf('Files')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dropEntered) {
|
||||
this.renderDrop();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragleave: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.dropEntered) {
|
||||
return;
|
||||
}
|
||||
|
||||
let fromElement = e.fromElement || e.relatedTarget;
|
||||
|
||||
if (
|
||||
fromElement &&
|
||||
$.contains(this.view.$el.parent().get(0), fromElement)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
fromElement &&
|
||||
fromElement.parentNode &&
|
||||
fromElement.parentNode.toString() === '[object ShadowRoot]'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeDrop();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ define(() => {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
if (!this.acl.checkScope(model.entityType, 'read')) {
|
||||
if (model && !this.acl.checkScope(model.entityType, 'read')) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
|
||||
@@ -707,7 +707,7 @@ function (marked, DOMPurify, /** typeof Handlebars */Handlebars) {
|
||||
|
||||
text = text.replace(
|
||||
/<a href="mailto:(.*)"/gm,
|
||||
'<a type="button" class="selectable" data-email-address="$1" data-action="mailTo"'
|
||||
'<a role="button" class="selectable" data-email-address="$1" data-action="mailTo"'
|
||||
);
|
||||
|
||||
return new Handlebars.SafeString(text);
|
||||
|
||||
@@ -68,6 +68,8 @@ define('views/email/list', ['views/list'], function (Dep) {
|
||||
'drafts',
|
||||
],
|
||||
|
||||
stickableTop: null,
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -299,6 +301,29 @@ define('views/email/list', ['views/list'], function (Dep) {
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
createSearchView: function () {
|
||||
/** @type {Promise<module:view.Class>}*/
|
||||
let promise = Dep.prototype.createSearchView.call(this);
|
||||
|
||||
promise.then(view => {
|
||||
this.listenTo(view, 'update-ui', () => {
|
||||
this.stickableTop = null;
|
||||
|
||||
setTimeout(() => {
|
||||
$(window).trigger('scroll')
|
||||
|
||||
// If search fields are not yet rendered, the value may be wrong.
|
||||
this.stickableTop = null;
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
initEmailShortcuts: function () {
|
||||
this.shortcutKeys['Control+Delete'] = e => {
|
||||
if (!this.hasSelectedRecords()) {
|
||||
@@ -587,9 +612,15 @@ define('views/email/list', ['views/list'], function (Dep) {
|
||||
return value - offset;
|
||||
};
|
||||
|
||||
let start = getOffsetTop($list);
|
||||
this.stickableTop = getOffsetTop($list);
|
||||
|
||||
let control = () => {
|
||||
let start = this.stickableTop;
|
||||
|
||||
if (start === null) {
|
||||
start = this.stickableTop = getOffsetTop($list);
|
||||
}
|
||||
|
||||
let scrollTop = $window.scrollTop();
|
||||
|
||||
if (scrollTop <= start || isSmallScreen) {
|
||||
@@ -606,17 +637,18 @@ define('views/email/list', ['views/list'], function (Dep) {
|
||||
}
|
||||
|
||||
if (scrollTop > start) {
|
||||
let maxHeight = $window.height() - start - bottomSpaceHeight;
|
||||
|
||||
let scroll = $window.scrollTop() - start;
|
||||
|
||||
$container
|
||||
.addClass('sticked')
|
||||
.width($left.outerWidth(true))
|
||||
.scrollTop(scroll)
|
||||
.css({
|
||||
maxHeight: maxHeight,
|
||||
});
|
||||
.scrollTop(scroll);
|
||||
|
||||
let topStickPosition = parseInt(window.getComputedStyle($container.get(0)).top);
|
||||
|
||||
let maxHeight = $window.height() - topStickPosition - bottomSpaceHeight;
|
||||
|
||||
$container.css({maxHeight: maxHeight});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -158,54 +158,6 @@ function (Dep, /** module:ui/select*/Select) {
|
||||
return this.formatNumberDetail(value);
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo Remove. Used in range.
|
||||
*/
|
||||
formatNumberEdit: function (value) {
|
||||
let currencyDecimalPlaces = this.decimalPlaces;
|
||||
|
||||
if (value !== null) {
|
||||
var parts = value.toString().split(".");
|
||||
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator);
|
||||
|
||||
if (parts.length > 1) {
|
||||
if (
|
||||
currencyDecimalPlaces &&
|
||||
parts[1].length < currencyDecimalPlaces
|
||||
) {
|
||||
var limit = currencyDecimalPlaces - parts[1].length;
|
||||
|
||||
for (var i = 0; i < limit; i++) {
|
||||
parts[1] += '0';
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.params.decimal &&
|
||||
currencyDecimalPlaces &&
|
||||
parts[1].length > currencyDecimalPlaces
|
||||
) {
|
||||
let i = parts[1].length - 1;
|
||||
|
||||
while (i >= currencyDecimalPlaces) {
|
||||
if (parts[1][i] !== '0') {
|
||||
break;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
parts[1] = parts[1].substring(0, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join(this.decimalMark);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
formatNumberDetail: function (value) {
|
||||
if (value !== null) {
|
||||
let currencyDecimalPlaces = this.decimalPlaces;
|
||||
|
||||
@@ -60,7 +60,7 @@ define('views/fields/file', ['views/fields/link', 'helpers/file-upload'], functi
|
||||
|
||||
searchTypeList: ['isNotEmpty', 'isEmpty'],
|
||||
|
||||
ROW_HEIGHT: 35,
|
||||
ROW_HEIGHT: 37,
|
||||
|
||||
events: {
|
||||
'click a.remove-attachment': function (e) {
|
||||
|
||||
@@ -101,21 +101,6 @@ define('views/fields/float', ['views/fields/int'], function (Dep) {
|
||||
return this.formatNumberDetail(value);
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo Remove. Used in range.
|
||||
*/
|
||||
formatNumberEdit: function (value) {
|
||||
if (value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let parts = value.toString().split(".");
|
||||
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator);
|
||||
|
||||
return parts.join(this.decimalMark);
|
||||
},
|
||||
|
||||
formatNumberDetail: function (value) {
|
||||
if (value === null) {
|
||||
return '';
|
||||
|
||||
@@ -203,21 +203,6 @@ define('views/fields/int', ['views/fields/base', 'lib!autonumeric'], function (D
|
||||
return stringValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo Remove. Used in range.
|
||||
*/
|
||||
formatNumberEdit: function (value) {
|
||||
if (value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let stringValue = value.toString();
|
||||
|
||||
stringValue = stringValue.replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator);
|
||||
|
||||
return stringValue;
|
||||
},
|
||||
|
||||
setupSearch: function () {
|
||||
this.events = _.extend({
|
||||
'change select.search-type': (e) => {
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/fields/range-currency', ['views/fields/range-float'], function (Dep, Float) {
|
||||
define('views/fields/range-currency',
|
||||
['views/fields/range-float', 'views/fields/currency', 'ui/select'], function (Dep, Currency, Select) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
@@ -55,46 +56,74 @@ define('views/fields/range-currency', ['views/fields/range-float'], function (De
|
||||
|
||||
this.currencyField = this.name + 'Currency';
|
||||
this.currencyList = this.getConfig().get('currencyList') || ['USD'];
|
||||
this.decimalPlaces = this.getConfig().get('currencyDecimalPlaces');
|
||||
},
|
||||
|
||||
setupAutoNumericOptions: function () {
|
||||
this.autoNumericOptions = {
|
||||
digitGroupSeparator: this.thousandSeparator || '',
|
||||
decimalCharacter: this.decimalMark,
|
||||
modifyValueOnWheel: false,
|
||||
selectOnFocus: false,
|
||||
decimalPlaces: this.decimalPlaces,
|
||||
allowDecimalPadding: true,
|
||||
showWarnings: false,
|
||||
formulaMode: true,
|
||||
};
|
||||
|
||||
if (this.decimalPlaces === null) {
|
||||
this.autoNumericOptions.decimalPlaces = this.decimalPlacesRawValue;
|
||||
this.autoNumericOptions.decimalPlacesRawValue = this.decimalPlacesRawValue;
|
||||
this.autoNumericOptions.allowDecimalPadding = false;
|
||||
}
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
|
||||
if (this.mode === 'edit') {
|
||||
if (this.mode === this.MODE_EDIT) {
|
||||
this.$currency = this.$el.find('[data-name="' + this.currencyField + '"]');
|
||||
|
||||
Select.init(this.$currency);
|
||||
}
|
||||
},
|
||||
|
||||
formatNumber: function (value) {
|
||||
return Currency.prototype.formatNumberDetail.call(this, value);
|
||||
},
|
||||
|
||||
getValueForDisplay: function () {
|
||||
var fromValue = this.model.get(this.fromField);
|
||||
var toValue = this.model.get(this.toField);
|
||||
let fromValue = this.model.get(this.fromField);
|
||||
let toValue = this.model.get(this.toField);
|
||||
|
||||
fromValue = isNaN(fromValue) ? null : fromValue;
|
||||
toValue = isNaN(toValue) ? null : toValue;
|
||||
|
||||
var currencyValue = this.model.get(this.fromCurrencyField) ||
|
||||
let currencyValue = this.model.get(this.fromCurrencyField) ||
|
||||
this.model.get(this.toCurrencyField);
|
||||
|
||||
let symbol = this.getMetadata().get(['app', 'currency', 'symbolMap', currencyValue]) || currencyValue;
|
||||
|
||||
if (fromValue !== null && toValue !== null) {
|
||||
return this.formatNumber(fromValue) + ' – ' +
|
||||
this.formatNumber(toValue) + ' ' + currencyValue + '';
|
||||
this.formatNumber(toValue) + ' ' + symbol + '';
|
||||
}
|
||||
else if (fromValue) {
|
||||
return '>= ' + this.formatNumber(fromValue) + ' '+currencyValue+'';
|
||||
|
||||
if (fromValue) {
|
||||
return '>= ' + this.formatNumber(fromValue) + ' ' + symbol+'';
|
||||
}
|
||||
else if (toValue) {
|
||||
return '<= ' + this.formatNumber(toValue) + ' '+currencyValue+'';
|
||||
}
|
||||
else {
|
||||
return this.translate('None');
|
||||
|
||||
if (toValue) {
|
||||
return '<= ' + this.formatNumber(toValue) + ' ' + symbol+'';
|
||||
}
|
||||
|
||||
return this.translate('None');
|
||||
},
|
||||
|
||||
fetch: function () {
|
||||
var data = Dep.prototype.fetch.call(this);
|
||||
|
||||
var currencyValue = this.$currency.val();
|
||||
|
||||
let currencyValue = this.$currency.val();
|
||||
|
||||
if (data[this.fromField] !== null) {
|
||||
data[this.fromCurrencyField] = currencyValue;
|
||||
|
||||
@@ -34,10 +34,26 @@ define('views/fields/range-float', ['views/fields/range-int', 'views/fields/floa
|
||||
|
||||
validations: ['required', 'float', 'range', 'order'],
|
||||
|
||||
decimalPlacesRawValue: 10,
|
||||
|
||||
setupAutoNumericOptions: function () {
|
||||
this.autoNumericOptions = {
|
||||
digitGroupSeparator: this.thousandSeparator || '',
|
||||
decimalCharacter: this.decimalMark,
|
||||
modifyValueOnWheel: false,
|
||||
selectOnFocus: false,
|
||||
decimalPlaces: this.decimalPlacesRawValue,
|
||||
decimalPlacesRawValue: this.decimalPlacesRawValue,
|
||||
allowDecimalPadding: false,
|
||||
showWarnings: false,
|
||||
formulaMode: true,
|
||||
};
|
||||
},
|
||||
|
||||
validateFloat: function () {
|
||||
var validate = (name) => {
|
||||
let validate = (name) => {
|
||||
if (isNaN(this.model.get(name))) {
|
||||
var msg = this.translate('fieldShouldBeFloat', 'messages')
|
||||
let msg = this.translate('fieldShouldBeFloat', 'messages')
|
||||
.replace('{field}', this.getLabelText());
|
||||
|
||||
this.showValidationMessage(msg, '[data-name="'+name+'"]');
|
||||
@@ -46,7 +62,7 @@ define('views/fields/range-float', ['views/fields/range-int', 'views/fields/floa
|
||||
}
|
||||
};
|
||||
|
||||
var result = false;
|
||||
let result = false;
|
||||
|
||||
result = validate(this.fromField) || result;
|
||||
result = validate(this.toField) || result;
|
||||
@@ -59,16 +75,8 @@ define('views/fields/range-float', ['views/fields/range-int', 'views/fields/floa
|
||||
},
|
||||
|
||||
formatNumber: function (value) {
|
||||
return Float.prototype.formatNumber.call(this, value);
|
||||
},
|
||||
|
||||
formatNumberDetail: function (value) {
|
||||
return Float.prototype.formatNumberDetail.call(this, value);
|
||||
},
|
||||
|
||||
formatNumberEdit: function (value) {
|
||||
return Float.prototype.formatNumberEdit.call(this, value);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -26,22 +26,21 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], function (Dep, Int) {
|
||||
define('views/fields/range-int',
|
||||
['views/fields/base', 'views/fields/int', 'lib!autonumeric'], function (Dep, Int, AutoNumeric) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
type: 'rangeInt',
|
||||
|
||||
listTemplate: 'fields/range-int/detail',
|
||||
|
||||
detailTemplate: 'fields/range-int/detail',
|
||||
|
||||
editTemplate: 'fields/range-int/edit',
|
||||
|
||||
validations: ['required', 'int', 'range', 'order'],
|
||||
|
||||
data: function () {
|
||||
var data = Dep.prototype.data.call(this);
|
||||
let data = Dep.prototype.data.call(this);
|
||||
|
||||
data.ucName = Espo.Utils.upperCaseFirst(this.name);
|
||||
data.fromValue = this.model.get(this.fromField);
|
||||
@@ -60,8 +59,8 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
},
|
||||
|
||||
getValueForDisplay: function () {
|
||||
var fromValue = this.model.get(this.fromField);
|
||||
var toValue = this.model.get(this.toField);
|
||||
let fromValue = this.model.get(this.fromField);
|
||||
let toValue = this.model.get(this.toField);
|
||||
|
||||
fromValue = isNaN(fromValue) ? null : fromValue;
|
||||
toValue = isNaN(toValue) ? null : toValue;
|
||||
@@ -100,10 +99,37 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
}
|
||||
},
|
||||
|
||||
setupFinal: function () {
|
||||
Dep.prototype.setupFinal.call(this);
|
||||
|
||||
this.setupAutoNumericOptions();
|
||||
},
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
setupAutoNumericOptions: function () {
|
||||
let separator = (!this.disableFormatting ? this.thousandSeparator : null) || '';
|
||||
let decimalCharacter = '.';
|
||||
|
||||
if (separator === '.') {
|
||||
decimalCharacter = ',';
|
||||
}
|
||||
|
||||
this.autoNumericOptions = {
|
||||
digitGroupSeparator: separator,
|
||||
decimalCharacter: decimalCharacter,
|
||||
modifyValueOnWheel: false,
|
||||
decimalPlaces: 0,
|
||||
selectOnFocus: false,
|
||||
formulaMode: true,
|
||||
};
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
|
||||
if (this.mode === 'edit') {
|
||||
if (this.mode === this.MODE_EDIT) {
|
||||
this.$from = this.$el.find('[data-name="' + this.fromField + '"]');
|
||||
this.$to = this.$el.find('[data-name="' + this.toField + '"]');
|
||||
|
||||
@@ -114,6 +140,11 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
this.$to.on('change', () => {
|
||||
this.trigger('change');
|
||||
});
|
||||
|
||||
if (this.autoNumericOptions) {
|
||||
this.autoNumericInstance1 = new AutoNumeric(this.$from.get(0), this.autoNumericOptions);
|
||||
this.autoNumericInstance2 = new AutoNumeric(this.$to.get(0), this.autoNumericOptions);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -131,7 +162,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
}
|
||||
};
|
||||
|
||||
var result = false;
|
||||
let result = false;
|
||||
|
||||
result = validate(this.fromField) || result;
|
||||
result = validate(this.toField) || result;
|
||||
@@ -140,7 +171,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
},
|
||||
|
||||
validateInt: function () {
|
||||
var validate = (name) => {
|
||||
let validate = (name) => {
|
||||
if (isNaN(this.model.get(name))) {
|
||||
var msg = this.translate('fieldShouldBeInt', 'messages')
|
||||
.replace('{field}', this.getLabelText());
|
||||
@@ -151,7 +182,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
}
|
||||
};
|
||||
|
||||
var result = false;
|
||||
let result = false;
|
||||
|
||||
result = validate(this.fromField) || result;
|
||||
result = validate(this.toField) || result;
|
||||
@@ -160,7 +191,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
},
|
||||
|
||||
validateRange: function () {
|
||||
var validate = (name) => {
|
||||
let validate = (name) => {
|
||||
var value = this.model.get(name);
|
||||
|
||||
if (value === null) {
|
||||
@@ -172,7 +203,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
|
||||
if (minValue !== null && maxValue !== null) {
|
||||
if (value < minValue || value > maxValue ) {
|
||||
var msg = this.translate('fieldShouldBeBetween', 'messages')
|
||||
let msg = this.translate('fieldShouldBeBetween', 'messages')
|
||||
.replace('{field}', this.translate(name, 'fields', this.model.name))
|
||||
.replace('{min}', minValue)
|
||||
.replace('{max}', maxValue);
|
||||
@@ -184,7 +215,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
} else {
|
||||
if (minValue !== null) {
|
||||
if (value < minValue) {
|
||||
var msg = this.translate('fieldShouldBeLess', 'messages')
|
||||
let msg = this.translate('fieldShouldBeLess', 'messages')
|
||||
.replace('{field}', this.translate(name, 'fields', this.model.name))
|
||||
.replace('{value}', minValue);
|
||||
|
||||
@@ -194,7 +225,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
}
|
||||
} else if (maxValue !== null) {
|
||||
if (value > maxValue) {
|
||||
var msg = this.translate('fieldShouldBeGreater', 'messages')
|
||||
let msg = this.translate('fieldShouldBeGreater', 'messages')
|
||||
.replace('{field}', this.translate(name, 'fields', this.model.name))
|
||||
.replace('{value}', maxValue);
|
||||
|
||||
@@ -206,7 +237,7 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
}
|
||||
};
|
||||
|
||||
var result = false;
|
||||
let result = false;
|
||||
|
||||
result = validate(this.fromField) || result;
|
||||
result = validate(this.toField) || result;
|
||||
@@ -215,12 +246,12 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
},
|
||||
|
||||
validateOrder: function () {
|
||||
var fromValue = this.model.get(this.fromField);
|
||||
var toValue = this.model.get(this.toField);
|
||||
let fromValue = this.model.get(this.fromField);
|
||||
let toValue = this.model.get(this.toField);
|
||||
|
||||
if (fromValue !== null && toValue !== null) {
|
||||
if (fromValue > toValue) {
|
||||
var msg = this.translate('fieldShouldBeGreater', 'messages')
|
||||
let msg = this.translate('fieldShouldBeGreater', 'messages')
|
||||
.replace('{field}', this.translate(this.toField, 'fields', this.model.name))
|
||||
.replace('{value}', this.translate(this.fromField, 'fields', this.model.name));
|
||||
|
||||
@@ -241,11 +272,11 @@ define('views/fields/range-int', ['views/fields/base', 'views/fields/int'], func
|
||||
},
|
||||
|
||||
formatNumber: function (value) {
|
||||
return value;
|
||||
return Int.prototype.formatNumberDetail.call(this, value);
|
||||
},
|
||||
|
||||
fetch: function (form) {
|
||||
var data = {};
|
||||
fetch: function () {
|
||||
let data = {};
|
||||
|
||||
data[this.fromField] = this.parse(this.$from.val().trim());
|
||||
data[this.toField] = this.parse(this.$to.val().trim());
|
||||
|
||||
@@ -36,17 +36,15 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
Dep.prototype.setupSearch.call(this);
|
||||
|
||||
this.searchTypeList = Espo.Utils.clone(this.searchTypeList);
|
||||
|
||||
this.searchTypeList.push('isFromTeams');
|
||||
|
||||
this.searchData.teamIdList = this.getSearchParamsData().teamIdList ||
|
||||
this.searchParams.teamIdList || [];
|
||||
|
||||
this.searchData.teamNameHash = this.getSearchParamsData().teamNameHash ||
|
||||
this.searchParams.teamNameHash || {};
|
||||
|
||||
this.events['click a[data-action="clearLinkTeams"]'] = function (e) {
|
||||
var id = $(e.currentTarget).data('id').toString();
|
||||
let id = $(e.currentTarget).data('id').toString();
|
||||
|
||||
this.deleteLinkTeams(id);
|
||||
};
|
||||
@@ -61,25 +59,25 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
scope: 'Team',
|
||||
createButton: false,
|
||||
multiple: true,
|
||||
}, function (view) {
|
||||
}, (view) => {
|
||||
view.render();
|
||||
|
||||
this.notify(false);
|
||||
|
||||
this.listenToOnce(view, 'select', function (models) {
|
||||
this.listenToOnce(view, 'select', models => {
|
||||
if (Object.prototype.toString.call(models) !== '[object Array]') {
|
||||
models = [models];
|
||||
}
|
||||
|
||||
models.forEach(function (model) {
|
||||
models.forEach(model => {
|
||||
this.addLinkTeams(model.id, model.get('name'));
|
||||
}, this);
|
||||
});
|
||||
});
|
||||
}, this);
|
||||
});
|
||||
});
|
||||
|
||||
this.events['click a[data-action="clearLinkTeams"]'] = function (e) {
|
||||
var id = $(e.currentTarget).data('id').toString();
|
||||
let id = $(e.currentTarget).data('id').toString();
|
||||
|
||||
this.deleteLinkTeams(id);
|
||||
};
|
||||
@@ -100,10 +98,10 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
|
||||
if (this.mode === 'search') {
|
||||
var $elemeneTeams = this.$el.find('input.element-teams');
|
||||
let $elementTeams = this.$el.find('input.element-teams');
|
||||
|
||||
$elemeneTeams.autocomplete({
|
||||
serviceUrl: (q) => {
|
||||
$elementTeams.autocomplete({
|
||||
serviceUrl: () => {
|
||||
return 'Team?&maxSize=' + this.getAutocompleteMaxCount() + '&select=id,name';
|
||||
},
|
||||
minChars: 1,
|
||||
@@ -114,8 +112,8 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
return this.getHelper().escapeString(suggestion.name);
|
||||
},
|
||||
transformResult: (response) => {
|
||||
var response = JSON.parse(response);
|
||||
var list = [];
|
||||
response = JSON.parse(response);
|
||||
let list = [];
|
||||
|
||||
response.list.forEach(item => {
|
||||
list.push({
|
||||
@@ -132,22 +130,22 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
},
|
||||
onSelect: (s) => {
|
||||
this.addLinkTeams(s.id, s.name);
|
||||
$elemeneTeams.val('');
|
||||
$elemeneTeams.focus();
|
||||
$elementTeams.val('');
|
||||
$elementTeams.focus();
|
||||
},
|
||||
});
|
||||
|
||||
$elemeneTeams.attr('autocomplete', 'espo-' + this.name);
|
||||
$elementTeams.attr('autocomplete', 'espo-' + this.name);
|
||||
|
||||
this.once('render', () => {
|
||||
$elemeneTeams.autocomplete('dispose');
|
||||
$elementTeams.autocomplete('dispose');
|
||||
});
|
||||
|
||||
this.once('remove', () => {
|
||||
$elemeneTeams.autocomplete('dispose');
|
||||
$elementTeams.autocomplete('dispose');
|
||||
});
|
||||
|
||||
var type = this.$el.find('select.search-type').val();
|
||||
let type = this.$el.find('select.search-type').val();
|
||||
|
||||
if (type === 'isFromTeams') {
|
||||
this.searchData.teamIdList.forEach(id => {
|
||||
@@ -160,7 +158,7 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
deleteLinkTeams: function (id) {
|
||||
this.deleteLinkTeamsHtml(id);
|
||||
|
||||
var index = this.searchData.teamIdList.indexOf(id);
|
||||
let index = this.searchData.teamIdList.indexOf(id);
|
||||
|
||||
if (index > -1) {
|
||||
this.searchData.teamIdList.splice(index, 1);
|
||||
@@ -191,8 +189,8 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
id = Handlebars.Utils.escapeExpression(id);
|
||||
name = Handlebars.Utils.escapeExpression(name);
|
||||
|
||||
var $container = this.$el.find('.link-teams-container');
|
||||
var $el = $('<div />').addClass('link-' + id).addClass('list-group-item');
|
||||
let $container = this.$el.find('.link-teams-container');
|
||||
let $el = $('<div />').addClass('link-' + id).addClass('list-group-item');
|
||||
|
||||
$el.html(name + ' ');
|
||||
|
||||
@@ -207,7 +205,7 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
},
|
||||
|
||||
fetchSearch: function () {
|
||||
var type = this.$el.find('select.search-type').val();
|
||||
let type = this.$el.find('select.search-type').val();
|
||||
|
||||
if (type === 'isFromTeams') {
|
||||
return {
|
||||
@@ -218,7 +216,7 @@ define('views/fields/user',[ 'views/fields/link'], function (Dep) {
|
||||
type: type,
|
||||
teamIdList: this.searchData.teamIdList,
|
||||
teamNameHash: this.searchData.teamNameHash,
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -326,8 +326,20 @@ function (Dep, /** typeof module:search-manager.Class */SearchManager) {
|
||||
|
||||
/**
|
||||
* Set up a search panel.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
setupSearchPanel: function () {
|
||||
this.createSearchView();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a search view.
|
||||
*
|
||||
* @return {Promise<module:view.Class>}
|
||||
* @protected
|
||||
*/
|
||||
createSearchView: function () {
|
||||
let filterList = Espo.Utils
|
||||
.clone(this.getMetadata().get(['clientDefs', this.foreignScope, 'filterList']) || []);
|
||||
|
||||
@@ -358,7 +370,7 @@ function (Dep, /** typeof module:search-manager.Class */SearchManager) {
|
||||
filterList = [];
|
||||
}
|
||||
|
||||
this.createView('search', this.searchView, {
|
||||
return this.createView('search', this.searchView, {
|
||||
collection: this.collection,
|
||||
el: '#main > .search-container',
|
||||
searchManager: this.searchManager,
|
||||
@@ -369,7 +381,7 @@ function (Dep, /** typeof module:search-manager.Class */SearchManager) {
|
||||
filterList: filterList,
|
||||
}, view => {
|
||||
if (this.viewModeList.length > 1) {
|
||||
this.listenTo(view, 'change-view-mode', this.switchViewMode, this);
|
||||
this.listenTo(view, 'change-view-mode', () => this.switchViewMode());
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -338,9 +338,21 @@ function (Dep, /** typeof module:search-manager.Class */SearchManager) {
|
||||
|
||||
/**
|
||||
* Set up a search panel.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
setupSearchPanel: function () {
|
||||
this.createView('search', this.searchView, {
|
||||
this.createSearchView();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a search view.
|
||||
*
|
||||
* @return {Promise<module:view.Class>}
|
||||
* @protected
|
||||
*/
|
||||
createSearchView: function () {
|
||||
return this.createView('search', this.searchView, {
|
||||
collection: this.collection,
|
||||
el: '#main > .search-container',
|
||||
searchManager: this.searchManager,
|
||||
@@ -348,13 +360,11 @@ function (Dep, /** typeof module:search-manager.Class */SearchManager) {
|
||||
viewMode: this.viewMode,
|
||||
viewModeList: this.viewModeList,
|
||||
isWide: true,
|
||||
}, (view) => {
|
||||
this.listenTo(view, 'reset', () => {
|
||||
this.resetSorting();
|
||||
});
|
||||
}, view => {
|
||||
this.listenTo(view, 'reset', () => this.resetSorting());
|
||||
|
||||
if (this.viewModeList.length > 1) {
|
||||
this.listenTo(view, 'change-view-mode', this.switchViewMode, this);
|
||||
this.listenTo(view, 'change-view-mode', mode => this.switchViewMode(mode));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -561,15 +561,23 @@ define('views/main', ['view'], function (Dep) {
|
||||
});
|
||||
});
|
||||
|
||||
let processUi = () => {
|
||||
this.$headerActionsContainer.find('li > .action[data-name="'+name+'"]').parent().removeClass('hidden');
|
||||
this.$headerActionsContainer.find('a.action[data-name="'+name+'"]').removeClass('hidden');
|
||||
|
||||
this.controlMenuDropdownVisibility();
|
||||
this.adjustButtons();
|
||||
};
|
||||
|
||||
if (!this.isRendered()) {
|
||||
if (this.isBeingRendered()) {
|
||||
this.whenRendered().then(() => processUi());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.$headerActionsContainer.find('li > .action[data-name="'+name+'"]').parent().removeClass('hidden');
|
||||
this.$headerActionsContainer.find('a.action[data-name="'+name+'"]').removeClass('hidden');
|
||||
|
||||
this.controlMenuDropdownVisibility();
|
||||
this.adjustButtons();
|
||||
processUi();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -545,6 +545,8 @@ define('views/record/search', ['view'], function (Dep) {
|
||||
this.selectPreset(this.presetName, true);
|
||||
|
||||
this.hideApplyFiltersButton();
|
||||
|
||||
this.trigger('update-ui');
|
||||
},
|
||||
|
||||
savePreset: function (name) {
|
||||
@@ -629,6 +631,8 @@ define('views/record/search', ['view'], function (Dep) {
|
||||
else {
|
||||
this.$el.find('button.add-filter-button').removeClass('disabled');
|
||||
}
|
||||
|
||||
this.trigger('update-ui');
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
|
||||
@@ -2346,9 +2346,10 @@ stream-head-text-container .span {
|
||||
table.audited-summary-table {
|
||||
margin-top: 8px;
|
||||
background-color: transparent;
|
||||
table-layout: fixed;
|
||||
|
||||
td {
|
||||
white-space: nowrap;
|
||||
//white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -2512,8 +2513,8 @@ table.table td.cell .html-container {
|
||||
h5:first-child,
|
||||
h6:first-child,
|
||||
p:first-child,
|
||||
ul:first-child,
|
||||
ol:first-child,
|
||||
> ul:first-child,
|
||||
> ol:first-child,
|
||||
pre:first-child,
|
||||
blockquote:first-child {
|
||||
margin-top: 0 !important;
|
||||
@@ -2525,7 +2526,7 @@ table.table td.cell .html-container {
|
||||
}
|
||||
h2, h3 {
|
||||
font-weight: 600;
|
||||
margin-top: (@line-height-computed / 2);
|
||||
margin-top: (@line-height-computed / 2) * 1.2;
|
||||
margin-bottom: (@line-height-computed / 2);
|
||||
}
|
||||
h4, h5, h6 {
|
||||
@@ -2536,7 +2537,10 @@ table.table td.cell .html-container {
|
||||
h1 {
|
||||
font-size: floor(@font-size-base * 1.2);
|
||||
}
|
||||
h2, h3, h4, h5, h6 {
|
||||
h2 {
|
||||
font-size: floor(@font-size-base * 1.1);
|
||||
}
|
||||
h3, h4, h5, h6 {
|
||||
font-size: floor(@font-size-base);
|
||||
}
|
||||
|
||||
@@ -2549,13 +2553,23 @@ table.table td.cell .html-container {
|
||||
}
|
||||
|
||||
p:last-child,
|
||||
ul:last-child,
|
||||
ol:last-child,
|
||||
> ul:last-child,
|
||||
> ol:last-child,
|
||||
blockquote:last-child,
|
||||
pre:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
> li {
|
||||
ul, ol{
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul > li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
@@ -598,6 +598,7 @@ body {
|
||||
}
|
||||
|
||||
> .panel-body {
|
||||
.list.bottom-border-radius,
|
||||
> .list-container:last-child > .list {
|
||||
border-bottom-left-radius: var(--panel-border-radius);
|
||||
border-bottom-right-radius: var(--panel-border-radius);
|
||||
|
||||
@@ -15,6 +15,7 @@ body {
|
||||
}
|
||||
|
||||
background-color: var(--panel-bg);
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "espocrm",
|
||||
"version": "7.4.3",
|
||||
"version": "7.4.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "espocrm",
|
||||
"version": "7.4.3",
|
||||
"version": "7.4.4",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "espocrm",
|
||||
"version": "7.4.3",
|
||||
"version": "7.4.4",
|
||||
"description": "Open-source CRM.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user