diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72b32063..88d8d40d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
* [UITEN-287](https://folio-org.atlassian.net/browse/UITEN-287) Add new permission to create, edit and remove reading room access in tenant settings.
* [UITEN-277](https://issues.folio.org/browse/UITEN-277) Ensure Reading Room Access settings page is wrapped by `Title Manager`.
* [UITEN-276](https://issues.folio.org/browse/UITEN-276) Reading Room Access (settings): Basic Layout.
+* [UITEN-278] (https://issues.folio.org/browse/UITEN-278) Reading Room Access (settings): Create new reading room.
## [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 5928570c..484d7ed7 100644
--- a/package.json
+++ b/package.json
@@ -214,6 +214,7 @@
"displayName": "Settings (tenant): Can view reading room access",
"subPermissions": [
"reading-room.collection.get",
+ "inventory-storage.service-points.collection.get",
"settings.tenant-settings.enabled"
],
"visible": true
@@ -242,8 +243,8 @@
"devDependencies": {
"@babel/core": "^7.20.12",
"@babel/eslint-parser": "^7.19.1",
- "@babel/plugin-transform-class-properties": "^7.12.1",
"@babel/plugin-proposal-decorators": "^7.0.0",
+ "@babel/plugin-transform-class-properties": "^7.12.1",
"@babel/plugin-transform-private-methods": "^7.18.6",
"@babel/plugin-transform-private-property-in-object": "^7.21.11",
"@babel/plugin-transform-runtime": "^7.10.5",
diff --git a/src/settings/ReadingRoomAccess/ReadingRoomAccess.js b/src/settings/ReadingRoomAccess/ReadingRoomAccess.js
index 282d64fa..0ce12ac7 100644
--- a/src/settings/ReadingRoomAccess/ReadingRoomAccess.js
+++ b/src/settings/ReadingRoomAccess/ReadingRoomAccess.js
@@ -1,68 +1,18 @@
-import React from 'react';
+import React, { useCallback, useMemo } from 'react';
+import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
+import _ from 'lodash';
import { TitleManager, useStripes } from '@folio/stripes/core';
-import {
- Label,
- Checkbox,
-} from '@folio/stripes/components';
+import { Label } from '@folio/stripes/components';
import { ControlledVocab } from '@folio/stripes/smart-components';
-const readingRoomsData = {
- values: { records: [
- {
- 'id': 1,
- 'name': 'RR1',
- 'public': true,
- 'servicePoint': [
- {
- name: 'Circ Desk 1',
- id: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f',
- },
- {
- id: 'c4c90014-c8c9-4ade-8f24-b5e313319f4b',
- name: 'Circ Desk 2'
- },
- ],
- // metadata: {
- // 'createdDate': '2024-03-21T10:59:25.085+00:00',
- // 'createdByUserId': 'af5ad81e-6857-5b65-9c0c-60942e56f872',
- // 'updatedDate': '2024-03-21T10:59:25.085+00:00',
- // 'updatedByUserId': 'af5ad81e-6857-5b65-9c0c-60942e56f872'
- // }
- },
- {
- 'id': 2,
- 'name': 'RR2',
- 'public': true,
- 'servicePoint': [{
- name: 'Circ Desk 1',
- id: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f',
- }],
- // metadata: {
- // 'createdDate': '2024-03-21T10:59:25.085+00:00',
- // 'createdByUserId': 'af5ad81e-6857-5b65-9c0c-60942e56f872',
- // 'updatedDate': '2024-03-21T10:59:25.085+00:00',
- // 'updatedByUserId': 'af5ad81e-6857-5b65-9c0c-60942e56f872'
- // }
- },
- ] },
- updaters: {
- records: []
- },
- updaterIds: [],
-};
+import { readingRoomAccessColumns } from './constant';
+import { getFormatter } from './getFormatter';
+import { getFieldComponents } from './getFieldComponents';
+import { getValidators } from './getValidators';
const hiddenFields = ['numberOfObjects', 'lastUpdated'];
-const visibleFields = ['name', 'public', 'servicePoint'];
-const formatter = {
- 'public': (record) => ,
- 'servicePoint': (value) => {
- const asp = value.servicePoint || [];
- const items = asp.map(a =>
{a.name});
- return ;
- }
-};
const translations = {
cannotDeleteTermHeader: 'ui-tenant-settings.settings.addresses.cannotDeleteTermHeader',
cannotDeleteTermMessage: 'ui-tenant-settings.settings.addresses.cannotDeleteTermMessage',
@@ -74,44 +24,113 @@ const translations = {
const ReadingRoomAccess = (props) => {
const intl = useIntl();
const stripes = useStripes();
+ const { resources } = props;
+
+ // service points defined in the tenant
+ const servicePoints = _.get(resources, ['RRAServicePoints', 'records', 0, 'servicepoints'], []);
+ /**
+ * A reading room can have more than one service points assigned to it.
+ * but a servicepoint cannot be mapped to more than one reading room
+ */
+ const sps = [];
+ const rrs = _.get(resources, ['values', 'records']);
+
+ rrs.forEach(rr => {
+ const asp = rr.servicePoints || [];
+ asp.forEach(s => {
+ if (!sps.includes(s.value)) {
+ sps.push(s.value);
+ }
+ });
+ });
+
+ const options = servicePoints.reduce((acc, s) => {
+ if (!sps.includes(s.id) || s.name === 'None') {
+ acc.push({ value: s.id, label: s.name });
+ }
+ return acc;
+ }, []);
+
+ const fieldLabels = useMemo(() => ({
+ [readingRoomAccessColumns.NAME]: intl.formatMessage({ id: 'ui-tenant-settings.settings.reading-room-access.name' }),
+ [readingRoomAccessColumns.ISPUBLIC]: intl.formatMessage({ id: 'ui-tenant-settings.settings.reading-room-access.public' }),
+ [readingRoomAccessColumns.SERVICEPOINTS]: intl.formatMessage({ id: 'ui-tenant-settings.settings.reading-room-access.asp' }),
+ }), [intl]);
+
+ const visibleFields = useMemo(() => ([
+ readingRoomAccessColumns.NAME,
+ readingRoomAccessColumns.ISPUBLIC,
+ readingRoomAccessColumns.SERVICEPOINTS,
+ ]), []);
+
+ const getRequiredLabel = useCallback(columnLabel => (
+
+ ), []);
- const columnMapping = {
- name: (
- ),
- public: intl.formatMessage({ id:'ui-tenant-settings.settings.reading-room-access.public' }),
- servicePoint: intl.formatMessage({ id:'ui-tenant-settings.settings.reading-room-access.asp' }),
- };
- const editable = false; // stripes.hasPerm('ui-users.settings.reading-room-access.all');
+ return acc;
+ }, {});
+
+ return errors;
+ }, []);
+
+ const validate = (item, index, items) => validateItem(item, items) || {};
+
+ const editable = stripes.hasPerm('ui-tenant-settings.settings.reading-room-access.all');
return (
true,
+ delete: () => true,
+ }}
+ formType="final-form"
/>
);
};
ReadingRoomAccess.manifest = Object.freeze({
+ values: {
+ type: 'okapi',
+ records: 'readingRooms',
+ path: 'reading-room',
+ GET: {
+ path: 'reading-room?query=cql.allRecords=1 sortby name&limit=100'
+ }
+ },
+ updaterIds: [],
RRAServicePoints: {
type: 'okapi',
resource: 'service-points',
@@ -119,4 +138,9 @@ ReadingRoomAccess.manifest = Object.freeze({
},
});
+ReadingRoomAccess.propTypes = {
+ resources: PropTypes.object,
+ mutator: PropTypes.object
+};
+
export default ReadingRoomAccess;
diff --git a/src/settings/ReadingRoomAccess/ReadingRoomAccess.test.js b/src/settings/ReadingRoomAccess/ReadingRoomAccess.test.js
index 177ce4c1..dd3d6344 100644
--- a/src/settings/ReadingRoomAccess/ReadingRoomAccess.test.js
+++ b/src/settings/ReadingRoomAccess/ReadingRoomAccess.test.js
@@ -1,45 +1,214 @@
-import { screen } from '@testing-library/react';
+import { screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+import { Form } from 'react-final-form';
import '../../../test/jest/__mocks__';
import buildStripes from '../../../test/jest/__new_mocks__/stripesCore.mock';
-import {
- renderWithRouter,
- renderWithReduxForm,
-} from '../../../test/jest/helpers';
+import { renderWithRouter } from '../../../test/jest/helpers';
import ReadingRoomAccess from './ReadingRoomAccess';
const STRIPES = buildStripes();
-const renderReadingRoomAccess = (props) => {
- const component = () => (
-
- );
+const mutatorMock = {
+ values: {
+ // PUT: jest.fn(() => Promise.resolve()),
+ // DELETE: jest.fn(() => Promise.resolve()),
+ GET: jest.fn(() => Promise.resolve()),
+ POST: jest.fn(() => Promise.resolve()),
+ },
+};
- return renderWithRouter(renderWithReduxForm(component));
+const resourcesMock = {
+ values: {
+ dataKey: 'reading-room',
+ failed: false,
+ hasLoaded: true,
+ httpStatus: 200,
+ isPending: false,
+ module: '@folio/tenant-settings',
+ records: [
+ {
+ 'id': '04efd73f-f7e3-4c19-8614-861941dd1d8e',
+ 'name': 'readingroom-422',
+ 'isPublic': true,
+ 'servicePoints': [
+ {
+ 'value': '7c5abc9f-f3d7-4856-b8d7-6712462ca007',
+ 'label': 'Online'
+ }
+ ],
+ 'metadata': {
+ 'createdDate': '2024-04-22T11:41:52.904334',
+ 'createdByUserId': '2db30b15-7a36-4f02-9c77-999dbb470874'
+ }
+ },
+ {
+ 'id': '75e44262-f68c-418c-ab4c-88c9198669c1',
+ 'name': 'reading-room-4221',
+ 'isPublic': true,
+ 'servicePoints': [
+ {
+ 'value': '3a40852d-49fd-4df2-a1f9-6e2641a6e91f',
+ 'label': 'Circ Desk 1'
+ }
+ ],
+ 'metadata': {
+ 'createdDate': '2024-04-22T11:48:50.255863',
+ 'createdByUserId': '2db30b15-7a36-4f02-9c77-999dbb470874'
+ }
+ },
+ {
+ 'id': '7c5abc9f-f3d7-4856-b8d7-6712462ca009',
+ 'name': 'reading-room-555',
+ 'isPublic': false,
+ 'servicePoints': [
+ {
+ 'value': 'c4c90014-c8c9-4ade-8f24-b5e313319f4b',
+ 'label': 'Circ Desk 4'
+ }
+ ],
+ 'metadata': {
+ 'createdDate': '2024-04-19T11:56:15.192057',
+ 'createdByUserId': '2db30b15-7a36-4f02-9c77-999dbb470874',
+ 'updatedDate': '2024-04-22T04:38:00.75285',
+ 'updatedByUserId': '2db30b15-7a36-4f02-9c77-999dbb470874'
+ }
+ }
+ ],
+ },
+ RRAServicePoints: {
+ 'hasLoaded': true,
+ 'isPending': false,
+ 'failed': false,
+ 'records': [
+ {
+ 'servicepoints': [
+ {
+ 'id': 'c4c90014-c8c9-4ade-8f24-b5e313319f4b',
+ 'name': 'Circ Desk 2',
+ 'code': 'cd2',
+ 'discoveryDisplayName': 'Circulation Desk -- Back Entrance',
+ 'pickupLocation': true,
+ 'holdShelfExpiryPeriod': {
+ 'duration': 5,
+ 'intervalId': 'Days'
+ },
+ 'holdShelfClosedLibraryDateManagement': 'Keep_the_current_due_date',
+ 'staffSlips': [],
+ 'metadata': {
+ 'createdDate': '2024-04-23T01:53:59.590+00:00',
+ 'updatedDate': '2024-04-23T01:53:59.590+00:00'
+ }
+ },
+ {
+ 'id': '3a40852d-49fd-4df2-a1f9-6e2641a6e91f',
+ 'name': 'Circ Desk 1',
+ 'code': 'cd1',
+ 'discoveryDisplayName': 'Circulation Desk -- Hallway',
+ 'pickupLocation': true,
+ 'holdShelfExpiryPeriod': {
+ 'duration': 3,
+ 'intervalId': 'Weeks'
+ },
+ 'holdShelfClosedLibraryDateManagement': 'Keep_the_current_due_date',
+ 'staffSlips': [],
+ 'metadata': {
+ 'createdDate': '2024-04-23T01:53:59.598+00:00',
+ 'updatedDate': '2024-04-23T01:53:59.598+00:00'
+ }
+ },
+ {
+ 'id': '7c5abc9f-f3d7-4856-b8d7-6712462ca007',
+ 'name': 'Online',
+ 'code': 'Online',
+ 'discoveryDisplayName': 'Online',
+ 'shelvingLagTime': 0,
+ 'pickupLocation': false,
+ 'holdShelfClosedLibraryDateManagement': 'Keep_the_current_due_date',
+ 'staffSlips': [],
+ 'metadata': {
+ 'createdDate': '2024-04-23T01:53:59.593+00:00',
+ 'updatedDate': '2024-04-23T01:53:59.593+00:00'
+ }
+ },
+ {
+ 'id': '9d1b77e8-f02e-4b7f-b296-3f2042ddac54',
+ 'name': 'DCB',
+ 'code': '000',
+ 'discoveryDisplayName': 'DCB',
+ 'pickupLocation': true,
+ 'holdShelfExpiryPeriod': {
+ 'duration': 3,
+ 'intervalId': 'Days'
+ },
+ 'holdShelfClosedLibraryDateManagement': 'Keep_the_current_due_date',
+ 'staffSlips': [],
+ 'metadata': {
+ 'createdDate': '2024-04-23T01:56:03.899+00:00',
+ 'updatedDate': '2024-04-23T01:56:03.899+00:00'
+ }
+ }
+ ],
+ 'totalRecords': 4
+ }
+ ],
+ }
};
+const renderReadingRoomAccess = (props) => renderWithRouter(
+