Skip to content

Implemented UrlFilterApplier component #28932

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

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<referenceContainer name="content">
<uiComponent name="product_listing"/>
<block class="Magento\Catalog\Block\Adminhtml\Product" name="products_list"/>
<block class="Magento\Backend\Block\Template" template="Magento_Catalog::product/grid/url_filter_applier.phtml" />
</referenceContainer>
</body>
</page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

/** @var $block \Magento\Backend\Block\Template */
?>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/grid/url-filter-applier": {}
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<body>
<referenceContainer name="content">
<uiComponent name="cms_block_listing"/>
<block class="Magento\Backend\Block\Template" template="Magento_Cms::url_filter_applier.phtml" />
Copy link
Contributor

@konarshankar07 konarshankar07 Jul 9, 2020

Choose a reason for hiding this comment

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

I think we can add Urlfilter component in ui_component instead of creating a new block. Please check the similar implementation
https://github.com/magento/adobe-stock-integration/blob/f8f7257d30bf54646536491ad5366ae082c13570/AdobeStockImageAdminUi/view/adminhtml/ui_component/adobe_stock_images_listing.xml#L55-L70
Let me know your thoughts
Thanks

Copy link
Member

Choose a reason for hiding this comment

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

@konarshankar07 I think both approaches are fine

Copy link
Contributor

Choose a reason for hiding this comment

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

@sivaschenko ... Yes, you are right but my concerns is the namespace are hard coded in the url_filter_applier.phtml file which can be easily exported using ui_component.

</referenceContainer>
<referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way -->
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<body>
<referenceContainer name="content">
<uiComponent name="cms_page_listing"/>
<block class="Magento\Backend\Block\Template" template="Magento_Cms::url_filter_applier.phtml" />
</referenceContainer>
</body>
</page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

/** @var $block \Magento\Backend\Block\Template */
?>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/grid/url-filter-applier": {}
}
}
</script>
74 changes: 74 additions & 0 deletions app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

define([
'uiComponent',
'underscore',
], function (Component, _) {
'use strict';

return Component.extend({
defaults: {
filterProvider: 'componentType = filters',
Copy link
Member

Choose a reason for hiding this comment

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

how this component is behaving on a page with multiple grids?
I.e. media gallery + adobe stock

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, will have a look on this, probably will have to introduce a parameter to handle the component namespace.

filterKey: 'filters',
searchString: location.search,
modules: {
filterComponent: '${ $.filterProvider }',
}
},

/**
* Init component
*
* @return {exports}
*/
initialize: function () {
this._super();
this.apply();

return this;
},

/**
* Apply filter
*/
apply: function () {
var urlFilter = this.getFilterParam(this.searchString);

if (_.isUndefined(this.filterComponent())) {
setTimeout(function () {this.apply()}.bind(this), 100);
} else {
if (Object.keys(urlFilter).length) {
this.filterComponent().setData(urlFilter, false);
this.filterComponent().apply();
}
}
},

/**
* Get filter param from url
*
* @returns {Object}
*/
getFilterParam: function (url) {
var searchString = decodeURI(url);

return _.chain(searchString.slice(1).split('&'))
.map(function (item) {
if (item && item.search(this.filterKey) !== -1) {
var itemArray = item.split('=');

itemArray[0] = itemArray[0].replace(this.filterKey, '')
.replace(/[\[\]]/g, '');

return itemArray
}
}.bind(this))
.compact()
.object()
.value();
}
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

/*eslint max-nested-callbacks: 0*/
define([
'Magento_Ui/js/grid/url-filter-applier'
], function (UrlFilterApplier) {
'use strict';

describe('Magento_Ui/js/grid/url-filter-applier', function () {
var urlFilterApplierObj,
filterComponentMock = {
setData: jasmine.createSpy(),
apply: jasmine.createSpy()
};

beforeEach(function () {
urlFilterApplierObj = new UrlFilterApplier({});
urlFilterApplierObj.filterComponent = jasmine.createSpy().and.returnValue(filterComponentMock);
});

describe('"getFilterParam" method', function () {
it('return object from url with a simple filters parameter', function () {
var urlSearch = '?filters[name]=test';

expect(urlFilterApplierObj.getFilterParam(urlSearch)).toEqual({'name': 'test'});
});
it('return object from url with multiple filters parameter', function () {
var urlSearch = '?filters[name]=test&filters[qty]=1';

expect(urlFilterApplierObj.getFilterParam(urlSearch)).toEqual({
'name': 'test',
'qty': '1'
});
});
it('return object from url with multiple filters parameter and another parameter', function () {
var urlSearch = '?filters[name]=test&filters[qty]=1&anotherparam=1';

expect(urlFilterApplierObj.getFilterParam(urlSearch)).toEqual({
'name': 'test',
'qty': '1'
});
});
it('return object from url with another parameter', function () {
var urlSearch = '?anotherparam=1';

expect(urlFilterApplierObj.getFilterParam(urlSearch)).toEqual({});
});
});

describe('"apply" method', function () {
it('applies url filter on filter component', function () {
urlFilterApplierObj.searchString = '?filters[name]=test&filters[qty]=1';
urlFilterApplierObj.apply();
expect(urlFilterApplierObj.filterComponent().setData).toHaveBeenCalledWith({
'name': 'test',
'qty': '1'
}, false);
expect(urlFilterApplierObj.filterComponent().apply).toHaveBeenCalled();
});
});
});
});