improve relationship panels

This commit is contained in:
yuri
2015-01-09 11:37:03 +02:00
parent 6e1cef3d2f
commit ca40c99ac2
6 changed files with 194 additions and 190 deletions
+39 -40
View File
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
(function (Espo, _) {
Espo.SearchManager = function (collection, type, storage, dateTime, defaultData) {
@@ -26,20 +26,20 @@
this.storage = storage;
this.type = type || 'list';
this.dateTime = dateTime;
this.data = this.defaultData = defaultData || {
textFilter: '',
textFilter: '',
bool: {},
advanced: {},
};
this.sanitizeData();
};
_.extend(Espo.SearchManager.prototype, {
data: null,
sanitizeData: function () {
if (!('advanced' in this.data)) {
this.data.advanced = {};
@@ -49,19 +49,19 @@
}
if (!('textFilter' in this.data)) {
this.data.textFilter = '';
}
}
},
getWhere: function () {
var where = [];
getWhere: function () {
var where = [];
if (this.data.textFilter && this.data.textFilter != '') {
where.push({
type: 'textFilter',
value: this.data.textFilter
});
}
if (this.data.bool) {
var o = {
type: 'boolFilters',
@@ -74,26 +74,25 @@
}
if (o.value.length) {
where.push(o);
}
}
}
if (this.data.advanced) {
for (var name in this.data.advanced) {
var field = name;
var defs = this.data.advanced[name];
if (!defs) {
continue;
}
if ('where' in defs) {
where.push(defs.where);
} else {
} else {
if ('field' in defs) {
field = defs.field;
}
var type = defs.type;
}
var type = defs.type;
if (defs.dateTime) {
where.push(this.getDateTimeWhere(type, field, defs.value));
} else {
@@ -103,42 +102,42 @@
field: field,
value: value,
});
}
}
}
}
}
return where;
},
},
loadStored: function () {
this.data = this.storage.get(this.type + 'Search', this.scope) || _.clone(this.defaultData);
this.sanitizeData();
this.sanitizeData();
return this;
},
get: function () {
return this.data;
},
setAdvanced: function (advanced) {
this.data.advanced = advanced;
},
set: function (data) {
this.data = data;
if (this.storage) {
this.storage.set(this.type + 'Search', this.scope, data);
}
},
reset: function () {
this.data = _.clone(this.defaultData);
if (this.storage) {
this.storage.clear(this.type + 'Search', this.scope);
}
},
getDateTimeWhere: function (type, field, value) {
var where = {
field: field
@@ -146,13 +145,13 @@
if (!value && ~['on', 'before', 'after'].indexOf(type)) {
return null;
}
switch (type) {
case 'today':
where.type = 'between';
var start = this.dateTime.getNowMoment().startOf('day').utc();
var from = start.format(this.dateTime.internalDateTimeFormat);
var from = start.format(this.dateTime.internalDateTimeFormat);
var to = start.add('days', 1).format(this.dateTime.internalDateTimeFormat);
where.value = [from, to];
break;
@@ -167,22 +166,22 @@
case 'on':
where.type = 'between';
var start = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc();
var from = start.format(this.dateTime.internalDateTimeFormat);
var to = start.add('days', 1).format(this.dateTime.internalDateTimeFormat);
where.value = [from, to];
break;
case 'before':
where.type = 'before';
where.type = 'before';
where.value = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat);
break;
case 'after':
where.type = 'after';
where.type = 'after';
where.value = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat);
break;
case 'between':
where.type = 'between';
where.type = 'between';
if (value[0] && value[1]) {
var from = moment(value[0], this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat);
var to = moment(value[1], this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat);
@@ -190,9 +189,9 @@
}
break;
default:
where.type = type;
where.type = type;
}
return where;
},
});
+19 -19
View File
@@ -17,9 +17,9 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
Espo.define('Views.List', 'Views.Main', function (Dep) {
Espo.define('Views.List', ['Views.Main', 'SearchManager'], function (Dep, SearchManager) {
return Dep.extend({
@@ -37,11 +37,11 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
view: 'Header'
}
},
searchPanel: true,
searchManager: true,
createButton: true,
setup: function () {
@@ -51,20 +51,20 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
if (this.getMetadata().get('clientDefs.' + this.scope + '.disableSearchPanel')) {
this.searchPanel = false;
}
if (this.searchPanel) {
this.createView('search', 'Record.Search', {
collection: this.collection,
el: '#main > .search-container',
searchManager: this.searchManager,
}, function (view) {
}, function (view) {
this.listenTo(view, 'reset', function () {
this.collection.sortBy = this.defaultSortBy;
this.collection.asc = this.defaultAsc;
this.getStorage().clear('listSorting', this.collection.name)
}, this);
}.bind(this));
}
}
if (this.createButton) {
this.menu.buttons.unshift({
@@ -73,21 +73,21 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
style: 'primary',
acl: 'edit'
});
}
}
},
getSearchDefaultData: function () {
return null;
},
setupSearchManager: function () {
var collection = this.collection;
var searchManager = new Espo.SearchManager(collection, 'list', this.getStorage(), this.getDateTime(), this.getSearchDefaultData());
var searchManager = new SearchManager(collection, 'list', this.getStorage(), this.getDateTime(), this.getSearchDefaultData());
searchManager.loadStored();
collection.where = searchManager.getWhere();
collection.maxSize = this.getConfig().get('recordsPerPage') || collection.maxSize;
this.searchManager = searchManager;
},
@@ -97,7 +97,7 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
var collection = this.collection;
var sortingParams = this.getStorage().get('listSorting', collection.name) || {};
this.defaultSortBy = collection.sortBy;
this.defaultAsc = collection.asc;
@@ -111,9 +111,9 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
afterRender: function () {
this.notify('Loading...');
var listViewName = this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') || 'Record.List';
this.listenToOnce(this.collection, 'sync', function () {
this.createView('list', listViewName, {
collection: this.collection,
@@ -121,13 +121,13 @@ Espo.define('Views.List', 'Views.Main', function (Dep) {
}, function (view) {
view.render();
view.notify(false);
if (this.searchPanel) {
this.listenTo(this.getView('list'), 'sort', function (obj) {
this.getStorage().set('listSorting', this.collection.name, obj);
}, this);
}
}.bind(this));
}, this);
this.collection.fetch();
@@ -17,14 +17,14 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
Espo.define('Views.Record.DetailBottom', 'View', function (Dep) {
return Dep.extend({
template: 'record.bottom',
mode: 'detail',
data: function () {
@@ -53,13 +53,13 @@ Espo.define('Views.Record.DetailBottom', 'View', function (Dep) {
},
setup: function () {
this.panels = [];
this.panels = [];
var scope = this.model.name;
this.wait(true);
var panels = _.clone(this.getMetadata().get('clientDefs.' + scope + '.bottomPanels.' + this.mode) || []);
if (this.mode == 'detail' && this.getMetadata().get('scopes.' + scope + '.stream')) {
panels.unshift({
"name":"stream",
@@ -67,7 +67,7 @@ Espo.define('Views.Record.DetailBottom', 'View', function (Dep) {
"view":"Stream.Panel"
});
}
panels.forEach(function (p) {
var name = p.name;
this.panels.push(p);
@@ -83,29 +83,30 @@ Espo.define('Views.Record.DetailBottom', 'View', function (Dep) {
p.buttons = this.filterActions(view.getButtons());
}
if (p.label) {
p.title = this.translate(p.label, 'labels', scope);
p.title = this.translate(p.label, 'labels', scope);
} else {
p.title = view.title;
}
}.bind(this));
}.bind(this));
}.bind(this));
this._helper.layoutManager.get(this.model.name, 'relationships', function (layout) {
var panelList = layout;
panelList.forEach(function (name) {
var p = {name: name};
var name = p.name;
var foreignScope = this.model.defs.links[name].entity;
var foreignScope = this.model.defs.links[name].entity;
if (!this.getAcl().check(foreignScope, 'read')) {
return;
}
this.panels.push(p);
var viewName = 'Record.Panels.Relationship';
var defs = this.getMetadata().get('clientDefs.' + scope + '.relationshipPanels.' + name) || {};
var defs = this.getMetadata().get('clientDefs.' + scope + '.relationshipPanels.' + name) || {};
var viewName = defs.view || 'Record.Panels.Relationship';
var total = 8;
@@ -123,13 +124,12 @@ Espo.define('Views.Record.DetailBottom', 'View', function (Dep) {
p.buttons = this.filterActions(view.getButtons());
}
p.title = view.title;
}.bind(this));
}.bind(this));
}.bind(this));
this.wait(false);
}.bind(this));
},
filterActions: function (actions) {
@@ -17,18 +17,18 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', function (Dep) {
Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', 'SearchManager'], function (Dep, SearchManager) {
return Dep.extend({
template: 'record.panels.relationship',
rowActionsView: 'Record.RowActions.Relationship',
setup: function () {
this.link = this.panelName;
this.link = this.panelName;
if (!(this.link in this.model.defs.links)) {
throw new Error('Link \'' + this.link + '\' is not defined in model \'' + this.model.name + '\'');
}
@@ -50,7 +50,7 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
if (this.getAcl().check(this.scope, 'edit')) {
this.buttons.create = this.defs.create;
}
this.actions = _.clone(this.defs.actions || []);
if (this.defs.select) {
@@ -62,7 +62,7 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
}
});
}
var type = 'listSmall';
var listLayout = null;
var layout = this.defs.layout || null;
@@ -77,10 +77,17 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
var sortBy = this.defs.sortBy || null;
var asc = this.defs.asc || null;
this.wait(true);
this.getCollectionFactory().create(this.scope, function (collection) {
this.getCollectionFactory().create(this.scope, function (collection) {
collection.maxSize = this.getConfig().get('recordsPerPageSmall') || 5;
if (this.defs.filters) {
var searchManager = new SearchManager(collection, 'listRelationship', false, this.getDateTime());
searchManager.setAdvanced(this.defs.filters);
collection.where = searchManager.getWhere();
}
collection.url = collection.urlRoot = url;
if (sortBy) {
collection.sortBy = sortBy;
@@ -88,9 +95,9 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
if (asc) {
collection.asc = asc;
}
this.collection = collection;
this.once('after:render', function () {
this.collection = collection;
this.once('after:render', function () {
collection.once('sync', function () {
this.createView('list', 'Record.List', {
collection: collection,
@@ -105,17 +112,15 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
}, this);
collection.fetch();
}, this);
this.wait(false);
}.bind(this));
}, this);
},
getActions: function () {
return this.actions || [];
},
getButtons: function () {
if (this.buttons && this.buttons.create) {
return [{
@@ -168,7 +173,7 @@ Espo.define('Views.Record.Panels.Relationship', 'Views.Record.Panels.Bottom', fu
});
}
},
actionRemoveRelated: function (id) {
var self = this;
if (confirm(this.translate('removeRecordConfirmation', 'messages'))) {
@@ -22,7 +22,7 @@
Espo.define('Views.Record.RowActions.Relationship', 'Views.Record.RowActions.Default', function (Dep) {
return Dep.extend({
getActions: function () {
if (this.options.acl.edit) {
return [
@@ -50,7 +50,7 @@ Espo.define('Views.Record.RowActions.Relationship', 'Views.Record.RowActions.Def
];
}
},
});
});
+92 -92
View File
@@ -36,7 +36,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
advanced: null,
bool: null,
disableSavePreset: false,
data: function () {
@@ -56,7 +56,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
setup: function () {
this.scope = this.collection.name;
this.searchManager = this.options.searchManager;
if ('disableSavePreset' in this.options) {
this.disableSavePreset = this.options.disableSavePreset;
}
@@ -64,15 +64,15 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.addReadyCondition(function () {
return this.fields != null && this.moreFields != null;
}.bind(this));
this.boolFilters = this.getMetadata().get('clientDefs.' + this.scope + '.boolFilters') || [];
this._helper.layoutManager.get(this.scope, 'filters', function (list) {
this.moreFields = list;
this.tryReady();
}.bind(this));
this.presetFilters = _.clone(this.getMetadata().get('clientDefs.' + this.scope + '.presetFilters') || []);
this.presetFilters = _.clone(this.getMetadata().get('clientDefs.' + this.scope + '.presetFilters') || []);
((this.getPreferences().get('presetFilters') || {})[this.scope] || []).forEach(function (item) {
this.presetFilters.push(item);
}, this);
@@ -80,21 +80,21 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.loadSearchData();
this.model = new this.collection.model();
this.model.clear();
this.model.clear();
this.createFilters();
},
createFilters: function (callback) {
createFilters: function (callback) {
var i = 0;
var count = Object.keys(this.advanced || {}).length;
if (count == 0) {
if (count == 0) {
if (typeof callback === 'function') {
callback();
}
}
for (var field in this.advanced) {
this.createFilter(field, this.advanced[field], function () {
i++;
@@ -116,65 +116,65 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
'click button[data-action="search"]': function (e) {
this.search();
},
'click a[data-action="addFilter"]': function (e) {
'click a[data-action="addFilter"]': function (e) {
var $target = $(e.currentTarget);
var name = $target.data('name');
this.advanced[name] = {};
this.advanced[name] = {};
$target.closest('li').addClass('hide');
this.presetName = null;
this.createFilter(name, {}, function () {
this.createFilter(name, {}, function () {
this.fetch();
this.updateSearch();
}.bind(this));
this.updateAddFilterButton();
this.managePresetFilters();
},
'click .advanced-filters a.remove-filter': function (e) {
'click .advanced-filters a.remove-filter': function (e) {
var $target = $(e.currentTarget);
var name = $target.data('name');
this.$el.find('ul.filter-list li[data-name="' + name + '"]').removeClass('hide');
var container = this.getView('filter-' + name).$el.closest('div.filter');
this.clearView('filter-' + name);
this.clearView('filter-' + name);
container.remove();
delete this.advanced[name];
this.presetName = null;
this.updateAddFilterButton();
this.updateAddFilterButton();
this.fetch();
this.updateSearch();
this.managePresetFilters();
},
'click button[data-action="reset"]': function (e) {
this.resetFilters();
},
'click button[data-action="refresh"]': function (e) {
this.notify('Loading...');
this.notify('Loading...');
this.listenToOnce(this.collection, 'sync', function () {
this.notify(false);
}.bind(this));
this.collection.reset();
this.collection.fetch();
},
'click a[data-action="selectPreset"]': function (e) {
this.presetName = $(e.currentTarget).data('name') || null;
this.removeFilters();
this.advanced = this.getPresetData();
this.advanced = this.getPresetData();
this.updateSearch();
this.managePresetFilters();
this.createFilters(function () {
this.render();
}.bind(this));
@@ -185,17 +185,17 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
},
'click .advanced-filters-bar a[data-action="savePreset"]': function (e) {
this.createView('savePreset', 'Modals.SaveFilters', {}, function (view) {
view.render();
view.render();
this.listenToOnce(view, 'save', function (name) {
this.savePreset(name);
view.close();
this.removeFilters();
this.createFilters(function () {
this.render();
}.bind(this));
}.bind(this));
}, this);
}, this);
}.bind(this));
},
'click .advanced-filters-bar a[data-action="removePreset"]': function (e) {
@@ -209,19 +209,19 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.search();
}
},
removeFilters: function () {
this.$advancedFiltersPanel.empty();
for (var name in this.advanced) {
this.$advancedFiltersPanel.empty();
for (var name in this.advanced) {
this.clearView('filter-' + name);
}
},
resetFilters: function () {
this.trigger('reset');
this.removeFilters();
this.presetName = null;
this.searchManager.reset();
@@ -230,74 +230,74 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.render();
this.updateCollection();
},
savePreset: function (name) {
var id = 'f' + (Math.floor(Math.random() * 1000001)).toString();
this.fetch();
this.updateSearch();
var presetFilters = this.getPreferences().get('presetFilters') || {};
if (!(this.scope in presetFilters)) {
presetFilters[this.scope] = [];
}
var data = {
id: id,
name: id,
label: name,
data: this.advanced
};
presetFilters[this.scope].push(data);
this.presetFilters.push(data);
this.getPreferences().set('presetFilters', presetFilters);
this.getPreferences().save({patch: true});
this.getPreferences().trigger('update');
this.presetName = id;
this.presetName = id;
},
removePreset: function (id) {
removePreset: function (id) {
var presetFilters = this.getPreferences().get('presetFilters') || {};
if (!(this.scope in presetFilters)) {
presetFilters[this.scope] = [];
}
var list;
list = presetFilters[this.scope];
list.forEach(function (item, i) {
if (item.id == id) {
list.splice(i, 1);
return;
return;
}
}, this);
list = this.presetFilters;
list.forEach(function (item, i) {
if (item.id == id) {
list.splice(i, 1);
return;
return;
}
}, this);
}, this);
this.getPreferences().set('presetFilters', presetFilters);
this.getPreferences().save({patch: true});
this.getPreferences().trigger('update');
this.getPreferences().trigger('update');
this.presetName = null;
this.advanced = {};
this.removeFilters();
this.render();
this.updateSearch();
this.updateCollection();
},
updateAddFilterButton: function () {
var $ul = this.$el.find('ul.filter-list');
if ($ul.children().not('.hide').size() == 0) {
@@ -309,22 +309,22 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
afterRender: function () {
this.updateAddFilterButton();
this.$advancedFiltersBar = this.$el.find('.advanced-filters-bar');
this.$advancedFiltersPanel = this.$el.find('.advanced-filters');
this.managePresetFilters();
},
managePresetFilters: function () {
managePresetFilters: function () {
var name = this.presetName || null;
var data = this.getPresetData();
this.$el.find('ul.filter-menu a.preset span').remove();
if (name) {
this.$advancedFiltersPanel.addClass('hidden');
var label = null;
var style = null;
var id = null;
@@ -335,33 +335,33 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
id = item.id;
return;
}
}, this);
label = label || this.translate(this.presetName, 'presetFilters', this.scope);
}, this);
label = label || this.translate(this.presetName, 'presetFilters', this.scope);
var barContentHtml = '<a href="javascript:" class="label label-'+style+'" data-action="showFiltersPanel">' + label + '</a>';
if (id) {
barContentHtml += ' <a href="javascript:" title="'+this.translate('Remove')+'" class="small" data-action="removePreset" data-id="'+id+'"><span class="glyphicon glyphicon-remove"></span></a>';
}
this.$advancedFiltersBar.removeClass('hidden').html(barContentHtml);
this.$advancedFiltersBar.removeClass('hidden').html(barContentHtml);
} else {
this.$advancedFiltersPanel.removeClass('hidden');
if (Object.keys(this.advanced).length !== 0) {
if (!this.disableSavePreset) {
this.$advancedFiltersPanel.removeClass('hidden');
if (Object.keys(this.advanced).length !== 0) {
if (!this.disableSavePreset) {
var barHtml = '<a href="javascript:" class="small" data-action="savePreset">' + this.translate('Save Filters') + '</a>';
this.$advancedFiltersBar.removeClass('hidden').html(barHtml);
this.$advancedFiltersBar.removeClass('hidden').html(barHtml);
} else {
this.$advancedFiltersBar.addClass('hidden').empty();
}
}
return;
} else {
this.$advancedFiltersBar.addClass('hidden').empty();
}
this.$advancedFiltersBar.addClass('hidden').empty();
}
}
name = name || '';
this.$el.find('ul.filter-menu a.preset[data-name="'+name+'"]').prepend('<span class="glyphicon glyphicon-ok pull-right"></span>');
},
@@ -389,7 +389,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.collection.fetch();
},
getPresetData: function () {
var data = {};
this.presetFilters.forEach(function (item) {
@@ -404,11 +404,11 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
loadSearchData: function () {
var searchData = this.searchManager.get();
this.textFilter = searchData.textFilter;
if ('presetName' in searchData) {
this.presetName = searchData.presetName;
}
this.presetName = searchData.presetName;
}
if (this.presetName) {
this.advanced = this.getPresetData();
} else {
@@ -447,7 +447,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) {
this.textFilter = this.$el.find('input[name="textFilter"]').val();
this.bool = {};
this.boolFilters.forEach(function (name) {
this.bool[name] = this.$el.find('input[name="' + name + '"]').prop('checked');
}, this);