modal/main supporting elements

This commit is contained in:
Yuri Kuznetsov
2022-07-10 18:57:09 +03:00
parent 77c5471656
commit 863ea657ed
5 changed files with 139 additions and 50 deletions
+42 -15
View File
@@ -26,11 +26,14 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
define('views/address-map/view', 'views/main', function (Dep) {
define('views/address-map/view', ['views/main'], function (Dep) {
return Dep.extend({
templateContent: '<div class="header page-header">{{{header}}}</div><div class="map-container">{{{map}}}</div>',
templateContent: `
<div class="header page-header">{{{header}}}</div>
<div class="map-container">{{{map}}}</div>
`,
setup: function () {
var field = this.options.field;
@@ -52,43 +55,67 @@ define('views/address-map/view', 'views/main', function (Dep) {
afterRender: function () {
var field = this.options.field;
var viewName = this.model.getFieldParam(field + 'Map', 'view') || this.getFieldManager().getViewName('map');
var viewName = this.model.getFieldParam(field + 'Map', 'view') ||
this.getFieldManager().getViewName('map');
this.createView('map', viewName, {
model: this.model,
name: field + 'Map',
el: this.getSelector() + ' .map-container',
height: this.getHelper().calculateContentContainerHeight(this.$el.find('.map-container')),
}, function (view) {
}, (view) => {
view.render();
});
},
getHeader: function () {
var name = Handlebars.Utils.escapeExpression(this.model.get('name'));
let name = this.model.get('name');
if (name === '') {
name = this.model.id;
}
name = '<span class="font-size-flexible title">' + name + '</span>';
let recordUrl = '#' + this.model.entityType + '/view/' + this.model.id
let scopeLabel = this.getLanguage().translate(this.model.entityType, 'scopeNamesPlural');
let fieldLabel = this.translate(this.options.field, 'fields', this.model.entityType);
let rootUrl = this.options.rootUrl ||
this.options.params.rootUrl ||
'#' + this.model.entityType;
let $name = $('<a>')
.attr('href', recordUrl)
.append(
$('<span>')
.addClass('font-size-flexible title')
.text(name)
);
if (this.model.get('deleted')) {
name = '<span style="text-decoration: line-through;">' + name + '</span>';
$name.css('text-decoration', 'line-through');
}
var rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.model.entityType;
let $root = $('<span>')
.append(
$('<a>')
.attr('href', rootUrl)
.addClass('action')
.attr('data-action', 'navigateToRoot')
.text(scopeLabel)
);
var headerIconHtml = this.getHeaderIconHtml();
let headerIconHtml = this.getHeaderIconHtml();
if (headerIconHtml) {
$root.prepend(headerIconHtml);
}
let $field = $('<span>').text(fieldLabel)
return this.buildHeaderHtml([
headerIconHtml +
'<a href="' + rootUrl + '" class="action" data-action="navigateToRoot">' +
this.getLanguage().translate(this.model.entityType, 'scopeNamesPlural') + '</a>',
name,
this.translate(this.options.field, 'fields', this.model.entityType)
$root,
$name,
$field,
]);
},
});
});
+32 -18
View File
@@ -260,34 +260,46 @@ define('views/detail', ['views/main'], function (Dep) {
* @inheritDoc
*/
getHeader: function () {
var name = Handlebars.Utils.escapeExpression(this.model.get('name'));
let name = this.model.get('name');
if (name === '') {
name = this.model.id;
}
name = '<span class="font-size-flexible title">' + name + '</span>';
let $name =
$('<span>')
.addClass('font-size-flexible title')
.text(name)
if (this.model.get('deleted')) {
name = '<span style="text-decoration: line-through;">' + name + '</span>';
$name.css('text-decoration', 'line-through');
}
var rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.scope;
let rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.scope;
let headerIconHtml = this.getHeaderIconHtml();
let scopeLabel = this.getLanguage().translate(this.scope, 'scopeNamesPlural');
var headerIconHtml = this.getHeaderIconHtml();
var rootHtml = this.getLanguage().translate(this.scope, 'scopeNamesPlural');
let $root = $('<span>').text(scopeLabel);
if (!this.rootLinkDisabled) {
rootHtml =
'<a href="' + rootUrl + '" class="action" data-action="navigateToRoot">' +
rootHtml +
'</a>';
$root = $('<span>')
.append(
$('<a>')
.attr('href', rootUrl)
.addClass('action')
.attr('data-action', 'navigateToRoot')
.text(scopeLabel)
);
}
if (headerIconHtml) {
$root.prepend(headerIconHtml);
}
return this.buildHeaderHtml([
headerIconHtml + rootHtml,
name,
$root,
$name,
]);
},
@@ -485,8 +497,10 @@ define('views/detail', ['views/main'], function (Dep) {
var massRelateEnabled = data.massSelect;
let filters;
if (link in this.selectRelatedFilters) {
var filters = Espo.Utils.cloneDeep(this.selectRelatedFilters[link]) || {};
filters = Espo.Utils.cloneDeep(this.selectRelatedFilters[link]) || {};
for (var filterName in filters) {
if (typeof filters[filterName] === 'function') {
@@ -514,7 +528,7 @@ define('views/detail', ['views/main'], function (Dep) {
~['belongsTo', 'belongsToParent'].indexOf(foreignLinkType) &&
foreignLinkFieldType
) {
var filters = {};
filters = {};
if (foreignLinkFieldType === 'link' || foreignLinkFieldType === 'linkParent') {
filters[foreignLink] = {
@@ -541,7 +555,8 @@ define('views/detail', ['views/main'], function (Dep) {
dataBoolFilterList = data.boolFilterList.split(',');
}
var boolFilterList = dataBoolFilterList || Espo.Utils.cloneDeep(this.selectBoolFilterLists[link] || []);
var boolFilterList = dataBoolFilterList ||
Espo.Utils.cloneDeep(this.selectBoolFilterLists[link] || []);
if (typeof boolFilterList === 'function') {
boolFilterList = boolFilterList.call(this);
@@ -615,8 +630,7 @@ define('views/detail', ['views/main'], function (Dep) {
actionDuplicate: function () {
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
this
.ajaxPostRequest(this.scope + '/action/getDuplicateAttributes', {
Espo.Ajax.postRequest(this.scope + '/action/getDuplicateAttributes', {
id: this.model.id
})
.then((attributes) => {
+30 -9
View File
@@ -190,7 +190,9 @@ define('views/main', ['view'], function (Dep) {
}
if (item.accessDataList) {
if (!Espo.Utils.checkAccessDataList(item.accessDataList, this.getAcl(), this.getUser())) {
if (!Espo.Utils
.checkAccessDataList(item.accessDataList, this.getAcl(), this.getUser())
) {
return;
}
}
@@ -223,19 +225,38 @@ define('views/main', ['view'], function (Dep) {
/**
* Build a header HTML. To be called from the #getHeader method.
* Beware of XSS.
*
* @param {string[]} arr A breadcrumb path. Like: Account > Name > edit.
* @param {(string|Element|JQuery)[]} itemList A breadcrumb path. Like: Account > Name > edit.
* @returns {string} HTML
*/
buildHeaderHtml: function (arr) {
var a = [];
arr.forEach(item => {
a.push('<div class="breadcrumb-item">' + item + '</div>');
buildHeaderHtml: function (itemList) {
let $itemList = itemList.map(item => {
return $('<div>')
.addClass('breadcrumb-item')
.append(item);
});
return '<div class="header-breadcrumbs">' +
a.join('<div class="breadcrumb-separator"><span class="chevron-right"></span></div>') + '</div>';
let $div = $('<div>')
.addClass('header-breadcrumbs');
$itemList.forEach(($item, i) => {
$div.append($item);
if (i === $itemList.length - 1) {
return;
}
$div.append(
$('<div>')
.addClass('breadcrumb-separator')
.append(
$('<span>').addClass('chevron-right')
)
)
});
return $div.get(0).outerHTML;
},
+23 -1
View File
@@ -32,6 +32,7 @@ define('views/modal', ['view'], function (Dep) {
* A base modal view. Can be extended or used directly.
*
* Options:
* - `headerElement`
* - `headerHtml`
* - `headerText`
* - `$header`
@@ -88,13 +89,29 @@ define('views/modal', ['view'], function (Dep) {
header: false,
/**
* A header HTML.
* A header HTML. Beware of XSS.
*
* @protected
* @type {string}
*/
headerHtml: null,
/**
* A header JQuery instance.
*
* @protected
* @type {JQuery}
*/
$header: null,
/**
* A header element.
*
* @protected
* @type {Element}
*/
headerElement: null,
/**
* A dialog instance.
*
@@ -228,6 +245,7 @@ define('views/modal', ['view'], function (Dep) {
this.header = this.options.header || this.header;
this.headerHtml = this.options.headerHtml || this.headerHtml;
this.$header = this.options.$header || this.$header;
this.headerElement = this.options.headerElement || this.headerElement;
if (this.options.headerText) {
this.headerHtml = Handlebars.Utils.escapeExpression(this.options.headerText);
@@ -272,6 +290,10 @@ define('views/modal', ['view'], function (Dep) {
headerHtml = this.$header.get(0).outerHTML;
}
if (this.headerElement) {
headerHtml = this.headerElement.outerHTML;
}
this.dialog = new Espo.Ui.Dialog({
backdrop: this.backdrop,
header: headerHtml,
+12 -7
View File
@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
define('views/modals/view-map', 'views/modal', function (Dep) {
define('views/modals/view-map', ['views/modal'], function (Dep) {
return Dep.extend({
@@ -46,13 +46,19 @@ define('views/modals/view-map', 'views/modal', function (Dep) {
},
setup: function () {
var field = this.options.field;
let field = this.options.field;
this.headerHtml = this.getHelper().sanitizeHtml(
this.translate(field, 'fields', this.model.entityType)
);
let url = '#AddressMap/view/' + this.model.entityType + '/' + this.model.id + '/' + field;
let fieldLabel = this.translate(field, 'fields', this.model.entityType);
var viewName = this.model.getFieldParam(field + 'Map', 'view') || this.getFieldManager().getViewName('map');
this.headerElement =
$('<a>')
.attr('href', '#' + url)
.text(fieldLabel)
.get(0);
let viewName = this.model.getFieldParam(field + 'Map', 'view') ||
this.getFieldManager().getViewName('map');
this.createView('map', viewName, {
model: this.model,
@@ -61,6 +67,5 @@ define('views/modals/view-map', 'views/modal', function (Dep) {
height: 'auto',
});
},
});
});