diff --git a/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tests.tsx b/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tests.tsx index 1a5b46c9489..cbb4bf0124c 100644 --- a/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tests.tsx +++ b/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tests.tsx @@ -1,7 +1,8 @@ +import { screen } from "@testing-library/react-native" import { CreateArtworkAlertModal_artwork$data } from "__generated__/CreateArtworkAlertModal_artwork.graphql" import { CreateArtworkAlertModal, - computeArtworkAlertProps, + useComputeArtworkAlertProps, } from "app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal" import { CreateSavedSearchModal } from "app/Components/Artist/ArtistArtworks/CreateSavedSearchModal" import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" @@ -11,6 +12,10 @@ jest.mock("app/Components/Artist/ArtistArtworks/CreateSavedSearchModal", () => ( CreateSavedSearchModal: () => "CreateSavedSearchModal", })) +jest.mock("app/utils/hooks/useFeatureFlag", () => ({ + useFeatureFlag: () => true, +})) + describe("CreateArtworkAlertModal", () => { const { renderWithRelay } = setupTestWrapper({ Component: CreateArtworkAlertModal, @@ -24,13 +29,13 @@ describe("CreateArtworkAlertModal", () => { }) it("returns null if artwork is ineligible", () => { - const { queryByText } = renderWithRelay({ + renderWithRelay({ Artwork: () => ({ isEligibleToCreateAlert: false, }), }) - expect(queryByText("CreateSavedSearchModal")).toBeFalsy() + expect(screen.queryByText("CreateSavedSearchModal")).toBeFalsy() }) it("returns renders modal", () => { @@ -48,13 +53,14 @@ describe("CreateArtworkAlertModal", () => { }) }) -describe("computeArtworkAlertProps", () => { +describe("useCmputeArtworkAlertProps", () => { const artwork = { artistsArray: [{ name: "foo", internalID: "bar" }], isEligibleToCreateAlert: true, attributionClass: { internalID: "1", }, + artistSeriesIDs: [], title: "Test Artwork", internalID: "2", slug: "test-artwork", @@ -67,17 +73,13 @@ describe("computeArtworkAlertProps", () => { } as unknown as CreateArtworkAlertModal_artwork$data it("should return default props when artwork is ineligible for alert", () => { - const result = computeArtworkAlertProps({ ...artwork, isEligibleToCreateAlert: false }) + const result = useComputeArtworkAlertProps({ ...artwork, isEligibleToCreateAlert: false }) - expect(result).toEqual({ - entity: null, - attributes: null, - aggregations: null, - }) + expect(result).toEqual(null) }) it("should return correct props when artwork is eligible for alert", () => { - const result = computeArtworkAlertProps(artwork) + const result = useComputeArtworkAlertProps(artwork) expect(result).toEqual({ aggregations: [ @@ -89,6 +91,7 @@ describe("computeArtworkAlertProps", () => { attributes: { artistIDs: ["bar"], attributionClass: ["1"], + artistSeriesIDs: [], additionalGeneIDs: ["test-gene"], }, entity: { @@ -99,7 +102,7 @@ describe("computeArtworkAlertProps", () => { }) it("should omit a medium if filterGene isnt provided", () => { - const result = computeArtworkAlertProps({ ...artwork, mediumType: { filterGene: null } }) + const result = useComputeArtworkAlertProps({ ...artwork, mediumType: { filterGene: null } }) expect(result).toEqual({ aggregations: [], @@ -107,6 +110,7 @@ describe("computeArtworkAlertProps", () => { artistIDs: ["bar"], attributionClass: ["1"], additionalGeneIDs: [], + artistSeriesIDs: [], }, entity: { artists: [{ id: "bar", name: "foo" }], diff --git a/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tsx b/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tsx index 269f84ffa41..1108c453296 100644 --- a/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tsx +++ b/src/app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal.tsx @@ -11,6 +11,8 @@ import { SavedSearchEntityArtist, SearchCriteriaAttributes, } from "app/Components/ArtworkFilter/SavedSearch/types" +import { extractNodes } from "app/utils/extractNodes" +import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" import { compact } from "lodash" import { graphql, useFragment } from "react-relay" @@ -30,6 +32,13 @@ export const CreateArtworkAlertModal: React.FC = ( const data = useFragment( graphql` fragment CreateArtworkAlertModal_artwork on Artwork { + artistSeriesConnection(first: 5) { + edges { + node { + slug + } + } + } title internalID slug @@ -52,20 +61,24 @@ export const CreateArtworkAlertModal: React.FC = ( artwork ) + const artworkAlert = useComputeArtworkAlertProps(data) + const { isEligibleToCreateAlert } = data if (!isEligibleToCreateAlert) { return null } - const artworkAlert = computeArtworkAlertProps(data) + if (!artworkAlert) { + return null + } return ( = ( ) } -export const computeArtworkAlertProps = ( +export const useComputeArtworkAlertProps = ( artwork: CreateArtworkAlertModal_artwork$data | BrowseSimilarWorks_artwork$data ) => { + const enableArtistSeriesFilter = useFeatureFlag("AREnableArtistSeriesFilter") + const { isEligibleToCreateAlert } = artwork if (!isEligibleToCreateAlert) { - return { - entity: null, - attributes: null, - aggregations: null, - } + return null } let aggregations: Aggregations = [] @@ -93,7 +104,7 @@ export const computeArtworkAlertProps = ( const attributionClass = compact([artwork?.attributionClass?.internalID]) const formattedArtists: SavedSearchEntityArtist[] = artists.map((artist) => ({ id: artist.internalID, - name: artist.name!, + name: artist.name || "", })) const entity: SavedSearchEntity = { @@ -121,10 +132,15 @@ export const computeArtworkAlertProps = ( ] } + const artistSeriesIDs = enableArtistSeriesFilter + ? extractNodes(artwork?.artistSeriesConnection).map((series) => series.slug) + : [] + const attributes: SearchCriteriaAttributes = { artistIDs: formattedArtists.map((artist) => artist.id), attributionClass, additionalGeneIDs, + artistSeriesIDs, } return { diff --git a/src/app/Scenes/Artwork/Artwork.tsx b/src/app/Scenes/Artwork/Artwork.tsx index 327f258c071..ae4bde9e79b 100644 --- a/src/app/Scenes/Artwork/Artwork.tsx +++ b/src/app/Scenes/Artwork/Artwork.tsx @@ -589,7 +589,7 @@ export const ArtworkContainer = createRefetchContainer( } } } - artistSeriesConnection(first: 1) { + artistSeriesConnection(first: 5) { edges { node { filterArtworksConnection(first: 20, input: { sort: "-decayed_merch" }) { diff --git a/src/app/Scenes/Artwork/Components/ArtworksInSeriesRail.tsx b/src/app/Scenes/Artwork/Components/ArtworksInSeriesRail.tsx index c47cf1846e7..79eed5595d7 100644 --- a/src/app/Scenes/Artwork/Components/ArtworksInSeriesRail.tsx +++ b/src/app/Scenes/Artwork/Components/ArtworksInSeriesRail.tsx @@ -57,7 +57,7 @@ const artworkFragment = graphql` fragment ArtworksInSeriesRail_artwork on Artwork { internalID slug - artistSeriesConnection(first: 1) { + artistSeriesConnection(first: 5) { edges { node { slug diff --git a/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorks.tsx b/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorks.tsx index 61d865f674a..18fb94a4985 100644 --- a/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorks.tsx +++ b/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorks.tsx @@ -1,7 +1,7 @@ import { Flex, Screen, Box, Spacer } from "@artsy/palette-mobile" import { BrowseSimilarWorksQuery } from "__generated__/BrowseSimilarWorksQuery.graphql" import { BrowseSimilarWorks_artwork$key } from "__generated__/BrowseSimilarWorks_artwork.graphql" -import { computeArtworkAlertProps } from "app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal" +import { useComputeArtworkAlertProps } from "app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal" import { Aggregations } from "app/Components/ArtworkFilter/ArtworkFilterHelpers" import { SavedSearchEntity, @@ -44,19 +44,23 @@ export interface BrowseSimilarWorksProps { const BrowseSimilarWorks: React.FC<{ artwork: BrowseSimilarWorks_artwork$key }> = (props) => { const artwork = useFragment(similarWorksFragment, props.artwork) + const artworkAlertProps = useComputeArtworkAlertProps(artwork) + if (!artwork.isEligibleToCreateAlert) { return null } - const artworkAlert = computeArtworkAlertProps(artwork) - - const params: BrowseSimilarWorksProps = { - aggregations: artworkAlert.aggregations!, - attributes: artworkAlert.attributes!, - entity: artworkAlert.entity!, + if (!artworkAlertProps) { + return null } - return + return ( + + ) } export const BrowseSimilarWorksQueryRenderer: React.FC<{ artworkID: string }> = withSuspense( @@ -69,7 +73,7 @@ export const BrowseSimilarWorksQueryRenderer: React.FC<{ artworkID: string }> = return } - return + return }, BrowseSimilarWorksPlaceholder ) @@ -84,6 +88,13 @@ const similarWorksFragment = graphql` internalID name } + artistSeriesConnection(first: 5) { + edges { + node { + slug + } + } + } attributionClass { internalID } diff --git a/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorksContent.tsx b/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorksContent.tsx index 710e079a681..5e612ac654e 100644 --- a/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorksContent.tsx +++ b/src/app/Scenes/Artwork/Components/BrowseSimilarWorks/BrowseSimilarWorksContent.tsx @@ -27,13 +27,11 @@ import { graphql, useLazyLoadQuery } from "react-relay" const NUMBER_OF_ARTWORKS_TO_SHOW = 10 -export interface BrowseSimilarWorksContentProps { - params: BrowseSimilarWorksProps -} - -export const BrowseSimilarWorksContent: React.FC = (props) => { - const { params } = props - const { attributes, aggregations, entity } = params +export const BrowseSimilarWorksContent: React.FC = ({ + attributes, + aggregations, + entity, +}) => { const { localizedUnit } = useLocalizedUnit() const { space } = useTheme() const { bottom: bottomInset } = useSafeAreaInsets() diff --git a/src/app/Scenes/SavedSearchAlert/EditSavedSearchAlert.tests.tsx b/src/app/Scenes/SavedSearchAlert/EditSavedSearchAlert.tests.tsx index 975804a91ac..240fb6efd09 100644 --- a/src/app/Scenes/SavedSearchAlert/EditSavedSearchAlert.tests.tsx +++ b/src/app/Scenes/SavedSearchAlert/EditSavedSearchAlert.tests.tsx @@ -47,6 +47,7 @@ describe("EditSavedSearchAlert", () => { expect(screen.getAllByTestId("alert-pill").map(extractText)).toEqual([ "name-1", + "Monkeys", "Lithograph", "Paper", ]) diff --git a/src/app/Scenes/SavedSearchAlert/pillExtractors.ts b/src/app/Scenes/SavedSearchAlert/pillExtractors.ts index b9e556bfd16..bcf6f128d7c 100644 --- a/src/app/Scenes/SavedSearchAlert/pillExtractors.ts +++ b/src/app/Scenes/SavedSearchAlert/pillExtractors.ts @@ -1,3 +1,4 @@ +import { toTitleCase } from "@artsy/to-title-case" import { aggregationForFilter, Aggregations, @@ -156,6 +157,16 @@ export const extractAdditionalGeneIDsPills = (values: string[]): SavedSearchPill }) } +export const extractPillFromArtistSeriesIDs = (values: string[]): SavedSearchPill[] => { + return values.map((value) => { + return { + label: toTitleCase(value.replaceAll("-", " ")), + value, + paramName: SearchCriteria.artistSeriesIDs, + } + }) +} + export const extractPriceRangePill = (value: string): SavedSearchPill => { const { min, max } = parseRange(value) @@ -239,6 +250,10 @@ export const extractPillsFromCriteria = ( return extractAdditionalGeneIDsPills(paramValue) } + if (paramName === SearchCriteria.artistSeriesIDs) { + return extractPillFromArtistSeriesIDs(paramValue) + } + // Extract label from aggregations if (shouldExtractValueNamesFromAggregation.includes(paramName)) { return extractPillFromAggregation(paramName, paramValue, aggregations)