Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
* Rename the `ui-users.settings.departments.create.edit.view` permission to avoid displaying the edit capability as a view. Fixes UIU-3403.
* Disable the submit button while the affiliations manager is processing. Refs UIU-3497.
* Optimize role fetching to load only selected tenant's roles instead of all tenants. Fixes UIU-3499.
* Add condition to check for non-empty servicePoints before showing handler in withServicePoints component. Fixes UIU-3503.

## [12.1.14] (https://github.com/folio-org/ui-users/tree/v12.1.14) (2025-10-08)
[Full Changelog](https://github.com/folio-org/ui-users/compare/v12.1.13...v12.1.14)
Expand Down
2 changes: 1 addition & 1 deletion src/components/Wrappers/withServicePoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ const withServicePoints = WrappedComponent => class WithServicePointsComponent e
if (defaultServicePointId) {
const curServicePoint = servicePoints.find(r => r.id === defaultServicePointId);
updateUser(store, { curServicePoint });
} else if (this._isMounted) {
} else if (this._isMounted && servicePoints.length) {
this.setState({
showChangeServicePointHandler: true
});
Expand Down
38 changes: 35 additions & 3 deletions src/components/Wrappers/withServicePoints.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useEffect } from 'react';
import React, { act, useEffect } from 'react';
import { render, screen } from '@folio/jest-config-stripes/testing-library/react';
import PropTypes from 'prop-types';
import '__mock__/currencyData.mock';
import okapiCurrentUser from 'fixtures/okapiCurrentUser';

import okapiCurrentUser from '../../../test/jest/fixtures/okapiCurrentUser';

import withServicePoints from './withServicePoints';

Expand Down Expand Up @@ -91,4 +91,36 @@ describe('withDeclareLost', () => {
renderWithServicePoints();
expect(mockGet).toHaveBeenCalled();
});
describe('when servicePoints array is empty', () => {
it('should not show HandlerManager', async () => {
const MockComponentEmpty = ({ updateServicePoints }) => {
useEffect(() => {
updateServicePoints([], '-');
}, [updateServicePoints]);

return (
<div data-testid="userService">Test Mock Component</div>
);
};

const WrappedComponentEmpty = withServicePoints(MockComponentEmpty);
const propsWithCurrentUser = {
...props,
match: { params: { id: props.stripes.user.user.id } },
stripes: {
...props.stripes,
hasAnyPerm: jest.fn().mockReturnValue(true),
store: {
getState: jest.fn(),
dispatch: jest.fn(),
subscribe: jest.fn(),
}
}
};

await act(async () => render(<WrappedComponentEmpty {...propsWithCurrentUser} />));

expect(screen.queryByText('HandlerManagerMock')).not.toBeInTheDocument();
});
});
});
4 changes: 2 additions & 2 deletions src/routes/AccountDetailsContainer.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import renderWithRouter from 'helpers/renderWithRouter';
import renderWithRouter from '../../test/jest/helpers/renderWithRouter';
import AccountDetailsContainer from './AccountDetailsContainer';

const resources = {
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('AccountDetailsContainer', () => {

const { getByText } = renderAccountDetailsContainer(props);

expect(getByText('ui-users.accounts.loading')).toBeInTheDocument();
expect(getByText('LoadingView')).toBeInTheDocument();
});
});
});
25 changes: 22 additions & 3 deletions src/views/UserEdit/UserEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@ class UserEdit extends React.Component {

static contextType = CalloutContext;

state = {
isLoading: true,
};

componentDidUpdate() {
const { resources } = this.props;
const { isLoading } = this.state;

const isDataLoading = !resourcesLoaded(resources, ['uniquenessValidator']) || (!this.getUser() && this.props.match.params.id);

// Show loading only when opening the page, because some resources are re-fetched during form save,
// which remounts custom fields components, triggering form.change(), which makes the form dirty
// and prevents redirection by showing the "Are you sure?" modal.
if (isLoading && !isDataLoading) {
this.setState({ isLoading: false });
}
}

getUser() {
const { resources, match: { params: { id } } } = this.props;
const selUser = (resources.selUser || {}).records || [];
Expand Down Expand Up @@ -281,7 +299,7 @@ class UserEdit extends React.Component {
});
}

update({ requestPreferences, readingRoomsAccessList, ...userFormData }) {
async update({ requestPreferences, readingRoomsAccessList, ...userFormData }) {
const {
updateProxies,
updateSponsors,
Expand Down Expand Up @@ -347,7 +365,7 @@ class UserEdit extends React.Component {
data.active = (dayjs(user.expirationDate).endOf('day').isSameOrAfter(today));
}

this.updateUserData(data, user);
await this.updateUserData(data);
}

async updateUserData(data) {
Expand Down Expand Up @@ -487,10 +505,11 @@ class UserEdit extends React.Component {
isLoadingAffiliationRoles,
assignedRoleIds
} = this.props;
const { isLoading } = this.state;

const profilePictureConfig = get(resources, 'settings.records[0]');

if (!resourcesLoaded(resources, ['uniquenessValidator']) || (!this.getUser() && this.props.match.params.id)) {
if (isLoading) {
return (
<LoadingView
data-test-form-page
Expand Down
Loading
Loading