Skip to content

Commit

Permalink
Merge branch '2.1' into 2
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Sep 25, 2023
2 parents 76009ee + a09a16b commit 0792f49
Show file tree
Hide file tree
Showing 5 changed files with 488 additions and 84 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/js/vendor.js

Large diffs are not rendered by default.

69 changes: 48 additions & 21 deletions client/src/legacy/GridField.js
Expand Up @@ -200,42 +200,69 @@ $.entwine('ss', function($) {
}
},

/**
* This will first retrieve state of the gridfield which is generated by PHP and sent to the
* browser as HTML via PJAX and stored in the data-schema attribute on all of the '3 dots'
* elements on each gridfield row
*
* It will then update the browser location with the new state of the gridfield using
* window.ss.router
*
* This allows users to bookmark different views in the CMS
*/
keepStateInHistory: function() {
const newSchema = $(this).find('.gridfield-actionmenu__container').data('schema');
const gridFieldName = $(this).data('name');
if (newSchema && newSchema.length > 0) {
newSchema.filter( e => {
if (e.type === 'link') {
const reqString = this.buildURLString(e.url)
const searchParam = reqString ? '?' + reqString.join('&') : '';
window.ss.router.replace(window.location.pathname + searchParam, undefined, undefined, false);
const urlQueryString = this.buildUrlQueryString(e.url, gridFieldName);
const url = window.location.pathname + urlQueryString;
window.ss.router.replace(url, undefined, undefined, false);
}
})
}
},

/**
* A params string can have duplicate keys.
* Function buildURLString splits string to "key => value" array
* and replaces values for existing keys with the new value
* and returns string with unique keys only
* Builds a url query string from the existing query string in window.location
* and overrides it with the params from the query string in the pjaxUrl param
*
* For any query string params that relate to the gridState of the gridFieldName, only
* take these from the pjaxUrl param
*
* @param {string} url
* @returns string
*/
buildURLString: function(url) {
const link = [window.location.origin, url].join('/');
const params = [window.location.search, (new URL(link)).searchParams.toString()].join('&').substring(1);
const newrequest = [];
const reqString = [];
params.split('&').forEach(param => {
const newVal = param.split('=');
newrequest[newVal[0]] = newVal[1] ? newVal[1] : '';
});
Object.keys(newrequest).forEach(param => {
reqString.push([param, newrequest[param]].join('='));
});

return reqString;
buildUrlQueryString: function(pjaxUrl, gridFieldName) {
const locationObj = {};
for (const param of window.location.search.replace(/^\?/, '').split('&')) {
const [key, val] = param.split('=');
// This regex will naively match the gridfield number \-[0-9]$, so if there are multiple
// gridfields with the same name (i.e. class) on the screen, it will be overly
// aggressive in removing their state. This limitation is because I couldn't find an
// easy way to extract the gridfield number from the gridfield
if (key.match(new RegExp(`^gridState\\-${gridFieldName}\\-[0-9]$`))) {
continue;
}
locationObj[key] = val;
}
const pjaxUrlObj = {};
const link = [window.location.origin, pjaxUrl].join('/');
const searchParams = (new URL(link)).searchParams;
for (const [key, val] of searchParams.entries()) {
pjaxUrlObj[key] = val;
}
const retObj = Object.assign(locationObj, pjaxUrlObj);
const retArr = [];
for (const key in retObj) {
if (key === '') {
continue;
}
const val = encodeURIComponent(retObj[key]);
retArr.push([key, val].join('='));
}
return retArr.length === 0 ? '' : '?' + retArr.join('&');
}
});

Expand Down
34 changes: 29 additions & 5 deletions tests/behat/features/gridfield-search.feature
Expand Up @@ -4,16 +4,21 @@ Feature: Search in GridField
So that I see proper result and don't see warning

Background:
Given the "Company" "Walmart" with "Category"="Retail"
And the "Company" "ExxonMobil" with "Category"="Oil"
And the "Company" "Chevron" with "Category"="Oil"
Given the "Company" "ExxonMobil" with "Category"="Oil"
And the "Company" "Vitol" with "Category"="Other"
And the "Company" "Walmart" with "Category"="Retail"
And the "Company" "Walmart B" with "Category"="Retail"
And the "Company" "Walmart C" with "Category"="Retail"
And the "Company" "Walmart D" with "Category"="Retail"
And the "Company" "ConocoPhillips" with "Category"="Oil"
And the "Company" "Saudi Aramco" with "Category"="Oil"
And the "Company" "Eni" with "Category"="Oil"
And the "Company" "Gazprom" with "Category"="Oil"
And the "Company" "Pemex" with "Category"="Oil"
And the "Company" "Vitol" with "Category"="Other"
And the "Company" "Chevron" with "Category"="Oil"
And the "group" "EDITOR" has permissions "Access to 'Pages' section" and "Access to 'Test ModelAdmin' section" and "Access to 'GridField Test Navigation' section" and "TEST_DATAOBJECT_EDIT"
# This extension will limit to only showing 3 records per page so that pagination shows
And I add an extension "FrameworkTestModelAdminExtension" to the "TestModelAdmin" class
And I am logged in as a member of "EDITOR" group

Scenario: I can search and go to item
Expand Down Expand Up @@ -45,4 +50,23 @@ Feature: Search in GridField
Then I click on the "#action_pagination_next" element
And I should see "View 6–7 of 7" in the ".pagination-records-number" element
And I should see "Pemex" in the "#Form_EditForm" element


Scenario: I can clear search and paginate
When I go to "/admin/test"
And I press the "Open search and filter" button
# This will match on all of the "Walmart" records
And I fill in "SearchBox__q" with "a a"
And I press the "Enter" key in the "SearchBox__q" field
Then the "[name=SearchBox__q]" element "value" attribute should be "a a"
And I should see "Walmart" in the ".ss-gridfield-item:nth-of-type(1) .col-Name" element
And I should see "Walmart B" in the ".ss-gridfield-item:nth-of-type(2) .col-Name" element
And I should see "Walmart C" in the ".ss-gridfield-item:nth-of-type(3) .col-Name" element
And I should not see "ExxonMobil" in the ".col-Name" element
And I should not see "Vitol" in the ".col-Name" element
And I click on the ".search-box__cancel" element
When I click on the "#action_pagination_next" element
And I press the "Open search and filter" button
Then the "[name=SearchBox__q]" element "value" attribute should be ""
And I should see "Walmart B" in the ".ss-gridfield-item:nth-of-type(1) .col-Name" element
And I should see "Walmart C" in the ".ss-gridfield-item:nth-of-type(2) .col-Name" element
And I should see "Walmart D" in the ".ss-gridfield-item:nth-of-type(3) .col-Name" element

0 comments on commit 0792f49

Please sign in to comment.