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

UIU-2942: Assign/unassign a users affiliations adjustments #2557

Merged
merged 19 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from 10 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
* Add auto focus to textarea on staff and patron info modal. Fixes UIU-2932.
* ECS - Filter users by "User Type". Refs UIU-2943.
* Users App: Consume {{FormattedDate}} and {{FormattedTime}} via stripes-component. Refs UIU-1860.
* Assign/unassign a users affiliations adjustments. Refs UIU-2942.

## [9.0.0](https://github.com/folio-org/ui-users/tree/v9.0.0) (2023-02-20)
[Full Changelog](https://github.com/folio-org/ui-users/compare/v8.1.0...v9.0.0)
Expand Down
16 changes: 5 additions & 11 deletions src/components/AffiliationsManager/AffiliationsManager.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('AffiliationsManager', () => {

describe('Filters', () => {
it('should filter results by search query', async () => {
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length + 1);
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length);

await userEvent.type(await screen.findByLabelText('ui-users.affiliations.manager.modal.aria.search'), affiliations[0].tenantName);
await userEvent.click(await screen.findByText('ui-users.search'));
Expand All @@ -77,7 +77,7 @@ describe('AffiliationsManager', () => {
});

it('should filter results by assignment status', async () => {
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length + 1);
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length);

const assignmentCheckboxes = await screen.findAllByLabelText('ui-users.affiliations.manager.modal.aria.assign');

Expand All @@ -86,27 +86,21 @@ describe('AffiliationsManager', () => {
await userEvent.click(assignmentCheckboxes[2]);
await userEvent.click(await screen.findByText('ui-users.affiliations.manager.filter.assignment.assigned'));

expect(await screen.findAllByRole('row')).toHaveLength((affiliations.length - 3) + 1);
expect(await screen.findAllByRole('row')).toHaveLength((affiliations.length - 3));

await userEvent.click(await screen.findByLabelText(/Clear selected filters for/));

expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length + 1);
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length);
});

it('should reset search and filters when \'Reset all\' button was clicked', async () => {
alisher-epam marked this conversation as resolved.
Show resolved Hide resolved
await userEvent.click(await screen.findByLabelText('ui-users.affiliations.manager.modal.aria.assignAll'));
await userEvent.click(await screen.findByText('ui-users.affiliations.manager.filter.assignment.unassigned'));

expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length + 1);

await userEvent.type(await screen.findByLabelText('ui-users.affiliations.manager.modal.aria.search'), 'Columbia');
await userEvent.click(await screen.findByText('ui-users.search'));

expect(await screen.findAllByRole('row')).toHaveLength(2);

await userEvent.click(await screen.findByTestId('reset-all-affiliations-filters'));

expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length + 1);
expect(await screen.findAllByRole('row')).toHaveLength(affiliations.length);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const AffiliationManagerModal = ({ onClose, onSubmit, userId }) => {
isLoading: isConsortiumTenantsLoading,
} = useConsortiumTenants();

const primaryAffiliation = useMemo(() => affiliations.find(({ isPrimary }) => isPrimary), [affiliations]);

const {
assignment,
isAllAssigned,
Expand All @@ -73,7 +75,9 @@ const AffiliationManagerModal = ({ onClose, onSubmit, userId }) => {

const isLoading = isConsortiumTenantsLoading || isUsersAffiliationsLoading;

const affiliationIds = useMemo(() => affiliations.map(({ tenantId }) => tenantId), [affiliations]);
const affiliationIds = useMemo(() => {
return affiliations.map(({ tenantId }) => tenantId);
}, [affiliations]);

const handleOnSubmit = useCallback(async () => {
const getAffiliationIds = (assigned) => (
Expand Down Expand Up @@ -115,12 +119,24 @@ const AffiliationManagerModal = ({ onClose, onSubmit, userId }) => {
orderBy(
filtersConfig
.reduce((filtered, config) => config.filter(filtered, activeFilters, assignment), tenants)
.filter(({ name }) => (searchQuery ? name.toLowerCase().includes(searchQuery.toLowerCase()) : true)),
.filter(({ name, isCentral, id }) => {
if (isCentral || primaryAffiliation.tenantId === id) return false;

return (searchQuery ? name.toLowerCase().includes(searchQuery.toLowerCase()) : true);
}),
sorters[sortOrder],
sortDirection.name,
)
);
}, [assignment, filters, sortDirection.name, sortOrder, sorters, tenants]);
}, [
assignment,
filters,
primaryAffiliation.tenantId,
sortDirection.name,
sortOrder,
sorters,
tenants,
]);

return (
<Modal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ const useAffiliationsAssignment = ({ affiliations, tenants }) => {
setAssignment(() => {
const affiliationsMap = keyBy(affiliations, 'tenantId');

return tenants.reduce((acc, { id }) => {
acc[id] = Boolean(affiliationsMap[id]);
return tenants.reduce((acc, { id, isCentral }) => {
if (!isCentral) {
acc[id] = Boolean(affiliationsMap[id]);
}

return acc;
}, {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe('UserAffiliations', () => {
name: 'ui-users.affiliations.manager.modal.aria.assign',
checked: true,
});
expect(listOfAssignedTenants).toHaveLength(affiliations.length);
expect(listOfAssignedTenants).toHaveLength(affiliations.length - 1);
const saveAndCloseButton = screen.getByText('ui-users.saveAndClose');
userEvent.click(saveAndCloseButton);
await waitForElementToBeRemoved(() => screen.queryByText('ui-users.affiliations.manager.modal.title'));
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useUserAffiliations/useUserAffiliations.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const useUserAffiliations = ({ userId } = {}, options = {}) => {

return ({
affiliations,
totalRecords: data.totalRecords,
totalRecords: data.totalRecords || 0,
isFetching,
isLoading,
refetch,
Expand Down
44 changes: 21 additions & 23 deletions src/views/UserDetail/UserDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,22 @@ import {
UserAffiliations,
UserServicePoints,
} from '../../components/UserDetailSections';

import HelperApp from '../../components/HelperApp';
import IfConsortium from '../../components/IfConsortium';
import {
PatronBlockMessage
} from '../../components/PatronBlock';
import {
getFormAddressList,
} from '../../components/data/converters/address';
import {
getFullName,
} from '../../components/util';
import { PatronBlockMessage } from '../../components/PatronBlock';
import { getFormAddressList } from '../../components/data/converters/address';
import { getFullName } from '../../components/util';
import RequestFeeFineBlockButtons from '../../components/RequestFeeFineBlockButtons';
import { departmentsShape } from '../../shapes';

import OpenTransactionModal from './components/OpenTransactionModal';
import DeleteUserModal from './components/DeleteUserModal';
import ExportFeesFinesReportButton from './components';
import ErrorPane from '../../components/ErrorPane';
import ActionMenuEditButton from './components/ActionMenuEditButton';
import ActionMenuDeleteButton from './components/ActionMenuDeleteButton';
import LostItemsLink from '../../components/LostItemsLink';
import IfConsortiumPermission from '../../components/IfConsortiumPermission';
import { USER_TYPES } from '../../constants';
import ActionMenuEditButton from './components/ActionMenuEditButton';
import ActionMenuDeleteButton from './components/ActionMenuDeleteButton';
import OpenTransactionModal from './components/OpenTransactionModal';
import DeleteUserModal from './components/DeleteUserModal';
import ExportFeesFinesReportButton from './components';

class UserDetail extends React.Component {
static propTypes = {
Expand Down Expand Up @@ -621,6 +614,7 @@ class UserDetail extends React.Component {
const userDepartments = (user?.departments || [])
.map(departmentId => departments.find(({ id }) => id === departmentId)?.name);
const accounts = resources?.accounts;
const isAffiliationEnabled = user?.type !== USER_TYPES.PATRON;

if (this.userNotFound()) {
return (
Expand Down Expand Up @@ -702,13 +696,17 @@ class UserDetail extends React.Component {

<IfConsortium>
<IfConsortiumPermission perm="consortia.user-tenants.collection.get">
<UserAffiliations
accordionId="affiliationsSection"
expanded={sections.affiliationsSection}
onToggle={this.handleSectionToggle}
userId={user?.id}
userName={user?.username}
/>
{
isAffiliationEnabled && (
<UserAffiliations
accordionId="affiliationsSection"
expanded={sections.affiliationsSection}
onToggle={this.handleSectionToggle}
userId={user?.id}
userName={user?.username}
/>
)
}
</IfConsortiumPermission>
</IfConsortium>

Expand Down
Loading