-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split availability hook into two separate hooks
Two major factors to be aware of here: * Three hooks are introduced instead of one: One main hook and one for physical and one for online materials, to get a better overview of the rules and the logic. * Apparently we cannot make use of `onSuccess` handlers on queries if the request have alredy been performed and the data is delivered the second time by the `QueryClient` cache. And that is the case of the availability labels on a material page, where they are used both in the header and in the "udagver" section later on the page.
- Loading branch information
Showing
7 changed files
with
217 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { | ||
Access, | ||
AccessTypeCode | ||
} from "../../core/dbc-gateway/generated/graphql"; | ||
import { FaustId } from "../../core/utils/types/ids"; | ||
import { isOnline } from "./helper"; | ||
import useOnlineAvailabilityData from "./useOnlineAvailabilityData"; | ||
import usePhysicalAvailabilityData from "./usePhysicalAvailabilityData"; | ||
|
||
const useAvailabilityData = ({ | ||
accessTypes, | ||
access, | ||
faustIds, | ||
manifestText, | ||
isbn | ||
}: { | ||
accessTypes: AccessTypeCode[]; | ||
access: Access["__typename"][]; | ||
faustIds: FaustId[]; | ||
manifestText: string; | ||
isbn: string | null; | ||
}) => { | ||
const availabilityOnline = useOnlineAvailabilityData({ | ||
enabled: isOnline(accessTypes), | ||
access, | ||
faustIds, | ||
isbn, | ||
manifestText | ||
}); | ||
|
||
const availabilityPhysical = usePhysicalAvailabilityData({ | ||
enabled: !isOnline(accessTypes), | ||
faustIds, | ||
manifestText | ||
}); | ||
|
||
if (isOnline(accessTypes)) { | ||
return availabilityOnline; | ||
} | ||
|
||
return availabilityPhysical; | ||
}; | ||
|
||
export default useAvailabilityData; |
99 changes: 99 additions & 0 deletions
99
src/components/availability-label/useOnlineAvailabilityData.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { useEffect, useState } from "react"; | ||
import { | ||
useGetV1LoanstatusIdentifier, | ||
useGetV1ProductsIdentifier | ||
} from "../../core/publizon/publizon"; | ||
import { Access } from "../../core/dbc-gateway/generated/graphql"; | ||
import { FaustId } from "../../core/utils/types/ids"; | ||
import { publizonProductStatuses } from "./types"; | ||
|
||
const useOnlineAvailabilityData = ({ | ||
enabled, | ||
access, | ||
faustIds, | ||
isbn, | ||
manifestText | ||
}: { | ||
enabled: boolean; | ||
access: Access["__typename"][]; | ||
faustIds: FaustId[] | null; | ||
isbn: string | null; | ||
manifestText: string; | ||
}) => { | ||
const [isAvailable, setIsAvailable] = useState<null | boolean>(null); | ||
|
||
// Find out if the material is cost free. | ||
const { isLoading: isLoadingIdentifier, data: dataIdentifier } = | ||
useGetV1ProductsIdentifier(isbn ?? "", { | ||
query: { | ||
// Publizon / useGetV1ProductsIdentifier is responsible for online | ||
// materials. It requires an ISBN to do lookups. | ||
enabled: enabled && isAvailable === null && isbn !== null | ||
} | ||
}); | ||
|
||
// Ereol request. | ||
const { isLoading: isLoadingEreolData, data: dataEreol } = | ||
useGetV1LoanstatusIdentifier(isbn || "", { | ||
// Publizon / useGetV1LoanstatusIdentifier shows loan status per material. | ||
// This status is only available for products found on Ereol. Other online | ||
// materials are always supposed to be shown as "available" | ||
enabled: | ||
enabled && | ||
isAvailable === null && | ||
!!isbn && | ||
// If the material is free (I think it is called blue material btw.) | ||
// we should not load the loan status because then we know that it is available. | ||
// So If the material is not free and we know it is an "Ereol" material we should load the loan status. | ||
dataIdentifier?.product?.costFree === false && | ||
access.some((acc) => acc === "Ereol") | ||
}); | ||
|
||
useEffect(() => { | ||
if ( | ||
!enabled || | ||
isAvailable !== null || | ||
isLoadingIdentifier !== false || | ||
isLoadingEreolData !== false | ||
) { | ||
return; | ||
} | ||
|
||
// If we have ereol data, we can use that to determine the availability. | ||
if (dataEreol && dataEreol.loanStatus) { | ||
setIsAvailable(publizonProductStatuses[dataEreol.loanStatus].isAvailable); | ||
} | ||
}, [ | ||
isLoadingIdentifier, | ||
isAvailable, | ||
manifestText, | ||
faustIds, | ||
enabled, | ||
dataEreol, | ||
isLoadingEreolData | ||
]); | ||
|
||
// If hook is not enabled make it clear that the loading and availability status is unknown. | ||
if (!enabled) { | ||
return { | ||
isLoading: null, | ||
isAvailable: null | ||
}; | ||
} | ||
|
||
// An online material is by default always available if the availability status has not been set yet. | ||
if (isAvailable === null) { | ||
return { | ||
isLoading: false, | ||
isAvailable: true | ||
}; | ||
} | ||
|
||
// Return the availability status. | ||
return { | ||
isLoading: isLoadingIdentifier && isLoadingEreolData, | ||
isAvailable | ||
}; | ||
}; | ||
|
||
export default useOnlineAvailabilityData; |
65 changes: 65 additions & 0 deletions
65
src/components/availability-label/usePhysicalAvailabilityData.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { useConfig } from "../../core/utils/config"; | ||
import { FaustId } from "../../core/utils/types/ids"; | ||
import useGetAvailability from "../../core/utils/useGetAvailability"; | ||
import { ManifestationMaterialType } from "../../core/utils/types/material-type"; | ||
|
||
const usePhysicalAvailabilityData = ({ | ||
enabled, | ||
faustIds, | ||
manifestText | ||
}: { | ||
enabled: boolean; | ||
faustIds: FaustId[] | null; | ||
manifestText: string; | ||
}) => { | ||
const config = useConfig(); | ||
|
||
const response = useGetAvailability({ | ||
faustIds: faustIds ?? [], | ||
config, | ||
options: { | ||
query: { | ||
// FBS / useGetAvailabilityV3 is responsible for handling availability | ||
// for physical items. This will be the majority of all materials so we | ||
// use this for everything except materials that are explicitly online. | ||
enabled: | ||
enabled && | ||
faustIds !== null && | ||
manifestText !== ManifestationMaterialType.article | ||
} | ||
} | ||
}); | ||
|
||
const { isLoading, data } = response; | ||
|
||
// Articles are always available. | ||
if (manifestText === ManifestationMaterialType.article) { | ||
return { | ||
isLoading: false, | ||
isAvailable: true | ||
}; | ||
} | ||
|
||
// If we do not have data yet, return loading state. | ||
if (!data) { | ||
return { | ||
isLoading, | ||
isAvailable: null | ||
}; | ||
} | ||
|
||
// If we have data, check if any of the items are available. | ||
if (data?.some((item) => item.available)) { | ||
return { | ||
isLoading: false, | ||
isAvailable: true | ||
}; | ||
} | ||
// Otherwise the manifestation is not available. | ||
return { | ||
isLoading: false, | ||
isAvailable: false | ||
}; | ||
}; | ||
|
||
export default usePhysicalAvailabilityData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.