diff --git a/code/aspen_app/src/components/Action/Holds/HoldPrompt.js b/code/aspen_app/src/components/Action/Holds/HoldPrompt.js index 659777adef..1481da3fb7 100644 --- a/code/aspen_app/src/components/Action/Holds/HoldPrompt.js +++ b/code/aspen_app/src/components/Action/Holds/HoldPrompt.js @@ -222,7 +222,7 @@ export const HoldPrompt = (props) => { {_.isArray(accounts) && _.size(accounts) > 0 ? ( - {isPlacingHold ? getTermFromDictionary('en', 'linked_place_hold_for_account') : getTermFromDictionary('en', 'linked_checkout_to_account')} + {isPlacingHold ? getTermFromDictionary(language, 'linked_place_hold_for_account') : getTermFromDictionary(language, 'linked_checkout_to_account')} setEmail(text)} - /> - setRememberPrompt(isSelected)} - > - {getTermFromDictionary(language, 'remember_settings')} - - - - - - - - - - - - - ); + return ( + handleOverDriveSettings(false)} avoidKeyboard closeOnOverlayClick={false}> + + + {promptTitle} + + + + {getTermFromDictionary(language, 'overdrive_email_field')} + setEmail(text)} /> + setRememberPrompt(isSelected)}> + {getTermFromDictionary(language, 'remember_settings')} + + + + + + + + + + + + + ); }; \ No newline at end of file diff --git a/code/aspen_app/src/screens/GroupedWork/Variations.js b/code/aspen_app/src/screens/GroupedWork/Variations.js index 252eb53e56..982eb29552 100644 --- a/code/aspen_app/src/screens/GroupedWork/Variations.js +++ b/code/aspen_app/src/screens/GroupedWork/Variations.js @@ -232,7 +232,7 @@ export const Variations = (props) => { bgColor={theme['colors']['primary']['500']} onPress={async () => { setPlacingItemHold(true); - await placeHold(library.baseUrl, selectedItem, 'ils', holdSelectItemResponse.patronId, holdSelectItemResponse.pickupLocation, '', 'item', null, null, null, holdSelectItemResponse.bibId).then(async (result) => { + await placeHold(library.baseUrl, selectedItem, 'ils', holdSelectItemResponse.patronId, holdSelectItemResponse.pickupLocation, '', 'item', null, null, null, holdSelectItemResponse.bibId, language).then(async (result) => { setResponse(result); queryClient.invalidateQueries({ queryKey: ['holds', holdSelectItemResponse.patronId, library.baseUrl, language] }); queryClient.invalidateQueries({ queryKey: ['user', library.baseUrl, language] }); diff --git a/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckout.js b/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckout.js index 69660c262a..7f9cadce42 100644 --- a/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckout.js +++ b/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckout.js @@ -225,7 +225,7 @@ export const MyCheckout = (props) => { isLoadingText={getTermFromDictionary(language, 'accessing', true)} onPress={() => { setAccess(true); - viewOverDriveItem(checkout.userId, formatId, checkout.overDriveId, library.baseUrl).then((result) => { + viewOverDriveItem(checkout.userId, formatId, checkout.overDriveId, library.baseUrl, language).then((result) => { setAccess(false); toggle(); }); @@ -241,7 +241,7 @@ export const MyCheckout = (props) => { isLoadingText={getTermFromDictionary(language, 'accessing', true)} onPress={() => { setAccess(true); - viewOnlineItem(checkout.userId, checkout.recordId, checkout.source, checkout.accessOnlineUrl, library.baseUrl).then((result) => { + viewOnlineItem(checkout.userId, checkout.recordId, checkout.source, checkout.accessOnlineUrl, library.baseUrl, language).then((result) => { setAccess(false); toggle(); }); @@ -254,7 +254,7 @@ export const MyCheckout = (props) => { isLoadingText={getTermFromDictionary(language, 'returning', true)} onPress={() => { setReturn(true); - returnCheckout(checkout.userId, checkout.recordId, checkout.source, checkout.overDriveId, library.baseUrl, version, checkout.transactionId).then((result) => { + returnCheckout(checkout.userId, checkout.recordId, checkout.source, checkout.overDriveId, library.baseUrl, version, checkout.transactionId, language).then((result) => { setReturn(false); reloadCheckouts(); toggle(); @@ -272,7 +272,7 @@ export const MyCheckout = (props) => { isLoadingText={getTermFromDictionary(language, 'returning', true)} onPress={() => { setReturn(true); - returnCheckout(checkout.userId, checkout.recordId, checkout.source, checkout.overDriveId, library.baseUrl, version, checkout.transactionId).then((result) => { + returnCheckout(checkout.userId, checkout.recordId, checkout.source, checkout.overDriveId, library.baseUrl, version, checkout.transactionId, language).then((result) => { setReturn(false); reloadCheckouts(); toggle(); diff --git a/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckouts.js b/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckouts.js index 371342aa60..55776d41db 100644 --- a/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckouts.js +++ b/code/aspen_app/src/screens/MyAccount/CheckedOutTitles/MyCheckouts.js @@ -216,7 +216,7 @@ export const MyCheckouts = () => { colorScheme="primary" onPress={() => { setRenewAll(true); - renewAllCheckouts(library.baseUrl).then((result) => { + renewAllCheckouts(library.baseUrl, language).then((result) => { if (result?.confirmRenewalFee && result.confirmRenewalFee) { setRenewConfirmationResponse({ message: result.api.message, @@ -334,7 +334,7 @@ export const MyCheckouts = () => { setConfirmingRenewal(true); if (renewConfirmationResponse.renewType === 'all') { - await confirmRenewAllCheckouts(library.baseUrl).then(async (result) => { + await confirmRenewAllCheckouts(library.baseUrl, language).then(async (result) => { queryClient.invalidateQueries({ queryKey: ['user', library.baseUrl, language] }); queryClient.invalidateQueries({ queryKey: ['checkouts', user.id, library.baseUrl, language, source] }); diff --git a/code/aspen_app/src/screens/MyAccount/Lists/EditList.js b/code/aspen_app/src/screens/MyAccount/Lists/EditList.js index 7fb3f58736..33edd90eb7 100644 --- a/code/aspen_app/src/screens/MyAccount/Lists/EditList.js +++ b/code/aspen_app/src/screens/MyAccount/Lists/EditList.js @@ -162,9 +162,9 @@ const DeleteList = (props) => { setIsOpen(!isOpen); if (res.success === false) { status = 'danger'; - popAlert('Unable to delete list', res.message, status); + popAlert(res.title, res.message, status); } else { - popAlert('List deleted', res.message, status); + popAlert(res.title, res.message, status); navigateStack('AccountScreenTab', 'MyLists', { libraryUrl: library.baseUrl, hasPendingChanges: true, diff --git a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/MyHold.js b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/MyHold.js index ac5ab09372..17e61a8e20 100644 --- a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/MyHold.js +++ b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/MyHold.js @@ -166,7 +166,7 @@ export const MyHold = (props) => { isLoadingText={getTermFromDictionary(language, 'checking_out', true)} onPress={async () => { startCheckingOut(true); - await checkoutItem(library.baseUrl, hold.recordId, hold.source, hold.userId, '', '', '').then((result) => { + await checkoutItem(library.baseUrl, hold.recordId, hold.source, hold.userId, '', '', '', language).then((result) => { popAlert(result.title, result.message, result.success ? 'success' : 'error'); resetGroup(); onClose(); @@ -197,7 +197,7 @@ export const MyHold = (props) => { startIcon={} onPress={() => { startCancelling(true); - cancelHold(hold.cancelId, hold.recordId, hold.source, library.baseUrl, hold.userId).then((r) => { + cancelHold(hold.cancelId, hold.recordId, hold.source, library.baseUrl, hold.userId, language).then((r) => { resetGroup(); onClose(); startCancelling(false); @@ -214,7 +214,7 @@ export const MyHold = (props) => { startIcon={} onPress={() => { startCancelling(true); - cancelVdxRequest(library.baseUrl, hold.sourceId, hold.cancelId).then((r) => { + cancelVdxRequest(library.baseUrl, hold.sourceId, hold.cancelId, language).then((r) => { resetGroup(); onClose(); startCancelling(false); @@ -241,7 +241,7 @@ export const MyHold = (props) => { startIcon={} onPress={() => { startThawing(true); - thawHold(hold.cancelId, hold.recordId, hold.source, library.baseUrl, hold.userId).then((r) => { + thawHold(hold.cancelId, hold.recordId, hold.source, library.baseUrl, hold.userId, language).then((r) => { resetGroup(); onClose(onClose); startThawing(false); @@ -378,7 +378,7 @@ export const ManageSelectedHolds = (props) => { { startCancelling(true); - cancelHolds(titlesToCancel, library.baseUrl).then((r) => { + cancelHolds(titlesToCancel, library.baseUrl, language).then((r) => { resetGroup(); onClose(onClose); startCancelling(false); @@ -400,7 +400,7 @@ export const ManageSelectedHolds = (props) => { { startThawing(true); - thawHolds(titlesToThaw, library.baseUrl).then((r) => { + thawHolds(titlesToThaw, library.baseUrl, language).then((r) => { resetGroup(); onClose(onClose); startThawing(false); @@ -503,7 +503,7 @@ export const ManageAllHolds = (props) => { isLoadingText={getTermFromDictionary(language, 'canceling', true)} onPress={() => { startCancelling(true); - cancelHolds(titlesToCancel, library.baseUrl).then((r) => { + cancelHolds(titlesToCancel, library.baseUrl, language).then((r) => { resetGroup(); onClose(); startCancelling(false); @@ -517,7 +517,7 @@ export const ManageAllHolds = (props) => { isLoadingText={getTermFromDictionary(language, 'thaw_hold', true)} onPress={() => { startThawing(true); - thawHolds(titlesToThaw, library.baseUrl).then((r) => { + thawHolds(titlesToThaw, library.baseUrl, language).then((r) => { resetGroup(); onClose(onClose); startThawing(false); diff --git a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectPickupLocation.js b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectPickupLocation.js index b004edf043..72733cb6e3 100644 --- a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectPickupLocation.js +++ b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectPickupLocation.js @@ -149,7 +149,7 @@ export const SelectPickupLocation = (props) => { isLoadingText={getTermFromDictionary(language, 'updating', true)} onPress={() => { setLoading(true); - changeHoldPickUpLocation(holdId, location, libraryContext.baseUrl, userId).then((r) => { + changeHoldPickUpLocation(holdId, location, libraryContext.baseUrl, userId, language).then((r) => { setShowModal(false); resetGroup(); onClose(onClose); diff --git a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectThawDate.js b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectThawDate.js index 6f00609422..0ffad5cf12 100644 --- a/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectThawDate.js +++ b/code/aspen_app/src/screens/MyAccount/TitlesOnHold/SelectThawDate.js @@ -1,75 +1,63 @@ import React from 'react'; -import DateTimePickerModal from "react-native-modal-datetime-picker"; +import DateTimePickerModal from 'react-native-modal-datetime-picker'; import { MaterialIcons } from '@expo/vector-icons'; import { Actionsheet, Icon, useToken, useColorModeValue } from 'native-base'; import { freezeHold, freezeHolds } from '../../../util/accountActions'; -import {getTermFromDictionary} from '../../../translations/TranslationService'; +import { getTermFromDictionary } from '../../../translations/TranslationService'; export const SelectThawDate = (props) => { - const { label, language, libraryContext, onClose, freezeId, recordId, source, userId, resetGroup, isOpen } = props; - let data = props.data; - const [loading, setLoading] = React.useState(false); - - const textColor = useToken('colors', useColorModeValue('text.500', 'text.50')); - const colorMode = useColorModeValue(false, true); - - let actionLabel = getTermFromDictionary(language, 'freeze_hold'); - if(label) { - actionLabel = label; - } - - const today = new Date(); - const [date, setDate] = React.useState(today); - - const [isDatePickerVisible, setDatePickerVisibility] = React.useState(false); - - const showDatePicker = () => { - setDatePickerVisibility(true); - }; - - const hideDatePicker = () => { - setDatePickerVisibility(false); - }; - - const onSelectDate = (date) => { - hideDatePicker(); - setLoading(true); - console.warn("A date has been picked: ", date); - setDate(date); - onClose(); - if(data) { - freezeHolds(data, libraryContext.baseUrl, date).then((result) => { - setLoading(false); - resetGroup(); - hideDatePicker(); - }); - } else { - freezeHold(freezeId, recordId, source, libraryContext.baseUrl, userId, date).then((result) => { - setLoading(false); - resetGroup(); - hideDatePicker(); - }); - } - } - - return ( - <> - } - onPress={showDatePicker}> - {actionLabel} - - - - ); + const { label, language, libraryContext, onClose, freezeId, recordId, source, userId, resetGroup, isOpen } = props; + let data = props.data; + const [loading, setLoading] = React.useState(false); + + const textColor = useToken('colors', useColorModeValue('text.500', 'text.50')); + const colorMode = useColorModeValue(false, true); + + let actionLabel = getTermFromDictionary(language, 'freeze_hold'); + if (label) { + actionLabel = label; + } + + const today = new Date(); + const [date, setDate] = React.useState(today); + + const [isDatePickerVisible, setDatePickerVisibility] = React.useState(false); + + const showDatePicker = () => { + setDatePickerVisibility(true); + }; + + const hideDatePicker = () => { + setDatePickerVisibility(false); + }; + + const onSelectDate = (date) => { + hideDatePicker(); + setLoading(true); + console.warn('A date has been picked: ', date); + setDate(date); + onClose(); + if (data) { + freezeHolds(data, libraryContext.baseUrl, date, language).then((result) => { + setLoading(false); + resetGroup(); + hideDatePicker(); + }); + } else { + freezeHold(freezeId, recordId, source, libraryContext.baseUrl, userId, date, language).then((result) => { + setLoading(false); + resetGroup(); + hideDatePicker(); + }); + } + }; + + return ( + <> + } onPress={showDatePicker}> + {actionLabel} + + + + ); }; \ No newline at end of file diff --git a/code/aspen_app/src/screens/SCO/SelfCheckOut.js b/code/aspen_app/src/screens/SCO/SelfCheckOut.js index 52f2591c4c..83f0136419 100644 --- a/code/aspen_app/src/screens/SCO/SelfCheckOut.js +++ b/code/aspen_app/src/screens/SCO/SelfCheckOut.js @@ -83,7 +83,7 @@ export const SelfCheckOut = () => { } else { // do the checkout setIsProcessingCheckout(true); - await checkoutItem(library.baseUrl, barcode, 'ils', activeAccount.userId ?? user.id, barcode, location.locationId, barcodeType).then((result) => { + await checkoutItem(library.baseUrl, barcode, 'ils', activeAccount.userId ?? user.id, barcode, location.locationId, barcodeType, language).then((result) => { if (!result.success) { // prompt error setHasError(true); diff --git a/code/aspen_app/src/screens/Search/AddToList.js b/code/aspen_app/src/screens/Search/AddToList.js index 2de824822f..daa646829b 100644 --- a/code/aspen_app/src/screens/Search/AddToList.js +++ b/code/aspen_app/src/screens/Search/AddToList.js @@ -197,7 +197,7 @@ export const AddToList = (props) => { isLoading={loading} onPress={() => { setLoading(true); - addTitlesToList(listId, item, library.baseUrl, source).then((res) => { + addTitlesToList(listId, item, library.baseUrl, source, language).then((res) => { updateLastListUsed(listId); queryClient.invalidateQueries({ queryKey: ['list', listId] }); setLoading(false); diff --git a/code/aspen_app/src/translations/defaults.json b/code/aspen_app/src/translations/defaults.json index d475419418..ac176e3ebd 100644 --- a/code/aspen_app/src/translations/defaults.json +++ b/code/aspen_app/src/translations/defaults.json @@ -152,16 +152,23 @@ "cancel_holds": "Cancel holds", "cancel_all_holds": "Cancel all holds", "cancel_selected_holds": "Cancel selected holds", + "holds_cancelled": "Holds cancelled", "thaw_hold": "Thaw Hold", "thaw_holds": "Thaw Holds", "thaw_all_holds": "Thaw all holds", "thaw_selected_holds": "Thaw selected holds", "thawing_hold": "Thawing", + "hold_thawed": "Hold thawed", + "holds_thawed": "Holds thawed", + "unable_thaw_hold": "Unable to thaw hold", "freeze_hold": "Freeze Hold", "freeze_holds": "Freeze Holds", "freeze_hold_with_reactivation": "Freeze Hold for 30 Days", "freeze_all_holds": "Freeze all holds", "freeze_selected_holds": "Freeze selected holds", + "hold_frozen": "Hold frozen", + "holds_frozen": "Holds frozen", + "unable_freeze_hold": "Unable to freeze hold", "freezing_hold": "Freezing", "hold_position": "Position", "hold_options": "Hold Options", diff --git a/code/aspen_app/src/util/accountActions.js b/code/aspen_app/src/util/accountActions.js index 4474369671..223142372c 100644 --- a/code/aspen_app/src/util/accountActions.js +++ b/code/aspen_app/src/util/accountActions.js @@ -114,7 +114,7 @@ export async function confirmRenewCheckout(barcode, recordId, source, itemId, li } } -export async function renewAllCheckouts(url) { +export async function renewAllCheckouts(url, language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', @@ -139,12 +139,12 @@ export async function renewAllCheckouts(url) { popAlert(result.title, result.renewalMessage[0], 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function confirmRenewAllCheckouts(url) { +export async function confirmRenewAllCheckouts(url, language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', @@ -172,12 +172,12 @@ export async function confirmRenewAllCheckouts(url) { popAlert(result.title, result.renewalMessage[0], 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function returnCheckout(userId, id, source, overDriveId = null, url, version, axis360Id = null) { +export async function returnCheckout(userId, id, source, overDriveId = null, url, version, axis360Id = null, language = 'en') { const postBody = await postData(); let itemId = id; @@ -211,7 +211,7 @@ export async function returnCheckout(userId, id, source, overDriveId = null, url popAlert(result.title, result.message, 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } else { @@ -237,13 +237,13 @@ export async function returnCheckout(userId, id, source, overDriveId = null, url popAlert(result.title, result.message, 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } } -export async function viewOnlineItem(userId, id, source, accessOnlineUrl, url) { +export async function viewOnlineItem(userId, id, source, accessOnlineUrl, url, language = 'en') { const postBody = await postData(); if (source === 'hoopla' || source === 'cloud_library') { @@ -277,17 +277,17 @@ export async function viewOnlineItem(userId, id, source, accessOnlineUrl, url) { console.log(response); }) .catch(async (error) => { - popToast(getTermFromDictionary('en', 'error_no_open_resource'), getTermFromDictionary('en', 'error_device_block_browser'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_open_resource'), getTermFromDictionary(language, 'error_device_block_browser'), 'error'); }); } catch (error) { console.log('Really borked.'); } } else { - popToast(getTermFromDictionary('en', 'error_no_open_resource'), getTermFromDictionary('en', 'error_device_block_browser'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_open_resource'), getTermFromDictionary(language, 'error_device_block_browser'), 'error'); } }); } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); } } else { await WebBrowser.openBrowserAsync(accessOnlineUrl) @@ -304,20 +304,20 @@ export async function viewOnlineItem(userId, id, source, accessOnlineUrl, url) { }) .catch((error) => { console.log(error); - popToast(getTermFromDictionary('en', 'error_no_open_resource'), getTermFromDictionary('en', 'error_device_block_browser'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_open_resource'), getTermFromDictionary(language, 'error_device_block_browser'), 'error'); }); } catch (error) { console.log(error); console.log('Unable to open.'); } } else { - popToast(getTermFromDictionary('en', 'error_no_open_resource'), getTermFromDictionary('en', 'error_device_block_browser'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_open_resource'), getTermFromDictionary(language, 'error_device_block_browser'), 'error'); } }); } } -export async function viewOverDriveItem(userId, formatId, overDriveId, url) { +export async function viewOverDriveItem(userId, formatId, overDriveId, url, language = 'en') { const postBody = await postData(); const api = create({ @@ -357,17 +357,17 @@ export async function viewOverDriveItem(userId, formatId, overDriveId, url) { console.log('Really borked.'); } } else { - popToast(getTermFromDictionary('en', 'error_no_open_resource'), getTermFromDictionary('en', 'error_device_block_browser'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_open_resource'), getTermFromDictionary(language, 'error_device_block_browser'), 'error'); } }); } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } /* ACTIONS ON HOLDS */ -export async function freezeHold(cancelId, recordId, source, url, patronId, selectedReactivationDate = null) { +export async function freezeHold(cancelId, recordId, source, url, patronId, selectedReactivationDate = null, language = 'en') { const postBody = await postData(); const today = moment().format('YYYY-MM-DD'); @@ -405,19 +405,19 @@ export async function freezeHold(cancelId, recordId, source, url, patronId, sele const result = fetchedData.result; if (result.success === true) { - popAlert('Hold frozen', result.message, 'success'); + popAlert(result.title ?? getTermFromDictionary(language, 'hold_frozen'), result.message, 'success'); // reload patron data in the background //await reloadHolds(libraryUrl); } else { - popAlert('Unable to freeze hold', result.message, 'error'); + popAlert(result.title ?? getTermFromDictionary(language, 'unable_freeze_hold'), result.message, 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function freezeHolds(data, url, selectedReactivationDate = null) { +export async function freezeHolds(data, url, selectedReactivationDate = null, language = 'en') { const postBody = await postData(); const today = moment().format('YYYY-MM-DD'); @@ -462,7 +462,7 @@ export async function freezeHolds(data, url, selectedReactivationDate = null) { numFailed = numFailed + 1; } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } }); @@ -479,10 +479,10 @@ export async function freezeHolds(data, url, selectedReactivationDate = null) { status = 'warning'; message = message.concat(' Unable to freeze ' + numFailed + ' holds.'); } - popAlert('Holds frozen', message, status); + popAlert(getTermFromDictionary(language, 'holds_frozen'), message, status); } -export async function thawHold(cancelId, recordId, source, url, patronId) { +export async function thawHold(cancelId, recordId, source, url, patronId, language = 'en') { const postBody = await postData(); const api = create({ @@ -505,19 +505,17 @@ export async function thawHold(cancelId, recordId, source, url, patronId) { const result = fetchedData.result; if (result.success === true) { - popAlert('Hold thawed', result.message, 'success'); - // reload patron data in the background - //await reloadHolds(); + popAlert(result.title ?? getTermFromDictionary(language, 'hold_thawed'), result.message, 'success'); } else { - popAlert('Unable to thaw hold', result.message, 'error'); + popAlert(result.title ?? getTermFromDictionary(language, 'unable_thaw_hold'), result.message, 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function thawHolds(data, url) { +export async function thawHolds(data, url, language = 'en') { const postBody = await postData(); let numSuccess = 0; @@ -548,7 +546,7 @@ export async function thawHolds(data, url) { numFailed = numFailed + 1; } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } }); @@ -565,10 +563,10 @@ export async function thawHolds(data, url) { status = 'warning'; message = message.concat(' Unable to thaw ' + numFailed + ' holds.'); } - popAlert('Holds thawed', message, status); + popAlert(getTermFromDictionary(language, 'holds_thawed'), message, status); } -export async function cancelHold(cancelId, recordId, source, url, patronId) { +export async function cancelHold(cancelId, recordId, source, url, patronId, language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', @@ -599,12 +597,12 @@ export async function cancelHold(cancelId, recordId, source, url, patronId) { //await getProfile(); } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function cancelHolds(data, url) { +export async function cancelHolds(data, url, language = 'en') { const postBody = await postData(); let numSuccess = 0; @@ -636,7 +634,7 @@ export async function cancelHolds(data, url) { numFailed = numFailed + 1; } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } }); @@ -653,10 +651,10 @@ export async function cancelHolds(data, url) { status = 'warning'; message = message.concat(' Unable to cancel ' + numFailed + ' holds.'); } - popAlert('Holds cancelled', message, status); + popAlert(getTermFromDictionary(language, 'holds_cancelled'), message, status); } -export async function changeHoldPickUpLocation(holdId, newLocation, url = null, userId) { +export async function changeHoldPickUpLocation(holdId, newLocation, url = null, userId, language = 'en') { let baseUrl = url ?? LIBRARY.url; const postBody = await postData(); const api = create({ @@ -686,12 +684,12 @@ export async function changeHoldPickUpLocation(holdId, newLocation, url = null, popAlert(result.title, result.message, 'error'); } } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function updateOverDriveEmail(itemId, source, patronId, overdriveEmail, promptForOverdriveEmail, libraryUrl) { +export async function updateOverDriveEmail(itemId, source, patronId, overdriveEmail, promptForOverdriveEmail, libraryUrl, language = 'en') { const postBody = await postData(); const api = create({ baseURL: libraryUrl + '/API', @@ -714,12 +712,12 @@ export async function updateOverDriveEmail(itemId, source, patronId, overdriveEm // reload patron data in the background return result; } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function cancelVdxRequest(libraryUrl, sourceId, cancelId) { +export async function cancelVdxRequest(libraryUrl, sourceId, cancelId, language = 'en') { const postBody = await postData(); const api = create({ baseURL: libraryUrl + '/API', @@ -737,7 +735,7 @@ export async function cancelVdxRequest(libraryUrl, sourceId, cancelId) { popAlert(response.data.result.title, response.data.result.message, 'success'); } else { console.log(response); - popAlert('Error', response.data.result.message, 'error'); + popAlert(getTermFromDictionary(language, 'error'), response.data.result.message, 'error'); } } else { const problem = problemCodeMap(response.problem); diff --git a/code/aspen_app/src/util/api/list.js b/code/aspen_app/src/util/api/list.js index c2fa49a704..626304c294 100644 --- a/code/aspen_app/src/util/api/list.js +++ b/code/aspen_app/src/util/api/list.js @@ -1,6 +1,7 @@ import { create } from 'apisauce'; import _ from 'lodash'; import { popAlert } from '../../components/loadError'; +import { getTermFromDictionary } from '../../translations/TranslationService'; import { createAuthTokens, ENDPOINT, getHeaders, postData } from '../apiAuth'; import { GLOBALS } from '../globals'; import { PATRON } from '../loadPatron'; @@ -169,7 +170,7 @@ export async function clearListTitles(listId, url) { } } -export async function addTitlesToList(id, itemId, url, source = 'GroupedWork') { +export async function addTitlesToList(id, itemId, url, source = 'GroupedWork', language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', @@ -186,9 +187,9 @@ export async function addTitlesToList(id, itemId, url, source = 'GroupedWork') { if (response.ok) { PATRON.listLastUsed = id; if (response.data.result.success) { - popAlert('Success', response.data.result.numAdded + ' added to list', 'success'); + popAlert(getTermFromDictionary(language, 'added_successfully'), response.data.result.numAdded + ' added to list', 'success'); } else { - popAlert('Error', 'Unable to add item to list', 'error'); + popAlert(getTermFromDictionary(language, 'error'), 'Unable to add item to list', 'error'); } return response.data.result; } else { diff --git a/code/aspen_app/src/util/recordActions.js b/code/aspen_app/src/util/recordActions.js index da3462a5b4..cd541a3ed6 100644 --- a/code/aspen_app/src/util/recordActions.js +++ b/code/aspen_app/src/util/recordActions.js @@ -9,7 +9,7 @@ import { GLOBALS } from './globals'; import { getTermFromDictionary } from '../translations/TranslationService'; // complete the action on the item, i.e. checkout, hold, or view sample -export async function completeAction(id, actionType, patronId, formatId = '', sampleNumber = '', pickupBranch = '', url, volumeId = '', holdType = '', holdNotificationPreferences, variationId = '', bibId = '') { +export async function completeAction(id, actionType, patronId, formatId = '', sampleNumber = '', pickupBranch = '', url, volumeId = '', holdType = '', holdNotificationPreferences, variationId = '', bibId = '', language = 'en') { const recordId = id.split(':'); const source = recordId[0]; let itemId = recordId[1]; @@ -27,7 +27,7 @@ export async function completeAction(id, actionType, patronId, formatId = '', sa } if (actionType.includes('checkout')) { - return await checkoutItem(url, itemId, source, patronId); + return await checkoutItem(url, itemId, source, patronId, '', '', '', language); } else if (actionType.includes('hold')) { if (volumeId) { return await placeHold(url, itemId, source, patronId, pickupBranch, volumeId, holdType, id, holdNotificationPreferences); @@ -43,7 +43,7 @@ export async function completeAction(id, actionType, patronId, formatId = '', sa return getPromptForOverdriveEmail; } } else { - return await placeHold(url, itemId, source, patronId, pickupBranch, volumeId, holdType, id, holdNotificationPreferences, variationId); + return await placeHold(url, itemId, source, patronId, pickupBranch, volumeId, holdType, id, holdNotificationPreferences, variationId, '', language); } } else if (actionType.includes('sample')) { return await overDriveSample(url, formatId, itemId, sampleNumber); @@ -66,8 +66,9 @@ export async function completeAction(id, actionType, patronId, formatId = '', sa * @param {string} barcode * @param {string} locationId * @param {string} barcodeType + * @param {string} language **/ -export async function checkoutItem(url, itemId, source, patronId, barcode = '', locationId = '', barcodeType) { +export async function checkoutItem(url, itemId, source, patronId, barcode = '', locationId = '', barcodeType, language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', @@ -91,7 +92,7 @@ export async function checkoutItem(url, itemId, source, patronId, barcode = '', return responseData.result; } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } @@ -117,8 +118,9 @@ export async function checkoutItem(url, itemId, source, patronId, barcode = '', * @param {array} holdNotificationPreferences * @param {string} variationId * @param {string} bibId + * @param {string} language **/ -export async function placeHold(url, itemId, source, patronId, pickupBranch, volumeId = '', holdType = '', recordId = '', holdNotificationPreferences = null, variationId = null, bibId = null) { +export async function placeHold(url, itemId, source, patronId, pickupBranch, volumeId = '', holdType = '', recordId = '', holdNotificationPreferences = null, variationId = null, bibId = null, language = 'en') { let id = itemId; if (variationId) { id = variationId; @@ -180,12 +182,12 @@ export async function placeHold(url, itemId, source, patronId, pickupBranch, vol if (response.ok) { return response.data.result; } else { - popToast(getTermFromDictionary('en', 'error_no_server_connection'), getTermFromDictionary('en', 'error_no_library_connection'), 'error'); + popToast(getTermFromDictionary(language, 'error_no_server_connection'), getTermFromDictionary(language, 'error_no_library_connection'), 'error'); console.log(response); } } -export async function overDriveSample(url, formatId, itemId, sampleNumber) { +export async function overDriveSample(url, formatId, itemId, sampleNumber, language = 'en') { const postBody = await postData(); const api = create({ baseURL: url + '/API', diff --git a/code/web/interface/themes/responsive/Search/home.tpl b/code/web/interface/themes/responsive/Search/home.tpl index 76b16e9b35..389b2e18a7 100644 --- a/code/web/interface/themes/responsive/Search/home.tpl +++ b/code/web/interface/themes/responsive/Search/home.tpl @@ -76,16 +76,12 @@
- - + +
{if !empty($isLoggedIn)}
-
{/if} @@ -136,8 +132,8 @@ {if !empty($isLoggedIn) && $numHiddenCategory > 0} @@ -152,6 +148,7 @@ AspenDiscovery.Browse.curCategory = '{$selectedBrowseCategory->textId}'; {if !empty($subCategoryTextId)}AspenDiscovery.Browse.curSubCategory = '{$subCategoryTextId}';{/if} {/if} + $('#'+AspenDiscovery.Browse.browseMode).removeClass('active'); {if empty($onInternalIP)} if (!Globals.opac && AspenDiscovery.hasLocalStorage()){ldelim} var temp = window.localStorage.getItem('browseMode'); @@ -162,7 +159,8 @@ {else} AspenDiscovery.Browse.browseMode = '{$browseMode}'; {/if} - $('#'+AspenDiscovery.Browse.browseMode).parent('label').addClass('active'); {* show user which one is selected *} + $('#'+AspenDiscovery.Browse.browseMode).addClass('active'); {* show user which one is selected *} + AspenDiscovery.Browse.toggleBrowseMode(); {rdelim}); \ No newline at end of file diff --git a/code/web/interface/themes/responsive/js/aspen.js b/code/web/interface/themes/responsive/js/aspen.js index d8d4df353e..1c802f07d3 100644 --- a/code/web/interface/themes/responsive/js/aspen.js +++ b/code/web/interface/themes/responsive/js/aspen.js @@ -10783,7 +10783,6 @@ AspenDiscovery.Browse = (function(){ }, toggleBrowseMode : function(selectedMode){ - console.log("Toggling browse mode..."); if(!AspenDiscovery.Browse.accessibleMode) { var mode = this.browseModeClasses.hasOwnProperty(selectedMode) ? selectedMode : this.browseMode; // check that selected mode is a valid option var categoryTextId = this.curCategory || $('#browse-category-carousel .selected').data('category-id'); diff --git a/code/web/interface/themes/responsive/js/aspen/browse.js b/code/web/interface/themes/responsive/js/aspen/browse.js index 12ec05384f..f628b3ac0f 100644 --- a/code/web/interface/themes/responsive/js/aspen/browse.js +++ b/code/web/interface/themes/responsive/js/aspen/browse.js @@ -133,7 +133,6 @@ AspenDiscovery.Browse = (function(){ }, toggleBrowseMode : function(selectedMode){ - console.log("Toggling browse mode..."); if(!AspenDiscovery.Browse.accessibleMode) { var mode = this.browseModeClasses.hasOwnProperty(selectedMode) ? selectedMode : this.browseMode; // check that selected mode is a valid option var categoryTextId = this.curCategory || $('#browse-category-carousel .selected').data('category-id'); diff --git a/code/web/release_notes/24.07.00.MD b/code/web/release_notes/24.07.00.MD index e84eba9a16..dc33d378e5 100644 --- a/code/web/release_notes/24.07.00.MD +++ b/code/web/release_notes/24.07.00.MD @@ -12,6 +12,11 @@ // kirstien +### Accessibility Updates +- "Show Hidden Browse Categories" is now accessible via keyboard navigation. (*KK*) + +### API Updates +- Hold status will now output the translated value instead of the default/ILS value. (Ticket 133530) (*KK*) // kodi @@ -37,4 +42,4 @@ - PTFS-Europe - Pedro Amorim (PA) - Alexander Blanchard (AB) - - Jacob O'Mara (JOM) + - Jacob O'Mara (JOM) \ No newline at end of file diff --git a/code/web/services/API/ListAPI.php b/code/web/services/API/ListAPI.php index a9d461e53a..01badfb30d 100644 --- a/code/web/services/API/ListAPI.php +++ b/code/web/services/API/ListAPI.php @@ -1326,21 +1326,21 @@ function deleteList() { $list->delete(); return [ 'success' => true, - 'title' => 'Success', - 'message' => 'List deleted successfully', + 'title' => translate(['text' => 'Success', 'isPublicFacing' => true]), + 'message' => translate(['text' => 'List deleted successfully', 'isPublicFacing' => true]), ]; } else { return [ - 'success' => true, - 'title' => 'Success', - 'message' => "Sorry you don't have permissions to delete this list.", + 'success' => false, + 'title' => translate(['text' => 'Error', 'isPublicFacing' => true]), + 'message' => translate(["text" => "Sorry you don't have permissions to delete this list.", 'isPublicFacing' => true]), ]; } } else { return [ 'success' => false, - 'title' => 'Error', - 'message' => 'List not found', + 'title' => translate(['text' => 'Error', 'isPublicFacing' => true]), + 'message' => translate(['text' => 'List not found', 'isPublicFacing' => true]), 'listId' => $list->id, 'listTitle' => $list->title, ]; diff --git a/code/web/sys/User/Hold.php b/code/web/sys/User/Hold.php index 23547749a1..2c24835c7d 100644 --- a/code/web/sys/User/Hold.php +++ b/code/web/sys/User/Hold.php @@ -119,6 +119,7 @@ public function getArrayForAPIs() { $hold['location'] = $location->code; } } + $hold['status'] = translate(['text' => $hold['status'], 'isPublicFacing' => true]); $recordDriver = $this->getRecordDriver(); if ($recordDriver && $recordDriver->isValid()) { $hold['isbn'] = $recordDriver->getCleanISBN();