ref
This commit is contained in:
@@ -57,9 +57,9 @@
|
||||
* @typedef {Object} module:search-manager~advancedFilter
|
||||
*
|
||||
* @property {string} type A type. E.g. `equals`.
|
||||
* @property {string} attribute An attribute.
|
||||
* @property {string} [attribute] An attribute.
|
||||
* @property {*} [value] A value.
|
||||
* @property {Object.<string,*>} [data] Additional data for UI.
|
||||
* @property {Object.<string, *>} [data] Additional data for UI.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -306,7 +306,7 @@ class SearchManager {
|
||||
/**
|
||||
* Set advanced filters.
|
||||
*
|
||||
* @param {{string: module:search-manager~advancedFilter}} advanced Advanced filters.
|
||||
* @param {Object.<string, module:search-manager~advancedFilter>} advanced Advanced filters.
|
||||
* Pairs of field => advancedFilter.
|
||||
*/
|
||||
setAdvanced(advanced) {
|
||||
|
||||
@@ -64,7 +64,7 @@ class ModalView extends View {
|
||||
* @property {'default'|'danger'|'success'|'warning'} [style='default'] A style.
|
||||
* @property {boolean} [hidden=false] Is hidden.
|
||||
* @property {boolean} [disabled=false] Disabled.
|
||||
* @property {function():void} [onClick] Called on click. If not defined, then
|
||||
* @property {function(module:ui.Dialog): void} [onClick] Called on click. If not defined, then
|
||||
* the `action<Name>` class method will be called.
|
||||
* @property {string} [className] An additional class name.
|
||||
*/
|
||||
|
||||
@@ -26,83 +26,93 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/kanban-move-over', ['views/modal'], function (Dep) {
|
||||
import ModalView from 'views/modal';
|
||||
|
||||
return Dep.extend({
|
||||
class KanbanMoveOverModalView extends ModalView {
|
||||
|
||||
template: 'modals/kanban-move-over',
|
||||
template = 'modals/kanban-move-over'
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
optionDataList: this.optionDataList
|
||||
};
|
||||
/** @inheritDoc */
|
||||
backdrop = true
|
||||
|
||||
data() {
|
||||
return {
|
||||
optionDataList: this.optionDataList,
|
||||
};
|
||||
}
|
||||
|
||||
events = {
|
||||
/** @this KanbanMoveOverModalView */
|
||||
'click [data-action="move"]': function (e) {
|
||||
let value = $(e.currentTarget).data('value');
|
||||
|
||||
this.moveTo(value);
|
||||
},
|
||||
}
|
||||
|
||||
events: {
|
||||
'click [data-action="move"]': function (e) {
|
||||
var value = $(e.currentTarget).data('value');
|
||||
this.moveTo(value);
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
this.scope = this.model.name;
|
||||
|
||||
setup: function () {
|
||||
this.scope = this.model.name;
|
||||
var iconHtml = this.getHelper().getScopeColorIconHtml(this.scope);
|
||||
let iconHtml = this.getHelper().getScopeColorIconHtml(this.scope);
|
||||
|
||||
this.statusField = this.options.statusField;
|
||||
this.statusField = this.options.statusField;
|
||||
|
||||
this.$header = $('<span>');
|
||||
this.$header = $('<span>');
|
||||
|
||||
this.$header.append(
|
||||
$('<span>').text(this.getLanguage().translate(this.scope, 'scopeNames'))
|
||||
);
|
||||
|
||||
if (this.model.get('name')) {
|
||||
this.$header.append(' <span class="chevron-right"></span> ');
|
||||
this.$header.append(
|
||||
$('<span>').text(this.getLanguage().translate(this.scope, 'scopeNames'))
|
||||
);
|
||||
$('<span>').text(this.model.get('name'))
|
||||
)
|
||||
}
|
||||
|
||||
if (this.model.get('name')) {
|
||||
this.$header.append(' <span class="chevron-right"></span> ');
|
||||
this.$header.append(
|
||||
$('<span>').text(this.model.get('name'))
|
||||
)
|
||||
this.$header.prepend(iconHtml);
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel'
|
||||
}
|
||||
];
|
||||
|
||||
this.$header.prepend(iconHtml);
|
||||
this.optionDataList = [];
|
||||
|
||||
this.buttonList = [
|
||||
(
|
||||
this.getMetadata()
|
||||
.get(['entityDefs', this.scope, 'fields', this.statusField, 'options']) || []
|
||||
)
|
||||
.forEach((item) => {
|
||||
this.optionDataList.push({
|
||||
value: item,
|
||||
label: this.getLanguage().translateOption(item, this.statusField, this.scope),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
moveTo(status) {
|
||||
var attributes = {};
|
||||
|
||||
attributes[this.statusField] = status;
|
||||
|
||||
this.model
|
||||
.save(
|
||||
attributes,
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel'
|
||||
patch: true,
|
||||
isMoveTo: true,
|
||||
}
|
||||
];
|
||||
)
|
||||
.then(() => {
|
||||
Espo.Ui.success(this.translate('Done'));
|
||||
});
|
||||
|
||||
this.optionDataList = [];
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
(this.getMetadata()
|
||||
.get(['entityDefs', this.scope, 'fields', this.statusField, 'options']) || [])
|
||||
.forEach((item) => {
|
||||
this.optionDataList.push({
|
||||
value: item,
|
||||
label: this.getLanguage().translateOption(item, this.statusField, this.scope),
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
moveTo: function (status) {
|
||||
var attributes = {};
|
||||
|
||||
attributes[this.statusField] = status;
|
||||
|
||||
this.model
|
||||
.save(
|
||||
attributes,
|
||||
{
|
||||
patch: true,
|
||||
isMoveTo: true,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
Espo.Ui.success(this.translate('Done'));
|
||||
});
|
||||
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
});
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default KanbanMoveOverModalView;
|
||||
|
||||
@@ -26,69 +26,70 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/last-viewed', ['views/modal', 'search-manager'], function (Dep) {
|
||||
import ModalView from 'views/modal';
|
||||
|
||||
return Dep.extend({
|
||||
class LastViewedModalView extends ModalView {
|
||||
|
||||
header: false,
|
||||
scope: 'ActionHistoryRecord',
|
||||
className: 'dialog dialog-record',
|
||||
template: 'modals/last-viewed',
|
||||
backdrop: true,
|
||||
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
|
||||
this.events['click .list .cell > a'] = () => {
|
||||
this.close();
|
||||
};
|
||||
|
||||
this.$header = $('<a>')
|
||||
.attr('href', '#LastViewed')
|
||||
.attr('data-action', 'listView')
|
||||
.addClass('action')
|
||||
.text(this.getLanguage().translate('LastViewed', 'scopeNamesPlural'));
|
||||
|
||||
this.waitForView('list');
|
||||
|
||||
this.getCollectionFactory().create(this.scope, (collection) => {
|
||||
collection.maxSize = this.getConfig().get('recordsPerPage');
|
||||
this.collection = collection;
|
||||
|
||||
collection.url = 'LastViewed';
|
||||
|
||||
this.loadList();
|
||||
collection.fetch();
|
||||
});
|
||||
},
|
||||
|
||||
actionListView: function () {
|
||||
this.getRouter().navigate('#LastViewed', {trigger: true});
|
||||
scope = 'ActionHistoryRecord'
|
||||
className = 'dialog dialog-record'
|
||||
template = 'modals/last-viewed'
|
||||
backdrop = true
|
||||
|
||||
setup() {
|
||||
this.events['click .list .cell > a'] = () => {
|
||||
this.close();
|
||||
},
|
||||
};
|
||||
|
||||
loadList: function () {
|
||||
var viewName =
|
||||
this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listLastViewed') ||
|
||||
'views/record/list';
|
||||
this.$header = $('<a>')
|
||||
.attr('href', '#LastViewed')
|
||||
.attr('data-action', 'listView')
|
||||
.addClass('action')
|
||||
.text(this.getLanguage().translate('LastViewed', 'scopeNamesPlural'));
|
||||
|
||||
this.listenToOnce(this.collection, 'sync', function () {
|
||||
this.createView('list', viewName, {
|
||||
collection: this.collection,
|
||||
el: this.containerSelector + ' .list-container',
|
||||
selectable: false,
|
||||
checkboxes: false,
|
||||
massActionsDisabled: true,
|
||||
rowActionsView: false,
|
||||
searchManager: this.searchManager,
|
||||
checkAllResultDisabled: true,
|
||||
buttonsDisabled: true,
|
||||
headerDisabled: true,
|
||||
layoutName: 'listForLastViewed',
|
||||
layoutAclDisabled: true,
|
||||
});
|
||||
}, this);
|
||||
},
|
||||
});
|
||||
});
|
||||
this.waitForView('list');
|
||||
|
||||
this.getCollectionFactory().create(this.scope, collection => {
|
||||
collection.maxSize = this.getConfig().get('recordsPerPage');
|
||||
collection.url = 'LastViewed';
|
||||
|
||||
this.collection = collection;
|
||||
|
||||
this.loadList();
|
||||
|
||||
collection.fetch();
|
||||
});
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionListView() {
|
||||
this.getRouter().navigate('#LastViewed', {trigger: true});
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
loadList() {
|
||||
let viewName =
|
||||
this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listLastViewed') ||
|
||||
'views/record/list';
|
||||
|
||||
this.listenToOnce(this.collection, 'sync', () => {
|
||||
this.createView('list', viewName, {
|
||||
collection: this.collection,
|
||||
el: this.containerSelector + ' .list-container',
|
||||
selectable: false,
|
||||
checkboxes: false,
|
||||
massActionsDisabled: true,
|
||||
rowActionsView: false,
|
||||
searchManager: this.searchManager,
|
||||
checkAllResultDisabled: true,
|
||||
buttonsDisabled: true,
|
||||
headerDisabled: true,
|
||||
layoutName: 'listForLastViewed',
|
||||
layoutAclDisabled: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default LastViewedModalView;
|
||||
|
||||
@@ -26,129 +26,129 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/mass-action', ['views/modal', 'model'], function (Dep, Model) {
|
||||
import ModalView from 'views/modal';
|
||||
import Model from 'model';
|
||||
|
||||
return Dep.extend({
|
||||
class MassActionModalView extends ModalView {
|
||||
|
||||
className: 'dialog dialog-record',
|
||||
template = 'modals/mass-action'
|
||||
|
||||
template: 'modals/mass-action',
|
||||
className = 'dialog dialog-record'
|
||||
checkInterval = 4000
|
||||
|
||||
checkInterval: 4000,
|
||||
data() {
|
||||
return {
|
||||
infoText: this.translate('infoText', 'messages', 'MassAction'),
|
||||
};
|
||||
}
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
infoText: this.translate('infoText', 'messages', 'MassAction'),
|
||||
};
|
||||
},
|
||||
setup() {
|
||||
this.action = this.options.action;
|
||||
this.id = this.options.id;
|
||||
this.status = 'Pending';
|
||||
|
||||
setup: function () {
|
||||
this.action = this.options.action;
|
||||
this.id = this.options.id;
|
||||
this.status = 'Pending';
|
||||
this.headerText =
|
||||
this.translate('Mass Action', 'scopeNames') + ': ' +
|
||||
this.translate(this.action, 'massActions', this.options.scope);
|
||||
|
||||
this.headerText =
|
||||
this.translate('Mass Action', 'scopeNames') + ': ' +
|
||||
this.translate(this.action, 'massActions', this.options.scope);
|
||||
this.model = new Model();
|
||||
this.model.name = 'MassAction';
|
||||
|
||||
this.model = new Model();
|
||||
this.model.name = 'MassAction';
|
||||
this.model.setDefs({
|
||||
fields: {
|
||||
'status': {
|
||||
type: 'enum',
|
||||
readOnly: true,
|
||||
options: [
|
||||
'Pending',
|
||||
'Running',
|
||||
'Success',
|
||||
'Failed',
|
||||
],
|
||||
style: {
|
||||
'Success': 'success',
|
||||
'Failed': 'danger',
|
||||
},
|
||||
},
|
||||
'processedCount': {
|
||||
type: 'int',
|
||||
readOnly: true,
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
this.model.setDefs({
|
||||
fields: {
|
||||
'status': {
|
||||
type: 'enum',
|
||||
readOnly: true,
|
||||
options: [
|
||||
'Pending',
|
||||
'Running',
|
||||
'Success',
|
||||
'Failed',
|
||||
this.model.set({
|
||||
status: this.status,
|
||||
processedCount: null,
|
||||
});
|
||||
|
||||
this.createView('record', 'views/record/edit-for-modal', {
|
||||
scope: 'None',
|
||||
model: this.model,
|
||||
el: this.getSelector() + ' .record',
|
||||
detailLayout: [
|
||||
{
|
||||
rows: [
|
||||
[
|
||||
{
|
||||
name: 'status',
|
||||
labelText: this.translate('status', 'fields', 'MassAction'),
|
||||
},
|
||||
{
|
||||
name: 'processedCount',
|
||||
labelText: this.translate('processedCount', 'fields', 'MassAction'),
|
||||
},
|
||||
],
|
||||
style: {
|
||||
'Success': 'success',
|
||||
'Failed': 'danger',
|
||||
},
|
||||
},
|
||||
'processedCount': {
|
||||
type: 'int',
|
||||
readOnly: true,
|
||||
},
|
||||
}
|
||||
});
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.model.set({
|
||||
status: this.status,
|
||||
processedCount: null,
|
||||
});
|
||||
this.on('close', () => {
|
||||
let status = this.model.get('status');
|
||||
|
||||
this.createView('record', 'views/record/edit-for-modal', {
|
||||
scope: 'None',
|
||||
model: this.model,
|
||||
el: this.getSelector() + ' .record',
|
||||
detailLayout: [
|
||||
{
|
||||
rows: [
|
||||
[
|
||||
{
|
||||
name: 'status',
|
||||
labelText: this.translate('status', 'fields', 'MassAction'),
|
||||
},
|
||||
{
|
||||
name: 'processedCount',
|
||||
labelText: this.translate('processedCount', 'fields', 'MassAction'),
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
});
|
||||
if (
|
||||
status !== 'Pending' &&
|
||||
status !== 'Running'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.on('close', () => {
|
||||
let status = this.model.get('status');
|
||||
Espo.Ajax.postRequest(`MassAction/${this.id}/subscribe`);
|
||||
});
|
||||
|
||||
this.checkStatus();
|
||||
}
|
||||
|
||||
checkStatus() {
|
||||
Espo.Ajax
|
||||
.getRequest(`MassAction/${this.id}/status`)
|
||||
.then(response => {
|
||||
let status = response.status;
|
||||
|
||||
this.model.set('status', status);
|
||||
|
||||
if (status === 'Pending' || status === 'Running') {
|
||||
setTimeout(() => this.checkStatus(), this.checkInterval);
|
||||
|
||||
if (
|
||||
status !== 'Pending' &&
|
||||
status !== 'Running'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ajax.postRequest(`MassAction/${this.id}/subscribe`);
|
||||
});
|
||||
|
||||
this.checkStatus();
|
||||
},
|
||||
|
||||
checkStatus: function () {
|
||||
Espo.Ajax
|
||||
.getRequest(`MassAction/${this.id}/status`)
|
||||
.then(response => {
|
||||
let status = response.status;
|
||||
|
||||
this.model.set('status', status);
|
||||
|
||||
if (status === 'Pending' || status === 'Running') {
|
||||
setTimeout(() => this.checkStatus(), this.checkInterval);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.set({
|
||||
processedCount: response.processedCount,
|
||||
});
|
||||
|
||||
if (status === 'Success') {
|
||||
this.trigger('success', {
|
||||
count: response.processedCount,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.$el) {
|
||||
this.$el.find('.info-text').addClass('hidden');
|
||||
}
|
||||
this.model.set({
|
||||
processedCount: response.processedCount,
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
if (status === 'Success') {
|
||||
this.trigger('success', {
|
||||
count: response.processedCount,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.$el) {
|
||||
this.$el.find('.info-text').addClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default MassActionModalView;
|
||||
|
||||
@@ -26,323 +26,331 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/mass-update', ['views/modal', 'helpers/mass-action'], function (Dep, MassActionHelper) {
|
||||
import ModalView from 'views/modal';
|
||||
import MassActionHelper from 'helpers/mass-action';
|
||||
|
||||
return Dep.extend({
|
||||
class MassUpdateModalView extends ModalView {
|
||||
|
||||
cssName: 'mass-update',
|
||||
template = 'modals/mass-update'
|
||||
|
||||
className: 'dialog dialog-record',
|
||||
cssName = 'mass-update'
|
||||
className = 'dialog dialog-record'
|
||||
layoutName = 'massUpdate'
|
||||
|
||||
template: 'modals/mass-update',
|
||||
ACTION_UPDATE = 'update'
|
||||
//ACTION_ADD = 'add'
|
||||
//ACTION_REMOVE = 'remove'
|
||||
|
||||
layoutName: 'massUpdate',
|
||||
data() {
|
||||
return {
|
||||
scope: this.scope,
|
||||
fieldList: this.fieldList,
|
||||
entityType: this.entityType,
|
||||
};
|
||||
}
|
||||
|
||||
ACTION_UPDATE: 'update',
|
||||
events = {
|
||||
/** @this MassUpdateModalView */
|
||||
'click a[data-action="add-field"]': function (e) {
|
||||
let field = $(e.currentTarget).data('name');
|
||||
|
||||
ACTION_ADD: 'add',
|
||||
|
||||
ACTION_REMOVE: 'remove',
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
scope: this.scope,
|
||||
fieldList: this.fieldList,
|
||||
entityType: this.entityType,
|
||||
};
|
||||
this.addField(field);
|
||||
},
|
||||
/** @this MassUpdateModalView */
|
||||
'click button[data-action="reset"]': function () {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
events: {
|
||||
'click button[data-action="update"]': function () {
|
||||
this.update();
|
||||
setup() {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'update',
|
||||
label: 'Update',
|
||||
style: 'danger',
|
||||
disabled: true,
|
||||
},
|
||||
'click a[data-action="add-field"]': function (e) {
|
||||
var field = $(e.currentTarget).data('name');
|
||||
this.addField(field);
|
||||
},
|
||||
'click button[data-action="reset"]': function (e) {
|
||||
this.reset();
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel',
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
setup: function () {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'update',
|
||||
label: 'Update',
|
||||
style: 'danger',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel',
|
||||
}
|
||||
];
|
||||
this.entityType = this.options.entityType || this.options.scope;
|
||||
this.scope = this.options.scope || this.entityType;
|
||||
|
||||
this.entityType = this.options.entityType || this.options.scope;
|
||||
this.scope = this.options.scope || this.entityType;
|
||||
this.ids = this.options.ids;
|
||||
this.where = this.options.where;
|
||||
this.searchParams = this.options.searchParams;
|
||||
this.byWhere = this.options.byWhere;
|
||||
|
||||
this.ids = this.options.ids;
|
||||
this.where = this.options.where;
|
||||
this.searchParams = this.options.searchParams;
|
||||
this.byWhere = this.options.byWhere;
|
||||
this.hasActionMap = {};
|
||||
|
||||
this.hasActionMap = {};
|
||||
let totalCount = this.options.totalCount;
|
||||
|
||||
let totalCount = this.options.totalCount;
|
||||
this.helper = new MassActionHelper(this);
|
||||
|
||||
this.helper = new MassActionHelper(this);
|
||||
this.idle = this.byWhere && this.helper.checkIsIdle(totalCount);
|
||||
|
||||
this.idle = this.byWhere && this.helper.checkIsIdle(totalCount);
|
||||
this.$header = $('<span>')
|
||||
.append(
|
||||
$('<span>').text(this.translate(this.scope, 'scopeNamesPlural')),
|
||||
' <span class="chevron-right"></span> ',
|
||||
$('<span>').text(this.translate('Mass Update'))
|
||||
)
|
||||
|
||||
this.$header = $('<span>')
|
||||
.append(
|
||||
$('<span>').text(this.translate(this.scope, 'scopeNamesPlural')),
|
||||
' <span class="chevron-right"></span> ',
|
||||
$('<span>').text(this.translate('Mass Update'))
|
||||
)
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenFieldList(this.entityType, 'edit') || [];
|
||||
|
||||
var forbiddenList = this.getAcl().getScopeForbiddenFieldList(this.entityType, 'edit') || [];
|
||||
this.wait(true);
|
||||
|
||||
this.wait(true);
|
||||
this.getModelFactory().create(this.entityType, (model) => {
|
||||
this.model = model;
|
||||
|
||||
this.getModelFactory().create(this.entityType, (model) => {
|
||||
this.model = model;
|
||||
this.getHelper().layoutManager.get(this.entityType, this.layoutName, (layout) => {
|
||||
layout = layout || [];
|
||||
|
||||
this.getHelper().layoutManager.get(this.entityType, this.layoutName, (layout) => {
|
||||
layout = layout || [];
|
||||
this.fieldList = [];
|
||||
|
||||
this.fieldList = [];
|
||||
layout.forEach((field) => {
|
||||
if (~forbiddenList.indexOf(field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
layout.forEach((field) => {
|
||||
if (~forbiddenList.indexOf(field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (model.hasField(field)) {
|
||||
this.fieldList.push(field);
|
||||
}
|
||||
});
|
||||
|
||||
this.wait(false);
|
||||
if (model.hasField(field)) {
|
||||
this.fieldList.push(field);
|
||||
}
|
||||
});
|
||||
|
||||
this.wait(false);
|
||||
});
|
||||
});
|
||||
|
||||
this.addedFieldList = [];
|
||||
}
|
||||
|
||||
addField(name) {
|
||||
this.$el.find('[data-action="reset"]').removeClass('hidden');
|
||||
|
||||
this.$el.find('ul.filter-list li[data-name="'+name+'"]').addClass('hidden');
|
||||
|
||||
if (this.$el.find('ul.filter-list li:not(.hidden)').length === 0) {
|
||||
this.$el.find('button.select-field').addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
this.addedFieldList.push(name);
|
||||
|
||||
let label = this.getHelper().escapeString(
|
||||
this.translate(name, 'fields', this.entityType)
|
||||
);
|
||||
|
||||
let $cell =
|
||||
$('<div>')
|
||||
.addClass('cell form-group')
|
||||
.attr('data-name', name)
|
||||
.append(
|
||||
$('<label>')
|
||||
.addClass('control-label')
|
||||
.text(label)
|
||||
)
|
||||
.append(
|
||||
$('<div>')
|
||||
.addClass('field')
|
||||
.attr('data-name', name)
|
||||
);
|
||||
|
||||
let $row =
|
||||
$('<div>')
|
||||
.addClass('item grid-auto-fill-md')
|
||||
.attr('data-name', name)
|
||||
.append($cell);
|
||||
|
||||
this.$el.find('.fields-container').append($row);
|
||||
|
||||
let type = this.model.getFieldType(name);
|
||||
let viewName = this.model.getFieldParam(name, 'view') || this.getFieldManager().getViewName(type);
|
||||
|
||||
let actionList = this.getMetadata().get(['entityDefs', this.entityType, name, 'massUpdateActionList']) ||
|
||||
this.getMetadata().get(['fields', type, 'massUpdateActionList']);
|
||||
|
||||
let hasActionDropdown = actionList !== null;
|
||||
|
||||
this.hasActionMap[name] = hasActionDropdown;
|
||||
|
||||
this.disableButton('update');
|
||||
|
||||
this.createView(name, viewName, {
|
||||
model: this.model,
|
||||
el: this.getSelector() + ' .field[data-name="' + name + '"]',
|
||||
defs: {
|
||||
name: name,
|
||||
},
|
||||
mode: 'edit',
|
||||
}, view => {
|
||||
this.enableButton('update');
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
if (hasActionDropdown) {
|
||||
let $select =
|
||||
$('<select>')
|
||||
.addClass('item-action form-control')
|
||||
.attr('data-name', name);
|
||||
|
||||
actionList.forEach(action => {
|
||||
let label = this.translate(Espo.Utils.upperCaseFirst(action));
|
||||
|
||||
$select.append(
|
||||
$('<option>')
|
||||
.text(label)
|
||||
.val(action)
|
||||
);
|
||||
});
|
||||
|
||||
this.addedFieldList = [];
|
||||
},
|
||||
|
||||
addField: function (name) {
|
||||
this.$el.find('[data-action="reset"]').removeClass('hidden');
|
||||
|
||||
this.$el.find('ul.filter-list li[data-name="'+name+'"]').addClass('hidden');
|
||||
|
||||
if (this.$el.find('ul.filter-list li:not(.hidden)').length === 0) {
|
||||
this.$el.find('button.select-field').addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
this.addedFieldList.push(name);
|
||||
|
||||
let label = this.getHelper().escapeString(
|
||||
this.translate(name, 'fields', this.entityType)
|
||||
);
|
||||
|
||||
let $cell =
|
||||
let $cellAction =
|
||||
$('<div>')
|
||||
.addClass('cell form-group')
|
||||
.addClass('cell call-action form-group')
|
||||
.attr('data-name', name)
|
||||
.append(
|
||||
$('<label>')
|
||||
.addClass('control-label')
|
||||
.text(label)
|
||||
.addClass('control-label hidden-xs')
|
||||
.html(' ')
|
||||
)
|
||||
.append(
|
||||
$('<div>')
|
||||
.addClass('field')
|
||||
.attr('data-name', name)
|
||||
.append($select)
|
||||
);
|
||||
|
||||
let $row =
|
||||
$('<div>')
|
||||
.addClass('item grid-auto-fill-md')
|
||||
.attr('data-name', name)
|
||||
.append($cell);
|
||||
$row.append($cellAction);
|
||||
}
|
||||
}
|
||||
|
||||
this.$el.find('.fields-container').append($row);
|
||||
/**
|
||||
* @param {string} field
|
||||
* @return {module:views/fields/base}
|
||||
*/
|
||||
getFieldView(field) {
|
||||
return this.getView(field);
|
||||
}
|
||||
|
||||
let type = this.model.getFieldType(name);
|
||||
let viewName = this.model.getFieldParam(name, 'view') || this.getFieldManager().getViewName(type);
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionUpdate() {
|
||||
this.disableButton('update');
|
||||
|
||||
let actionList = this.getMetadata().get(['entityDefs', this.entityType, name, 'massUpdateActionList']) ||
|
||||
this.getMetadata().get(['fields', type, 'massUpdateActionList']);
|
||||
let attributes = {};
|
||||
let actions = {};
|
||||
|
||||
let hasActionDropdown = actionList !== null;
|
||||
this.addedFieldList.forEach(field => {
|
||||
let action = this.fetchAction(field);
|
||||
let itemAttributes = this.getFieldView(field).fetch();
|
||||
|
||||
this.hasActionMap[name] = hasActionDropdown;
|
||||
let itemActualAttributes = {};
|
||||
|
||||
this.disableButton('update');
|
||||
this.getFieldManager()
|
||||
.getEntityTypeFieldActualAttributeList(this.entityType, field)
|
||||
.forEach(attribute => {
|
||||
actions[attribute] = action;
|
||||
|
||||
this.createView(name, viewName, {
|
||||
model: this.model,
|
||||
el: this.getSelector() + ' .field[data-name="' + name + '"]',
|
||||
defs: {
|
||||
name: name,
|
||||
},
|
||||
mode: 'edit',
|
||||
}, view => {
|
||||
this.enableButton('update');
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
if (hasActionDropdown) {
|
||||
let $select =
|
||||
$('<select>')
|
||||
.addClass('item-action form-control')
|
||||
.attr('data-name', name);
|
||||
|
||||
actionList.forEach(action => {
|
||||
let label = this.translate(Espo.Utils.upperCaseFirst(action));
|
||||
|
||||
$select.append(
|
||||
$('<option>')
|
||||
.text(label)
|
||||
.val(action)
|
||||
);
|
||||
itemActualAttributes[attribute] = itemAttributes[attribute];
|
||||
});
|
||||
|
||||
let $cellAction =
|
||||
$('<div>')
|
||||
.addClass('cell call-action form-group')
|
||||
.attr('data-name', name)
|
||||
.append(
|
||||
$('<label>')
|
||||
.addClass('control-label hidden-xs')
|
||||
.html(' ')
|
||||
)
|
||||
.append(
|
||||
$('<div>')
|
||||
.addClass('field')
|
||||
.attr('data-name', name)
|
||||
.append($select)
|
||||
);
|
||||
_.extend(attributes, itemActualAttributes);
|
||||
});
|
||||
|
||||
$row.append($cellAction);
|
||||
}
|
||||
},
|
||||
this.model.set(attributes);
|
||||
|
||||
actionUpdate: function () {
|
||||
this.disableButton('update');
|
||||
let notValid = false;
|
||||
|
||||
let attributes = {};
|
||||
let actions = {};
|
||||
this.addedFieldList.forEach(field => {
|
||||
let view = this.getFieldView(field);
|
||||
|
||||
this.addedFieldList.forEach(field => {
|
||||
let action = this.fetchAction(field);
|
||||
let itemAttributes = this.getView(field).fetch();
|
||||
notValid = view.validate() || notValid;
|
||||
});
|
||||
|
||||
let itemActualAttributes = {};
|
||||
if (notValid) {
|
||||
Espo.Ui.error(this.translate('Not valid'))
|
||||
|
||||
this.getFieldManager()
|
||||
.getEntityTypeFieldActualAttributeList(this.entityType, field)
|
||||
.forEach(attribute => {
|
||||
actions[attribute] = action;
|
||||
this.enableButton('update');
|
||||
|
||||
itemActualAttributes[attribute] = itemAttributes[attribute];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_.extend(attributes, itemActualAttributes);
|
||||
});
|
||||
Espo.Ui.notify(this.translate('saving', 'messages'));
|
||||
|
||||
this.model.set(attributes);
|
||||
Espo.Ajax
|
||||
.postRequest('MassAction', {
|
||||
action: 'update',
|
||||
entityType: this.entityType,
|
||||
params: {
|
||||
ids: this.ids || null,
|
||||
where: (!this.ids || this.ids.length === 0) ? this.options.where : null,
|
||||
searchParams: (!this.ids || this.ids.length === 0) ? this.options.searchParams : null,
|
||||
},
|
||||
data: {
|
||||
values: attributes,
|
||||
actions: actions,
|
||||
},
|
||||
idle: this.idle,
|
||||
})
|
||||
.then(result => {
|
||||
result = result || {};
|
||||
|
||||
let notValid = false;
|
||||
if (result.id) {
|
||||
this.helper
|
||||
.process(result.id, 'update')
|
||||
.then(view => {
|
||||
this.listenToOnce(view, 'close', () => this.close());
|
||||
|
||||
this.addedFieldList.forEach(field => {
|
||||
let view = this.getView(field);
|
||||
|
||||
notValid = view.validate() || notValid;
|
||||
});
|
||||
|
||||
if (notValid) {
|
||||
this.notify('Not valid', 'error');
|
||||
this.enableButton('update');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ui.notify(this.translate('saving', 'messages'));
|
||||
|
||||
Espo.Ajax
|
||||
.postRequest('MassAction', {
|
||||
action: 'update',
|
||||
entityType: this.entityType,
|
||||
params: {
|
||||
ids: this.ids || null,
|
||||
where: (!this.ids || this.ids.length === 0) ? this.options.where : null,
|
||||
searchParams: (!this.ids || this.ids.length === 0) ? this.options.searchParams : null,
|
||||
},
|
||||
data: {
|
||||
values: attributes,
|
||||
actions: actions,
|
||||
},
|
||||
idle: this.idle,
|
||||
})
|
||||
.then(result => {
|
||||
result = result || {};
|
||||
|
||||
if (result.id) {
|
||||
this.helper
|
||||
.process(result.id, 'update')
|
||||
.then(view => {
|
||||
this.listenToOnce(view, 'close', () => this.close());
|
||||
|
||||
this.listenToOnce(view, 'success', result => {
|
||||
this.trigger('after:update', {
|
||||
count: result.count,
|
||||
idle: true,
|
||||
});
|
||||
this.listenToOnce(view, 'success', result => {
|
||||
this.trigger('after:update', {
|
||||
count: result.count,
|
||||
idle: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.trigger('after:update', {
|
||||
count: result.count,
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.enableButton('update');
|
||||
this.trigger('after:update', {
|
||||
count: result.count,
|
||||
});
|
||||
},
|
||||
|
||||
fetchAction: function (name) {
|
||||
if (!this.hasActionMap[name]) {
|
||||
return this.ACTION_UPDATE;
|
||||
}
|
||||
|
||||
let $dropdown = this.$el.find('select.item-action[data-name="'+name+'"]');
|
||||
|
||||
return $dropdown.val() || this.ACTION_UPDATE;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
this.addedFieldList.forEach(field => {
|
||||
this.clearView(field);
|
||||
|
||||
this.$el.find('.item[data-name="'+field+'"]').remove();
|
||||
})
|
||||
.catch(() => {
|
||||
this.enableButton('update');
|
||||
});
|
||||
}
|
||||
|
||||
this.addedFieldList = [];
|
||||
this.hasActionMap = {};
|
||||
fetchAction(name) {
|
||||
if (!this.hasActionMap[name]) {
|
||||
return this.ACTION_UPDATE;
|
||||
}
|
||||
|
||||
this.model.clear();
|
||||
let $dropdown = this.$el.find('select.item-action[data-name="' + name + '"]');
|
||||
|
||||
this.$el.find('[data-action="reset"]').addClass('hidden');
|
||||
this.$el.find('button.select-field').removeClass('disabled').removeAttr('disabled');
|
||||
this.$el.find('ul.filter-list').find('li').removeClass('hidden');
|
||||
return $dropdown.val() || this.ACTION_UPDATE;
|
||||
}
|
||||
|
||||
this.disableButton('update');
|
||||
},
|
||||
});
|
||||
});
|
||||
reset() {
|
||||
this.addedFieldList.forEach(field => {
|
||||
this.clearView(field);
|
||||
|
||||
this.$el.find('.item[data-name="'+field+'"]').remove();
|
||||
});
|
||||
|
||||
this.addedFieldList = [];
|
||||
this.hasActionMap = {};
|
||||
|
||||
this.model.clear();
|
||||
|
||||
this.$el.find('[data-action="reset"]').addClass('hidden');
|
||||
this.$el.find('button.select-field').removeClass('disabled').removeAttr('disabled');
|
||||
this.$el.find('ul.filter-list').find('li').removeClass('hidden');
|
||||
|
||||
this.disableButton('update');
|
||||
}
|
||||
}
|
||||
|
||||
export default MassUpdateModalView;
|
||||
|
||||
@@ -26,170 +26,169 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/password-change-request', ['views/modal'], function (Dep) {
|
||||
import ModalView from 'views/modal';
|
||||
|
||||
return Dep.extend({
|
||||
class PasswordChangeRequestModalView extends ModalView {
|
||||
|
||||
cssName: 'password-change-request',
|
||||
template = 'modals/password-change-request'
|
||||
|
||||
className: 'dialog dialog-centered',
|
||||
cssName = 'password-change-request'
|
||||
className = 'dialog dialog-centered'
|
||||
noFullHeight = true
|
||||
footerAtTheTop = false
|
||||
|
||||
template: 'modals/password-change-request',
|
||||
setup() {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'submit',
|
||||
label: 'Submit',
|
||||
style: 'danger',
|
||||
className: 'btn-s-wide',
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Close',
|
||||
pullLeft: true,
|
||||
className: 'btn-s-wide',
|
||||
}
|
||||
];
|
||||
|
||||
noFullHeight: true,
|
||||
this.headerText = this.translate('Password Change Request', 'labels', 'User');
|
||||
|
||||
footerAtTheTop: false,
|
||||
this.once('close remove', () => {
|
||||
if (this.$userName) {
|
||||
this.$userName.popover('destroy');
|
||||
}
|
||||
|
||||
setup: function () {
|
||||
if (this.$emailAddress) {
|
||||
this.$emailAddress.popover('destroy');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'submit',
|
||||
label: 'Submit',
|
||||
style: 'danger',
|
||||
className: 'btn-s-wide',
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Close',
|
||||
pullLeft: true,
|
||||
className: 'btn-s-wide',
|
||||
}
|
||||
];
|
||||
afterRender() {
|
||||
this.$userName = this.$el.find('input[name="username"]');
|
||||
this.$emailAddress = this.$el.find('input[name="emailAddress"]');
|
||||
}
|
||||
|
||||
this.headerText = this.translate('Password Change Request', 'labels', 'User');
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionSubmit() {
|
||||
let $userName = this.$userName;
|
||||
let $emailAddress = this.$emailAddress;
|
||||
|
||||
this.once('close remove', () => {
|
||||
if (this.$userName) {
|
||||
this.$userName.popover('destroy');
|
||||
let userName = $userName.val();
|
||||
let emailAddress = $emailAddress.val();
|
||||
|
||||
let isValid = true;
|
||||
|
||||
if (userName === '') {
|
||||
isValid = false;
|
||||
|
||||
var message = this.getLanguage().translate('userCantBeEmpty', 'messages', 'User');
|
||||
|
||||
this.isPopoverUserNameDestroyed = false;
|
||||
|
||||
$userName.popover({
|
||||
container: 'body',
|
||||
placement: 'bottom',
|
||||
content: message,
|
||||
trigger: 'manual',
|
||||
}).popover('show');
|
||||
|
||||
let $cellUserName = $userName.closest('.form-group');
|
||||
|
||||
$cellUserName.addClass('has-error');
|
||||
|
||||
$userName.one('mousedown click', () => {
|
||||
$cellUserName.removeClass('has-error');
|
||||
|
||||
if (this.isPopoverUserNameDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.$emailAddress) {
|
||||
this.$emailAddress.popover('destroy');
|
||||
}
|
||||
$userName.popover('destroy');
|
||||
this.isPopoverUserNameDestroyed = true;
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
afterRender: function () {
|
||||
this.$userName = this.$el.find('input[name="username"]');
|
||||
this.$emailAddress = this.$el.find('input[name="emailAddress"]');
|
||||
},
|
||||
if (emailAddress === '') {
|
||||
isValid = false;
|
||||
|
||||
actionSubmit: function () {
|
||||
let $userName = this.$userName;
|
||||
let $emailAddress = this.$emailAddress;
|
||||
let message = this.getLanguage().translate('emailAddressCantBeEmpty', 'messages', 'User');
|
||||
|
||||
let userName = $userName.val();
|
||||
let emailAddress = $emailAddress.val();
|
||||
this.isPopoverEmailAddressDestroyed = false;
|
||||
|
||||
let isValid = true;
|
||||
$emailAddress.popover({
|
||||
container: 'body',
|
||||
placement: 'bottom',
|
||||
content: message,
|
||||
trigger: 'manual',
|
||||
}).popover('show');
|
||||
|
||||
if (userName === '') {
|
||||
isValid = false;
|
||||
let $cellEmailAddress = $emailAddress.closest('.form-group');
|
||||
|
||||
var message = this.getLanguage().translate('userCantBeEmpty', 'messages', 'User');
|
||||
$cellEmailAddress.addClass('has-error');
|
||||
|
||||
this.isPopoverUserNameDestroyed = false;
|
||||
$emailAddress.one('mousedown click', () => {
|
||||
$cellEmailAddress.removeClass('has-error');
|
||||
|
||||
$userName.popover({
|
||||
container: 'body',
|
||||
placement: 'bottom',
|
||||
content: message,
|
||||
trigger: 'manual',
|
||||
}).popover('show');
|
||||
if (this.isPopoverEmailAddressDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
let $cellUserName = $userName.closest('.form-group');
|
||||
$emailAddress.popover('destroy');
|
||||
|
||||
$cellUserName.addClass('has-error');
|
||||
this.isPopoverEmailAddressDestroyed = true;
|
||||
});
|
||||
}
|
||||
|
||||
$userName.one('mousedown click', () => {
|
||||
$cellUserName.removeClass('has-error');
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isPopoverUserNameDestroyed) {
|
||||
return;
|
||||
}
|
||||
let $submit = this.$el.find('button[data-name="submit"]');
|
||||
|
||||
$userName.popover('destroy');
|
||||
this.isPopoverUserNameDestroyed = true;
|
||||
});
|
||||
}
|
||||
$submit.addClass('disabled');
|
||||
|
||||
if (emailAddress === '') {
|
||||
isValid = false;
|
||||
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
|
||||
|
||||
let message = this.getLanguage().translate('emailAddressCantBeEmpty', 'messages', 'User');
|
||||
Espo.Ajax
|
||||
.postRequest('User/passwordChangeRequest', {
|
||||
userName: userName,
|
||||
emailAddress: emailAddress,
|
||||
url: this.options.url,
|
||||
})
|
||||
.then(() => {
|
||||
Espo.Ui.notify(false);
|
||||
|
||||
this.isPopoverEmailAddressDestroyed = false;
|
||||
let msg = this.translate('uniqueLinkHasBeenSent', 'messages', 'User');
|
||||
|
||||
$emailAddress.popover({
|
||||
container: 'body',
|
||||
placement: 'bottom',
|
||||
content: message,
|
||||
trigger: 'manual',
|
||||
}).popover('show');
|
||||
msg += ' ' + this.translate('passwordRecoverySentIfMatched', 'messages', 'User');
|
||||
|
||||
let $cellEmailAddress = $emailAddress.closest('.form-group');
|
||||
this.$el.find('.cell-userName').addClass('hidden');
|
||||
this.$el.find('.cell-emailAddress').addClass('hidden');
|
||||
|
||||
$cellEmailAddress.addClass('has-error');
|
||||
$submit.addClass('hidden');
|
||||
|
||||
$emailAddress.one('mousedown click', () => {
|
||||
$cellEmailAddress.removeClass('has-error');
|
||||
this.$el.find('.msg-box').removeClass('hidden');
|
||||
this.$el.find('.msg-box').html('<span class="text-success">' + msg + '</span>');
|
||||
})
|
||||
.catch(xhr => {
|
||||
if (xhr.status === 404) {
|
||||
Espo.Ui.error(this.translate('userNameEmailAddressNotFound', 'messages', 'User'));
|
||||
|
||||
if (this.isPopoverEmailAddressDestroyed) {
|
||||
return;
|
||||
}
|
||||
xhr.errorIsHandled = true;
|
||||
}
|
||||
|
||||
$emailAddress.popover('destroy');
|
||||
this.isPopoverEmailAddressDestroyed = true;
|
||||
});
|
||||
}
|
||||
if (xhr.status === 403 && xhr.getResponseHeader('X-Status-Reason') === 'Already-Sent') {
|
||||
Espo.Ui.error(this.translate('forbidden', 'messages', 'User'), true);
|
||||
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
xhr.errorIsHandled = true;
|
||||
}
|
||||
|
||||
let $submit = this.$el.find('button[data-name="submit"]');
|
||||
$submit.removeClass('disabled');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$submit.addClass('disabled');
|
||||
|
||||
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
|
||||
|
||||
Espo.Ajax
|
||||
.postRequest('User/passwordChangeRequest', {
|
||||
userName: userName,
|
||||
emailAddress: emailAddress,
|
||||
url: this.options.url,
|
||||
})
|
||||
.then(() => {
|
||||
Espo.Ui.notify(false);
|
||||
|
||||
let msg = this.translate('uniqueLinkHasBeenSent', 'messages', 'User');
|
||||
|
||||
msg += ' ' + this.translate('passwordRecoverySentIfMatched', 'messages', 'User');
|
||||
|
||||
this.$el.find('.cell-userName').addClass('hidden');
|
||||
this.$el.find('.cell-emailAddress').addClass('hidden');
|
||||
|
||||
$submit.addClass('hidden');
|
||||
|
||||
this.$el.find('.msg-box').removeClass('hidden');
|
||||
this.$el.find('.msg-box').html('<span class="text-success">' + msg + '</span>');
|
||||
})
|
||||
.catch(xhr => {
|
||||
if (xhr.status === 404) {
|
||||
Espo.Ui.error(this.translate('userNameEmailAddressNotFound', 'messages', 'User'));
|
||||
|
||||
xhr.errorIsHandled = true;
|
||||
}
|
||||
|
||||
if (xhr.status === 403 && xhr.getResponseHeader('X-Status-Reason') === 'Already-Sent') {
|
||||
Espo.Ui.error(this.translate('forbidden', 'messages', 'User'), true);
|
||||
|
||||
xhr.errorIsHandled = true;
|
||||
}
|
||||
|
||||
$submit.removeClass('disabled');
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
export default PasswordChangeRequestModalView;
|
||||
|
||||
@@ -26,158 +26,158 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/resolve-save-conflict', ['views/modal'], function (Dep) {
|
||||
import ModalView from 'views/modal';
|
||||
|
||||
return Dep.extend({
|
||||
class ResolveSaveConflictModalView extends ModalView {
|
||||
|
||||
backdrop: true,
|
||||
template = 'modals/resolve-save-conflict'
|
||||
|
||||
fitHeight: true,
|
||||
backdrop = true
|
||||
|
||||
template: 'modals/resolve-save-conflict',
|
||||
resolutionList = [
|
||||
'current',
|
||||
'actual',
|
||||
'original',
|
||||
]
|
||||
|
||||
resolutionList: [
|
||||
'current',
|
||||
'actual',
|
||||
'original',
|
||||
],
|
||||
defaultResolution = 'current'
|
||||
|
||||
defaultResolution: 'current',
|
||||
data() {
|
||||
let dataList = [];
|
||||
|
||||
data: function () {
|
||||
var dataList = [];
|
||||
|
||||
this.fieldList.forEach(item => {
|
||||
var o = {
|
||||
field: item,
|
||||
viewKey: item + 'Field',
|
||||
resolution: this.defaultResolution,
|
||||
};
|
||||
|
||||
dataList.push(o);
|
||||
});
|
||||
|
||||
return {
|
||||
dataList: dataList,
|
||||
entityType: this.entityType,
|
||||
resolutionList: this.resolutionList,
|
||||
this.fieldList.forEach(item => {
|
||||
let o = {
|
||||
field: item,
|
||||
viewKey: item + 'Field',
|
||||
resolution: this.defaultResolution,
|
||||
};
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
this.headerText = this.translate('Resolve Conflict');
|
||||
dataList.push(o);
|
||||
});
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'apply',
|
||||
label: 'Apply',
|
||||
style: 'danger',
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel',
|
||||
},
|
||||
];
|
||||
return {
|
||||
dataList: dataList,
|
||||
entityType: this.entityType,
|
||||
resolutionList: this.resolutionList,
|
||||
};
|
||||
}
|
||||
|
||||
this.entityType = this.model.entityType;
|
||||
setup() {
|
||||
this.headerText = this.translate('Resolve Conflict');
|
||||
|
||||
this.originalModel = this.model;
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'apply',
|
||||
label: 'Apply',
|
||||
style: 'danger',
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel',
|
||||
},
|
||||
];
|
||||
|
||||
this.originalAttributes = Espo.Utils.cloneDeep(this.options.originalAttributes);
|
||||
this.currentAttributes = Espo.Utils.cloneDeep(this.options.currentAttributes);
|
||||
this.actualAttributes = Espo.Utils.cloneDeep(this.options.actualAttributes);
|
||||
this.entityType = this.model.entityType;
|
||||
|
||||
var attributeList = this.options.attributeList;
|
||||
this.originalModel = this.model;
|
||||
|
||||
var fieldList = [];
|
||||
this.originalAttributes = Espo.Utils.cloneDeep(this.options.originalAttributes);
|
||||
this.currentAttributes = Espo.Utils.cloneDeep(this.options.currentAttributes);
|
||||
this.actualAttributes = Espo.Utils.cloneDeep(this.options.actualAttributes);
|
||||
|
||||
this.getFieldManager()
|
||||
.getEntityTypeFieldList(this.entityType)
|
||||
.forEach(field => {
|
||||
var fieldAttributeList = this.getFieldManager()
|
||||
.getEntityTypeFieldAttributeList(this.entityType, field);
|
||||
let attributeList = this.options.attributeList;
|
||||
|
||||
var intersect = attributeList.filter(value => fieldAttributeList.includes(value));
|
||||
let fieldList = [];
|
||||
|
||||
if (intersect.length) {
|
||||
fieldList.push(field);
|
||||
}
|
||||
});
|
||||
this.getFieldManager()
|
||||
.getEntityTypeFieldList(this.entityType)
|
||||
.forEach(field => {
|
||||
let fieldAttributeList = this.getFieldManager()
|
||||
.getEntityTypeFieldAttributeList(this.entityType, field);
|
||||
|
||||
this.fieldList = fieldList;
|
||||
let intersect = attributeList.filter(value => fieldAttributeList.includes(value));
|
||||
|
||||
this.wait(
|
||||
this.getModelFactory().create(this.entityType)
|
||||
.then(model => {
|
||||
this.model = model;
|
||||
|
||||
this.fieldList.forEach(field => {
|
||||
this.setResolution(field, this.defaultResolution);
|
||||
});
|
||||
|
||||
this.fieldList.forEach(field => {
|
||||
this.createField(field);
|
||||
});
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
setResolution: function (field, resolution) {
|
||||
let attributeList = this.getFieldManager()
|
||||
.getEntityTypeFieldAttributeList(this.entityType, field);
|
||||
|
||||
let values = {};
|
||||
|
||||
let source = this.currentAttributes;
|
||||
|
||||
if (resolution === 'actual') {
|
||||
source = this.actualAttributes;
|
||||
}
|
||||
else if (resolution === 'original') {
|
||||
source = this.originalAttributes;
|
||||
}
|
||||
|
||||
for (let attribute of attributeList) {
|
||||
values[attribute] = source[attribute] || null;
|
||||
}
|
||||
|
||||
this.model.set(values);
|
||||
},
|
||||
|
||||
createField: function (field) {
|
||||
let type = this.model.getFieldType(field);
|
||||
|
||||
let viewName =
|
||||
this.model.getFieldParam(field, 'view') ||
|
||||
this.getFieldManager().getViewName(type);
|
||||
|
||||
this.createView(field + 'Field', viewName, {
|
||||
readOnly: true,
|
||||
model: this.model,
|
||||
name: field,
|
||||
el: this.getSelector() + ' [data-name="field"][data-field="' + field + '"]',
|
||||
mode: 'list',
|
||||
if (intersect.length) {
|
||||
fieldList.push(field);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
this.$el.find('[data-name="resolution"]').on('change', e => {
|
||||
let $el = $(e.currentTarget);
|
||||
this.fieldList = fieldList;
|
||||
|
||||
let field = $el.attr('data-field');
|
||||
let resolution = $el.val();
|
||||
this.wait(
|
||||
this.getModelFactory().create(this.entityType)
|
||||
.then(model => {
|
||||
this.model = model;
|
||||
|
||||
this.setResolution(field, resolution);
|
||||
});
|
||||
},
|
||||
this.fieldList.forEach(field => {
|
||||
this.setResolution(field, this.defaultResolution);
|
||||
});
|
||||
|
||||
actionApply: function () {
|
||||
let attributes = this.model.attributes;
|
||||
this.fieldList.forEach(field => {
|
||||
this.createField(field);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.originalModel.set(attributes);
|
||||
setResolution(field, resolution) {
|
||||
let attributeList = this.getFieldManager()
|
||||
.getEntityTypeFieldAttributeList(this.entityType, field);
|
||||
|
||||
this.trigger('resolve');
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
});
|
||||
let values = {};
|
||||
|
||||
let source = this.currentAttributes;
|
||||
|
||||
if (resolution === 'actual') {
|
||||
source = this.actualAttributes;
|
||||
}
|
||||
else if (resolution === 'original') {
|
||||
source = this.originalAttributes;
|
||||
}
|
||||
|
||||
for (let attribute of attributeList) {
|
||||
values[attribute] = source[attribute] || null;
|
||||
}
|
||||
|
||||
this.model.set(values);
|
||||
}
|
||||
|
||||
createField(field) {
|
||||
let type = this.model.getFieldType(field);
|
||||
|
||||
let viewName =
|
||||
this.model.getFieldParam(field, 'view') ||
|
||||
this.getFieldManager().getViewName(type);
|
||||
|
||||
this.createView(field + 'Field', viewName, {
|
||||
readOnly: true,
|
||||
model: this.model,
|
||||
name: field,
|
||||
el: this.getSelector() + ' [data-name="field"][data-field="' + field + '"]',
|
||||
mode: 'list',
|
||||
});
|
||||
}
|
||||
|
||||
afterRender() {
|
||||
this.$el.find('[data-name="resolution"]').on('change', e => {
|
||||
let $el = $(e.currentTarget);
|
||||
|
||||
let field = $el.attr('data-field');
|
||||
let resolution = $el.val();
|
||||
|
||||
this.setResolution(field, resolution);
|
||||
});
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionApply() {
|
||||
let attributes = this.model.attributes;
|
||||
|
||||
this.originalModel.set(attributes);
|
||||
|
||||
this.trigger('resolve');
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
export default ResolveSaveConflictModalView;
|
||||
|
||||
@@ -26,63 +26,72 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/save-filters', ['views/modal', 'model'], function (Dep, Model) {
|
||||
import ModalView from 'views/modal';
|
||||
import Model from 'model';
|
||||
|
||||
return Dep.extend({
|
||||
class SaveFiltersModalView extends ModalView {
|
||||
|
||||
cssName: 'save-filters',
|
||||
template = 'modals/save-filters'
|
||||
|
||||
template: 'modals/save-filters',
|
||||
cssName = 'save-filters'
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
dashletList: this.dashletList,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dashletList: this.dashletList,
|
||||
};
|
||||
}
|
||||
|
||||
setup: function () {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'save',
|
||||
label: 'Save',
|
||||
style: 'primary'
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel'
|
||||
setup() {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'save',
|
||||
label: 'Save',
|
||||
style: 'primary',
|
||||
},
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel',
|
||||
},
|
||||
];
|
||||
|
||||
this.headerText = this.translate('Save Filter');
|
||||
|
||||
let model = new Model();
|
||||
|
||||
this.createView('name', 'views/fields/varchar', {
|
||||
el: this.options.el + ' .field[data-name="name"]',
|
||||
defs: {
|
||||
name: 'name',
|
||||
params: {
|
||||
required: true
|
||||
}
|
||||
];
|
||||
},
|
||||
mode: 'edit',
|
||||
model: model,
|
||||
});
|
||||
}
|
||||
|
||||
this.headerText = this.translate('Save Filter');
|
||||
/**
|
||||
* @param {string} field
|
||||
* @return {module:views/fields/base}
|
||||
*/
|
||||
getFieldView(field) {
|
||||
return this.getView(field);
|
||||
}
|
||||
|
||||
var model = new Model();
|
||||
actionSave() {
|
||||
let nameView = this.getFieldView('name');
|
||||
|
||||
this.createView('name', 'views/fields/varchar', {
|
||||
el: this.options.el + ' .field[data-name="name"]',
|
||||
defs: {
|
||||
name: 'name',
|
||||
params: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mode: 'edit',
|
||||
model: model,
|
||||
});
|
||||
},
|
||||
nameView.fetchToModel();
|
||||
|
||||
actionSave: function () {
|
||||
var nameView = this.getView('name');
|
||||
nameView.fetchToModel();
|
||||
if (nameView.validate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nameView.validate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.trigger('save', nameView.model.get('name'));
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
});
|
||||
this.trigger('save', nameView.model.get('name'));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export default SaveFiltersModalView;
|
||||
|
||||
@@ -26,124 +26,126 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/select-category-tree-records', ['views/modals/select-records'], function (Dep) {
|
||||
import SelectRecordsModalView from 'views/modals/select-records';
|
||||
|
||||
return Dep.extend({
|
||||
class SelectCategoryTreeRecordsModalView extends SelectRecordsModalView {
|
||||
|
||||
setup: function () {
|
||||
this.filters = this.options.filters || {};
|
||||
this.boolFilterList = this.options.boolFilterList || {};
|
||||
this.primaryFilterName = this.options.primaryFilterName || null;
|
||||
setup() {
|
||||
this.filters = this.options.filters || {};
|
||||
this.boolFilterList = this.options.boolFilterList || {};
|
||||
this.primaryFilterName = this.options.primaryFilterName || null;
|
||||
|
||||
if ('multiple' in this.options) {
|
||||
this.multiple = this.options.multiple;
|
||||
if ('multiple' in this.options) {
|
||||
this.multiple = this.options.multiple;
|
||||
}
|
||||
|
||||
this.createButton = false;
|
||||
this.massRelateEnabled = this.options.massRelateEnabled;
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel'
|
||||
}
|
||||
];
|
||||
|
||||
this.createButton = false;
|
||||
this.massRelateEnabled = this.options.massRelateEnabled;
|
||||
if (this.multiple) {
|
||||
this.buttonList.unshift({
|
||||
name: 'select',
|
||||
style: 'danger',
|
||||
label: 'Select',
|
||||
onClick: dialog => {
|
||||
let listView = this.getRecordView();
|
||||
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'cancel',
|
||||
label: 'Cancel'
|
||||
if (listView.allResultIsChecked) {
|
||||
this.trigger('select', {
|
||||
massRelate: true,
|
||||
where: this.collection.getWhere(),
|
||||
searchParams: this.collection.data,
|
||||
});
|
||||
}
|
||||
else {
|
||||
var list = listView.getSelected();
|
||||
if (list.length) {
|
||||
this.trigger('select', list);
|
||||
}
|
||||
}
|
||||
|
||||
dialog.close();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.scope = this.options.scope;
|
||||
|
||||
this.$header = $('<span>');
|
||||
|
||||
this.$header.append(
|
||||
$('<span>').text(
|
||||
this.translate('Select') + ': ' +
|
||||
this.getLanguage().translate(this.scope, 'scopeNamesPlural')
|
||||
)
|
||||
);
|
||||
|
||||
this.$header.prepend(
|
||||
this.getHelper().getScopeColorIconHtml(this.scope)
|
||||
);
|
||||
|
||||
this.waitForView('list');
|
||||
|
||||
Espo.loader.require('search-manager', SearchManager => {
|
||||
this.getCollectionFactory().create(this.scope, collection => {
|
||||
collection.maxSize = this.getConfig().get('recordsPerPageSelect') || 5;
|
||||
|
||||
this.collection = collection;
|
||||
|
||||
var searchManager = new SearchManager(collection, 'listSelect', null, this.getDateTime());
|
||||
|
||||
searchManager.emptyOnReset = true;
|
||||
|
||||
if (this.filters) {
|
||||
searchManager.setAdvanced(this.filters);
|
||||
}
|
||||
];
|
||||
|
||||
if (this.multiple) {
|
||||
this.buttonList.unshift({
|
||||
name: 'select',
|
||||
style: 'danger',
|
||||
label: 'Select',
|
||||
onClick: (dialog) => {
|
||||
var listView = this.getView('list');
|
||||
if (this.boolFilterList) {
|
||||
searchManager.setBool(this.boolFilterList);
|
||||
}
|
||||
|
||||
if (listView.allResultIsChecked) {
|
||||
this.trigger('select', {
|
||||
massRelate: true,
|
||||
where: this.collection.getWhere(),
|
||||
searchParams: this.collection.data,
|
||||
});
|
||||
}
|
||||
else {
|
||||
var list = listView.getSelected();
|
||||
if (list.length) {
|
||||
this.trigger('select', list);
|
||||
}
|
||||
}
|
||||
if (this.primaryFilterName) {
|
||||
searchManager.setPrimary(this.primaryFilterName);
|
||||
}
|
||||
|
||||
dialog.close();
|
||||
},
|
||||
});
|
||||
}
|
||||
collection.where = searchManager.getWhere();
|
||||
collection.url = collection.entityType + '/action/listTree';
|
||||
|
||||
this.scope = this.options.scope;
|
||||
var viewName = this.getMetadata()
|
||||
.get('clientDefs.' + this.scope + '.recordViews.listSelectCategoryTree') ||
|
||||
'views/record/list-tree';
|
||||
|
||||
this.$header = $('<span>');
|
||||
|
||||
this.$header.append(
|
||||
$('<span>').text(
|
||||
this.translate('Select') + ': ' +
|
||||
this.getLanguage().translate(this.scope, 'scopeNamesPlural')
|
||||
)
|
||||
);
|
||||
|
||||
this.$header.prepend(
|
||||
this.getHelper().getScopeColorIconHtml(this.scope)
|
||||
);
|
||||
|
||||
this.waitForView('list');
|
||||
|
||||
Espo.loader.require('search-manager', SearchManager => {
|
||||
this.getCollectionFactory().create(this.scope, collection => {
|
||||
collection.maxSize = this.getConfig().get('recordsPerPageSelect') || 5;
|
||||
|
||||
this.collection = collection;
|
||||
|
||||
var searchManager = new SearchManager(collection, 'listSelect', null, this.getDateTime());
|
||||
|
||||
searchManager.emptyOnReset = true;
|
||||
|
||||
if (this.filters) {
|
||||
searchManager.setAdvanced(this.filters);
|
||||
}
|
||||
|
||||
if (this.boolFilterList) {
|
||||
searchManager.setBool(this.boolFilterList);
|
||||
}
|
||||
|
||||
if (this.primaryFilterName) {
|
||||
searchManager.setPrimary(this.primaryFilterName);
|
||||
}
|
||||
|
||||
collection.where = searchManager.getWhere();
|
||||
collection.url = collection.entityType + '/action/listTree';
|
||||
|
||||
var viewName = this.getMetadata()
|
||||
.get('clientDefs.' + this.scope + '.recordViews.listSelectCategoryTree') ||
|
||||
'views/record/list-tree';
|
||||
|
||||
this.listenToOnce(collection, 'sync', () => {
|
||||
this.createView('list', viewName, {
|
||||
collection: collection,
|
||||
el: this.containerSelector + ' .list-container',
|
||||
readOnly: true,
|
||||
selectable: true,
|
||||
checkboxes: this.multiple,
|
||||
massActionsDisabled: true,
|
||||
searchManager: searchManager,
|
||||
checkAllResultDisabled: true,
|
||||
buttonsDisabled: true,
|
||||
}, listView => {
|
||||
listView.once('select', model => {
|
||||
this.trigger('select', model);
|
||||
this.close();
|
||||
});
|
||||
this.listenToOnce(collection, 'sync', () => {
|
||||
this.createView('list', viewName, {
|
||||
collection: collection,
|
||||
el: this.containerSelector + ' .list-container',
|
||||
readOnly: true,
|
||||
selectable: true,
|
||||
checkboxes: this.multiple,
|
||||
massActionsDisabled: true,
|
||||
searchManager: searchManager,
|
||||
checkAllResultDisabled: true,
|
||||
buttonsDisabled: true,
|
||||
}, listView => {
|
||||
listView.once('select', model => {
|
||||
this.trigger('select', model);
|
||||
this.close();
|
||||
});
|
||||
});
|
||||
|
||||
collection.fetch();
|
||||
});
|
||||
|
||||
collection.fetch();
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default SelectCategoryTreeRecordsModalView;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
import SelectRecordsModal from 'views/modals/select-records';
|
||||
import ListWithCategories from 'views/list-with-categories';
|
||||
|
||||
class SelectRecordsWithCategoriesModal extends SelectRecordsModal {
|
||||
class SelectRecordsWithCategoriesModalView extends SelectRecordsModal {
|
||||
|
||||
template = 'modals/select-records-with-categories'
|
||||
|
||||
@@ -117,9 +117,11 @@ class SelectRecordsWithCategoriesModal extends SelectRecordsModal {
|
||||
ListWithCategories.prototype.applyCategoryToCollection.call(this);
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
isCategoryMultiple() {
|
||||
ListWithCategories.prototype.isCategoryMultiple.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectRecordsWithCategoriesModal;
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default SelectRecordsWithCategoriesModalView;
|
||||
|
||||
@@ -34,14 +34,13 @@ import SearchManager from 'search-manager';
|
||||
/**
|
||||
* A select-records modal.
|
||||
*/
|
||||
class SelectRecordsModal extends ModalView {
|
||||
class SelectRecordsModalView extends ModalView {
|
||||
|
||||
template = 'modals/select-records'
|
||||
|
||||
cssName = 'select-modal'
|
||||
className = 'dialog dialog-record'
|
||||
multiple = false
|
||||
header = false
|
||||
createButton = true
|
||||
searchPanel = true
|
||||
scope = ''
|
||||
@@ -49,34 +48,34 @@ class SelectRecordsModal extends ModalView {
|
||||
|
||||
/** @inheritDoc */
|
||||
shortcutKeys = {
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'Control+Enter': function (e) {
|
||||
this.handleShortcutKeyCtrlEnter(e);
|
||||
},
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'Control+Space': function (e) {
|
||||
this.handleShortcutKeyCtrlSpace(e);
|
||||
},
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'Control+Slash': function (e) {
|
||||
this.handleShortcutKeyCtrlSlash(e);
|
||||
},
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'Control+Comma': function (e) {
|
||||
this.handleShortcutKeyCtrlComma(e);
|
||||
},
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'Control+Period': function (e) {
|
||||
this.handleShortcutKeyCtrlPeriod(e);
|
||||
},
|
||||
}
|
||||
|
||||
events = {
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'click button[data-action="create"]': function () {
|
||||
this.create();
|
||||
},
|
||||
/** @this SelectRecordsModal */
|
||||
/** @this SelectRecordsModalView */
|
||||
'click .list a': function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
@@ -459,9 +458,8 @@ class SelectRecordsModal extends ModalView {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {JQueryKeyEventObject} e
|
||||
*/
|
||||
handleShortcutKeyCtrlComma(e) {
|
||||
handleShortcutKeyCtrlComma() {
|
||||
if (!this.getSearchView()) {
|
||||
return;
|
||||
}
|
||||
@@ -471,9 +469,8 @@ class SelectRecordsModal extends ModalView {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {JQueryKeyEventObject} e
|
||||
*/
|
||||
handleShortcutKeyCtrlPeriod(e) {
|
||||
handleShortcutKeyCtrlPeriod() {
|
||||
if (!this.getSearchView()) {
|
||||
return;
|
||||
}
|
||||
@@ -482,4 +479,4 @@ class SelectRecordsModal extends ModalView {
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectRecordsModal;
|
||||
export default SelectRecordsModalView;
|
||||
|
||||
@@ -26,43 +26,38 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/select-template', ['views/modals/select-records'], function (Dep) {
|
||||
import SelectRecordsModalView from 'views/modals/select-records';
|
||||
|
||||
return Dep.extend({
|
||||
class SelectTemplateModalView extends SelectRecordsModalView {
|
||||
|
||||
multiple: false,
|
||||
multiple = false
|
||||
createButton = false
|
||||
searchPanel = false
|
||||
scope = 'Template'
|
||||
|
||||
createButton: false,
|
||||
loadSearch() {
|
||||
super.loadSearch();
|
||||
|
||||
searchPanel: false,
|
||||
this.searchManager.setAdvanced({
|
||||
entityType: {
|
||||
type: 'equals',
|
||||
value: this.options.entityType,
|
||||
},
|
||||
});
|
||||
|
||||
scope: 'Template',
|
||||
this.collection.where = this.searchManager.getWhere();
|
||||
}
|
||||
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
},
|
||||
afterRender() {
|
||||
super.afterRender();
|
||||
|
||||
loadSearch: function () {
|
||||
Dep.prototype.loadSearch.call(this);
|
||||
let firstLinkElement = this.$el.find('a.link').first().get(0);
|
||||
|
||||
this.searchManager.setAdvanced({
|
||||
entityType: {
|
||||
type: 'equals',
|
||||
value: this.options.entityType,
|
||||
}
|
||||
});
|
||||
if (firstLinkElement) {
|
||||
// noinspection JSUnresolvedReference
|
||||
setTimeout(() => firstLinkElement.focus({preventScroll: true}), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.collection.where = this.searchManager.getWhere();
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
|
||||
let firstLinkElement = this.$el.find('a.link').first().get(0);
|
||||
|
||||
if (firstLinkElement) {
|
||||
setTimeout(() => firstLinkElement.focus({preventScroll: true}), 10);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
export default SelectTemplateModalView;
|
||||
|
||||
@@ -26,46 +26,36 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/modals/view-map', ['views/modal'], function (Dep) {
|
||||
import ModalView from 'views/modal';
|
||||
|
||||
return Dep.extend({
|
||||
class ViewMapModalView extends ModalView {
|
||||
|
||||
backdrop: true,
|
||||
templateContent = `<div class="map-container no-side-margin">{{{map}}}</div>`
|
||||
|
||||
fitHeight: true,
|
||||
backdrop = true
|
||||
|
||||
templateContent: '<div class="map-container no-side-margin">{{{map}}}</div>',
|
||||
setup() {
|
||||
let field = this.options.field;
|
||||
|
||||
setup: function () {
|
||||
this.buttonList = [
|
||||
{
|
||||
name: 'close',
|
||||
label: 'Close',
|
||||
}
|
||||
];
|
||||
},
|
||||
let url = '#AddressMap/view/' + this.model.entityType + '/' + this.model.id + '/' + field;
|
||||
let fieldLabel = this.translate(field, 'fields', this.model.entityType);
|
||||
|
||||
setup: function () {
|
||||
let field = this.options.field;
|
||||
this.headerElement =
|
||||
$('<a>')
|
||||
.attr('href', '#' + url)
|
||||
.text(fieldLabel)
|
||||
.get(0);
|
||||
|
||||
let url = '#AddressMap/view/' + this.model.entityType + '/' + this.model.id + '/' + field;
|
||||
let fieldLabel = this.translate(field, 'fields', this.model.entityType);
|
||||
let viewName = this.model.getFieldParam(field + 'Map', 'view') ||
|
||||
this.getFieldManager().getViewName('map');
|
||||
|
||||
this.headerElement =
|
||||
$('<a>')
|
||||
.attr('href', '#' + url)
|
||||
.text(fieldLabel)
|
||||
.get(0);
|
||||
this.createView('map', viewName, {
|
||||
model: this.model,
|
||||
name: field + 'Map',
|
||||
el: this.getSelector() + ' .map-container',
|
||||
height: 'auto',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let 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: 'auto',
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
export default ViewMapModalView;
|
||||
|
||||
Reference in New Issue
Block a user