Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add Relation Filter Type to Custom Reports #16618

Open
wants to merge 9 commits into
base: 11.x
Choose a base branch
from
Expand Up @@ -113,7 +113,7 @@ pimcore.bundle.customreports.custom.item = Class.create({
checkOrder,
{
text: t("filter_type"),
width: 100,
width: 160,
sortable: false,
dataIndex: 'filter',
editable: true,
Expand All @@ -123,7 +123,13 @@ pimcore.bundle.customreports.custom.item = Class.create({
["string", t("text")],
["numeric", t("numeric")],
["date", t("date")],
["boolean", t("bool")]
["boolean", t("bool")],
["@manyToOneRelation:asset", t("Has one Asset relation")],
["@manyToOneRelation:object", t("Has one Object relation")],
["@manyToOneRelation:document", t("Has one Document relation")],
["@advancedManyToManyRelation:asset", t("Has many Asset relation")],
["@advancedManyToManyRelation:object", t("Has many Object relation")],
["@advancedManyToManyRelation:document", t("Has many Document relation")],
],
queryMode: 'local',
typeAhead: false,
Expand Down
221 changes: 218 additions & 3 deletions bundles/CustomReportsBundle/public/js/pimcore/report/custom/report.js
Expand Up @@ -20,6 +20,12 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
drillDownFilters: {},
drillDownStores: [],

filtersByRelation: {},
relationColumnTypes: {},
filterButtons: {},

systemColumns: [],

progressBar: {},
progressWindow: {},
progressStop: false,
Expand All @@ -41,6 +47,8 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
},

prepareGridConfig: function(data) {
this.RELATION_FILTER_REGEX = /^([^\:]+)(\:(.*))$/;

this.drillDownFilters = {};
this.drillDownStores = [];

Expand All @@ -51,6 +59,15 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
this.columnLabels = {};
this.gridfilters = {};


this.relationColumnTypes = {};
this.filtersByRelation = {
'@manyToOneRelation': [],
'@manyToManyRelation': []
};

this.systemColumns = [];

var gridColConfig = {};

for(var f=0; f<data.columnConfiguration.length; f++) {
Expand Down Expand Up @@ -78,8 +95,15 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
}

if(colConfig["filter"]) {
gridColConfig["filter"] = colConfig["filter"];
this.gridfilters[colConfig["name"]] = colConfig["filter"];
if (colConfig["filter"][0] != '@') {
gridColConfig["filter"] = colConfig["filter"];
this.gridfilters[colConfig["name"]] = colConfig["filter"];
} else {
var relationFilterKey = colConfig["filter"].match(this.RELATION_FILTER_REGEX);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use const or let where possible for new things...

this.filtersByRelation[relationFilterKey[1]] = this.filtersByRelation[relationFilterKey[1]] || [];
this.filtersByRelation[relationFilterKey[1]].push(colConfig["name"]);
this.relationColumnTypes[colConfig["name"]] = relationFilterKey[3] || 'object';
}
}

if (colConfig["displayType"] == "text") {
Expand Down Expand Up @@ -237,6 +261,51 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
trackMouseOver: true,
forceFit: false,
tbar: topBar,
listeners: {
afterrender: function(grid) {
var menu = grid.headerCt.getMenu();

var manyToOneRelation = menu.add({
text: t("filter_by_relation"),
iconCls: "pimcore_icon_filter pimcore_icon_overlay_add",
handler: function() {
var menu = grid.headerCt.getMenu();
var column = menu.activeHeader;
var dataType = this.relationColumnTypes[column.dataIndex];

this.filterByRelationPrepare(column, 'manyToOneRelation', dataType);
}.bind(this)
});
var manyToManyRelation = menu.add({
text: t("filter_by_relation"),
iconCls: "pimcore_icon_filter pimcore_icon_overlay_add",
handler: function() {
var menu = grid.headerCt.getMenu();
var column = menu.activeHeader;
var dataType = this.relationColumnTypes[column.dataIndex];

this.filterByRelationPrepare(column, 'manyToManyRelation', dataType);
}.bind(this)
});

menu.on('beforeshow', function() {
var currentDataIndex = menu.activeHeader.dataIndex;
if (this.filtersByRelation['@manyToOneRelation'].includes(currentDataIndex)) {
manyToOneRelation.show();
manyToManyRelation.hide();
} else {
manyToOneRelation.hide();
}

if (this.filtersByRelation['@manyToManyRelation'].includes(currentDataIndex)) {
manyToManyRelation.show();
manyToOneRelation.hide();
} else {
manyToManyRelation.hide();
}
}.bind(this));
}.bind(this)
},
viewConfig: {
enableTextSelection: true
}
Expand All @@ -254,6 +323,39 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
var drillDownFilterComboboxes = [];

for(var i = 0; i < this.drillDownFilterDefinitions.length; i++) {
var relationMatch = null;
if (relationMatch = this.drillDownFilterDefinitions[i]["filter"].match(this.RELATION_FILTER_REGEX)) {
var _item = this.drillDownFilterDefinitions[i];
var column = {
dataIndex: _item["name"],
text: _item["label"],
};

var filterKey = "x-gridfilter-" + _item["name"];
var filterButton = Ext.create({
xtype: 'button',
text: _item["label"] || _item["name"],
iconCls: 'pimcore_icon_filter',
});

filterButton.setHandler(function (button, column, relationMatch, filterKey) {
if (this.grid.filters.getStore().getFilters().getByKey(filterKey)) {
this.grid.filters.getStore().removeFilter(filterKey);

button.setIconCls('pimcore_icon_filter');
button.setText(column.text || column.dataIndex);
return;
}

this.filterByRelationPrepare(column, relationMatch[1].substr(1), relationMatch[3]);
}.bind(this, filterButton, column, relationMatch, filterKey))

// Store value into dictionary so we can change look on selection
this.filterButtons[filterKey] = filterButton;
drillDownFilterComboboxes.push(filterButton);
continue;
}

drillDownFilterComboboxes.push({
xtype: 'label',
text: this.drillDownFilterDefinitions[i]["label"] ? t(this.drillDownFilterDefinitions[i]["label"])
Expand Down Expand Up @@ -577,5 +679,118 @@ pimcore.bundle.customreports.custom.report = Class.create(pimcore.bundle.customr
}
}.bind(this)
});
}
},

filterByRelationPrepare: function (column, relationType, dataType) {
var dataIndexName = column.dataIndex
var fieldInfo = column;

var fieldInfoLayout = {
name: dataIndexName,
classes: [],
columns: [],
displayMode: 'grid',
objectsAllowed: dataType == 'object',
assetsAllowed: dataType == 'asset',
assetTypes: null,
documentsAllowed: dataType == 'document',
documentTypes: null
}

// Fix for editor so we can use existing functionality
var editor = new pimcore.object.tags[relationType](null, fieldInfoLayout);
editor.setObject({id: 1});

editor.updateContext({
containerType: "filterByRelationWindow"
});

var formPanel = Ext.create('Ext.form.Panel', {
xtype: "form",
border: false,
items: [editor.getLayoutEdit()],
bodyStyle: "padding: 10px;",
buttons: [
{
text: t("clear_relation_filter"),
iconCls: "pimcore_icon_filter_condition pimcore_icon_overlay_delete",
handler: function () {
this.filterByRelationWindow.close();
this.grid.store.filters.removeByKey("x-gridfilter-"+fieldInfo.dataIndex);
}.bind(this)
},
{
text: t("apply_filter"),
iconCls: "pimcore_icon_filter pimcore_icon_overlay_add",
handler: function () {
if (formPanel.isValid()) {
var filter = this.makeFilter(relationType, fieldInfo, editor);

if (filter) {
this.grid.filters.getStore().addFilter(filter);
this.markFilterButton(fieldInfo);
}

this.filterByRelationWindow.close();
}
}.bind(this)
}
]
});

var title = t("filter_by_relation_field") + " " + column.text;
this.filterByRelationWindow = new Ext.Window({
autoScroll: true,
modal: false,
title: title,
items: [formPanel],
bodyStyle: "background: #fff;",
width: 700,
maxHeight: 650
});
this.filterByRelationWindow.show();
this.filterByRelationWindow.updateLayout();
},

markFilterButton: function (fieldInfo) {
var button = this.filterButtons["x-gridfilter-" + fieldInfo.dataIndex];
button.setIconCls('pimcore_icon_clear_filters');
button.setText('Clear '+fieldInfo.text || fieldInfo.dataIndex);
},

makeFilter: function (relationType, fieldInfo, editor) {
var method = 'get' + relationType.charAt(0).toUpperCase() + relationType.slice(1) + 'Filter';
var filter = null;

if (typeof this[method] == 'function') {
filter = this[method](fieldInfo.dataIndex, editor);
} else {
console.warn('CustomReportsBundle: No method found for ' + method + '!');
}

return filter;
},

getManyToOneRelationFilter: function (dataIndex, editor) {
var filterValue = editor.data && editor.data.id || null;
return new Ext.util.Filter({
operator: "eq",
type: "int",
id: "x-gridfilter-" + dataIndex,
property: dataIndex,
dataIndex: dataIndex,
value: filterValue
});
},
getAdvancedManyToManyRelationFilter: function (dataIndex, editor) {
var filterValue = editor.store.getData().items.map(function (record) { return record.get('id'); });
return new Ext.util.Filter({
operator: "in",
type: "array",
id: "x-gridfilter-" + dataIndex,
property: dataIndex,
dataIndex: dataIndex,
value: filterValue
});
},
});