From 74ef3d3e6246d41ced0b70b535a2fd9c395e7d3f Mon Sep 17 00:00:00 2001 From: FOLIO Translations Bot <38661258+folio-translations@users.noreply.github.com> Date: Sun, 15 Dec 2024 13:15:08 -0500 Subject: [PATCH 1/5] Update translation strings --- translations/ui-requests/ar.json | 3 ++- translations/ui-requests/ber.json | 3 ++- translations/ui-requests/ca.json | 3 ++- translations/ui-requests/cs_CZ.json | 3 ++- translations/ui-requests/da.json | 3 ++- translations/ui-requests/de.json | 3 ++- translations/ui-requests/en_GB.json | 3 ++- translations/ui-requests/en_SE.json | 3 ++- translations/ui-requests/en_US.json | 3 ++- translations/ui-requests/es.json | 3 ++- translations/ui-requests/es_419.json | 3 ++- translations/ui-requests/es_ES.json | 3 ++- translations/ui-requests/fr.json | 3 ++- translations/ui-requests/fr_FR.json | 5 +++-- translations/ui-requests/he.json | 3 ++- translations/ui-requests/hi_IN.json | 3 ++- translations/ui-requests/hu.json | 3 ++- translations/ui-requests/it_IT.json | 3 ++- translations/ui-requests/ja.json | 3 ++- translations/ui-requests/ko.json | 3 ++- translations/ui-requests/nb.json | 3 ++- translations/ui-requests/nl.json | 3 ++- translations/ui-requests/nn.json | 3 ++- translations/ui-requests/pl.json | 3 ++- translations/ui-requests/pt_BR.json | 3 ++- translations/ui-requests/pt_PT.json | 3 ++- translations/ui-requests/ru.json | 3 ++- translations/ui-requests/sk.json | 3 ++- translations/ui-requests/sv.json | 3 ++- translations/ui-requests/ur.json | 3 ++- translations/ui-requests/zh_CN.json | 5 +++-- translations/ui-requests/zh_TW.json | 3 ++- 32 files changed, 66 insertions(+), 34 deletions(-) diff --git a/translations/ui-requests/ar.json b/translations/ui-requests/ar.json index 3f284be0..8b10c742 100644 --- a/translations/ui-requests/ar.json +++ b/translations/ui-requests/ar.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ber.json b/translations/ui-requests/ber.json index edc5f986..9dcf98ab 100644 --- a/translations/ui-requests/ber.json +++ b/translations/ui-requests/ber.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ca.json b/translations/ui-requests/ca.json index 2b8ff5b8..fd2e1ad0 100644 --- a/translations/ui-requests/ca.json +++ b/translations/ui-requests/ca.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/cs_CZ.json b/translations/ui-requests/cs_CZ.json index f6a7b6ca..b7ea2af0 100644 --- a/translations/ui-requests/cs_CZ.json +++ b/translations/ui-requests/cs_CZ.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Nevytištěno", "printDetails.printCount": "# Kopie", "permission.moveRequest.execute": "Požadavky: Přejít na novou jednotku, změnit pořadí fronty", - "permission.reorderQueue.execute": "Žádanky: Změna pořadí ve frontě" + "permission.reorderQueue.execute": "Žádanky: Změna pořadí ve frontě", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/da.json b/translations/ui-requests/da.json index efe02a48..a64f635e 100644 --- a/translations/ui-requests/da.json +++ b/translations/ui-requests/da.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/de.json b/translations/ui-requests/de.json index 9a38daa3..fe7df577 100644 --- a/translations/ui-requests/de.json +++ b/translations/ui-requests/de.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Nicht gedruckt", "printDetails.printCount": "# Exemplare", "permission.moveRequest.execute": "Bestandsanfragen: Verschieben zu neuem Exemplar, Warteliste neu anordnen", - "permission.reorderQueue.execute": "Bestandsanfragen: Warteliste neu anordnen" + "permission.reorderQueue.execute": "Bestandsanfragen: Warteliste neu anordnen", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_GB.json b/translations/ui-requests/en_GB.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/en_GB.json +++ b/translations/ui-requests/en_GB.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_SE.json b/translations/ui-requests/en_SE.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/en_SE.json +++ b/translations/ui-requests/en_SE.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_US.json b/translations/ui-requests/en_US.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/en_US.json +++ b/translations/ui-requests/en_US.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es.json b/translations/ui-requests/es.json index e393b91d..46bbe0ba 100644 --- a/translations/ui-requests/es.json +++ b/translations/ui-requests/es.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es_419.json b/translations/ui-requests/es_419.json index e393b91d..46bbe0ba 100644 --- a/translations/ui-requests/es_419.json +++ b/translations/ui-requests/es_419.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es_ES.json b/translations/ui-requests/es_ES.json index e393b91d..46bbe0ba 100644 --- a/translations/ui-requests/es_ES.json +++ b/translations/ui-requests/es_ES.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/fr.json b/translations/ui-requests/fr.json index 2b8ff5b8..fd2e1ad0 100644 --- a/translations/ui-requests/fr.json +++ b/translations/ui-requests/fr.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/fr_FR.json b/translations/ui-requests/fr_FR.json index 18e9032e..6b83f995 100644 --- a/translations/ui-requests/fr_FR.json +++ b/translations/ui-requests/fr_FR.json @@ -225,7 +225,7 @@ "duplicateRequest.success": "La réservation a été créée avec succès pour {requester}", "duplicateRequest.fail": "This request was not placed successfully", "requests": "{number} réservations", - "item.status.agedToLost": "Aged to lost", + "item.status.agedToLost": "Considéré comme perdu", "item.status.available": "Disponible", "item.status.awaitingDelivery": "En attente de livraison", "item.status.awaitingPickup": "En attente de retrait", @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/he.json b/translations/ui-requests/he.json index 2b8ff5b8..fd2e1ad0 100644 --- a/translations/ui-requests/he.json +++ b/translations/ui-requests/he.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/hi_IN.json b/translations/ui-requests/hi_IN.json index 2b8ff5b8..fd2e1ad0 100644 --- a/translations/ui-requests/hi_IN.json +++ b/translations/ui-requests/hi_IN.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/hu.json b/translations/ui-requests/hu.json index 19b2c628..76a7e1e6 100644 --- a/translations/ui-requests/hu.json +++ b/translations/ui-requests/hu.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/it_IT.json b/translations/ui-requests/it_IT.json index 464bbbb3..363a4056 100644 --- a/translations/ui-requests/it_IT.json +++ b/translations/ui-requests/it_IT.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ja.json b/translations/ui-requests/ja.json index a34aaf33..ecff3f9a 100644 --- a/translations/ui-requests/ja.json +++ b/translations/ui-requests/ja.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ko.json b/translations/ui-requests/ko.json index 0a44c13d..fff470cf 100644 --- a/translations/ui-requests/ko.json +++ b/translations/ui-requests/ko.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/nb.json b/translations/ui-requests/nb.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/nb.json +++ b/translations/ui-requests/nb.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/nl.json b/translations/ui-requests/nl.json index 8fc18fc5..a906ff56 100644 --- a/translations/ui-requests/nl.json +++ b/translations/ui-requests/nl.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Niet afgedrukt", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Ophaalservicepunt" } \ No newline at end of file diff --git a/translations/ui-requests/nn.json b/translations/ui-requests/nn.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/nn.json +++ b/translations/ui-requests/nn.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/pl.json b/translations/ui-requests/pl.json index 4bed57a3..41109e48 100644 --- a/translations/ui-requests/pl.json +++ b/translations/ui-requests/pl.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/pt_BR.json b/translations/ui-requests/pt_BR.json index 0d5a2a79..30744ca4 100644 --- a/translations/ui-requests/pt_BR.json +++ b/translations/ui-requests/pt_BR.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Não impresso", "printDetails.printCount": "# Cópias", "permission.moveRequest.execute": "Requisições: Mover para novo item, reordenar fila", - "permission.reorderQueue.execute": "Requisições: Reordenar fila" + "permission.reorderQueue.execute": "Requisições: Reordenar fila", + "requests.retrievalServicePoint": "Ponto de serviço de recuperação" } \ No newline at end of file diff --git a/translations/ui-requests/pt_PT.json b/translations/ui-requests/pt_PT.json index cca24cde..ed55eba7 100644 --- a/translations/ui-requests/pt_PT.json +++ b/translations/ui-requests/pt_PT.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ru.json b/translations/ui-requests/ru.json index e8c98aeb..9f2fd0d8 100644 --- a/translations/ui-requests/ru.json +++ b/translations/ui-requests/ru.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/sk.json b/translations/ui-requests/sk.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/sk.json +++ b/translations/ui-requests/sk.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/sv.json b/translations/ui-requests/sv.json index de6167ac..98b6ac3c 100644 --- a/translations/ui-requests/sv.json +++ b/translations/ui-requests/sv.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ur.json b/translations/ui-requests/ur.json index 47b69003..b5a9c149 100644 --- a/translations/ui-requests/ur.json +++ b/translations/ui-requests/ur.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/zh_CN.json b/translations/ui-requests/zh_CN.json index dec320b4..dad90bfe 100644 --- a/translations/ui-requests/zh_CN.json +++ b/translations/ui-requests/zh_CN.json @@ -298,6 +298,7 @@ "filters.printStatus.printed": "已打印", "filters.printStatus.notPrinted": "未打印", "printDetails.printCount": "# 份数", - "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.moveRequest.execute": "请求:移至新单件,重新排序队列", + "permission.reorderQueue.execute": "请求:重新排序队列", + "requests.retrievalServicePoint": "检索服务点" } \ No newline at end of file diff --git a/translations/ui-requests/zh_TW.json b/translations/ui-requests/zh_TW.json index b3bf63e2..321787ea 100644 --- a/translations/ui-requests/zh_TW.json +++ b/translations/ui-requests/zh_TW.json @@ -299,5 +299,6 @@ "filters.printStatus.notPrinted": "Not printed", "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", - "permission.reorderQueue.execute": "Requests: Reorder queue" + "permission.reorderQueue.execute": "Requests: Reorder queue", + "requests.retrievalServicePoint": "Retrieval service point" } \ No newline at end of file From cab7e2f8a729b6746cd44dee5ce6b851959c4cb8 Mon Sep 17 00:00:00 2001 From: Artem Blazhko Date: Mon, 16 Dec 2024 14:59:06 +0200 Subject: [PATCH 2/5] UIREQ-1046: Increase code coverage for src/ViewRequest.js by Jest/RTL tests (#1246) --- CHANGELOG.md | 1 + src/ViewRequest.test.js | 850 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 825 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49016346..95e13c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Add optional column "Retrieval service point" to requests search list. Refs UIREQ-1188. * Increase code coverage for src/ChooseRequestTypeDialog.js by Jest/RTL tests. Refs UIREQ-1044. * Cleanup retrieval service point implementation from deprecated folder. Refs UIREQ-1211. +* Increase code coverage for src/ViewRequest.js by Jest/RTL tests. Refs UIREQ-1046. ## [11.0.2] (https://github.com/folio-org/ui-requests/tree/v11.0.2) (2024-12-10) [Full Changelog](https://github.com/folio-org/ui-requests/compare/v11.0.1...v11.0.2) diff --git a/src/ViewRequest.test.js b/src/ViewRequest.test.js index 297d99bd..402e2fa1 100644 --- a/src/ViewRequest.test.js +++ b/src/ViewRequest.test.js @@ -1,13 +1,17 @@ -import moment from 'moment-timezone'; +import React from 'react'; import { render, screen, + waitFor, } from '@folio/jest-config-stripes/testing-library/react'; +import userEvent from '@folio/jest-config-stripes/testing-library/user-event'; import { CommandList, defaultKeyboardShortcuts, + Icon, + PaneHeaderIconButton, } from '@folio/stripes/components'; import ViewRequest, { @@ -15,25 +19,117 @@ import ViewRequest, { shouldHideMoveAndDuplicate, } from './ViewRequest'; import RequestForm from './RequestForm'; +import MoveRequestManager from './MoveRequestManager'; +import CancelRequestDialog from './CancelRequestDialog'; +import UserDetail from './UserDetail'; +import ItemDetail from './ItemDetail'; import { INVALID_REQUEST_HARDCODED_ID, requestStatuses, REQUEST_LEVEL_TYPES, DCB_INSTANCE_ID, DCB_HOLDINGS_RECORD_ID, + REQUEST_LAYERS, + fulfillmentTypeMap, } from './constants'; +import { + isProxyFunctionalityAvailable, + toUserAddress, +} from './utils'; import { duplicateRecordShortcut, editRecordShortcut, } from '../test/jest/helpers/shortcuts'; +const testIds = { + requestForm: 'requestForm', + moveRequestManager: 'moveRequestManager', + cancelRequestButton: 'cancelRequestButton', + saveRequestButton: 'saveRequestButton', + moveRequestButton: 'moveRequestButton', + cancelMoveButton: 'cancelMoveButton', +}; +const updatedRecordRequester = { + requester: { + personal: { + firstName: 'firstName', + }, + }, +}; +const requestQueueUrl = 'requestQueueUrl/'; + jest.mock('./RequestForm', () => jest.fn(() => null)); -jest.mock('./MoveRequestManager', () => jest.fn(() => null)); +jest.mock('./MoveRequestManager', () => jest.fn(({ + onMove, + onCancelMove, +}) => { + return ( +
+ + +
+ ); +})); jest.mock('./ItemDetail', () => jest.fn(() => null)); jest.mock('./UserDetail', () => jest.fn(() => null)); jest.mock('./CancelRequestDialog', () => jest.fn(() => null)); jest.mock('./PositionLink', () => jest.fn(() => null)); jest.mock('./components/TitleInformation', () => jest.fn(() => null)); +jest.mock('./RequestFormContainer', () => jest.fn(({ + onSubmit, + onCancelRequest, +}) => { + const handleSubmit = () => { + onSubmit(updatedRecordRequester); + }; + const cancelRequest = () => { + onCancelRequest({}); + }; + + return ( + <> +
+ + +
+ + ); +})); +jest.mock('./utils', () => ({ + ...jest.requireActual('./utils'), + toUserAddress: jest.fn(), + isProxyFunctionalityAvailable: jest.fn(() => true), +})); +jest.mock('./routes/urls', () => ({ + requestQueueView: jest.fn(() => requestQueueUrl), +})); describe('ViewRequest', () => { const labelIds = { @@ -43,6 +139,10 @@ describe('ViewRequest', () => { moveRequest: 'ui-requests.actions.moveRequest', reorderQueue: 'ui-requests.actions.reorderQueue', requestDetailTitle: 'ui-requests.request.detail.title', + showTags: 'ui-requests.showTags', + noItemInformation: 'ui-requests.item.noInformation', + cancellationReason: 'ui-requests.cancellationReason', + cancellationAdditionalInformation: 'ui-requests.cancellationAdditionalInformation', }; const mockedRequest = { instance: { @@ -59,6 +159,13 @@ describe('ViewRequest', () => { metadata: { createdDate: 'createdDate', }, + requester: { + id: 'requesterId', + }, + proxy: { + id: 'proxyUserId', + }, + proxyUserId: 'proxyUserId', }; const mockedRequestWithDCBUser = { ...mockedRequest, @@ -99,10 +206,22 @@ describe('ViewRequest', () => { onClose: jest.fn(), onCloseEdit: jest.fn(), buildRecordsForHoldsShelfReport: jest.fn(), + patronGroups: [ + { + id: 'groupId', + name: 'groupName', + } + ], optionLists: { cancellationReasons: [ - { id: '1' }, - { id: '2' }, + { + id: 'id_1', + name: 'name_1', + }, + { + id: 'id_2', + name: 'name_2', + }, ], servicePoints: [ { id: 'servicePoint' }, @@ -134,6 +253,13 @@ describe('ViewRequest', () => { }, isEcsTlrSettingEnabled: false, isEcsTlrSettingReceived: true, + onDuplicate: jest.fn(), + onEdit: jest.fn(), + }; + const openRequest = { + ...mockedRequest, + fulfillmentPreference: fulfillmentTypeMap.HOLD_SHELF, + status: requestStatuses.NOT_YET_FILLED, }; const defaultDCBLendingProps = { ...defaultProps, @@ -176,26 +302,6 @@ describe('ViewRequest', () => { expect(screen.getByText(labelIds.requestDetailTitle)).toBeInTheDocument(); }); - describe('when work with request editing', () => { - beforeAll(() => { - mockedLocation.search = '?layer=edit'; - }); - - it('should set "createTitleLevelRequest" to false when try to edit existed request', () => { - const expectedResult = { - initialValues : { - requestExpirationDate: null, - holdShelfExpirationDate: mockedRequest.holdShelfExpirationDate, - holdShelfExpirationTime: moment(mockedRequest.holdShelfExpirationDate).format('HH:mm'), - createTitleLevelRequest: false, - ...mockedRequest, - }, - }; - - expect(RequestForm).toHaveBeenCalledWith(expect.objectContaining(expectedResult), {}); - }); - }); - describe('when not working with request editing', () => { beforeAll(() => { mockedLocation.search = null; @@ -203,7 +309,7 @@ describe('ViewRequest', () => { describe('when current request is closed', () => { describe('request is valid', () => { - describe('TLR in enabled', () => { + describe('TLR is enabled', () => { beforeAll(() => { mockedConfig.records[0].value = { titleLevelRequestsFeatureEnabled: true, @@ -213,9 +319,17 @@ describe('ViewRequest', () => { it('should render "Duplicate" button', () => { expect(screen.getByText(labelIds.duplicateRequest)).toBeInTheDocument(); }); + + it('should trigger "onDuplicate"', async () => { + const duplicateButton = screen.getByText(labelIds.duplicateRequest); + + await userEvent.click(duplicateButton); + + expect(defaultProps.onDuplicate).toHaveBeenCalledWith(defaultProps.resources.selectedRequest.records[0]); + }); }); - describe('TLR in disabled', () => { + describe('TLR is disabled', () => { beforeAll(() => { mockedConfig.records[0].value = { titleLevelRequestsFeatureEnabled: false, @@ -505,6 +619,690 @@ describe('ViewRequest', () => { }); }); + describe('Component updating', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('When new request is loaded', () => { + const newProps = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [ + { + ...mockedRequest, + instance: { + title: 'instanceTitle', + }, + item: { + barcode: 'itemBarcode', + }, + id: 'id', + }, + ], + }, + }, + parentResources: { + configs: { + records: [ + { + value: { + test: 1, + titleLevelRequestsFeatureEnabled: false, + }, + } + ], + }, + }, + }; + + beforeEach(() => { + const { rerender } = render(); + + rerender(); + }); + + it('should trigger "joinRequest"', () => { + expect(defaultProps.joinRequest).toHaveBeenCalled(); + }); + }); + + describe('When new request is loading', () => { + const newProps = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: false, + records: [mockedRequest], + }, + }, + }; + + beforeEach(() => { + const { rerender } = render(); + + rerender(); + }); + + it('should not trigger "joinRequest"', () => { + expect(defaultProps.joinRequest).toHaveBeenCalled(); + }); + }); + }); + + describe('Request updating', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('When proxy functionality available', () => { + const props = { + ...defaultProps, + mutator: { + selectedRequest: { + PUT: jest.fn(() => Promise.resolve({})), + }, + }, + location: { + search: '?layer=edit', + layer: REQUEST_LAYERS.EDIT, + }, + }; + const sendCalloutMock = jest.fn(); + + beforeEach(() => { + jest.spyOn(React, 'createRef').mockReturnValue({ + current: { + sendCallout: sendCalloutMock, + }, + }); + render(); + }); + + it('should send correct data for record updating', async () => { + const saveButton = screen.getByTestId(testIds.saveRequestButton); + const dataToSubmit = { + proxy: mockedRequest.proxy, + proxyUserId: mockedRequest.proxyUserId, + id: mockedRequest.id, + instance: mockedRequest.instance, + item: mockedRequest.item, + metadata: mockedRequest.metadata, + pickupServicePointId: mockedRequest.pickupServicePointId, + requestLevel: mockedRequest.requestLevel, + status: mockedRequest.status, + holdShelfExpirationDate: mockedRequest.holdShelfExpirationDate, + requester: updatedRecordRequester.requester, + }; + + await userEvent.click(saveButton); + + expect(props.mutator.selectedRequest.PUT).toHaveBeenCalledWith(dataToSubmit); + }); + }); + + describe('When proxy functionality is not available', () => { + const props = { + ...defaultProps, + mutator: { + selectedRequest: { + PUT: jest.fn(() => Promise.resolve({})), + }, + }, + location: { + search: '?layer=edit', + layer: REQUEST_LAYERS.EDIT, + }, + }; + const sendCalloutMock = jest.fn(); + + beforeEach(() => { + isProxyFunctionalityAvailable.mockReturnValueOnce(false); + jest.spyOn(React, 'createRef').mockReturnValue({ + current: { + sendCallout: sendCalloutMock, + }, + }); + render(); + }); + + it('should send correct data for record updating', async () => { + const saveButton = screen.getByTestId(testIds.saveRequestButton); + const dataToSubmit = { + id: mockedRequest.id, + instance: mockedRequest.instance, + status: mockedRequest.status, + item: mockedRequest.item, + metadata: mockedRequest.metadata, + pickupServicePointId: mockedRequest.pickupServicePointId, + requestLevel: mockedRequest.requestLevel, + holdShelfExpirationDate: mockedRequest.holdShelfExpirationDate, + requester: updatedRecordRequester.requester, + }; + + await userEvent.click(saveButton); + + expect(props.mutator.selectedRequest.PUT).toHaveBeenCalledWith(dataToSubmit); + }); + }); + + describe('When error happens', () => { + const props = { + ...defaultProps, + mutator: { + selectedRequest: { + PUT: jest.fn(() => Promise.resolve({})), + }, + }, + location: { + layer: REQUEST_LAYERS.EDIT, + search: '?layer=edit', + }, + onCloseEdit: jest.fn(() => throw new Error('error message')), + }; + const sendCalloutMock = jest.fn(); + + beforeEach(() => { + jest.spyOn(React, 'createRef').mockReturnValue({ + current: { + sendCallout: sendCalloutMock, + }, + }); + render(); + }); + + it('should show error callout', async () => { + const saveButton = screen.getByTestId(testIds.saveRequestButton); + + userEvent.click(saveButton); + + await waitFor(() => { + expect(sendCalloutMock).toHaveBeenCalledWith(expect.objectContaining({ type: 'error' })); + }); + }); + }); + }); + + describe('Request canceling via RequestFormContainer', () => { + const props = { + ...defaultProps, + mutator: { + selectedRequest: { + PUT: jest.fn(() => Promise.resolve({})), + }, + }, + location: { + search: '?layer=edit', + layer: REQUEST_LAYERS.EDIT, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(async () => { + render(); + + const cancelButton = screen.getByTestId(testIds.cancelRequestButton); + + await userEvent.click(cancelButton); + }); + + it('should send correct data for record canceling', () => { + expect(props.mutator.selectedRequest.PUT).toHaveBeenCalledWith(mockedRequest); + }); + + it('should trigger "onCloseEdit"', () => { + expect(props.onCloseEdit).toHaveBeenCalled(); + }); + + it('should trigger "buildRecordsForHoldsShelfReport"', () => { + expect(props.buildRecordsForHoldsShelfReport).toHaveBeenCalled(); + }); + }); + + describe('Request canceling via action menu', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [ + { + ...defaultProps.resources.selectedRequest.records[0], + status: requestStatuses.NOT_YET_FILLED, + }, + ], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger CancelRequestDialog with correct "open" prop', async () => { + const cancelButton = screen.getByText(labelIds.cancelRequest); + const expectedProps = { + open: true, + }; + + CancelRequestDialog.mockClear(); + await userEvent.click(cancelButton); + + expect(CancelRequestDialog).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + }); + + describe('Request moving', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [openRequest], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(async () => { + render(); + + const moveRequestButton = screen.getByText(labelIds.moveRequest); + + await userEvent.click(moveRequestButton); + }); + + it('should trigger "MoveRequestManager" with correct props', () => { + const expectedProps = { + onMove: expect.any(Function), + onCancelMove: expect.any(Function), + request: props.resources.selectedRequest.records[0], + }; + + expect(MoveRequestManager).toHaveBeenCalledWith(expectedProps, {}); + }); + + it('should not trigger "MoveRequestManager"', async () => { + const cancelMoveButton = screen.getByTestId(testIds.cancelMoveButton); + + await userEvent.click(cancelMoveButton); + + const moveRequestManager = screen.queryByTestId(testIds.moveRequestManager); + + expect(moveRequestManager).not.toBeInTheDocument(); + }); + + it('should trigger "history.push" after request moving', async () => { + const moveRequestButton = screen.getByTestId(testIds.moveRequestButton); + const expectedArgs = [`${requestQueueUrl}${props.location.search}`, { afterMove: true }]; + + await userEvent.click(moveRequestButton); + + expect(props.history.push).toHaveBeenCalledWith(...expectedArgs); + }); + }); + + describe('Request reordering', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [openRequest], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger "history.push" after clicking on reorder request button', async () => { + const reorderQueueButton = screen.getByText(labelIds.reorderQueue); + const expectedArgs = [ + `${requestQueueUrl}${props.location.search}`, + { request: props.resources.selectedRequest.records[0] } + ]; + + await userEvent.click(reorderQueueButton); + + expect(props.history.push).toHaveBeenCalledWith(...expectedArgs); + }); + }); + + describe('Request editing', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [openRequest], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger "onEdit" after clicking on edit button', async () => { + const editButton = screen.getByText(labelIds.edit); + + await userEvent.click(editButton); + + expect(props.onEdit).toHaveBeenCalled(); + }); + }); + + describe('Request duplicating', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [openRequest], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger "onDuplicate" after clicking on duplicate button', async () => { + const duplicateButton = screen.getByText(labelIds.duplicateRequest); + + await userEvent.click(duplicateButton); + + expect(props.onDuplicate).toHaveBeenCalled(); + }); + }); + + describe('Detail menu', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [], + }, + }, + tagsEnabled: true, + tagsToggle: jest.fn(), + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger "PaneHeaderIconButton" with correct props', () => { + const expectedProps = { + icon: 'tag', + id: 'clickable-show-tags', + onClick: props.tagsToggle, + badgeCount: 0, + ariaLabel: [labelIds.showTags], + disabled: false, + }; + + expect(PaneHeaderIconButton).toHaveBeenCalledWith(expectedProps, {}); + }); + }); + + describe('Item details', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('When item information is provided', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [{ + ...openRequest, + requestCount: 1, + loan: { + id: 'loanId', + }, + }], + }, + }, + }; + + beforeEach(() => { + render(); + }); + + it('should trigger "ItemDetail" with correct props', async () => { + const request = props.resources.selectedRequest.records[0]; + const expectedProps = { + request, + item: request.item, + loan: request.loan, + requestCount: request.requestCount, + }; + + expect(ItemDetail).toHaveBeenCalledWith(expectedProps, {}); + }); + }); + + describe('When item information is not provided', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [{ + ...openRequest, + item: undefined, + }], + }, + }, + }; + + beforeEach(() => { + render(); + }); + + it('should render no item information message', () => { + const noItemInformationMessage = screen.getByText(labelIds.noItemInformation, { exact: false }); + + expect(noItemInformationMessage).toBeInTheDocument(); + }); + }); + }); + + describe('When cancellation reason is provided', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [{ + ...openRequest, + cancellationReasonId: defaultProps.optionLists.cancellationReasons[0].id, + }], + }, + }, + }; + + beforeEach(() => { + render(); + }); + + it('should render cancellation reason label', () => { + const cancellationReasonLabel = screen.getByText(labelIds.cancellationReason); + + expect(cancellationReasonLabel).toBeInTheDocument(); + }); + + it('should render cancellation reason value', () => { + const cancellationReasonValue = screen.getByText(defaultProps.optionLists.cancellationReasons[0].name); + + expect(cancellationReasonValue).toBeInTheDocument(); + }); + }); + + describe('When cancellation additional information is provided', () => { + const cancellationAdditionalInformation = 'cancellationAdditionalInformation'; + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [{ + ...openRequest, + cancellationReasonId: defaultProps.optionLists.cancellationReasons[0].id, + cancellationAdditionalInformation, + }], + }, + }, + }; + + beforeEach(() => { + render(); + }); + + it('should render cancellation additional information label', () => { + const cancellationInformationLabel = screen.getByText(labelIds.cancellationAdditionalInformation); + + expect(cancellationInformationLabel).toBeInTheDocument(); + }); + + it('should render cancellation additional information value', () => { + const cancellationInformationValue = screen.getByText(cancellationAdditionalInformation); + + expect(cancellationInformationValue).toBeInTheDocument(); + }); + }); + + describe('When fulfilment preference is delivery', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [{ + ...openRequest, + fulfillmentPreference: fulfillmentTypeMap.DELIVERY, + deliveryAddressTypeId: 'deliveryAddressTypeId', + }], + }, + }, + }; + const deliveryAddressDetail = 'deliveryAddressDetail'; + + beforeEach(() => { + toUserAddress.mockReturnValueOnce(deliveryAddressDetail); + render(); + }); + + it('should render "UserDetail" with delivery information', () => { + const request = props.resources.selectedRequest.records[0]; + const expectedProps = { + deliveryAddress: deliveryAddressDetail, + user:request.requester, + proxy: request.proxy, + selectedDelivery: true, + patronGroups: props.patronGroups, + stripes: props.stripes, + request, + }; + + expect(UserDetail).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + }); + + describe('When fulfilment preference is hold shelf', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [openRequest], + }, + }, + }; + + beforeEach(() => { + render(); + }); + + it('should render "UserDetail" without delivery information', () => { + const request = props.resources.selectedRequest.records[0]; + const expectedProps = { + deliveryAddress: undefined, + user:request.requester, + proxy: request.proxy, + selectedDelivery: false, + patronGroups: props.patronGroups, + stripes: props.stripes, + request, + }; + + expect(UserDetail).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + }); + + describe('Spinner', () => { + const props = { + ...defaultProps, + resources: { + selectedRequest: { + hasLoaded: true, + records: [], + }, + }, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + beforeEach(() => { + render(); + }); + + it('should trigger spinner "Icon" with correct props', () => { + const expectedProps = { + icon: 'spinner-ellipsis', + width: '100px', + }; + + expect(Icon).toHaveBeenCalledWith(expectedProps, {}); + }); + }); + describe('isAnyActionButtonVisible', () => { describe('When visibility conditions are provided', () => { it('should return true', () => { From 039a9eabc4568009ba66c496158b4b7c4ec5abd5 Mon Sep 17 00:00:00 2001 From: Dmitriy-Litvinenko Date: Tue, 17 Dec 2024 17:43:52 +0200 Subject: [PATCH 3/5] UIREQ-1101: React v19: refactor away from default props for functional components (#1251) --- CHANGELOG.md | 1 + src/ItemsDialog.js | 6 +----- .../FulfilmentPreference.js | 15 ++++----------- src/components/PrintContent/PrintContent.js | 6 +----- .../PickupServicePointFilter.js | 9 ++------- .../RequestLevelFilter/RequestLevelFilter.js | 6 +----- src/components/SortableList/SortableList.js | 12 +++--------- .../TitleInformation/TitleInformation.js | 18 +++++------------- 8 files changed, 18 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e13c83..0a399006 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Increase code coverage for src/ChooseRequestTypeDialog.js by Jest/RTL tests. Refs UIREQ-1044. * Cleanup retrieval service point implementation from deprecated folder. Refs UIREQ-1211. * Increase code coverage for src/ViewRequest.js by Jest/RTL tests. Refs UIREQ-1046. +* React v19: refactor away from default props for functional components. Refs UIREQ-1101. ## [11.0.2] (https://github.com/folio-org/ui-requests/tree/v11.0.2) (2024-12-10) [Full Changelog](https://github.com/folio-org/ui-requests/compare/v11.0.1...v11.0.2) diff --git a/src/ItemsDialog.js b/src/ItemsDialog.js index 1dd77754..1ffd64c6 100644 --- a/src/ItemsDialog.js +++ b/src/ItemsDialog.js @@ -79,7 +79,7 @@ const ItemsDialog = ({ onRowClick = noop, mutator, skippedItemId, - title, + title = '', instanceId, }) => { const [areItemsBeingLoaded, setAreItemsBeingLoaded] = useState(false); @@ -233,10 +233,6 @@ ItemsDialog.manifest = { }, }; -ItemsDialog.defaultProps = { - title: '', -}; - ItemsDialog.propTypes = { open: PropTypes.bool.isRequired, onClose: PropTypes.func.isRequired, diff --git a/src/components/FulfilmentPreference/FulfilmentPreference.js b/src/components/FulfilmentPreference/FulfilmentPreference.js index 714d46cb..b2cb978f 100644 --- a/src/components/FulfilmentPreference/FulfilmentPreference.js +++ b/src/components/FulfilmentPreference/FulfilmentPreference.js @@ -26,11 +26,11 @@ const { const FulfilmentPreference = ({ isEditForm, - deliverySelected, - deliveryAddress, + deliverySelected = false, + deliveryAddress = '', onChangeAddress, - deliveryLocations, - fulfillmentTypeOptions, + deliveryLocations = [], + fulfillmentTypeOptions = [], defaultDeliveryAddressTypeId, changeDeliveryAddress, requestTypes, @@ -167,11 +167,4 @@ FulfilmentPreference.propTypes = { deliverySelected: PropTypes.bool, }; -FulfilmentPreference.defaultProps = { - deliveryAddress: '', - deliveryLocations: [], - fulfillmentTypeOptions: [], - deliverySelected: false, -}; - export default FulfilmentPreference; diff --git a/src/components/PrintContent/PrintContent.js b/src/components/PrintContent/PrintContent.js index 565bf9c3..9ff878d7 100644 --- a/src/components/PrintContent/PrintContent.js +++ b/src/components/PrintContent/PrintContent.js @@ -10,7 +10,7 @@ import css from './PrintContent.css'; const PrintContent = forwardRef(({ dataSource, template, - id, + id = 'printContent', }, ref) => { const templateFn = useMemo(() => buildTemplate(template), [template]); @@ -43,8 +43,4 @@ PrintContent.propTypes = { template: PropTypes.string.isRequired, }; -PrintContent.defaultProps = { - id: 'printContent', -}; - export default memo(PrintContent, isEqual); diff --git a/src/components/RequestsFilters/PickupServicePointFilter/PickupServicePointFilter.js b/src/components/RequestsFilters/PickupServicePointFilter/PickupServicePointFilter.js index dfabb668..7362de42 100644 --- a/src/components/RequestsFilters/PickupServicePointFilter/PickupServicePointFilter.js +++ b/src/components/RequestsFilters/PickupServicePointFilter/PickupServicePointFilter.js @@ -19,8 +19,8 @@ import { } from '../../../constants'; const PickupServicePointFilter = ({ - activeValues, - servicePoints, + activeValues = [], + servicePoints = [], onChange, onClear, }) => { @@ -67,9 +67,4 @@ PickupServicePointFilter.propTypes = { onClear: PropTypes.func.isRequired, }; -PickupServicePointFilter.defaultProps = { - activeValues: [], - servicePoints: [], -}; - export default PickupServicePointFilter; diff --git a/src/components/RequestsFilters/RequestLevelFilter/RequestLevelFilter.js b/src/components/RequestsFilters/RequestLevelFilter/RequestLevelFilter.js index 25c6f2b2..9c178dad 100644 --- a/src/components/RequestsFilters/RequestLevelFilter/RequestLevelFilter.js +++ b/src/components/RequestsFilters/RequestLevelFilter/RequestLevelFilter.js @@ -18,7 +18,7 @@ import { } from '../../../constants'; const RequestLevelFilter = ({ - activeValues, + activeValues = [], onChange, onClear, }) => { @@ -63,8 +63,4 @@ RequestLevelFilter.propTypes = { onClear: PropTypes.func.isRequired, }; -RequestLevelFilter.defaultProps = { - activeValues: [], -}; - export default RequestLevelFilter; diff --git a/src/components/SortableList/SortableList.js b/src/components/SortableList/SortableList.js index 6ab59862..cdb51867 100644 --- a/src/components/SortableList/SortableList.js +++ b/src/components/SortableList/SortableList.js @@ -14,10 +14,10 @@ import draggableRowFormatter from './draggableRowFormatter'; export default function SortableList(props) { const { - droppableId, + droppableId = uniqueId('droppable'), onDragEnd, - rowFormatter, - isRowDraggable, + rowFormatter = draggableRowFormatter, + isRowDraggable = () => true, rowProps, visibleColumns: originalVisibleColumns, columnWidths: originalColumnWidths, @@ -73,12 +73,6 @@ export default function SortableList(props) { ); } -SortableList.defaultProps = { - droppableId: uniqueId('droppable'), - rowFormatter: draggableRowFormatter, - isRowDraggable: () => true, -}; - SortableList.propTypes = { droppableId: PropTypes.string, onDragEnd: PropTypes.func, diff --git a/src/components/TitleInformation/TitleInformation.js b/src/components/TitleInformation/TitleInformation.js index fba65c0f..3730b288 100644 --- a/src/components/TitleInformation/TitleInformation.js +++ b/src/components/TitleInformation/TitleInformation.js @@ -33,15 +33,15 @@ export const getIdentifiers = (data, separator, limit) => data.slice(0, limit).m const TitleInformation = (props) => { const { - titleLevelRequestsLink, + titleLevelRequestsLink = true, holdingsRecordId, instanceId, titleLevelRequestsCount, title, - contributors, - publications, - editions, - identifiers, + contributors = [], + publications = [], + editions = [], + identifiers = [], intl:{ formatMessage, }, @@ -95,14 +95,6 @@ const TitleInformation = (props) => { ); }; -TitleInformation.defaultProps = { - contributors: [], - publications: [], - editions: [], - identifiers: [], - titleLevelRequestsLink: true, -}; - TitleInformation.propTypes = { titleLevelRequestsLink: PropTypes.bool, titleLevelRequestsCount: PropTypes.number.isRequired, From dac2d58f312ce2505b88b9cd5ddc865eda2d7df3 Mon Sep 17 00:00:00 2001 From: Priyanka Terala <104053200+Terala-Priyanka@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:57:39 +0530 Subject: [PATCH 4/5] UIREQ-1190 - Add "Retrieval service point" filter (#1244) * UIREQ-1190 - initial commit * UIREQ-1190 - Add "Retrieval service point" filter * fix failed tests * fix test * refine and fix tests * UIREQ-1190 - remove unnecessary mock * UIREQ-1190 - duplicate existing Request filters in deprecated folder so that 'Retrieval service point" filter is not available from deprecated folder path * update translation id * Update src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js Co-authored-by: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com> * move RequestFilters to components and remove unnecessary code from deprecated folder * fix tests * fix test failures and review comments --------- Co-authored-by: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com> --- CHANGELOG.md | 1 + package.json | 2 + .../RequestsFilters/RequestsFilters.js | 9 + .../RequestsFilters/RequestsFilters.test.js | 21 + .../RequestsFilters/RequestsFiltersConfig.js | 6 + .../RequestsFiltersConfig.test.js | 12 + .../RetrievalServicePointFilter.js | 62 +++ .../RetrievalServicePointFilter.test.js | 86 ++++ .../RetrievalServicePointFilter/index.js | 1 + src/constants.js | 4 + .../RequestsFilters/RequestsFilters.js | 172 ++++++++ .../RequestsFilters/RequestsFilters.test.js | 383 ++++++++++++++++++ .../RequestsFilters/RequestsFiltersConfig.js | 59 +++ .../RequestsFiltersConfig.test.js | 144 +++++++ .../components/RequestsFilters/index.js | 2 + .../routes/RequestsRoute/RequestsRoute.js | 2 +- .../RequestsRoute/RequestsRoute.test.js | 2 +- src/hooks/index.js | 1 + src/hooks/useRetrievalServicePoints/index.js | 1 + .../useRetrievalServicePoints.js | 72 ++++ .../useRetrievalServicePoints.test.js | 80 ++++ translations/ui-requests/en.json | 1 + 22 files changed, 1121 insertions(+), 2 deletions(-) create mode 100644 src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.js create mode 100644 src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.test.js create mode 100644 src/components/RequestsFilters/RetrievalServicePointFilter/index.js create mode 100644 src/deprecated/components/RequestsFilters/RequestsFilters.js create mode 100644 src/deprecated/components/RequestsFilters/RequestsFilters.test.js create mode 100644 src/deprecated/components/RequestsFilters/RequestsFiltersConfig.js create mode 100644 src/deprecated/components/RequestsFilters/RequestsFiltersConfig.test.js create mode 100644 src/deprecated/components/RequestsFilters/index.js create mode 100644 src/hooks/index.js create mode 100644 src/hooks/useRetrievalServicePoints/index.js create mode 100644 src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js create mode 100644 src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a399006..aa2ed54f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Cleanup retrieval service point implementation from deprecated folder. Refs UIREQ-1211. * Increase code coverage for src/ViewRequest.js by Jest/RTL tests. Refs UIREQ-1046. * React v19: refactor away from default props for functional components. Refs UIREQ-1101. +* Add "Retrieval service point" filter. Refs UIREQ-1190. ## [11.0.2] (https://github.com/folio-org/ui-requests/tree/v11.0.2) (2024-12-10) [Full Changelog](https://github.com/folio-org/ui-requests/compare/v11.0.1...v11.0.2) diff --git a/package.json b/package.json index a8cb21f3..8aee6514 100644 --- a/package.json +++ b/package.json @@ -197,6 +197,7 @@ "inflected": "^2.0.4", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-query": "^3.39.0", "react-intl": "^6.4.4", "react-router-dom": "^5.2.0", "regenerator-runtime": "^0.13.9" @@ -220,6 +221,7 @@ "@folio/stripes": "^9.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-query": "^3.39.0", "react-intl": "^6.4.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0" diff --git a/src/components/RequestsFilters/RequestsFilters.js b/src/components/RequestsFilters/RequestsFilters.js index 72288f31..b3924df8 100644 --- a/src/components/RequestsFilters/RequestsFilters.js +++ b/src/components/RequestsFilters/RequestsFilters.js @@ -25,6 +25,7 @@ import { } from '../../constants'; import { PickupServicePointFilter } from './PickupServicePointFilter'; +import { RetrievalServicePointFilter } from './RetrievalServicePointFilter'; import { RequestLevelFilter } from './RequestLevelFilter'; export default class RequestsFilters extends React.Component { @@ -35,6 +36,7 @@ export default class RequestsFilters extends React.Component { requestType: PropTypes.arrayOf(PropTypes.string), tags: PropTypes.arrayOf(PropTypes.string), pickupServicePoints: PropTypes.arrayOf(PropTypes.string), + retrievalServicePoints: PropTypes.arrayOf(PropTypes.string), printStatus: PropTypes.arrayOf(PropTypes.string), }).isRequired, resources: PropTypes.object.isRequired, @@ -65,6 +67,7 @@ export default class RequestsFilters extends React.Component { requestType = [], requestStatus = [], pickupServicePoints = [], + retrievalServicePoints = [], requestLevels = [], printStatus = [], }, @@ -146,6 +149,12 @@ export default class RequestsFilters extends React.Component { onChange={onChange} onClear={onClear} /> + {isViewPrintDetailsEnabled && ( ({ jest.mock('./PickupServicePointFilter', () => ({ PickupServicePointFilter: jest.fn((props) => (
)), })); +jest.mock('./RetrievalServicePointFilter', () => ({ + RetrievalServicePointFilter: jest.fn((props) => (
)), +})); jest.mock('@folio/stripes/smart-components', () => ({ CheckboxFilter: jest.fn((props) => (
)), MultiSelectionFilter: jest.fn((props) => (
)), @@ -38,6 +42,7 @@ const props = { requestStatus: ['Open'], requestType: ['Hold'], pickupServicePoints: ['1'], + retrievalServicePoints: ['1', '2'], tags: ['Urgent'], requestLevels: [], printStatus: ['Printed'], @@ -71,6 +76,7 @@ const testIds = { requestLevelFilter: 'requestLevelFilter', multiSelectionFilter: 'multiSelectionFilter', pickupServicePointFilter: 'pickupServicePointFilter', + retrievalServicePointFilter: 'retrievalServicePointFilter', }; const labelIds = { [requestFilterTypes.REQUEST_TYPE]: 'ui-requests.requestMeta.type', @@ -261,6 +267,21 @@ describe('RequestsFilters', () => { }); }); + describe('RetrievalServicePointFilter', () => { + it('should render RetrievalServicePointFilter', () => { + expect(screen.getByTestId(testIds.retrievalServicePointFilter)).toBeInTheDocument(); + }); + + it('should trigger retrievalServicePointFilter with correct props', () => { + expect(RetrievalServicePointFilter).toHaveBeenCalledWith(expect.objectContaining({ + 'data-testid': testIds.retrievalServicePointFilter, + activeValues: props.activeFilters.retrievalServicePoints, + onChange, + onClear, + }), {}); + }); + }); + describe('When activeFilters prop is empty', () => { const propsWithoutFilters = { ...props, diff --git a/src/components/RequestsFilters/RequestsFiltersConfig.js b/src/components/RequestsFilters/RequestsFiltersConfig.js index 8268f7d2..51de3546 100644 --- a/src/components/RequestsFilters/RequestsFiltersConfig.js +++ b/src/components/RequestsFilters/RequestsFiltersConfig.js @@ -43,6 +43,12 @@ export default [ values: [], operator: '==', }, + { + name: requestFilterTypes.RETRIEVAL_SERVICE_POINT, + cql: 'item.retrievalServicePointId', + values: [], + operator: '==', + }, { name: requestFilterTypes.PRINT_STATUS, cql: 'printStatus', diff --git a/src/components/RequestsFilters/RequestsFiltersConfig.test.js b/src/components/RequestsFilters/RequestsFiltersConfig.test.js index b6d13606..ef3b05c0 100644 --- a/src/components/RequestsFilters/RequestsFiltersConfig.test.js +++ b/src/components/RequestsFilters/RequestsFiltersConfig.test.js @@ -81,6 +81,18 @@ describe('RequestsFiltersConfig', () => { expect(pickupServicePointFilter).toEqual(expectedResult); }); + it('should have a filter for retrieval service point', () => { + const retrievalServicePointFilter = filtersConfig.find(f => f.name === requestFilterTypes.RETRIEVAL_SERVICE_POINT); + const expectedResult = { + name: 'retrievalServicePoints', + cql: 'item.retrievalServicePointId', + values: [], + operator: '==', + }; + + expect(retrievalServicePointFilter).toEqual(expectedResult); + }); + describe('Print Status Filter configuration', () => { it('should correctly match the filter configuration for printStatus', () => { const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus'); diff --git a/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.js b/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.js new file mode 100644 index 00000000..7f8ad9ef --- /dev/null +++ b/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.js @@ -0,0 +1,62 @@ +import { useCallback } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { isEmpty } from 'lodash'; +import PropTypes from 'prop-types'; + +import { + Accordion, + FilterAccordionHeader, +} from '@folio/stripes/components'; +import { + MultiSelectionFilter, +} from '@folio/stripes/smart-components'; + +import { + requestFilterTypes, +} from '../../../constants'; + +import { useRetrievalServicePoints } from '../../../hooks'; + +const RetrievalServicePointFilter = ({ + activeValues, + onChange, + onClear, +}) => { + const name = requestFilterTypes.RETRIEVAL_SERVICE_POINT; + const clearFilter = useCallback(() => { + onClear(name); + }, [name, onClear]); + + const { retrievalSPsOptions } = useRetrievalServicePoints(); + + return ( +
+ } + name={name} + separator={false} + onClearFilter={clearFilter} + > + + +
+ ); +}; + +RetrievalServicePointFilter.propTypes = { + activeValues: PropTypes.arrayOf(PropTypes.string), + onChange: PropTypes.func.isRequired, + onClear: PropTypes.func.isRequired, +}; +export default RetrievalServicePointFilter; diff --git a/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.test.js b/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.test.js new file mode 100644 index 00000000..6645e18f --- /dev/null +++ b/src/components/RequestsFilters/RetrievalServicePointFilter/RetrievalServicePointFilter.test.js @@ -0,0 +1,86 @@ +import { + render, + screen, +} from '@folio/jest-config-stripes/testing-library/react'; +import userEvent from '@folio/jest-config-stripes/testing-library/user-event'; + +import { + Accordion, + FilterAccordionHeader, +} from '@folio/stripes/components'; + +import RetrievalServicePointFilter from './RetrievalServicePointFilter'; +import { requestFilterTypes } from '../../../constants'; + +jest.mock('../../../hooks', () => ({ + ...jest.requireActual('../../../hooks'), + useRetrievalServicePoints: jest.fn().mockReturnValue([ + { + value: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f', + label: 'Circ desk 1', + }, + { + value: '9d1b77e8-f02e-4b7f-b296-3f2042ddac54', + label: 'Circ desk 2', + }, + ]), +})); + +const activeValues = ['test', 'test2']; +const onChange = jest.fn(); +const onClear = jest.fn(); +const testIds = { + retrievalServicePointAccordionButton: 'retrievalServicePointAccordionButton', +}; + +describe('RetrievalServicePointFilter', () => { + beforeEach(() => { + onChange.mockClear(); + onClear.mockClear(); + render( + + ); + }); + + it('should render "Accordion" with correct props', () => { + const expectedProps = { + id: requestFilterTypes.RETRIEVAL_SERVICE_POINT, + name: requestFilterTypes.RETRIEVAL_SERVICE_POINT, + header: FilterAccordionHeader, + separator: false, + onClearFilter: expect.any(Function), + }; + + expect(Accordion).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + + it('should render MultiSelectionFilter', () => { + const MultiSelectionFilter = screen.getByText('MultiSelectionFilter'); + + expect(MultiSelectionFilter).toBeInTheDocument(); + }); + + it('should perform onClear event', async () => { + const retrievalServicePointsButton = screen.getByTestId(testIds.retrievalServicePointAccordionButton); + + await userEvent.click(retrievalServicePointsButton); + + expect(onClear).toHaveBeenCalledWith(requestFilterTypes.RETRIEVAL_SERVICE_POINT); + }); + + describe('MultiSelectionFilter activeValues', () => { + activeValues.forEach(value => { + it(`should render "${value}"`, () => { + const activeValue = screen.getByText(value, { + exact: false, + }); + + expect(activeValue).toBeInTheDocument(); + }); + }); + }); +}); diff --git a/src/components/RequestsFilters/RetrievalServicePointFilter/index.js b/src/components/RequestsFilters/RetrievalServicePointFilter/index.js new file mode 100644 index 00000000..c397fd61 --- /dev/null +++ b/src/components/RequestsFilters/RetrievalServicePointFilter/index.js @@ -0,0 +1 @@ +export { default as RetrievalServicePointFilter } from './RetrievalServicePointFilter'; diff --git a/src/constants.js b/src/constants.js index 225b174b..de534664 100644 --- a/src/constants.js +++ b/src/constants.js @@ -240,6 +240,7 @@ export const requestFilterTypes = { REQUEST_STATUS: 'requestStatus', REQUEST_LEVELS: 'requestLevels', PICKUP_SERVICE_POINT: 'pickupServicePoints', + RETRIEVAL_SERVICE_POINT: 'retrievalServicePoints', PRINT_STATUS: 'printStatus', }; @@ -429,3 +430,6 @@ export const SETTINGS_SCOPES = { export const SETTINGS_KEYS = { GENERAL_TLR: 'generalTlr', }; + +export const LOCATIONS_API = 'locations'; +export const SERVICE_POINTS_API = 'service-points'; diff --git a/src/deprecated/components/RequestsFilters/RequestsFilters.js b/src/deprecated/components/RequestsFilters/RequestsFilters.js new file mode 100644 index 00000000..2a2cb682 --- /dev/null +++ b/src/deprecated/components/RequestsFilters/RequestsFilters.js @@ -0,0 +1,172 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import { + get, + isEmpty, + sortBy, +} from 'lodash'; + +import { + Accordion, + AccordionSet, + FilterAccordionHeader, +} from '@folio/stripes/components'; +import { + CheckboxFilter, + MultiSelectionFilter, +} from '@folio/stripes/smart-components'; + +import { + requestFilterTypes, + requestPrintStatusFilters, + requestStatusFilters, + requestTypeFilters, +} from '../../../constants'; + +import { PickupServicePointFilter } from '../../../components/RequestsFilters/PickupServicePointFilter'; +import { RequestLevelFilter } from '../../../components/RequestsFilters/RequestLevelFilter'; + +export default class RequestsFilters extends React.Component { + static propTypes = { + activeFilters: PropTypes.shape({ + requestStatus: PropTypes.arrayOf(PropTypes.string), + requestLevels: PropTypes.arrayOf(PropTypes.string), + requestType: PropTypes.arrayOf(PropTypes.string), + tags: PropTypes.arrayOf(PropTypes.string), + pickupServicePoints: PropTypes.arrayOf(PropTypes.string), + printStatus: PropTypes.arrayOf(PropTypes.string), + }).isRequired, + resources: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, + onClear: PropTypes.func.isRequired, + titleLevelRequestsFeatureEnabled: PropTypes.bool.isRequired, + isViewPrintDetailsEnabled: PropTypes.bool.isRequired, + }; + + transformRequestFilterOptions = (source = []) => { + return source.map(({ label, value }) => ({ + label: , + value, + })); + }; + + transformTagsOptions = () => { + const tags = get(this.props.resources, 'tags.records', []) + .map(({ label }) => ({ label, value: label })); + + return sortBy(tags, 'label'); + }; + + render() { + const { + activeFilters: { + tags = [], + requestType = [], + requestStatus = [], + pickupServicePoints = [], + requestLevels = [], + printStatus = [], + }, + onChange, + onClear, + titleLevelRequestsFeatureEnabled, + isViewPrintDetailsEnabled, + } = this.props; + + return ( + + } + name={requestFilterTypes.REQUEST_TYPE} + separator={false} + onClearFilter={() => onClear(requestFilterTypes.REQUEST_TYPE)} + > + + + } + name={requestFilterTypes.REQUEST_STATUS} + separator={false} + onClearFilter={() => onClear(requestFilterTypes.REQUEST_STATUS)} + > + + + {titleLevelRequestsFeatureEnabled && ( + + )} + } + name={requestFilterTypes.TAGS} + separator={false} + onClearFilter={() => onClear(requestFilterTypes.TAGS)} + > + + + + {isViewPrintDetailsEnabled && ( + } + name={requestFilterTypes.PRINT_STATUS} + separator={false} + onClearFilter={() => onClear(requestFilterTypes.PRINT_STATUS)} + > + + + )} + + ); + } +} diff --git a/src/deprecated/components/RequestsFilters/RequestsFilters.test.js b/src/deprecated/components/RequestsFilters/RequestsFilters.test.js new file mode 100644 index 00000000..58b0f8c9 --- /dev/null +++ b/src/deprecated/components/RequestsFilters/RequestsFilters.test.js @@ -0,0 +1,383 @@ +import { + render, + screen, +} from '@folio/jest-config-stripes/testing-library/react'; +import userEvent from '@folio/jest-config-stripes/testing-library/user-event'; + +import { + Accordion, +} from '@folio/stripes/components'; +import { + CheckboxFilter, + MultiSelectionFilter, +} from '@folio/stripes/smart-components'; + +import RequestsFilters from './RequestsFilters'; +import { RequestLevelFilter } from '../../../components/RequestsFilters/RequestLevelFilter'; +import { PickupServicePointFilter } from '../../../components/RequestsFilters/PickupServicePointFilter'; + +import { + requestFilterTypes, +} from '../../../constants'; + +jest.mock('../../../components/RequestsFilters/RequestLevelFilter', () => ({ + RequestLevelFilter: jest.fn((props) => (
)), +})); +jest.mock('../../../components/RequestsFilters/PickupServicePointFilter', () => ({ + PickupServicePointFilter: jest.fn((props) => (
)), +})); +jest.mock('@folio/stripes/smart-components', () => ({ + CheckboxFilter: jest.fn((props) => (
)), + MultiSelectionFilter: jest.fn((props) => (
)), +})); + +const onChange = jest.fn(); +const onClear = jest.fn(); +const props = { + activeFilters: { + requestStatus: ['Open'], + requestType: ['Hold'], + pickupServicePoints: ['1'], + tags: ['Urgent'], + requestLevels: [], + printStatus: ['Printed'], + }, + onChange, + onClear, + resources: { + servicePoints: { + records: [{ + id: '1', + name: 'Service Point 1', + }], + }, + tags: { + records: [{ + label: 'Urgent', + }], + }, + }, + titleLevelRequestsFeatureEnabled: false, + isViewPrintDetailsEnabled: false, +}; +const testIds = { + [requestFilterTypes.REQUEST_TYPE]: requestFilterTypes.REQUEST_TYPE, + [`${requestFilterTypes.REQUEST_TYPE}Filter`]: `${requestFilterTypes.REQUEST_TYPE}Filter`, + [requestFilterTypes.REQUEST_STATUS]: requestFilterTypes.REQUEST_STATUS, + [`${requestFilterTypes.REQUEST_STATUS}Filter`]: `${requestFilterTypes.REQUEST_STATUS}Filter`, + [requestFilterTypes.TAGS]: requestFilterTypes.TAGS, + [requestFilterTypes.PRINT_STATUS]: requestFilterTypes.PRINT_STATUS, + [`${requestFilterTypes.PRINT_STATUS}Filter`]: `${requestFilterTypes.PRINT_STATUS}Filter`, + requestLevelFilter: 'requestLevelFilter', + multiSelectionFilter: 'multiSelectionFilter', + pickupServicePointFilter: 'pickupServicePointFilter', +}; +const labelIds = { + [requestFilterTypes.REQUEST_TYPE]: 'ui-requests.requestMeta.type', + [requestFilterTypes.REQUEST_STATUS]: 'ui-requests.requestMeta.status', + [requestFilterTypes.TAGS]: 'ui-requests.requestMeta.tags', + [requestFilterTypes.PRINT_STATUS]: 'ui-requests.requestMeta.printStatus', +}; + +describe('RequestsFilters', () => { + beforeEach(() => { + render(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Request type accordion', () => { + it('should render request type accordion', () => { + expect(screen.getByTestId(testIds[requestFilterTypes.REQUEST_TYPE])).toBeInTheDocument(); + }); + + it('should render label for request type accordion', () => { + expect(screen.getByText(labelIds[requestFilterTypes.REQUEST_TYPE])).toBeInTheDocument(); + }); + + it('should trigger request type accordion with correct props', () => { + expect(Accordion).toHaveBeenNthCalledWith(1, expect.objectContaining({ + displayClearButton: true, + id: requestFilterTypes.REQUEST_TYPE, + 'data-testid': requestFilterTypes.REQUEST_TYPE, + name: requestFilterTypes.REQUEST_TYPE, + onClearFilter: expect.any(Function), + header: expect.any(Function), + separator: false, + }), {}); + }); + + it('should be called onClearFilter with request filter types Request type', async () => { + await userEvent.click(screen.getByTestId(`${testIds[requestFilterTypes.REQUEST_TYPE]}Button`)); + + expect(onClear).toHaveBeenCalledWith(requestFilterTypes.REQUEST_TYPE); + }); + + it('should render CheckboxFilter for Request type accordion', () => { + expect(screen.getByTestId(testIds[`${requestFilterTypes.REQUEST_TYPE}Filter`])).toBeInTheDocument(); + }); + + it('should trigger CheckboxFilter for Request type accordion with correct props', () => { + expect(CheckboxFilter).toHaveBeenNthCalledWith(1, expect.objectContaining({ + 'data-testid': testIds[`${requestFilterTypes.REQUEST_TYPE}Filter`], + name: requestFilterTypes.REQUEST_TYPE, + selectedValues: props.activeFilters[requestFilterTypes.REQUEST_TYPE], + onChange, + }), {}); + }); + }); + + describe('Request status accordion', () => { + it('should render request status accordion', () => { + expect(screen.getByTestId(testIds[requestFilterTypes.REQUEST_STATUS])).toBeInTheDocument(); + }); + + it('should render label for request status accordion', () => { + expect(screen.getByText(labelIds[requestFilterTypes.REQUEST_STATUS])).toBeInTheDocument(); + }); + + it('should trigger request status accordion with correct props', () => { + expect(Accordion).toHaveBeenNthCalledWith(2, expect.objectContaining({ + displayClearButton: true, + id: requestFilterTypes.REQUEST_STATUS, + 'data-testid': requestFilterTypes.REQUEST_STATUS, + name: requestFilterTypes.REQUEST_STATUS, + onClearFilter: expect.any(Function), + header: expect.any(Function), + separator: false, + }), {}); + }); + + it('should be called onClearFilter with request filter types Request status', async () => { + await userEvent.click(screen.getByTestId(`${testIds[requestFilterTypes.REQUEST_STATUS]}Button`)); + + expect(onClear).toHaveBeenCalledWith(requestFilterTypes.REQUEST_STATUS); + }); + + it('should render CheckboxFilter for Request status accordion', () => { + expect(screen.getByTestId(testIds[`${requestFilterTypes.REQUEST_STATUS}Filter`])).toBeInTheDocument(); + }); + + it('should trigger CheckboxFilter for Request status accordion with correct props', () => { + expect(CheckboxFilter).toHaveBeenNthCalledWith(1, expect.objectContaining({ + 'data-testid': testIds[`${requestFilterTypes.REQUEST_TYPE}Filter`], + name: requestFilterTypes.REQUEST_TYPE, + selectedValues: props.activeFilters[requestFilterTypes.REQUEST_TYPE], + onChange, + }), {}); + }); + }); + + describe('Tags accordion', () => { + it('should render tags accordion', () => { + expect(screen.getByTestId(testIds[requestFilterTypes.TAGS])).toBeInTheDocument(); + }); + + it('should render label for tags accordion', () => { + expect(screen.getByText(labelIds[requestFilterTypes.TAGS])).toBeInTheDocument(); + }); + + it('should trigger tags accordion with correct props', () => { + expect(Accordion).toHaveBeenNthCalledWith(3, expect.objectContaining({ + displayClearButton: true, + id: requestFilterTypes.TAGS, + 'data-testid': requestFilterTypes.TAGS, + name: requestFilterTypes.TAGS, + onClearFilter: expect.any(Function), + header: expect.any(Function), + separator: false, + }), {}); + }); + + it('should be called onClearFilter with request filter types tags', async () => { + await userEvent.click(screen.getByTestId(`${testIds[requestFilterTypes.TAGS]}Button`)); + + expect(onClear).toHaveBeenCalledWith(requestFilterTypes.TAGS); + }); + + it('should render MultiSelectionFilter for tags accordion', () => { + expect(screen.getByTestId(testIds.multiSelectionFilter)).toBeInTheDocument(); + }); + + it('should trigger MultiSelectionFilter for Tags accordion with correct props', () => { + expect(MultiSelectionFilter).toHaveBeenCalledWith(expect.objectContaining({ + 'data-testid': testIds.multiSelectionFilter, + dataOptions: [{ + label: 'Urgent', + value: 'Urgent', + }], + name: requestFilterTypes.TAGS, + selectedValues: props.activeFilters.tags, + onChange, + ariaLabelledBy: requestFilterTypes.TAGS, + }), {}); + }); + }); + + describe('RequestLevelFilter', () => { + it('should not render RequestLevelFilter', () => { + expect(screen.queryByTestId(testIds.requestLevelFilter)).not.toBeInTheDocument(); + }); + + describe('with titleLevelRequestsFeatureEnabled true', () => { + const currentProps = { + ...props, + titleLevelRequestsFeatureEnabled: true, + }; + beforeEach(() => { + render(); + }); + + it('should render RequestLevelFilter', () => { + expect(screen.getByTestId(testIds.requestLevelFilter)).toBeInTheDocument(); + }); + + it('should trigger RequestLevelFilter with correct props', () => { + expect(RequestLevelFilter).toHaveBeenCalledWith(expect.objectContaining({ + 'data-testid': testIds.requestLevelFilter, + activeValues: props.activeFilters.requestLevels, + onChange, + onClear, + }), {}); + }); + }); + }); + + describe('PickupServicePointFilter', () => { + it('should render PickupServicePointFilter', () => { + expect(screen.getByTestId(testIds.pickupServicePointFilter)).toBeInTheDocument(); + }); + + it('should trigger PickupServicePointFilter with correct props', () => { + expect(PickupServicePointFilter).toHaveBeenCalledWith(expect.objectContaining({ + 'data-testid': testIds.pickupServicePointFilter, + activeValues: props.activeFilters.pickupServicePoints, + servicePoints: props.resources.servicePoints.records, + onChange, + onClear, + }), {}); + }); + }); + + describe('When activeFilters prop is empty', () => { + const propsWithoutFilters = { + ...props, + activeFilters: {}, + titleLevelRequestsFeatureEnabled: true, + }; + const checkboxFilterCallOrder = { + requestTypeCheckbox: 1, + requestStatusCheckbox: 2, + }; + + beforeEach(() => { + jest.clearAllMocks(); + + render( + + ); + }); + + it('should trigger tags filter with correct selectedValues prop', () => { + const expectedProps = { + selectedValues: [], + }; + + expect(MultiSelectionFilter).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + + it('should trigger request type filter with correct selectedValues prop', () => { + const expectedProps = { + selectedValues: [], + }; + + expect(CheckboxFilter).toHaveBeenNthCalledWith(checkboxFilterCallOrder.requestTypeCheckbox, expect.objectContaining(expectedProps), {}); + }); + + it('should trigger request status filter with correct selectedValues prop', () => { + const expectedProps = { + selectedValues: [], + }; + + expect(CheckboxFilter).toHaveBeenNthCalledWith(checkboxFilterCallOrder.requestStatusCheckbox, expect.objectContaining(expectedProps), {}); + }); + + it('should trigger pickup service point filter with correct activeValues prop', () => { + const expectedProps = { + activeValues: [], + }; + + expect(PickupServicePointFilter).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + + it('should trigger request level filter with correct activeValues prop', () => { + const expectedProps = { + activeValues: [], + }; + + expect(RequestLevelFilter).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {}); + }); + }); + + describe('Print status accordion', () => { + describe('when isViewPrintDetailsEnabled is disabled', () => { + it('should not render Print status accordion', () => { + expect(screen.queryByTestId(testIds[requestFilterTypes.PRINT_STATUS])).not.toBeInTheDocument(); + }); + }); + + describe('when isViewPrintDetailsEnabled is enabled', () => { + const currentProps = { + ...props, + isViewPrintDetailsEnabled: true, + }; + beforeEach(() => { + jest.clearAllMocks(); + render(); + }); + + it('should render Print status accordion', () => { + expect(screen.getByTestId(testIds[requestFilterTypes.PRINT_STATUS])).toBeInTheDocument(); + }); + + it('should render label for Print status accordion', () => { + expect(screen.getByText(labelIds[requestFilterTypes.PRINT_STATUS])).toBeInTheDocument(); + }); + + it('should trigger Print status accordion with correct props', () => { + expect(Accordion).toHaveBeenNthCalledWith(4, expect.objectContaining({ + displayClearButton: true, + id: requestFilterTypes.PRINT_STATUS, + 'data-testid': requestFilterTypes.PRINT_STATUS, + name: requestFilterTypes.PRINT_STATUS, + onClearFilter: expect.any(Function), + header: expect.any(Function), + separator: false, + }), {}); + }); + + it('should be called onClearFilter with request filter types Print status', async () => { + await userEvent.click(screen.getByTestId(`${testIds[requestFilterTypes.PRINT_STATUS]}Button`)); + + expect(onClear).toHaveBeenCalledWith(requestFilterTypes.PRINT_STATUS); + }); + + it('should render CheckboxFilter for Print status accordion', () => { + expect(screen.getByTestId(testIds[`${requestFilterTypes.PRINT_STATUS}Filter`])).toBeInTheDocument(); + }); + + it('should trigger CheckboxFilter for Print status accordion with correct props', () => { + expect(CheckboxFilter).toHaveBeenNthCalledWith(3, expect.objectContaining({ + 'data-testid': testIds[`${requestFilterTypes.PRINT_STATUS}Filter`], + name: requestFilterTypes.PRINT_STATUS, + selectedValues: props.activeFilters[requestFilterTypes.PRINT_STATUS], + onChange, + }), {}); + }); + }); + }); +}); diff --git a/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.js b/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.js new file mode 100644 index 00000000..56108183 --- /dev/null +++ b/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.js @@ -0,0 +1,59 @@ +import { requestFilterTypes } from '../../../constants'; + +export const escapingForSpecialCharactersWhichCanBreakCQL = (string = '') => string.replace(/[\\"?*]/g, '\\$&'); + +export default [ + { + name: 'requestType', + cql: 'requestType', + values: [], + operator: '==', + }, + { + label: 'ui-requests.requestMeta.status', + name: 'requestStatus', + cql: 'status', + values: [], + operator: '==', + }, + { + name: requestFilterTypes.REQUEST_LEVELS, + cql: 'requestLevel', + values: [], + operator: '==', + }, + { + name: 'tags', + cql: 'tags.tagList', + values: [], + operator: '==', + parse: (value) => { + if (Array.isArray(value)) { + return `(tags.tagList==(${value.map(v => `"*\\"*${escapingForSpecialCharactersWhichCanBreakCQL(v)}*\\"*"`).join(' or ')}))`; + } else { + return `(tags.tagList==("*\\"*${escapingForSpecialCharactersWhichCanBreakCQL(value)}*\\"*"))`; + } + } + }, + { + name: requestFilterTypes.PICKUP_SERVICE_POINT, + cql: 'pickupServicePointId', + values: [], + operator: '==', + }, + { + name: requestFilterTypes.PRINT_STATUS, + cql: 'printStatus', + values: [], + operator: '==', + parse: (value) => { + if (value.length === 1 && value.includes('Printed')) { + return 'printDetails.isPrinted==true'; + } else if (value.length === 1 && value.includes('Not printed')) { + return 'cql.allRecords=1 NOT printDetails.isPrinted=""'; + } else { + return '(cql.allRecords=1 NOT printDetails.printed="" or printDetails.printed==true)'; + } + } + }, +]; diff --git a/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.test.js b/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.test.js new file mode 100644 index 00000000..503dd2ef --- /dev/null +++ b/src/deprecated/components/RequestsFilters/RequestsFiltersConfig.test.js @@ -0,0 +1,144 @@ +import filtersConfig, { + escapingForSpecialCharactersWhichCanBreakCQL, +} from './RequestsFiltersConfig'; + +import { + requestFilterTypes, +} from '../../../constants'; + +describe('RequestsFiltersConfig', () => { + it('should have a filter for requestType', () => { + const requestTypeFilter = filtersConfig.find(f => f.name === 'requestType'); + const expectedResult = { + name: 'requestType', + cql: 'requestType', + values: [], + operator: '==', + }; + + expect(requestTypeFilter).toEqual(expectedResult); + }); + + it('should have a filter for requestStatus', () => { + const requestStatusFilter = filtersConfig.find(f => f.name === 'requestStatus'); + const expectedResult = { + name: 'requestStatus', + cql: 'status', + values: [], + operator: '==', + label: 'ui-requests.requestMeta.status', + }; + + expect(requestStatusFilter).toEqual(expectedResult); + }); + + it('should have a filter for request levels', () => { + const requestLevelsFilter = filtersConfig.find(f => f.name === requestFilterTypes.REQUEST_LEVELS); + const expectedResult = { + name: 'requestLevels', + cql: 'requestLevel', + values: [], + operator: '==', + }; + + expect(requestLevelsFilter).toEqual(expectedResult); + }); + + it('should return the expected query string for a single tag', () => { + const tagsFilter = filtersConfig.find(f => f.name === 'tags'); + const expectedResult = { + name: 'tags', + cql: 'tags.tagList', + values: [], + operator: '==', + parse: expect.any(Function), + }; + + expect(tagsFilter).toEqual(expectedResult); + }); + + it('should return the expected query string for a single tag', () => { + const tagsFilter = filtersConfig.find(f => f.name === 'tags'); + + expect(tagsFilter.parse('tag1')).toEqual('(tags.tagList==("*\\"*tag1*\\"*"))'); + }); + + it('should return the expected query string for an array of tags', () => { + const tagsFilter = filtersConfig.find(f => f.name === 'tags'); + + expect(tagsFilter.parse(['tag1', 'tag2'])).toEqual('(tags.tagList==("*\\"*tag1*\\"*" or "*\\"*tag2*\\"*"))'); + }); + + it('should have a filter for pickup service point', () => { + const pickupServicePointFilter = filtersConfig.find(f => f.name === requestFilterTypes.PICKUP_SERVICE_POINT); + const expectedResult = { + name: 'pickupServicePoints', + cql: 'pickupServicePointId', + values: [], + operator: '==', + }; + + expect(pickupServicePointFilter).toEqual(expectedResult); + }); + + describe('Print Status Filter configuration', () => { + it('should correctly match the filter configuration for printStatus', () => { + const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus'); + const expectedResult = { + name: 'printStatus', + cql: 'printStatus', + values: [], + operator: '==', + parse: expect.any(Function), + }; + + expect(printStatusFilter).toEqual(expectedResult); + }); + + it('should generate the correct query string for the "Printed" filter', () => { + const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus'); + + expect(printStatusFilter.parse(['Printed'])).toEqual('printDetails.isPrinted==true'); + }); + + it('should generate the correct query string for the "Not printed" filter', () => { + const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus'); + + expect(printStatusFilter.parse(['Not printed'])).toEqual('cql.allRecords=1 NOT printDetails.isPrinted=""'); + }); + + it('should generate the correct query string for a combination of "Printed" and "Not printed" filters', () => { + const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus'); + + expect(printStatusFilter.parse(['Printed', 'Not printed'])) + .toEqual('(cql.allRecords=1 NOT printDetails.printed="" or printDetails.printed==true)'); + }); + }); + + describe('escapingForSpecialCharactersWhichCanBreakCQL', () => { + it('should return empty string', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL()).toBe(''); + }); + + it('should escape \\', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL('\\')).toBe('\\\\'); + }); + + it('should escape "', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL('"')).toBe('\\"'); + }); + + it('should escape ?', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL('?')).toBe('\\?'); + }); + + it('should escape *', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL('*')).toBe('\\*'); + }); + + it('should escape special characters in string', () => { + expect(escapingForSpecialCharactersWhichCanBreakCQL('(test") + [test] * ? \\ (){}[]-_=+<>/?.,~')) + .toBe('(test\\") + [test] \\* \\? \\\\ (){}[]-_=+<>/\\?.,~'); + }); + }); +}); diff --git a/src/deprecated/components/RequestsFilters/index.js b/src/deprecated/components/RequestsFilters/index.js new file mode 100644 index 00000000..1ec650c6 --- /dev/null +++ b/src/deprecated/components/RequestsFilters/index.js @@ -0,0 +1,2 @@ +export { default as RequestsFilters } from './RequestsFilters'; +export { default as RequestsFiltersConfig } from './RequestsFiltersConfig'; diff --git a/src/deprecated/routes/RequestsRoute/RequestsRoute.js b/src/deprecated/routes/RequestsRoute/RequestsRoute.js index 8f25e6f3..f53829f9 100644 --- a/src/deprecated/routes/RequestsRoute/RequestsRoute.js +++ b/src/deprecated/routes/RequestsRoute/RequestsRoute.js @@ -94,7 +94,7 @@ import { import { RequestsFilters, RequestsFiltersConfig, -} from '../../../components/RequestsFilters'; +} from '../../components/RequestsFilters'; import RequestsRouteShortcutsWrapper from '../../../components/RequestsRouteShortcutsWrapper'; import { isReorderableRequest, diff --git a/src/deprecated/routes/RequestsRoute/RequestsRoute.test.js b/src/deprecated/routes/RequestsRoute/RequestsRoute.test.js index 76fb1d64..51834545 100644 --- a/src/deprecated/routes/RequestsRoute/RequestsRoute.test.js +++ b/src/deprecated/routes/RequestsRoute/RequestsRoute.test.js @@ -155,7 +155,7 @@ jest.mock('../../../components', () => ({ }), PrintContent: jest.fn(({ printContentTestId }) =>
PrintContent
) })); -jest.mock('../../../components/RequestsFilters/RequestsFilters', () => ({ onClear }) => { +jest.mock('../../components/RequestsFilters/RequestsFilters', () => ({ onClear }) => { return (
RequestsFilter diff --git a/src/hooks/index.js b/src/hooks/index.js new file mode 100644 index 00000000..7df9cbd4 --- /dev/null +++ b/src/hooks/index.js @@ -0,0 +1 @@ +export { useRetrievalServicePoints } from './useRetrievalServicePoints'; diff --git a/src/hooks/useRetrievalServicePoints/index.js b/src/hooks/useRetrievalServicePoints/index.js new file mode 100644 index 00000000..7532d2aa --- /dev/null +++ b/src/hooks/useRetrievalServicePoints/index.js @@ -0,0 +1 @@ +export { default as useRetrievalServicePoints } from './useRetrievalServicePoints'; diff --git a/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js b/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js new file mode 100644 index 00000000..822f476f --- /dev/null +++ b/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js @@ -0,0 +1,72 @@ +import { useQuery } from 'react-query'; + +import { + useNamespace, + useOkapiKy, + useStripes, +} from '@folio/stripes/core'; + +import { LOCATIONS_API, SERVICE_POINTS_API } from '../../constants'; + +const DEFAULT_DATA = []; +const MAX_RECORDS = 1000; + +const useRetrievalServicePoints = (params = {}, options = {}) => { + const stripes = useStripes(); + const [namespace] = useNamespace('locations'); + const { + limit = stripes?.config?.maxUnpagedResourceCount || MAX_RECORDS, + query = 'cql.allRecords=1', + } = params; + const { + enabled = true, + tenantId, + } = options; + const ky = useOkapiKy({ tenant: tenantId }); + const searchParams = { limit, query }; + + const { + data, + isFetched, + isFetching, + isLoading, + } = useQuery( + [namespace], + async ({ signal }) => { + const servicePointsData = await ky.get(SERVICE_POINTS_API, { searchParams }) + .json() + .then(({ servicepoints }) => servicepoints); + + const locationsData = await ky.get(LOCATIONS_API, { searchParams, signal }) + .json() + .then(({ locations }) => locations); + + const retrievalSPs = new Set(); + + // primary SP of item's effective location is a retrieval service point + // collect the primary service point of each location of a tenant. + // prepare the options for retrieval service points filter + locationsData.forEach(location => { + if (location.primaryServicePoint) retrievalSPs.add(location.primaryServicePoint); + }); + + const retrievalSPsOptions = servicePointsData + .filter(sp => retrievalSPs.has(sp.id)) + .map(sp => ({ label: sp.name, value: sp.id })); + + return retrievalSPsOptions; + }, + enabled, + ); + + const retrievalSPsOptions = data?.length ? data : DEFAULT_DATA; + + return { + isFetched, + isFetching, + isLoading, + retrievalSPsOptions + }; +}; + +export default useRetrievalServicePoints; diff --git a/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.test.js b/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.test.js new file mode 100644 index 00000000..ffb1d322 --- /dev/null +++ b/src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.test.js @@ -0,0 +1,80 @@ +import { + QueryClient, + QueryClientProvider, +} from 'react-query'; + +import { + renderHook, + waitFor, +} from '@folio/jest-config-stripes/testing-library/react'; + +import { useOkapiKy } from '@folio/stripes/core'; + +import useRetrievalServicePoints from './useRetrievalServicePoints'; +import { LOCATIONS_API, SERVICE_POINTS_API } from '../../constants'; + +const mockTenantId = 'tenantId'; + +jest.mock('@folio/stripes/core', () => ({ + ...jest.requireActual('@folio/stripes/core'), + useNamespace: jest.fn(() => ['test']), + useOkapiKy: jest.fn(), + useStripes: jest.fn(() => ({ + okapi: { + tenant: mockTenantId, + }, + })), +})); + +const queryClient = new QueryClient(); +const wrapper = ({ children }) => ( + + {children} + +); + +const retrievalSPsOptions = [ + { + value: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f', + label: 'Circ desk 1', + }, + { + value: '9d1b77e8-f02e-4b7f-b296-3f2042ddac54', + label: 'Circ desk 2', + }, +]; + +const kyResponseMap = { + [LOCATIONS_API]: { locations: [ + { id: '1', primaryServicePoint: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f' }, + { id: '2', primaryServicePoint: '9d1b77e8-f02e-4b7f-b296-3f2042ddac54' }, + ] }, + [SERVICE_POINTS_API]: { servicepoints: [ + { id: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f', name: 'Circ desk 1' }, + { id: '9d1b77e8-f02e-4b7f-b296-3f2042ddac54', name: 'Circ desk 2' }, + { id: '1', name: 'Circ desk 3' }, + { id: '2', name: 'Circ desk 4' }, + ] }, +}; + +describe('useRetrievalServicePoints', () => { + const mockUseOkapiKyValue = { + get: jest.fn((path) => ({ + json: () => Promise.resolve(kyResponseMap[path]), + })), + }; + const mockUseOkapiKy = useOkapiKy; + + beforeEach(() => { + mockUseOkapiKy.mockClear(); + mockUseOkapiKyValue.get.mockClear(); + mockUseOkapiKy.mockReturnValue(mockUseOkapiKyValue); + }); + + it('should fetch retrieval service points', async () => { + const { result } = renderHook(() => useRetrievalServicePoints(), { wrapper }); + await waitFor(() => expect(result.current.isLoading).toBe(false)); + + expect(result.current.retrievalSPsOptions).toEqual(retrievalSPsOptions); + }); +}); diff --git a/translations/ui-requests/en.json b/translations/ui-requests/en.json index 19923c7a..67aaa56c 100644 --- a/translations/ui-requests/en.json +++ b/translations/ui-requests/en.json @@ -198,6 +198,7 @@ "deliveryAddress": "Delivery address", "requester.pickupLocation": "Pickup location", "pickupServicePoint.name": "Pickup service point", + "retrievalServicePoint.name": "Retrieval service point", "requester.patronGroup.group": "Requester patron group", "tags.tagList": "Tags", "printDetails.printCount": "# Copies", From c58915b6c4d870b060cd6e3271d08415f451ea24 Mon Sep 17 00:00:00 2001 From: FOLIO Translations Bot <38661258+folio-translations@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:53:51 -0500 Subject: [PATCH 5/5] Update translation strings --- translations/ui-requests/ar.json | 3 ++- translations/ui-requests/ber.json | 3 ++- translations/ui-requests/ca.json | 3 ++- translations/ui-requests/cs_CZ.json | 3 ++- translations/ui-requests/da.json | 3 ++- translations/ui-requests/de.json | 3 ++- translations/ui-requests/en_GB.json | 3 ++- translations/ui-requests/en_SE.json | 3 ++- translations/ui-requests/en_US.json | 3 ++- translations/ui-requests/es.json | 3 ++- translations/ui-requests/es_419.json | 3 ++- translations/ui-requests/es_ES.json | 3 ++- translations/ui-requests/fr.json | 3 ++- translations/ui-requests/fr_FR.json | 3 ++- translations/ui-requests/he.json | 3 ++- translations/ui-requests/hi_IN.json | 3 ++- translations/ui-requests/hu.json | 3 ++- translations/ui-requests/it_IT.json | 3 ++- translations/ui-requests/ja.json | 3 ++- translations/ui-requests/ko.json | 3 ++- translations/ui-requests/nb.json | 3 ++- translations/ui-requests/nl.json | 3 ++- translations/ui-requests/nn.json | 3 ++- translations/ui-requests/pl.json | 3 ++- translations/ui-requests/pt_BR.json | 3 ++- translations/ui-requests/pt_PT.json | 3 ++- translations/ui-requests/ru.json | 3 ++- translations/ui-requests/sk.json | 3 ++- translations/ui-requests/sv.json | 3 ++- translations/ui-requests/ur.json | 3 ++- translations/ui-requests/zh_CN.json | 3 ++- translations/ui-requests/zh_TW.json | 3 ++- 32 files changed, 64 insertions(+), 32 deletions(-) diff --git a/translations/ui-requests/ar.json b/translations/ui-requests/ar.json index 8b10c742..7bc25f44 100644 --- a/translations/ui-requests/ar.json +++ b/translations/ui-requests/ar.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ber.json b/translations/ui-requests/ber.json index 9dcf98ab..96988853 100644 --- a/translations/ui-requests/ber.json +++ b/translations/ui-requests/ber.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ca.json b/translations/ui-requests/ca.json index fd2e1ad0..8b745e68 100644 --- a/translations/ui-requests/ca.json +++ b/translations/ui-requests/ca.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/cs_CZ.json b/translations/ui-requests/cs_CZ.json index b7ea2af0..10d998aa 100644 --- a/translations/ui-requests/cs_CZ.json +++ b/translations/ui-requests/cs_CZ.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Kopie", "permission.moveRequest.execute": "Požadavky: Přejít na novou jednotku, změnit pořadí fronty", "permission.reorderQueue.execute": "Žádanky: Změna pořadí ve frontě", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/da.json b/translations/ui-requests/da.json index a64f635e..4279450e 100644 --- a/translations/ui-requests/da.json +++ b/translations/ui-requests/da.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/de.json b/translations/ui-requests/de.json index fe7df577..bb59f9d8 100644 --- a/translations/ui-requests/de.json +++ b/translations/ui-requests/de.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Exemplare", "permission.moveRequest.execute": "Bestandsanfragen: Verschieben zu neuem Exemplar, Warteliste neu anordnen", "permission.reorderQueue.execute": "Bestandsanfragen: Warteliste neu anordnen", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_GB.json b/translations/ui-requests/en_GB.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/en_GB.json +++ b/translations/ui-requests/en_GB.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_SE.json b/translations/ui-requests/en_SE.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/en_SE.json +++ b/translations/ui-requests/en_SE.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/en_US.json b/translations/ui-requests/en_US.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/en_US.json +++ b/translations/ui-requests/en_US.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es.json b/translations/ui-requests/es.json index 46bbe0ba..8b961b4e 100644 --- a/translations/ui-requests/es.json +++ b/translations/ui-requests/es.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es_419.json b/translations/ui-requests/es_419.json index 46bbe0ba..8b961b4e 100644 --- a/translations/ui-requests/es_419.json +++ b/translations/ui-requests/es_419.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/es_ES.json b/translations/ui-requests/es_ES.json index 46bbe0ba..8b961b4e 100644 --- a/translations/ui-requests/es_ES.json +++ b/translations/ui-requests/es_ES.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/fr.json b/translations/ui-requests/fr.json index fd2e1ad0..8b745e68 100644 --- a/translations/ui-requests/fr.json +++ b/translations/ui-requests/fr.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/fr_FR.json b/translations/ui-requests/fr_FR.json index 6b83f995..3f1f8261 100644 --- a/translations/ui-requests/fr_FR.json +++ b/translations/ui-requests/fr_FR.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/he.json b/translations/ui-requests/he.json index fd2e1ad0..8b745e68 100644 --- a/translations/ui-requests/he.json +++ b/translations/ui-requests/he.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/hi_IN.json b/translations/ui-requests/hi_IN.json index fd2e1ad0..8b745e68 100644 --- a/translations/ui-requests/hi_IN.json +++ b/translations/ui-requests/hi_IN.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/hu.json b/translations/ui-requests/hu.json index 76a7e1e6..42d89c98 100644 --- a/translations/ui-requests/hu.json +++ b/translations/ui-requests/hu.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/it_IT.json b/translations/ui-requests/it_IT.json index 363a4056..c9187415 100644 --- a/translations/ui-requests/it_IT.json +++ b/translations/ui-requests/it_IT.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ja.json b/translations/ui-requests/ja.json index ecff3f9a..24373e50 100644 --- a/translations/ui-requests/ja.json +++ b/translations/ui-requests/ja.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ko.json b/translations/ui-requests/ko.json index fff470cf..c2b4629a 100644 --- a/translations/ui-requests/ko.json +++ b/translations/ui-requests/ko.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/nb.json b/translations/ui-requests/nb.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/nb.json +++ b/translations/ui-requests/nb.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/nl.json b/translations/ui-requests/nl.json index a906ff56..ef2da0eb 100644 --- a/translations/ui-requests/nl.json +++ b/translations/ui-requests/nl.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Ophaalservicepunt" + "requests.retrievalServicePoint": "Ophaalservicepunt", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/nn.json b/translations/ui-requests/nn.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/nn.json +++ b/translations/ui-requests/nn.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/pl.json b/translations/ui-requests/pl.json index 41109e48..16819c68 100644 --- a/translations/ui-requests/pl.json +++ b/translations/ui-requests/pl.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/pt_BR.json b/translations/ui-requests/pt_BR.json index 30744ca4..c19e709a 100644 --- a/translations/ui-requests/pt_BR.json +++ b/translations/ui-requests/pt_BR.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Cópias", "permission.moveRequest.execute": "Requisições: Mover para novo item, reordenar fila", "permission.reorderQueue.execute": "Requisições: Reordenar fila", - "requests.retrievalServicePoint": "Ponto de serviço de recuperação" + "requests.retrievalServicePoint": "Ponto de serviço de recuperação", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/pt_PT.json b/translations/ui-requests/pt_PT.json index ed55eba7..fde0aa94 100644 --- a/translations/ui-requests/pt_PT.json +++ b/translations/ui-requests/pt_PT.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ru.json b/translations/ui-requests/ru.json index 9f2fd0d8..f78c9493 100644 --- a/translations/ui-requests/ru.json +++ b/translations/ui-requests/ru.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/sk.json b/translations/ui-requests/sk.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/sk.json +++ b/translations/ui-requests/sk.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/sv.json b/translations/ui-requests/sv.json index 98b6ac3c..40029e84 100644 --- a/translations/ui-requests/sv.json +++ b/translations/ui-requests/sv.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/ur.json b/translations/ui-requests/ur.json index b5a9c149..e335081b 100644 --- a/translations/ui-requests/ur.json +++ b/translations/ui-requests/ur.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/zh_CN.json b/translations/ui-requests/zh_CN.json index dad90bfe..0251bf79 100644 --- a/translations/ui-requests/zh_CN.json +++ b/translations/ui-requests/zh_CN.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# 份数", "permission.moveRequest.execute": "请求:移至新单件,重新排序队列", "permission.reorderQueue.execute": "请求:重新排序队列", - "requests.retrievalServicePoint": "检索服务点" + "requests.retrievalServicePoint": "检索服务点", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file diff --git a/translations/ui-requests/zh_TW.json b/translations/ui-requests/zh_TW.json index 321787ea..61e752e6 100644 --- a/translations/ui-requests/zh_TW.json +++ b/translations/ui-requests/zh_TW.json @@ -300,5 +300,6 @@ "printDetails.printCount": "# Copies", "permission.moveRequest.execute": "Requests: Move to new item, reorder queue", "permission.reorderQueue.execute": "Requests: Reorder queue", - "requests.retrievalServicePoint": "Retrieval service point" + "requests.retrievalServicePoint": "Retrieval service point", + "retrievalServicePoint.name": "Retrieval service point" } \ No newline at end of file