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

UIPFU-87 - Fix User Search Modal pagination issue. #256

Merged
merged 5 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 7.2.0 IN PROGRESS

* Fix Select User Modal with User Assignment Status Filters pagination issue. Refs UIPFU-87.

## [7.1.0](https://github.com/folio-org/ui-plugin-find-user/tree/v7.1.0) (2024-03-20)
[Full Changelog](https://github.com/folio-org/ui-plugin-find-user/compare/v7.0.0...v7.1.0)

Expand Down
1 change: 0 additions & 1 deletion src/PluginFindUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ PluginFindUser.defaultProps = {
id: 'clickable-plugin-find-user',
searchButtonStyle: 'primary noRightRadius',
dataKey: 'find_patron',
initialSelectedUsers: {},
};

PluginFindUser.propTypes = {
Expand Down
56 changes: 42 additions & 14 deletions src/UserSearchContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ const compileQuery = template(
);

export function buildQuery(queryParams, pathComponents, resourceData, logger, props) {
const filters = Object.keys(props.initialSelectedUsers).length ? filterConfigWithUserAssignedStatus : filterConfig;
const updatedResourceData = Object.keys(props.initialSelectedUsers).length && resourceData?.query?.filters?.includes(UAS) ? updateResourceData(resourceData) : resourceData;
const filters = props.initialSelectedUsers ? filterConfigWithUserAssignedStatus : filterConfig;
const updatedResourceData = props.initialSelectedUsers &&
resourceData?.query?.filters?.includes(UAS) ? updateResourceData(resourceData) : resourceData;

return makeQueryFunction(
'cql.allRecords=1',
Expand Down Expand Up @@ -159,10 +160,17 @@ class UserSearchContainer extends React.Component {

onNeedMoreData = (askAmount, index) => {
const { resultOffset } = this.props.mutator;

let offset = index;
if (offset < askAmount) {
/*
This condition sets offset to 100 when there are less than 100 records in the current
paginated result in order to skip the first 100 records and make an API call to fetch next 100.
*/
offset = 100;
}
if (this.source) {
if (resultOffset && index >= 0) {
this.source.fetchOffset(index);
if (resultOffset && offset >= 0) {
this.source.fetchOffset(offset);
} else {
this.source.fetchMore(RESULT_COUNT_INCREMENT);
}
Expand All @@ -186,28 +194,48 @@ class UserSearchContainer extends React.Component {
resources,
initialSelectedUsers,
} = this.props;

const users = {
records : [],
count: 0
};
const fetchedUsers = get(resources, 'records.records', []);
const activeFilters = get(resources, 'query.filters', '');
const assignedUsers = Object.values(initialSelectedUsers);
const assignedUsers = this.props.initialSelectedUsers ? Object.values(initialSelectedUsers) : [];

if (activeFilters === ASSIGNED_FILTER_KEY) return assignedUsers;
if (activeFilters === ASSIGNED_FILTER_KEY) {
users.records = assignedUsers;
users.count = assignedUsers.length;
return users;
}

if (activeFilters.includes(UAS)) {
if (activeFilters.includes(UAS) && this.source && this.source.loaded()) {
const assignedUserIds = Object.keys(initialSelectedUsers);
const hasBothUASFilters = activeFilters.includes(ASSIGNED_FILTER_KEY) && activeFilters.includes(UNASSIGNED_FILTER_KEY);
const hasNoneOfUASFilters = !activeFilters.includes(ASSIGNED_FILTER_KEY) && !activeFilters.includes(UNASSIGNED_FILTER_KEY);
const uasFilterValue = activeFilters.split(',').filter(f => f.includes(UAS))[0].split('.')[1];

if (hasBothUASFilters || hasNoneOfUASFilters) {
return fetchedUsers;
if (hasBothUASFilters) {
users.records = fetchedUsers;
users.count = this.source.totalCount();
return users;
}

if (uasFilterValue === ASSIGNED) {
return fetchedUsers.filter(u => assignedUserIds.includes(u.id));
const filteredAssignedUsers = fetchedUsers.filter(u => assignedUserIds.includes(u.id));
users.records = filteredAssignedUsers;
users.count = filteredAssignedUsers.length;
return users;
}
return fetchedUsers.filter(u => !assignedUserIds.includes(u.id));

const filteredUnassignedUsers = fetchedUsers.filter(u => !assignedUserIds.includes(u.id));
users.records = filteredUnassignedUsers;
users.count = this.source.totalCount() - assignedUsers.length;
return users;
}
return fetchedUsers;

users.records = fetchedUsers;
users.count = this.source?.totalCount() || 0;
return users;
}

render() {
Expand Down
15 changes: 7 additions & 8 deletions src/UserSearchView.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class UserSearchView extends React.Component {
isSelected = ({ item }) => Boolean(this.state.checkedMap[item.id]);

getFilterConfig = () => {
if (Object.keys(this.props.initialSelectedUsers).length) {
if (this.props.initialSelectedUsers) {
return filterConfigWithUserAssignedStatus;
}
return filterConfig;
Expand All @@ -201,13 +201,13 @@ class UserSearchView extends React.Component {

const { patronGroups, users } = data;
const checkedUsersLength = Object.values(checkedMap).filter(Boolean).length;
const hasInitialSelectedUsers = Object.keys(initialSelectedUsers).length;
const hasInitialSelectedUsers = initialSelectedUsers && Object.keys(initialSelectedUsers).length;
const disabled = !hasInitialSelectedUsers && !checkedUsersLength;

const builtVisibleColumns = isMultiSelect ? ['isChecked', ...visibleColumns] : visibleColumns;

const query = queryGetter ? queryGetter() || {} : {};
const count = users?.length;
const count = users.count;
const sortOrder = query.sort || '';
const resultsStatusMessage = source ? (
<div data-test-find-user-no-results-message>
Expand All @@ -221,10 +221,9 @@ class UserSearchView extends React.Component {
</div>) : 'no source yet';

const resultsHeader = 'User Search Results';
let resultPaneSub = <FormattedMessage id="stripes-smart-components.searchCriteria" />;
if (source && source.loaded()) {
resultPaneSub = <FormattedMessage id="stripes-smart-components.searchResultsCountHeader" values={{ count }} />;
}
const resultPaneSub = count ?
<FormattedMessage id="stripes-smart-components.searchResultsCountHeader" values={{ count }} /> :
<FormattedMessage id="stripes-smart-components.searchCriteria" />;

const resultsFormatter = {
isChecked: user => (
Expand Down Expand Up @@ -362,7 +361,7 @@ class UserSearchView extends React.Component {
<MultiColumnList
visibleColumns={builtVisibleColumns}
isSelected={this.isSelected}
contentData={users}
contentData={users.records}
totalCount={count}
id="list-plugin-find-user"
columnMapping={{
Expand Down
1 change: 1 addition & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
export const updateResourceData = (rData) => {
const filterString = rData?.query?.filters;
const newRData = cloneDeep(rData);

if (filterString === UNASSIGNED_FILTER_KEY || filterString === `${ASSIGNED_FILTER_KEY},${UNASSIGNED_FILTER_KEY}` || filterString === `${UNASSIGNED_FILTER_KEY},${ASSIGNED_FILTER_KEY}`) {
/*
* When Unassigned filter is selected on 'User assignment Status' filter group, with no other filter from other groups,
Expand Down
Loading