From b7c19d1bd14c5306ee40cc3f62cadf8b12910f8f Mon Sep 17 00:00:00 2001 From: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:11:15 +0300 Subject: [PATCH 1/2] UIIN-2453: Instance 3rd pane: Adjust behaviour when returning to instance from holdings/item full screen (#2305) --- CHANGELOG.md | 4 ++ src/Instance/HoldingsList/Holding/Holding.js | 7 +++ .../HoldingsList/Holding/Holding.test.js | 2 + .../HoldingsList/Holding/HoldingAccordion.js | 14 +++++- .../Holding/HoldingAccordion.test.js | 2 + .../HoldingsList/Holding/HoldingContainer.js | 16 +++++++ .../Holding/HoldingContainer.test.js | 1 + src/Instance/HoldingsList/HoldingsList.js | 4 ++ .../HoldingsList/HoldingsListContainer.js | 10 +++-- .../ConsortialHoldings/ConsortialHoldings.js | 31 ++++++++++--- .../MemberTenantHoldings.js | 11 ++++- .../HoldingsListMovement.js | 4 ++ src/ViewInstance.js | 2 + src/hooks/index.js | 1 + src/hooks/useHoldingsAccordionState/index.js | 1 + .../useHoldingsAccordionState.js | 42 ++++++++++++++++++ .../useHoldingsAccordionState.test.js | 43 +++++++++++++++++++ 17 files changed, 184 insertions(+), 11 deletions(-) create mode 100644 src/hooks/useHoldingsAccordionState/index.js create mode 100644 src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.js create mode 100644 src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 047214f03..af713044d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change history for ui-inventory +## 10.0.1 IN PROGRESS + +* Instance 3rd pane: Adjust behavior when returning to instance from holdings/item full screen. Refs UIIN-2453. + ## [10.0.0](https://github.com/folio-org/ui-inventory/tree/v10.0.0) (2023-10-13) [Full Changelog](https://github.com/folio-org/ui-inventory/compare/v9.4.12...v10.0.0) diff --git a/src/Instance/HoldingsList/Holding/Holding.js b/src/Instance/HoldingsList/Holding/Holding.js index b04382bb0..aea2e7d98 100644 --- a/src/Instance/HoldingsList/Holding/Holding.js +++ b/src/Instance/HoldingsList/Holding/Holding.js @@ -20,6 +20,8 @@ const Holding = ({ isDraggable, isItemsDroppable, tenantId, + instanceId, + pathToAccordionsState, }) => { return (
@@ -49,6 +51,8 @@ const Holding = ({ onViewHolding={onViewHolding} onAddItem={onAddItem} tenantId={tenantId} + instanceId={instanceId} + pathToAccordionsState={pathToAccordionsState} > ( ( isHoldingDragSelected={isHoldingDragSelected} isDraggable={isDraggable} isItemsDroppable={isItemsDroppable} + pathToAccordionsState={['holdings']} /> ); diff --git a/src/Instance/HoldingsList/Holding/HoldingAccordion.js b/src/Instance/HoldingsList/Holding/HoldingAccordion.js index 8fb96e77b..02b4c2ff4 100644 --- a/src/Instance/HoldingsList/Holding/HoldingAccordion.js +++ b/src/Instance/HoldingsList/Holding/HoldingAccordion.js @@ -13,7 +13,10 @@ import { import { callNumberLabel } from '../../../utils'; import HoldingButtonsGroup from './HoldingButtonsGroup'; import useHoldingItemsQuery from '../../../hooks/useHoldingItemsQuery'; -import { useLocationsQuery } from '../../../hooks'; +import { + useHoldingsAccordionState, + useLocationsQuery, +} from '../../../hooks'; const HoldingAccordion = ({ children, @@ -23,13 +26,16 @@ const HoldingAccordion = ({ onAddItem, withMoveDropdown, tenantId, + instanceId, + pathToAccordionsState, }) => { const searchParams = { limit: 0, offset: 0, }; - const [open, setOpen] = useState(false); + const pathToAccordion = [...pathToAccordionsState, holding?.id]; + const [open, setOpen] = useHoldingsAccordionState({ instanceId, pathToAccordion }); const [openFirstTime, setOpenFirstTime] = useState(false); const { totalRecords, isFetching } = useHoldingItemsQuery(holding.id, { searchParams, key: 'itemCount', tenantId }); const { data: locations } = useLocationsQuery({ tenantId }); @@ -113,10 +119,14 @@ HoldingAccordion.propTypes = { holding: PropTypes.object.isRequired, onViewHolding: PropTypes.func.isRequired, onAddItem: PropTypes.func.isRequired, + instanceId: PropTypes.string.isRequired, holdings: PropTypes.arrayOf(PropTypes.object), withMoveDropdown: PropTypes.bool, children: PropTypes.object, tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), }; +HoldingAccordion.defaultProps = { pathToAccordionsState: [] }; + export default HoldingAccordion; diff --git a/src/Instance/HoldingsList/Holding/HoldingAccordion.test.js b/src/Instance/HoldingsList/Holding/HoldingAccordion.test.js index 45df04f4c..b8aa058f9 100644 --- a/src/Instance/HoldingsList/Holding/HoldingAccordion.test.js +++ b/src/Instance/HoldingsList/Holding/HoldingAccordion.test.js @@ -37,6 +37,8 @@ const HoldingAccordionSetup = () => ( onViewHolding={noop} onAddItem={noop} withMoveDropdown={false} + instanceId="instanceId" + pathToAccordionsState={['holdings']} > <> diff --git a/src/Instance/HoldingsList/Holding/HoldingContainer.js b/src/Instance/HoldingsList/Holding/HoldingContainer.js index 93f77f883..9a907bd49 100644 --- a/src/Instance/HoldingsList/Holding/HoldingContainer.js +++ b/src/Instance/HoldingsList/Holding/HoldingContainer.js @@ -36,6 +36,8 @@ const DraggableHolding = ({ onViewHolding, onAddItem, tenantId, + instanceId, + pathToAccordionsState, ...rest }) => { const rowStyles = useMemo(() => ( @@ -68,6 +70,8 @@ const DraggableHolding = ({ onViewHolding={onViewHolding} onAddItem={onAddItem} tenantId={tenantId} + instanceId={instanceId} + pathToAccordionsState={pathToAccordionsState} /> ) } @@ -83,12 +87,16 @@ DraggableHolding.propTypes = { draggingHoldingsCount: PropTypes.number, provided: PropTypes.object.isRequired, snapshot: PropTypes.object.isRequired, + instanceId: PropTypes.string.isRequired, holding: PropTypes.object, onViewHolding: PropTypes.func, onAddItem: PropTypes.func, tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), }; +DraggableHolding.defaultProps = { pathToAccordionsState: [] }; + const HoldingContainer = ({ location, history, @@ -99,6 +107,7 @@ const HoldingContainer = ({ holdingIndex, draggingHoldingsCount, tenantId, + pathToAccordionsState, ...rest }) => { const onViewHolding = useCallback(() => { @@ -130,6 +139,8 @@ const HoldingContainer = ({ onViewHolding={onViewHolding} onAddItem={onAddItem} tenantId={tenantId} + instanceId={instance?.id} + pathToAccordionsState={pathToAccordionsState} {...rest} /> )} @@ -141,6 +152,8 @@ const HoldingContainer = ({ onViewHolding={onViewHolding} onAddItem={onAddItem} tenantId={tenantId} + instanceId={instance?.id} + pathToAccordionsState={pathToAccordionsState} /> ); }; @@ -157,6 +170,9 @@ HoldingContainer.propTypes = { isDraggable: PropTypes.bool, draggingHoldingsCount: PropTypes.number, tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), }; +HoldingContainer.defaultProps = { pathToAccordionsState: [] }; + export default withRouter(HoldingContainer); diff --git a/src/Instance/HoldingsList/Holding/HoldingContainer.test.js b/src/Instance/HoldingsList/Holding/HoldingContainer.test.js index 1cb2c6129..d053d5e37 100644 --- a/src/Instance/HoldingsList/Holding/HoldingContainer.test.js +++ b/src/Instance/HoldingsList/Holding/HoldingContainer.test.js @@ -54,6 +54,7 @@ const renderHoldingContainer = (props = {}) => renderWithIntl( provided={{ draggableProps: { style: true } }} onViewHolding={jest.fn()} onAddItem={jest.fn()} + pathToAccordionsState={['holdings']} {...props} /> diff --git a/src/Instance/HoldingsList/HoldingsList.js b/src/Instance/HoldingsList/HoldingsList.js index 97c01fff5..b378b7d17 100644 --- a/src/Instance/HoldingsList/HoldingsList.js +++ b/src/Instance/HoldingsList/HoldingsList.js @@ -7,6 +7,7 @@ const HoldingsList = ({ instance, holdings, tenantId, + pathToAccordionsState, draggable, droppable, @@ -19,6 +20,7 @@ const HoldingsList = ({ droppable={droppable} holdings={holdings} tenantId={tenantId} + pathToAccordionsState={pathToAccordionsState} /> )); @@ -26,6 +28,7 @@ HoldingsList.propTypes = { instance: PropTypes.object.isRequired, holdings: PropTypes.arrayOf(PropTypes.object), tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), draggable: PropTypes.bool, droppable: PropTypes.bool, @@ -33,6 +36,7 @@ HoldingsList.propTypes = { HoldingsList.defaultProps = { holdings: [], + pathToAccordionsState: [], }; export default HoldingsList; diff --git a/src/Instance/HoldingsList/HoldingsListContainer.js b/src/Instance/HoldingsList/HoldingsListContainer.js index be19ea8ee..343284e36 100644 --- a/src/Instance/HoldingsList/HoldingsListContainer.js +++ b/src/Instance/HoldingsList/HoldingsListContainer.js @@ -1,9 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { - Loading, -} from '@folio/stripes/components'; +import { Loading } from '@folio/stripes/components'; import HoldingsList from './HoldingsList'; import { HoldingsListMovement } from '../InstanceMovement/HoldingMovementList'; @@ -13,6 +11,7 @@ const HoldingsListContainer = ({ instance, isHoldingsMove, tenantId, + pathToAccordionsState, ...rest }) => { const { holdingsRecords: holdings, isLoading } = useInstanceHoldingsQuery(instance.id, { tenantId }); @@ -26,6 +25,7 @@ const HoldingsListContainer = ({ holdings={holdings} instance={instance} tenantId={tenantId} + pathToAccordionsState={pathToAccordionsState} /> ) : ( ) ); @@ -42,6 +43,9 @@ HoldingsListContainer.propTypes = { instance: PropTypes.object.isRequired, isHoldingsMove: PropTypes.bool, tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), }; +HoldingsListContainer.defaultProps = { pathToAccordionsState: [] }; + export default HoldingsListContainer; diff --git a/src/Instance/InstanceDetails/ConsortialHoldings/ConsortialHoldings.js b/src/Instance/InstanceDetails/ConsortialHoldings/ConsortialHoldings.js index d3623b753..aae864206 100644 --- a/src/Instance/InstanceDetails/ConsortialHoldings/ConsortialHoldings.js +++ b/src/Instance/InstanceDetails/ConsortialHoldings/ConsortialHoldings.js @@ -1,4 +1,8 @@ -import React, { useContext } from 'react'; +import React, { + useContext, + useEffect, + useRef, +} from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; @@ -13,25 +17,42 @@ import { import { MemberTenantHoldings } from '../MemberTenantHoldings'; import { DataContext } from '../../../contexts'; -import { useSearchForShadowInstanceTenants } from '../../../hooks'; +import { + useHoldingsAccordionState, + useSearchForShadowInstanceTenants, +} from '../../../hooks'; const ConsortialHoldings = ({ instance }) => { + const instanceId = instance?.id; + const prevInstanceId = useRef(instanceId); + const stripes = useStripes(); const { consortiaTenantsById } = useContext(DataContext); - const { tenants } = useSearchForShadowInstanceTenants({ instanceId: instance?.id }); + const { tenants } = useSearchForShadowInstanceTenants({ instanceId }); const memberTenants = tenants .map(tenant => consortiaTenantsById[tenant.id]) .filter(tenant => !tenant?.isCentral && (tenant?.id !== stripes.okapi.tenant)) .sort((a, b) => a.name.localeCompare(b.name)); + const pathToAccordion = ['consortialHoldings', '_state']; + const [isConsortialAccOpen, setConsortialAccOpen] = useHoldingsAccordionState({ instanceId, pathToAccordion }); + + useEffect(() => { + if (instanceId !== prevInstanceId.current) { + setConsortialAccOpen(false); + prevInstanceId.current = instanceId; + } + }, [instanceId]); + return ( } - closedByDefault + open={isConsortialAccOpen} + onToggle={() => setConsortialAccOpen(prevState => !prevState)} > {!memberTenants.length ? @@ -39,7 +60,7 @@ const ConsortialHoldings = ({ instance }) => { {memberTenants.map(memberTenant => ( diff --git a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js index 0ada3eff2..47fc6aa2f 100644 --- a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js +++ b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js @@ -16,6 +16,7 @@ import { InstanceNewHolding } from '../InstanceNewHolding'; import { MoveItemsContext } from '../../MoveItemsContext'; import { useInstanceHoldingsQuery } from '../../../providers'; +import { useHoldingsAccordionState } from '../../../hooks'; import css from './MemberTenantHoldings.css'; @@ -27,7 +28,13 @@ const MemberTenantHoldings = ({ name, id, } = memberTenant; + const instanceId = instance?.id; const stripes = useStripes(); + + const pathToAccordion = ['consortialHoldings', id, '_state']; + const pathToHoldingsAccordion = ['consortialHoldings', id]; + const [isMemberTenantAccOpen, setMemberTenantAccOpen] = useHoldingsAccordionState({ instanceId, pathToAccordion }); + const { holdingsRecords, isLoading } = useInstanceHoldingsQuery(instance?.id, { tenantId: id }); const isUserInCentralTenant = checkIfUserInCentralTenant(stripes); @@ -38,7 +45,8 @@ const MemberTenantHoldings = ({ className={css.memberTenantHoldings} id={`${name}-holdings`} label={name} - closedByDefault + open={isMemberTenantAccOpen} + onToggle={() => setMemberTenantAccOpen(prevValue => !prevValue)} >
{isLoading @@ -51,6 +59,7 @@ const MemberTenantHoldings = ({ tenantId={id} draggable={false} droppable={false} + pathToAccordionsState={pathToHoldingsAccordion} /> )} diff --git a/src/Instance/InstanceMovement/HoldingMovementList/HoldingsListMovement.js b/src/Instance/InstanceMovement/HoldingMovementList/HoldingsListMovement.js index 5c0788920..825a8b514 100644 --- a/src/Instance/InstanceMovement/HoldingMovementList/HoldingsListMovement.js +++ b/src/Instance/InstanceMovement/HoldingMovementList/HoldingsListMovement.js @@ -23,6 +23,7 @@ const HoldingsListMovement = ({ draggable, droppable, tenantId, + pathToAccordionsState, }) => { const { selectItemsForDrag, @@ -58,6 +59,7 @@ const HoldingsListMovement = ({ holdingIndex={index} draggingHoldingsCount={draggingHoldingsCount} tenantId={tenantId} + pathToAccordionsState={pathToAccordionsState} /> )) ) : ( @@ -80,10 +82,12 @@ HoldingsListMovement.propTypes = { draggable: PropTypes.bool, droppable: PropTypes.bool, tenantId: PropTypes.string, + pathToAccordionsState: PropTypes.arrayOf(PropTypes.string), }; HoldingsListMovement.defaultProps = { holdings: [], + pathToAccordionsState: [], }; export default HoldingsListMovement; diff --git a/src/ViewInstance.js b/src/ViewInstance.js index 67946a013..f67977944 100644 --- a/src/ViewInstance.js +++ b/src/ViewInstance.js @@ -900,6 +900,7 @@ class ViewInstance extends React.Component { }, ]; const isInstanceLoading = this.state.isLoading || !instance || isCentralTenantPermissionsLoading; + const keyInStorageToHoldingsAccsState = ['holdings']; return ( @@ -927,6 +928,7 @@ class ViewInstance extends React.Component { instance={instance} draggable={this.state.isItemsMovement} tenantId={okapi.tenant} + pathToAccordionsState={keyInStorageToHoldingsAccsState} droppable /> diff --git a/src/hooks/index.js b/src/hooks/index.js index 8d61406b9..51310d19e 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -3,6 +3,7 @@ export { default as useBrowseValidation } from './useBrowseValidation'; export { default as useCallout } from './useCallout'; export { default as useHoldingItemsQuery } from './useHoldingItemsQuery'; export { default as useHoldingMutation } from './useHoldingMutation'; +export { default as useHoldingsAccordionState } from './useHoldingsAccordionState'; export { default as useInstanceMutation } from './useInstanceMutation'; export { default as useHoldingsQueryByHrids } from './useHoldingsQueryByHrids'; export { default as useInventoryBrowse } from './useInventoryBrowse'; diff --git a/src/hooks/useHoldingsAccordionState/index.js b/src/hooks/useHoldingsAccordionState/index.js new file mode 100644 index 000000000..83af4d1a1 --- /dev/null +++ b/src/hooks/useHoldingsAccordionState/index.js @@ -0,0 +1 @@ +export { default } from './useHoldingsAccordionState'; diff --git a/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.js b/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.js new file mode 100644 index 000000000..86cad1abb --- /dev/null +++ b/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.js @@ -0,0 +1,42 @@ +import { + useEffect, + useState, +} from 'react'; +import { + cloneDeep, + get, + set, +} from 'lodash'; + +import { useNamespace } from '@folio/stripes/core'; + +import { + getItem, + setItem, +} from '../../storage'; + +const useHoldingsAccordionState = ({ instanceId, pathToAccordion = [] }) => { + const [namespace] = useNamespace(); + const key = `${namespace}.instanceHoldingsAccordionsState`; + + const instanceHoldingsAccordionsState = getItem(key) ?? {}; + const currentAccState = get(instanceHoldingsAccordionsState, [instanceId, ...pathToAccordion], false); + + const [isOpen, setIsOpen] = useState(currentAccState); + + useEffect(() => { + let newState = { + [instanceId]: { + ...cloneDeep(instanceHoldingsAccordionsState[instanceId]), + } + }; + + newState = set(newState, [instanceId, ...pathToAccordion], isOpen); + + setItem(key, newState); + }, [instanceHoldingsAccordionsState, isOpen, instanceId]); + + return [isOpen, setIsOpen]; +}; + +export default useHoldingsAccordionState; diff --git a/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.test.js b/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.test.js new file mode 100644 index 000000000..8e60b2ffa --- /dev/null +++ b/src/hooks/useHoldingsAccordionState/useHoldingsAccordionState.test.js @@ -0,0 +1,43 @@ +import { + renderHook, + waitFor, + act, +} from '@folio/jest-config-stripes/testing-library/react'; + +import '../../../test/jest/__mock__'; + +import useHoldingsAccordionState from './useHoldingsAccordionState'; + +import { getItem } from '../../storage'; + +describe('useHoldingsAccordionState', () => { + it('should save initial holdings state in storage', () => { + const { result } = renderHook(() => useHoldingsAccordionState({ + instanceId: 'instanceId', + pathToAccordion: ['holdings', '_self'], + })); + + const expectedResult = { instanceId: { holdings: { _self: false } } }; + + expect(getItem('@folio/inventory.instanceHoldingsAccordionsState')).toEqual(expectedResult); + expect(result.current[0]).toEqual(false); + }); + + it('should set new state on accordion toggle', () => { + const { result } = renderHook(() => useHoldingsAccordionState({ + instanceId: 'instanceId', + pathToAccordion: ['holdings', '_self'], + })); + + const [isOpen, setOpen] = result.current; + + act(() => { + setOpen(true); + }); + + const expectedResult = { instanceId: { holdings: { _self: true } } }; + + waitFor(() => expect(isOpen).toBeTruthy()); + waitFor(() => expect(getItem('@folio/inventory.instanceHoldingsAccordionsState')).toEqual(expectedResult)); + }); +}); From e03476fba5f3321589a7cfc27d910e57cf7b8b0e Mon Sep 17 00:00:00 2001 From: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:01:26 +0300 Subject: [PATCH 2/2] UIIN-2629: Consortial holdings accordion is not appearing after the sharing of Instance (#2312) --- CHANGELOG.md | 1 + .../InstanceDetails/InstanceDetails.js | 4 +- .../InstanceDetails/InstanceDetails.test.js | 157 ++++++++---------- 3 files changed, 70 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af713044d..23a2b3217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 10.0.1 IN PROGRESS * Instance 3rd pane: Adjust behavior when returning to instance from holdings/item full screen. Refs UIIN-2453. +* Consortial holdings accordion is not appearing after the sharing of Instance. Fixes UIIN-2629. ## [10.0.0](https://github.com/folio-org/ui-inventory/tree/v10.0.0) (2023-10-13) [Full Changelog](https://github.com/folio-org/ui-inventory/compare/v9.4.12...v10.0.0) diff --git a/src/Instance/InstanceDetails/InstanceDetails.js b/src/Instance/InstanceDetails/InstanceDetails.js index 36df56a26..a1d1a40f6 100644 --- a/src/Instance/InstanceDetails/InstanceDetails.js +++ b/src/Instance/InstanceDetails/InstanceDetails.js @@ -123,6 +123,8 @@ const InstanceDetails = forwardRef(({ ); } + const isConsortialHoldingsVisible = instance?.shared || isInstanceShadowCopy(instance?.source); + const renderPaneTitle = () => { const isInstanceShared = Boolean(isShared || isInstanceShadowCopy(instance?.source)); @@ -196,7 +198,7 @@ const InstanceDetails = forwardRef(({ )} - {instance?.shared && ( + {isConsortialHoldingsVisible && ( )} diff --git a/src/Instance/InstanceDetails/InstanceDetails.test.js b/src/Instance/InstanceDetails/InstanceDetails.test.js index 2898391a2..daf483dcd 100644 --- a/src/Instance/InstanceDetails/InstanceDetails.test.js +++ b/src/Instance/InstanceDetails/InstanceDetails.test.js @@ -17,9 +17,14 @@ jest.mock('../InstanceDetails/ControllableDetail/ControllableDetail', () => jest jest.mock('../InstanceDetails/SubInstanceGroup/SubInstanceGroup', () => jest.fn().mockReturnValue('SubInstanceGroup')); jest.mock('../InstanceDetails/InstanceAcquisition/InstanceAcquisition', () => jest.fn().mockReturnValue('InstanceAcquisition')); jest.mock('../InstanceDetails/InstanceTitleData/InstanceTitleData', () => jest.fn().mockReturnValue('InstanceTitleData')); +jest.mock('./ConsortialHoldings', () => ({ + ...jest.requireActual('./ConsortialHoldings'), + ConsortialHoldings: () => , +})); const instance = { title: 'Test Title', + source: 'FOLIO', contributors: [], identifiers: [], instanceTypeId: '1234', @@ -30,6 +35,7 @@ const instance = { notes: [], staffSuppress: false, discoverySuppress: false, + shared: false, }; const mockReferenceData = { @@ -48,23 +54,31 @@ const queryClient = new QueryClient(); const actionMenu = jest.fn(); const onClose = jest.fn(); const tagsEnabled = true; + +const renderInstanceDetails = (props) => { + const component = ( + + + + + + + + ); + + return renderWithIntl(component, translationsProperties); +}; + describe('InstanceDetails', () => { it('renders the InstanceDetails component', () => { - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails(); + expect(screen.getByText('InstanceTitle')).toBeInTheDocument(); expect(screen.getByText('Add holdings')).toBeInTheDocument(); expect(screen.getByText('Administrative data')).toBeInTheDocument(); @@ -103,21 +117,7 @@ describe('InstanceDetails', () => { ...instance, staffSuppress: true, }; - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails({ instance: staffSuppressedInstance }); expect(screen.getByText('Warning: Instance is marked staff suppressed')).toBeInTheDocument(); expect(screen.getByText('Staff suppressed')).toBeInTheDocument(); @@ -128,21 +128,7 @@ describe('InstanceDetails', () => { ...instance, discoverySuppress: true, }; - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails({ instance: discoverySuppressedInstance }); expect(screen.getByText('Warning: Instance is marked suppressed from discovery')).toBeInTheDocument(); expect(screen.getByText('Suppressed from discovery')).toBeInTheDocument(); @@ -153,48 +139,21 @@ describe('InstanceDetails', () => { staffSuppress: true, discoverySuppress: true, }; - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails({ instance: bothSuppressedInstance }); expect(screen.getByText('Warning: Instance is marked suppressed from discovery and staff suppressed')).toBeInTheDocument(); }); it('expands and collapses the accordion sections', () => { - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails(); const expandAllButtons = screen.getByText('Expand all'); const firstAccordionSection = screen.getByRole('button', { name: /Administrative data/i }); const secondAccordionSection = screen.getByRole('button', { name: /Instance notes/i }); const thirdAccordionSection = screen.getByRole('button', { name: /Electronic access/i }); const fourthAccordionSection = screen.getByRole('button', { name: /Classification/i }); - expect(firstAccordionSection.getAttribute('aria-expanded')).toBe('false'); + // Administrative data is open because it has initial data inside it + expect(firstAccordionSection.getAttribute('aria-expanded')).toBe('true'); expect(secondAccordionSection.getAttribute('aria-expanded')).toBe('false'); expect(thirdAccordionSection.getAttribute('aria-expanded')).toBe('false'); expect(fourthAccordionSection.getAttribute('aria-expanded')).toBe('false'); @@ -212,23 +171,39 @@ describe('InstanceDetails', () => { }); it('renders tags button if tagsEnabled is true', () => { - renderWithIntl( - - - - , - - - , - translationsProperties - ); + renderInstanceDetails(); + const button = screen.getAllByRole('button', { id: 'clickable-show-tags' }); fireEvent.click(button[1]); expect(button[1]).toBeEnabled(); }); + + describe('Consortial holdings accordion', () => { + it('should be visible for shared instances', () => { + const sharedInstance = { + ...instance, + shared: true, + }; + renderInstanceDetails({ instance: sharedInstance }); + + expect(screen.getByRole('button', { name: 'Consortial holdings' })).toBeInTheDocument(); + }); + + it('should be visible for shadow instances', () => { + const shadowInstance = { + ...instance, + shared: false, + source: 'CONSORTIUM-FOLIO', + }; + renderInstanceDetails({ instance: shadowInstance }); + + expect(screen.getByRole('button', { name: 'Consortial holdings' })).toBeInTheDocument(); + }); + + it('should not be visible for local instances', () => { + renderInstanceDetails(); + + expect(screen.queryByRole('button', { name: 'Consortial holdings' })).not.toBeInTheDocument(); + }); + }); });