diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea3a3c4..3bc599a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
* [UITEN-301] (https://issues.folio.org/browse/UITEN-301) Display Reading room access in alphabetical order on settings page.
* [UITEN-212](https://folio-org.atlassian.net/browse/UITEN-212) Permission changes for service point management.
* [UITEN-299](https://folio-org.atlassian.net/browse/UITEN-299) Rewrite class components to functional ones (ui-tenant-settings module).
+* [UITEN-292](https://folio-org.atlassian.net/browse/UITEN-292) Change visibility rules for routing service points.
## [8.1.0](https://github.com/folio-org/ui-tenant-settings/tree/v8.1.0)(2024-03-19)
[Full Changelog](https://github.com/folio-org/ui-tenant-settings/compare/v8.0.0...v8.1.0)
diff --git a/package.json b/package.json
index dda5033..0201ceb 100644
--- a/package.json
+++ b/package.json
@@ -194,7 +194,8 @@
"inventory-storage.location-units.libraries.collection.get",
"inventory-storage.service-points.collection.get",
"inventory-storage.service-points.item.get",
- "circulation-storage.staff-slips.collection.get"
+ "circulation-storage.staff-slips.collection.get",
+ "circulation.settings.collection.get"
],
"visible": false
},
@@ -284,6 +285,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^6.4.4",
+ "react-query": "^3.6.0",
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"redux": "^4.0.0",
diff --git a/src/hooks/index.js b/src/hooks/index.js
new file mode 100644
index 0000000..86ec60a
--- /dev/null
+++ b/src/hooks/index.js
@@ -0,0 +1 @@
+export { default as useCirculationSettingsEcsTlrFeature } from './useCirculationSettingsEcsTlrFeature';
diff --git a/src/hooks/useCirculationSettingsEcsTlrFeature/index.js b/src/hooks/useCirculationSettingsEcsTlrFeature/index.js
new file mode 100644
index 0000000..e02e3cc
--- /dev/null
+++ b/src/hooks/useCirculationSettingsEcsTlrFeature/index.js
@@ -0,0 +1 @@
+export { default } from './useCirculationSettingsEcsTlrFeature';
diff --git a/src/hooks/useCirculationSettingsEcsTlrFeature/useCirculationSettingsEcsTlrFeature.js b/src/hooks/useCirculationSettingsEcsTlrFeature/useCirculationSettingsEcsTlrFeature.js
new file mode 100644
index 0000000..0266cbe
--- /dev/null
+++ b/src/hooks/useCirculationSettingsEcsTlrFeature/useCirculationSettingsEcsTlrFeature.js
@@ -0,0 +1,27 @@
+import { useQuery } from 'react-query';
+
+import { useNamespace, useOkapiKy } from '@folio/stripes/core';
+
+import { getEcsTlrFeature } from '../../settings/ServicePoints/utils';
+
+const useCirculationSettingsEcsTlrFeature = (enabled) => {
+ const ky = useOkapiKy();
+ const [namespace] = useNamespace({ key: 'circulationSettingsEcsTlrFeature' });
+ const searchParams = {
+ query: 'name==ecsTlrFeature',
+ };
+ const { isLoading, data, refetch, isFetching } = useQuery(
+ [namespace],
+ () => ky.get('circulation/settings', { searchParams }).json(),
+ { enabled },
+ );
+
+ return ({
+ titleLevelRequestsFeatureEnabled: getEcsTlrFeature(data?.circulationSettings),
+ isLoading,
+ isFetching,
+ refetch,
+ });
+};
+
+export default useCirculationSettingsEcsTlrFeature;
diff --git a/src/settings/ServicePoints/ServicePointDetail.js b/src/settings/ServicePoints/ServicePointDetail.js
index 0b35ecf..fa21919 100644
--- a/src/settings/ServicePoints/ServicePointDetail.js
+++ b/src/settings/ServicePoints/ServicePointDetail.js
@@ -21,11 +21,11 @@ class ServicePointDetail extends React.Component {
intl: PropTypes.object,
stripes: PropTypes.shape({
connect: PropTypes.func.isRequired,
- hasInterface: PropTypes.func.isRequired,
}).isRequired,
initialValues: PropTypes.object,
parentResources: PropTypes.object,
- parentMutator: PropTypes.object
+ parentMutator: PropTypes.object,
+ titleLevelRequestsFeatureEnabled: PropTypes.bool,
};
constructor(props) {
@@ -83,7 +83,7 @@ class ServicePointDetail extends React.Component {
}
render() {
- const { initialValues, parentResources, stripes } = this.props;
+ const { initialValues, parentResources, titleLevelRequestsFeatureEnabled } = this.props;
const locations = (parentResources.locations || {}).records || [];
const staffSlips = orderBy((parentResources.staffSlips || {}).records || [], 'name');
const servicePoint = initialValues;
@@ -136,7 +136,7 @@ class ServicePointDetail extends React.Component {
/>
- {isEcsRequestRoutingVisible(stripes) && (
+ {isEcsRequestRoutingVisible(titleLevelRequestsFeatureEnabled) && (
}>
@@ -148,7 +148,7 @@ class ServicePointDetail extends React.Component {
)}
- {isEcsRequestRoutingAssociatedFieldsVisible(stripes, servicePoint.ecsRequestRouting) && (
+ {isEcsRequestRoutingAssociatedFieldsVisible(titleLevelRequestsFeatureEnabled, servicePoint.ecsRequestRouting) && (
<>
@@ -196,7 +196,7 @@ class ServicePointDetail extends React.Component {
)}
- {isEcsRequestRoutingAssociatedFieldsVisible(stripes, servicePoint.ecsRequestRouting) && (
+ {isEcsRequestRoutingAssociatedFieldsVisible(titleLevelRequestsFeatureEnabled, servicePoint.ecsRequestRouting) && (
{
+ const { titleLevelRequestsFeatureEnabled } = useCirculationSettingsEcsTlrFeature(true);
const [sections, setSections] = useState({
generalSection: true,
locationSection: true
@@ -302,7 +307,7 @@ const ServicePointForm = ({
/>
- {isEcsRequestRoutingVisible(stripes) && (
+ {isEcsRequestRoutingVisible(titleLevelRequestsFeatureEnabled) && (
)}
- {isEcsRequestRoutingAssociatedFieldsVisible(stripes, formValues.ecsRequestRouting) && (
+ {isEcsRequestRoutingAssociatedFieldsVisible(titleLevelRequestsFeatureEnabled, formValues.ecsRequestRouting) && (
<>
@@ -376,7 +381,7 @@ const ServicePointForm = ({
>
)}
- {isEcsRequestRoutingAssociatedFieldsVisible(stripes, formValues.ecsRequestRouting) && (
+ {isEcsRequestRoutingAssociatedFieldsVisible(titleLevelRequestsFeatureEnabled, formValues.ecsRequestRouting) && (
({
+ useCirculationSettingsEcsTlrFeature: jest.fn().mockReturnValue({ titleLevelRequestsFeatureEnabled: true }),
+}));
+
const onSave = jest.fn();
const staffSlips = [true, true, true, true];
diff --git a/src/settings/ServicePoints/ServicePointManager.js b/src/settings/ServicePoints/ServicePointManager.js
index 2dce366..090b7b6 100644
--- a/src/settings/ServicePoints/ServicePointManager.js
+++ b/src/settings/ServicePoints/ServicePointManager.js
@@ -7,6 +7,7 @@ import { TitleManager } from '@folio/stripes/core';
import { injectIntl } from 'react-intl';
import ServicePointDetail from './ServicePointDetail';
import ServicePointFormContainer from './ServicePointFormContainer';
+import { getEcsTlrFeature } from './utils';
class ServicePointManager extends React.Component {
static manifest = Object.freeze({
@@ -49,6 +50,11 @@ class ServicePointManager extends React.Component {
limit: '1000',
},
},
+ settings: {
+ type: 'okapi',
+ path: 'circulation/settings?query=(name==ecsTlrFeature)',
+ records: 'circulationSettings',
+ },
});
static propTypes = {
@@ -57,6 +63,9 @@ class ServicePointManager extends React.Component {
entries: PropTypes.shape({
records: PropTypes.arrayOf(PropTypes.object),
}),
+ settings: PropTypes.shape({
+ records: PropTypes.arrayOf(PropTypes.object),
+ }),
staffSlips: PropTypes.object,
}).isRequired,
mutator: PropTypes.shape({
@@ -87,6 +96,8 @@ class ServicePointManager extends React.Component {
}
render() {
+ const { resources } = this.props;
+ const titleLevelRequestsFeatureEnabled = getEcsTlrFeature(resources?.settings?.records);
let entryList = sortBy((this.props.resources.entries || {}).records || [], ['name']);
entryList = entryList.map(item => {
item.pickupLocation = item.pickupLocation || false;
@@ -117,6 +128,7 @@ class ServicePointManager extends React.Component {
nameKey="name"
editable={isEditable}
permissions={permissions}
+ titleLevelRequestsFeatureEnabled={titleLevelRequestsFeatureEnabled}
/>
);
diff --git a/src/settings/ServicePoints/utils.js b/src/settings/ServicePoints/utils.js
index af581fa..0ac4b4c 100644
--- a/src/settings/ServicePoints/utils.js
+++ b/src/settings/ServicePoints/utils.js
@@ -1,5 +1,6 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
+import { get } from 'lodash';
export const validateServicePointForm = (values) => {
const errors = {};
@@ -54,10 +55,14 @@ export const getUniquenessValidation = (field, mutator) => {
};
};
-export const isEcsRequestRoutingVisible = (stripes) => (
- stripes.hasInterface('consortia') && stripes.hasInterface('ecs-tlr')
+export const isEcsRequestRoutingVisible = (titleLevelRequestsFeatureEnabled) => (
+ !!titleLevelRequestsFeatureEnabled
);
-export const isEcsRequestRoutingAssociatedFieldsVisible = (stripes, ecsRequestRouting) => (
- (isEcsRequestRoutingVisible(stripes) && !ecsRequestRouting) || !isEcsRequestRoutingVisible(stripes)
+export const isEcsRequestRoutingAssociatedFieldsVisible = (titleLevelRequestsFeatureEnabled, ecsRequestRouting) => (
+ (isEcsRequestRoutingVisible(titleLevelRequestsFeatureEnabled) && !ecsRequestRouting) || !isEcsRequestRoutingVisible(titleLevelRequestsFeatureEnabled)
+);
+
+export const getEcsTlrFeature = (data = []) => (
+ get(data, '[0].value.enabled', false)
);
diff --git a/src/settings/ServicePoints/utils.test.js b/src/settings/ServicePoints/utils.test.js
index 41bd7c3..0bdd987 100644
--- a/src/settings/ServicePoints/utils.test.js
+++ b/src/settings/ServicePoints/utils.test.js
@@ -1,128 +1,63 @@
import {
isEcsRequestRoutingVisible,
isEcsRequestRoutingAssociatedFieldsVisible,
+ getEcsTlrFeature,
} from './utils';
describe('isEcsRequestRoutingVisible', () => {
- it('should return true when both interfaces present', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: true,
- 'ecs-tlr': true,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingVisible(stripes)).toBe(true);
+ it('should return true when titleLevelRequestsFeatureEnabled true', () => {
+ expect(isEcsRequestRoutingVisible(true)).toBe(true);
});
- it('should return false when ecs-tlr interface absent', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: true,
- 'ecs-tlr': false,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingVisible(stripes)).toBe(false);
+ it('should return false when titleLevelRequestsFeatureEnabled false', () => {
+ expect(isEcsRequestRoutingVisible(false)).toBe(false);
});
- it('should return false when consortia interface absent', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: false,
- 'ecs-tlr': true,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingVisible(stripes)).toBe(false);
- });
-
- it('should return false when both interfaces absent', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: false,
- 'ecs-tlr': false,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingVisible(stripes)).toBe(false);
+ it('should return false when titleLevelRequestsFeatureEnabled absent', () => {
+ expect(isEcsRequestRoutingVisible(undefined)).toBe(false);
});
});
describe('isEcsRequestRoutingAssociatedFieldsVisible', () => {
it('should return false when both condition true', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: true,
- 'ecs-tlr': true,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingAssociatedFieldsVisible(stripes, true)).toBe(false);
+ expect(isEcsRequestRoutingAssociatedFieldsVisible(true, true)).toBe(false);
});
it('should return true when first condition false', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: false,
- 'ecs-tlr': false,
- };
-
- return interfaces[currentInterface];
- },
- };
-
- expect(isEcsRequestRoutingAssociatedFieldsVisible(stripes, true)).toBe(true);
+ expect(isEcsRequestRoutingAssociatedFieldsVisible(false, true)).toBe(true);
});
it('should return true when second condition false', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: true,
- 'ecs-tlr': true,
- };
+ expect(isEcsRequestRoutingAssociatedFieldsVisible(true, false)).toBe(true);
+ });
+
+ it('should return true when both condition false', () => {
+ expect(isEcsRequestRoutingAssociatedFieldsVisible(false, false)).toBe(true);
+ });
+});
- return interfaces[currentInterface];
+describe('getEcsTlrFeature', () => {
+ it('should return true when ecsTlrFeature true', () => {
+ const data = [{
+ value: {
+ enabled: true,
},
- };
+ }];
- expect(isEcsRequestRoutingAssociatedFieldsVisible(stripes, false)).toBe(true);
+ expect(getEcsTlrFeature(data)).toBe(true);
});
- it('should return true when both condition false', () => {
- const stripes = {
- hasInterface: (currentInterface) => {
- const interfaces = {
- consortia: false,
- 'ecs-tlr': false,
- };
-
- return interfaces[currentInterface];
+ it('should return false when ecsTlrFeature false', () => {
+ const data = [{
+ value: {
+ enabled: false,
},
- };
+ }];
+
+ expect(getEcsTlrFeature(data)).toBe(false);
+ });
- expect(isEcsRequestRoutingAssociatedFieldsVisible(stripes, false)).toBe(true);
+ it('should return false when ecsTlrFeature absent', () => {
+ expect(getEcsTlrFeature(undefined)).toBe(false);
});
});