diff --git a/data/schema.graphql b/data/schema.graphql index 447c049a106..0bef2ed3e73 100644 --- a/data/schema.graphql +++ b/data/schema.graphql @@ -3051,6 +3051,9 @@ type Artwork implements Node & Searchable & Sellable { # Whether a user can make an offer on the work through inquiry isOfferableFromInquiry: Boolean isOnHold: String + + # Whether a partner can send an offer for this work + isPartnerOfferable: Boolean! isPartnerPromoted: Boolean # Whether a work is available for pickup @@ -9947,6 +9950,19 @@ type Conversation implements Node { states: [CommerceOrderStateEnum!] ): CommerceOrderConnectionWithTotalCount + # Partner offers for this conversation's artwork, scoped to the user who initiated the conversation (from_id). + partnerOffersConnection( + after: String + before: String + first: Int + last: Int + + # Filter by offer type(s). Gravity defaults to bulk offers when omitted. + offerType: [PartnerOfferTypeEnum] + page: Int + size: Int + ): PartnerOfferConnection + # A connection of orders for artworks in this conversation from the partner's perspective. partnerOrdersConnection( after: String @@ -17895,6 +17911,9 @@ type Me implements Node { before: String first: Int last: Int + + # Filter by offer type(s). Gravity defaults to all a users partner offers when omitted. + offerType: [PartnerOfferTypeEnum] page: Int size: Int sort: PartnerOfferToCollectorSorts diff --git a/src/Apps/Conversations/ConversationsContext.tsx b/src/Apps/Conversations/ConversationsContext.tsx index 80be6933c12..15bf7c1ab35 100644 --- a/src/Apps/Conversations/ConversationsContext.tsx +++ b/src/Apps/Conversations/ConversationsContext.tsx @@ -112,7 +112,7 @@ export const useConversationsContext = () => { const VIEWER_FRAGMENT = graphql` fragment ConversationsContext_viewer on Viewer { me { - partnerOffersConnection(first: 100) { + partnerOffersConnection(first: 100, offerType: [PERSONALIZED]) { edges { node { artworkId diff --git a/src/Apps/Conversations/components/ConversationCTA/ConversationCTA.tsx b/src/Apps/Conversations/components/ConversationCTA/ConversationCTA.tsx index 7ce1658654d..b911a7400ce 100644 --- a/src/Apps/Conversations/components/ConversationCTA/ConversationCTA.tsx +++ b/src/Apps/Conversations/components/ConversationCTA/ConversationCTA.tsx @@ -1,6 +1,7 @@ import VerifiedIcon from "@artsy/icons/VerifiedIcon" import { Box, Flex, type FlexProps, Spacer, Text } from "@artsy/palette" import { themeGet } from "@styled-system/theme-get" +import { useFlag } from "@unleash/proxy-client-react" import { useConversationsContext } from "Apps/Conversations/ConversationsContext" import { ConversationConfirmModal } from "Apps/Conversations/components/ConversationCTA/ConversationConfirmModal" import { ConversationMakeOfferButton } from "Apps/Conversations/components/ConversationCTA/ConversationMakeOfferButton" @@ -31,6 +32,8 @@ export const ConversationCTA: React.FC< partnerOffer?.endAt ?? new Date(0).toISOString(), ) + const isPartnerOfferConvoEnabled = useFlag("topaz_partner-offer-convo") + const activeOrder = extractNodes(data.activeOrderCTA)[0] const activePartnerOffer = !activeOrder && partnerOffer && !partnerOfferTimer.hasEnded @@ -50,7 +53,12 @@ export const ConversationCTA: React.FC< const canPurchase = artwork.isAcquireable || !!activePartnerOffer const canMakeOffer = artwork.isOfferable || artwork.isOfferableFromInquiry const showTransactionButtons = - !activeOrder && artwork.published && (canPurchase || canMakeOffer) + !activeOrder && + // When the new convo offer UI is on, an active offer is shown via the CTA + // bar instead, so the transaction buttons are suppressed. + !(isPartnerOfferConvoEnabled && activePartnerOffer) && + artwork.published && + (canPurchase || canMakeOffer) return ( <> diff --git a/src/Apps/Conversations/components/ConversationCTA/__tests__/ConversationCTA.jest.tsx b/src/Apps/Conversations/components/ConversationCTA/__tests__/ConversationCTA.jest.tsx index b43299d26a8..b4cf87f3c3f 100644 --- a/src/Apps/Conversations/components/ConversationCTA/__tests__/ConversationCTA.jest.tsx +++ b/src/Apps/Conversations/components/ConversationCTA/__tests__/ConversationCTA.jest.tsx @@ -1,4 +1,5 @@ import { screen } from "@testing-library/react" +import { useFlag } from "@unleash/proxy-client-react" import { ConversationsProvider } from "Apps/Conversations/ConversationsContext" import { ConversationCTA } from "Apps/Conversations/components/ConversationCTA/ConversationCTA" import { setupTestWrapperTL } from "DevTools/setupTestWrapperTL" @@ -10,6 +11,8 @@ jest.unmock("react-relay") jest.mock("react-tracking") jest.mock("System/Hooks/useSystemContext") +const mockUseFlag = useFlag as jest.Mock + describe("ConversationCTA", () => { const { renderWithRelay } = setupTestWrapperTL({ Component: (props: any) => ( @@ -190,34 +193,61 @@ describe("ConversationCTA", () => { expect(screen.queryByText("Purchase")).not.toBeInTheDocument() expect(screen.queryByText("Make an Offer")).not.toBeInTheDocument() }) - it("renders purchase button on orders with an active partner offer", () => { + const offerViewer = () => { const futureTime = new Date() futureTime.setHours(futureTime.getHours() + 1) - renderWithRelay({ - Conversation: mockConversationWithArtwork({ - internalID: "artwork-id", - isAcquireable: false, - }), - Viewer: () => ({ - me: { - partnerOffersConnection: { - edges: [ - { - node: { - internalID: "partner-offer-id", - artworkId: "artwork-id", - endAt: futureTime.toISOString(), - }, + return () => ({ + me: { + partnerOffersConnection: { + edges: [ + { + node: { + internalID: "partner-offer-id", + artworkId: "artwork-id", + endAt: futureTime.toISOString(), }, - ], - }, + }, + ], }, - }), + }, }) + } - expect(screen.queryByText("Purchase")).toBeInTheDocument() - expect(screen.queryByText("Make an Offer")).not.toBeInTheDocument() + describe("with the partner-offer-convo flag on", () => { + beforeEach(() => { + mockUseFlag.mockImplementation(() => true) + }) + + it("hides the transaction buttons when there is an active partner offer", () => { + renderWithRelay({ + Conversation: mockConversationWithArtwork({ + internalID: "artwork-id", + isAcquireable: true, + }), + Viewer: offerViewer(), + }) + + expect(screen.queryByText("Purchase")).not.toBeInTheDocument() + expect(screen.queryByText("Make an Offer")).not.toBeInTheDocument() + }) + }) + + describe("with the partner-offer-convo flag off", () => { + beforeEach(() => { + mockUseFlag.mockImplementation(() => false) + }) + + it("ignores the partner offer and shows the normal transaction buttons", () => { + renderWithRelay({ + Conversation: mockConversationWithArtwork({ + internalID: "artwork-id", + isAcquireable: true, + }), + Viewer: offerViewer(), + }) + expect(screen.queryByText("Purchase")).toBeInTheDocument() + }) }) it("renders Make Offer button on MO-only artworks", () => { diff --git a/src/Apps/Conversations/components/ConversationReply.tsx b/src/Apps/Conversations/components/ConversationReply.tsx index fd36a147314..80a4a9e9274 100644 --- a/src/Apps/Conversations/components/ConversationReply.tsx +++ b/src/Apps/Conversations/components/ConversationReply.tsx @@ -1,6 +1,7 @@ import { sentConversationMessage } from "@artsy/cohesion" import { Button, Flex, TextArea, useToasts } from "@artsy/palette" import { ConversationCTA } from "Apps/Conversations/components/ConversationCTA/ConversationCTA" +import { ConversationPartnerOfferCTA } from "Apps/Conversations/components/Message/ConversationPartnerOfferCTA" import { useSendConversationMessage } from "Apps/Conversations/mutations/useSendConversationMessage" import { useRouter } from "System/Hooks/useRouter" import { useSystemContext } from "System/Hooks/useSystemContext" @@ -53,6 +54,7 @@ export const ConversationReply: FC< item { ... on Artwork { id + ...ConversationPartnerOfferCTA_artwork } } } @@ -172,6 +174,8 @@ export const ConversationReply: FC< backgroundColor="mono5" flexDirection="column" > + +
diff --git a/src/Apps/Conversations/components/Message/ConversationPartnerOfferCTA.tsx b/src/Apps/Conversations/components/Message/ConversationPartnerOfferCTA.tsx new file mode 100644 index 00000000000..96fcfe93030 --- /dev/null +++ b/src/Apps/Conversations/components/Message/ConversationPartnerOfferCTA.tsx @@ -0,0 +1,79 @@ +import ChevronRightIcon from "@artsy/icons/ChevronRightIcon" +import { Clickable, Flex, Message, Text } from "@artsy/palette" +import { useFlag } from "@unleash/proxy-client-react" +import { useConversationsContext } from "Apps/Conversations/ConversationsContext" +import { RouterLink } from "System/Components/RouterLink" +import { useTimer } from "Utils/Hooks/useTimer" +import type { ConversationPartnerOfferCTA_artwork$key } from "__generated__/ConversationPartnerOfferCTA_artwork.graphql" +import type { FC } from "react" +import { graphql, useFragment } from "react-relay" + +interface ConversationPartnerOfferCTAProps { + artwork?: ConversationPartnerOfferCTA_artwork$key | null +} + +export const ConversationPartnerOfferCTA: FC< + React.PropsWithChildren +> = ({ artwork }) => { + const isPartnerOfferConvoEnabled = useFlag("topaz_partner-offer-convo") + + const data = useFragment(ARTWORK_FRAGMENT, artwork) + + const { findPartnerOffer } = useConversationsContext() + + const partnerOffer = data?.internalID + ? findPartnerOffer(data.internalID) + : null + + const { hasEnded } = useTimer(partnerOffer?.endAt ?? "") + + if (!isPartnerOfferConvoEnabled || !partnerOffer || !data?.href) { + return null + } + + if (hasEnded || !partnerOffer.isAvailable) { + return null + } + + const message = partnerOffer.priceWithDiscount?.display + ? `Offer Received for ${partnerOffer.priceWithDiscount.display}` + : "Offer Received" + + const href = `${data.href}?partner_offer_id=${partnerOffer.internalID}` + + return ( + + + + + Tap to review the offer from the gallery + + + + + + + ) +} + +const ARTWORK_FRAGMENT = graphql` + fragment ConversationPartnerOfferCTA_artwork on Artwork { + internalID + href + } +` diff --git a/src/Apps/Conversations/components/Message/__tests__/ConversationPartnerOfferCTA.jest.tsx b/src/Apps/Conversations/components/Message/__tests__/ConversationPartnerOfferCTA.jest.tsx new file mode 100644 index 00000000000..a1fecff444a --- /dev/null +++ b/src/Apps/Conversations/components/Message/__tests__/ConversationPartnerOfferCTA.jest.tsx @@ -0,0 +1,129 @@ +import { screen } from "@testing-library/react" +import { useFlag } from "@unleash/proxy-client-react" +import { ConversationsProvider } from "Apps/Conversations/ConversationsContext" +import { ConversationPartnerOfferCTA } from "Apps/Conversations/components/Message/ConversationPartnerOfferCTA" +import { setupTestWrapperTL } from "DevTools/setupTestWrapperTL" +import { graphql } from "react-relay" + +jest.unmock("react-relay") + +const mockUseFlag = useFlag as jest.Mock + +beforeEach(() => { + mockUseFlag.mockImplementation(() => true) +}) + +const futureDate = () => { + const date = new Date() + date.setHours(date.getHours() + 1) + return date.toISOString() +} + +const pastDate = () => { + const date = new Date() + date.setHours(date.getHours() - 1) + return date.toISOString() +} + +const { renderWithRelay } = setupTestWrapperTL({ + Component: (props: any) => ( + + + + ), + query: graphql` + query ConversationPartnerOfferCTA_Test_Query @relay_test_operation { + viewer { + ...ConversationsContext_viewer + } + artwork(id: "artwork-id") { + ...ConversationPartnerOfferCTA_artwork + } + } + `, +}) + +const Artwork = () => ({ + internalID: "artwork-id", + href: "/artwork/some-artwork", +}) + +const offerViewer = (offer: Record) => () => ({ + me: { + partnerOffersConnection: { + edges: [ + { + node: { + internalID: "partner-offer-id", + artworkId: "artwork-id", + isAvailable: true, + priceWithDiscount: { display: "$450" }, + endAt: futureDate(), + ...offer, + }, + }, + ], + }, + }, +}) + +describe("ConversationPartnerOfferCTA", () => { + it("renders the offer bar linking to the artwork with the partner offer id", () => { + renderWithRelay({ Artwork, Viewer: offerViewer({}) }) + + expect(screen.getByText("Offer Received for $450")).toBeInTheDocument() + + expect(screen.getByTestId("partnerOfferActionLink")).toHaveAttribute( + "href", + "/artwork/some-artwork?partner_offer_id=partner-offer-id", + ) + }) + + it("falls back to a generic message when there is no discounted price", () => { + renderWithRelay({ + Artwork, + Viewer: offerViewer({ priceWithDiscount: null }), + }) + + expect(screen.getByText("Offer Received")).toBeInTheDocument() + }) + + it("renders nothing when there is no offer for the artwork", () => { + renderWithRelay({ + Artwork, + Viewer: () => ({ + me: { partnerOffersConnection: { edges: [] } }, + }), + }) + + expect( + screen.queryByTestId("partnerOfferActionLink"), + ).not.toBeInTheDocument() + }) + + it("renders nothing when the offer has expired", () => { + renderWithRelay({ Artwork, Viewer: offerViewer({ endAt: pastDate() }) }) + + expect( + screen.queryByTestId("partnerOfferActionLink"), + ).not.toBeInTheDocument() + }) + + it("renders nothing when the offer is unavailable", () => { + renderWithRelay({ Artwork, Viewer: offerViewer({ isAvailable: false }) }) + + expect( + screen.queryByTestId("partnerOfferActionLink"), + ).not.toBeInTheDocument() + }) + + it("renders nothing when the partner-offer-convo flag is off", () => { + mockUseFlag.mockImplementation(() => false) + + renderWithRelay({ Artwork, Viewer: offerViewer({}) }) + + expect( + screen.queryByTestId("partnerOfferActionLink"), + ).not.toBeInTheDocument() + }) +}) diff --git a/src/Apps/Conversations/components/__tests__/ConversationReply.jest.tsx b/src/Apps/Conversations/components/__tests__/ConversationReply.jest.tsx index d33c4c6f470..a692cb0bdbe 100644 --- a/src/Apps/Conversations/components/__tests__/ConversationReply.jest.tsx +++ b/src/Apps/Conversations/components/__tests__/ConversationReply.jest.tsx @@ -1,6 +1,7 @@ import { sentConversationMessage } from "@artsy/cohesion" import { useToasts } from "@artsy/palette" import { act, fireEvent, screen } from "@testing-library/react" +import { ConversationsProvider } from "Apps/Conversations/ConversationsContext" import { ConversationReply } from "Apps/Conversations/components/ConversationReply" import { setupTestWrapperTL } from "DevTools/setupTestWrapperTL" import type { ConversationReplyTestQuery } from "__generated__/ConversationReplyTestQuery.graphql" @@ -67,14 +68,19 @@ describe("ConversationReply", () => { } const { renderWithRelay } = setupTestWrapperTL({ - Component: ({ conversation }) => ( - + Component: ({ conversation, viewer }) => ( + + + ), query: graphql` query ConversationReplyTestQuery @relay_test_operation { conversation(id: "conversation-id") { ...ConversationReply_conversation } + viewer { + ...ConversationsContext_viewer + } } `, }) diff --git a/src/Apps/Order2/Order2App.tsx b/src/Apps/Order2/Order2App.tsx index a06753d3deb..b1667d8a4ad 100644 --- a/src/Apps/Order2/Order2App.tsx +++ b/src/Apps/Order2/Order2App.tsx @@ -3,6 +3,7 @@ import { CHECKOUT_REDESIGN_FLAG } from "Apps/Order/redirects" import { useTrackFeatureVariantOnMount } from "System/Hooks/useTrackFeatureVariant" import { findCurrentRoute } from "System/Router/Utils/routeUtils" import { useRouter } from "System/Hooks/useRouter" +import { getENV } from "Utils/getENV" import { type FC, type PropsWithChildren, useEffect, useRef } from "react" let navigationGuardsEnabled = true @@ -73,6 +74,15 @@ export const Order2App: FC = ({ children }) => { return true } + // On mobile web, let browser back / swipe-back exit cleanly to the + // artwork without a warning. Farce blocks the navigation by rewinding it + // and showing a `window.confirm`, which the iOS swipe-back gesture cannot + // clear — the user gets rewound back into checkout instead of leaving. So + // we skip the warning on mobile and keep it for desktop only. + if (getENV("IS_MOBILE")) { + return true + } + // leaving the order page, closing, or refreshing const route = findCurrentRoute(match) diff --git a/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx b/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx index 3439c49f5ed..f2eb161fe44 100644 --- a/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx +++ b/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx @@ -38,6 +38,21 @@ const createSteps = (activeStep: CheckoutStepName) => { })) } +const createStepsWithMultipleActive = (activeSteps: CheckoutStepName[]) => { + const activeIndices = activeSteps.map(s => ALL_STEPS.indexOf(s)) + const firstActive = Math.min(...activeIndices) + const lastActive = Math.max(...activeIndices) + return ALL_STEPS.map((name, index) => ({ + name, + state: + index < firstActive + ? CheckoutStepState.COMPLETED + : index >= firstActive && index <= lastActive + ? CheckoutStepState.ACTIVE + : CheckoutStepState.UPCOMING, + })) +} + describe("useCheckoutAutoScroll", () => { let mockJumpTo: jest.Mock @@ -159,4 +174,77 @@ describe("useCheckoutAutoScroll", () => { offset: 30, }) }) + + describe("combined FULFILLMENT_DETAILS + DELIVERY_OPTION step", () => { + it("scrolls to the first active step (FULFILLMENT_DETAILS) on initial load", () => { + const steps = createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]) + + mockUseCheckoutContext.mockReturnValue({ isLoading: true, steps }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ isLoading: false, steps }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("fulfillment-details-step", { + behavior: "smooth", + offset: 30, + }) + }) + + it("scrolls to DELIVERY_OPTION when advancing from the combined step to PAYMENT", () => { + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]), + }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createSteps(CheckoutStepName.PAYMENT), + }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("delivery-options-step", { + behavior: "smooth", + offset: 30, + }) + }) + + it("scrolls to FULFILLMENT_DETAILS when going back from PAYMENT to the combined step", () => { + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createSteps(CheckoutStepName.PAYMENT), + }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]), + }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("fulfillment-details-step", { + behavior: "smooth", + offset: 30, + }) + }) + }) }) diff --git a/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts b/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts index 1c6c13ea7ce..6430405443f 100644 --- a/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts +++ b/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts @@ -24,10 +24,16 @@ export const useCheckoutAutoScroll = () => { const { isLoading, steps } = useCheckoutContext() const { scrollToStep } = useScrollToStep() - const activeStep = steps.find(step => step.state === CheckoutStepState.ACTIVE) + // Combined steps (FULFILLMENT_DETAILS + DELIVERY_OPTION) are ACTIVE + // together, use the last one so forward-advance previousStep is correct. + const activeSteps = steps.filter( + step => step.state === CheckoutStepState.ACTIVE, + ) + const activeStep = activeSteps[0] + const trailingActiveStep = activeSteps[activeSteps.length - 1] const activeStepIndex = stepWithIndex(activeStep, steps) - const previousStep = usePrevious(activeStep) + const previousStep = usePrevious(trailingActiveStep) const previousStepIndex = stepWithIndex(previousStep, steps) const wasLoading = usePrevious(isLoading) diff --git a/src/Apps/Order2/__tests__/Order2App.jest.tsx b/src/Apps/Order2/__tests__/Order2App.jest.tsx index e1b08a304ae..17212654af5 100644 --- a/src/Apps/Order2/__tests__/Order2App.jest.tsx +++ b/src/Apps/Order2/__tests__/Order2App.jest.tsx @@ -2,6 +2,9 @@ import { render } from "@testing-library/react" import { useVariant } from "@unleash/proxy-client-react" import { CHECKOUT_REDESIGN_FLAG } from "Apps/Order/redirects" import { useTrackFeatureVariantOnMount } from "System/Hooks/useTrackFeatureVariant" +import { useRouter } from "System/Hooks/useRouter" +import { findCurrentRoute } from "System/Router/Utils/routeUtils" +import { getENV } from "Utils/getENV" import { Order2App } from "../Order2App" jest.mock("@unleash/proxy-client-react", () => ({ @@ -13,26 +16,39 @@ jest.mock("System/Hooks/useTrackFeatureVariant", () => ({ useTrackFeatureVariantOnMount: jest.fn(), })) -jest.mock("System/Hooks/useRouter", () => ({ - useRouter: () => ({ - router: { - addNavigationListener: jest.fn(() => jest.fn()), - }, - match: {}, - }), -})) - -jest.mock("System/Router/Utils/routeUtils", () => ({ - findCurrentRoute: jest.fn(() => ({})), -})) +jest.mock("System/Hooks/useRouter") +jest.mock("System/Router/Utils/routeUtils") +jest.mock("Utils/getENV") const mockUseVariant = useVariant as jest.Mock const mockUseTrackFeatureVariantOnMount = useTrackFeatureVariantOnMount as jest.Mock +const mockUseRouter = useRouter as jest.Mock +const mockFindCurrentRoute = findCurrentRoute as jest.Mock +const mockGetENV = getENV as jest.Mock + +type TransitionHandler = ( + newLocation: { pathname?: string; action?: string } | null, +) => boolean | string + +let transitionHandler: TransitionHandler | null = null describe("Order2App", () => { beforeEach(() => { jest.clearAllMocks() + transitionHandler = null + mockUseVariant.mockReturnValue({ enabled: false, name: "control" }) + mockFindCurrentRoute.mockReturnValue({}) + mockGetENV.mockReturnValue(false) + mockUseRouter.mockReturnValue({ + router: { + addNavigationListener: jest.fn((handler: TransitionHandler) => { + transitionHandler = handler + return jest.fn() + }), + }, + match: {}, + }) }) it("tracks the experiment variant on mount", () => { @@ -61,4 +77,40 @@ describe("Order2App", () => { variantName: "disabled", }) }) + + describe("leaving the order flow", () => { + const leaveTransition = { pathname: "/artwork/foo", action: "POP" } + + beforeEach(() => { + mockFindCurrentRoute.mockReturnValue({ shouldWarnBeforeLeaving: true }) + }) + + it("warns before leaving on desktop", () => { + mockGetENV.mockReturnValue(false) // IS_MOBILE + render(children) + + expect(transitionHandler?.(leaveTransition)).toBe( + "Are you sure you want to leave? Your changes will not be saved.", + ) + }) + + it("exits cleanly without warning on mobile web (swipe-back)", () => { + mockGetENV.mockReturnValue(true) // IS_MOBILE + render(children) + + expect(transitionHandler?.(leaveTransition)).toBe(true) + }) + + it("never warns when navigating within the order flow", () => { + mockGetENV.mockReturnValue(false) + render(children) + + expect( + transitionHandler?.({ + pathname: "/orders2/123/checkout", + action: "POP", + }), + ).toBe(true) + }) + }) }) diff --git a/src/Components/Address/AddressAutocompleteInput.tsx b/src/Components/Address/AddressAutocompleteInput.tsx index 426d45fea0d..db3570df3b3 100644 --- a/src/Components/Address/AddressAutocompleteInput.tsx +++ b/src/Components/Address/AddressAutocompleteInput.tsx @@ -30,6 +30,7 @@ const { key: API_KEY } = getENV("SMARTY_EMBEDDED_KEY_JSON") || { key: "" } const THROTTLE_DELAY = 500 const INTERNATIONAL_LICENSE = "international-autocomplete-v2-cloud" +const INTERNATIONAL_MAX_RESULTS = 10 const SMARTY_US_AUTOCOMPLETE_URL = "https://us-autocomplete-pro.api.smarty.com/lookup" const SMARTY_INTL_AUTOCOMPLETE_URL = @@ -384,7 +385,7 @@ export const AddressAutocompleteInput = ({ // Multiple entry suggestions require secondary address selection which we // don't have a UI for yet. .filter((c: ProviderSuggestionInternational) => c.entries === 1) - .slice(0, 5), + .slice(0, INTERNATIONAL_MAX_RESULTS), }) } } catch (e) { @@ -596,7 +597,7 @@ const fetchInternationalSuggestionsWithThrottle = throttle( key: apiKey, search, country, - max_results: "5", + max_results: String(INTERNATIONAL_MAX_RESULTS), license: INTERNATIONAL_LICENSE, } diff --git a/src/__generated__/ConversationCTA_Test_Query.graphql.ts b/src/__generated__/ConversationCTA_Test_Query.graphql.ts index 23960e3f1a9..c8cbd4954c0 100644 --- a/src/__generated__/ConversationCTA_Test_Query.graphql.ts +++ b/src/__generated__/ConversationCTA_Test_Query.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -885,6 +885,13 @@ return { "kind": "Literal", "name": "first", "value": 100 + }, + { + "kind": "Literal", + "name": "offerType", + "value": [ + "PERSONALIZED" + ] } ], "concreteType": "PartnerOfferToCollectorConnection", @@ -955,7 +962,7 @@ return { "storageKey": null } ], - "storageKey": "partnerOffersConnection(first:100)" + "storageKey": "partnerOffersConnection(first:100,offerType:[\"PERSONALIZED\"])" }, (v4/*: any*/) ], @@ -967,7 +974,7 @@ return { ] }, "params": { - "cacheID": "15baf297ec0a41c4b3a26d351bc8bdc1", + "cacheID": "c94105435af417530fefb2f1f00c7e99", "id": null, "metadata": { "relayTestingSelectionTypeInfo": { @@ -1156,7 +1163,7 @@ return { }, "name": "ConversationCTA_Test_Query", "operationKind": "query", - "text": "query ConversationCTA_Test_Query {\n me {\n conversation(id: \"1234\") {\n ...ConversationCTA_conversation\n id\n }\n id\n }\n viewer {\n ...ConversationsContext_viewer\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" + "text": "query ConversationCTA_Test_Query {\n me {\n conversation(id: \"1234\") {\n ...ConversationCTA_conversation\n id\n }\n id\n }\n viewer {\n ...ConversationsContext_viewer\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100, offerType: [PERSONALIZED]) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" } }; })(); diff --git a/src/__generated__/ConversationPartnerOfferCTA_Test_Query.graphql.ts b/src/__generated__/ConversationPartnerOfferCTA_Test_Query.graphql.ts new file mode 100644 index 00000000000..e4221b0785c --- /dev/null +++ b/src/__generated__/ConversationPartnerOfferCTA_Test_Query.graphql.ts @@ -0,0 +1,323 @@ +/** + * @generated SignedSource<<53937e9f22dac200a462a6b47638bbd6>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type ConversationPartnerOfferCTA_Test_Query$variables = Record; +export type ConversationPartnerOfferCTA_Test_Query$data = { + readonly artwork: { + readonly " $fragmentSpreads": FragmentRefs<"ConversationPartnerOfferCTA_artwork">; + } | null | undefined; + readonly viewer: { + readonly " $fragmentSpreads": FragmentRefs<"ConversationsContext_viewer">; + } | null | undefined; +}; +export type ConversationPartnerOfferCTA_Test_Query = { + response: ConversationPartnerOfferCTA_Test_Query$data; + variables: ConversationPartnerOfferCTA_Test_Query$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "kind": "Literal", + "name": "id", + "value": "artwork-id" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "internalID", + "storageKey": null +}, +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v3 = { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "String" +}, +v4 = { + "enumValues": null, + "nullable": false, + "plural": false, + "type": "ID" +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "ConversationPartnerOfferCTA_Test_Query", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Viewer", + "kind": "LinkedField", + "name": "viewer", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "ConversationsContext_viewer" + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": "Artwork", + "kind": "LinkedField", + "name": "artwork", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "ConversationPartnerOfferCTA_artwork" + } + ], + "storageKey": "artwork(id:\"artwork-id\")" + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "ConversationPartnerOfferCTA_Test_Query", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Viewer", + "kind": "LinkedField", + "name": "viewer", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Me", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 100 + }, + { + "kind": "Literal", + "name": "offerType", + "value": [ + "PERSONALIZED" + ] + } + ], + "concreteType": "PartnerOfferToCollectorConnection", + "kind": "LinkedField", + "name": "partnerOffersConnection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PartnerOfferToCollectorEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PartnerOfferToCollector", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "artworkId", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endAt", + "storageKey": null + }, + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "isAvailable", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "note", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Money", + "kind": "LinkedField", + "name": "priceWithDiscount", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "display", + "storageKey": null + } + ], + "storageKey": null + }, + (v2/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "partnerOffersConnection(first:100,offerType:[\"PERSONALIZED\"])" + }, + (v2/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v0/*: any*/), + "concreteType": "Artwork", + "kind": "LinkedField", + "name": "artwork", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "href", + "storageKey": null + }, + (v2/*: any*/) + ], + "storageKey": "artwork(id:\"artwork-id\")" + } + ] + }, + "params": { + "cacheID": "790c33dd84f791a1a00504165453f130", + "id": null, + "metadata": { + "relayTestingSelectionTypeInfo": { + "artwork": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Artwork" + }, + "artwork.href": (v3/*: any*/), + "artwork.id": (v4/*: any*/), + "artwork.internalID": (v4/*: any*/), + "viewer": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Viewer" + }, + "viewer.me": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Me" + }, + "viewer.me.id": (v4/*: any*/), + "viewer.me.partnerOffersConnection": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "PartnerOfferToCollectorConnection" + }, + "viewer.me.partnerOffersConnection.edges": { + "enumValues": null, + "nullable": true, + "plural": true, + "type": "PartnerOfferToCollectorEdge" + }, + "viewer.me.partnerOffersConnection.edges.node": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "PartnerOfferToCollector" + }, + "viewer.me.partnerOffersConnection.edges.node.artworkId": (v3/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.endAt": (v3/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.id": (v4/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.internalID": (v4/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.isAvailable": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Boolean" + }, + "viewer.me.partnerOffersConnection.edges.node.note": (v3/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.priceWithDiscount": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Money" + }, + "viewer.me.partnerOffersConnection.edges.node.priceWithDiscount.display": (v3/*: any*/) + } + }, + "name": "ConversationPartnerOfferCTA_Test_Query", + "operationKind": "query", + "text": "query ConversationPartnerOfferCTA_Test_Query {\n viewer {\n ...ConversationsContext_viewer\n }\n artwork(id: \"artwork-id\") {\n ...ConversationPartnerOfferCTA_artwork\n id\n }\n}\n\nfragment ConversationPartnerOfferCTA_artwork on Artwork {\n internalID\n href\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100, offerType: [PERSONALIZED]) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n" + } +}; +})(); + +(node as any).hash = "7305faed3dafe4e7d5c3c8b33f419db9"; + +export default node; diff --git a/src/__generated__/ConversationPartnerOfferCTA_artwork.graphql.ts b/src/__generated__/ConversationPartnerOfferCTA_artwork.graphql.ts new file mode 100644 index 00000000000..3f54b0d75a5 --- /dev/null +++ b/src/__generated__/ConversationPartnerOfferCTA_artwork.graphql.ts @@ -0,0 +1,50 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type ConversationPartnerOfferCTA_artwork$data = { + readonly href: string | null | undefined; + readonly internalID: string; + readonly " $fragmentType": "ConversationPartnerOfferCTA_artwork"; +}; +export type ConversationPartnerOfferCTA_artwork$key = { + readonly " $data"?: ConversationPartnerOfferCTA_artwork$data; + readonly " $fragmentSpreads": FragmentRefs<"ConversationPartnerOfferCTA_artwork">; +}; + +const node: ReaderFragment = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "ConversationPartnerOfferCTA_artwork", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "internalID", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "href", + "storageKey": null + } + ], + "type": "Artwork", + "abstractKey": null +}; + +(node as any).hash = "de318ab3b87c9382c433addbdb571356"; + +export default node; diff --git a/src/__generated__/ConversationReplyTestQuery.graphql.ts b/src/__generated__/ConversationReplyTestQuery.graphql.ts index a159713cdfc..f759bd74e84 100644 --- a/src/__generated__/ConversationReplyTestQuery.graphql.ts +++ b/src/__generated__/ConversationReplyTestQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<9145dfab6f905a94976283e3b8d36fb3>> * @lightSyntaxTransform * @nogrep */ @@ -15,6 +15,9 @@ export type ConversationReplyTestQuery$data = { readonly conversation: { readonly " $fragmentSpreads": FragmentRefs<"ConversationReply_conversation">; } | null | undefined; + readonly viewer: { + readonly " $fragmentSpreads": FragmentRefs<"ConversationsContext_viewer">; + } | null | undefined; }; export type ConversationReplyTestQuery = { response: ConversationReplyTestQuery$data; @@ -111,11 +114,7 @@ v11 = { "type": "Node", "abstractKey": "__isNode" }, -v12 = [ - (v1/*: any*/), - (v4/*: any*/) -], -v13 = { +v12 = { "kind": "Literal", "name": "states", "value": [ @@ -126,35 +125,35 @@ v13 = { "REFUNDED" ] }, -v14 = { +v13 = { "alias": null, "args": null, "kind": "ScalarField", "name": "state", "storageKey": null }, -v15 = { +v14 = { "alias": null, "args": null, "kind": "ScalarField", "name": "stateReason", "storageKey": null }, -v16 = { +v15 = { "alias": null, "args": null, "kind": "ScalarField", "name": "stateExpiresAt", "storageKey": null }, -v17 = { +v16 = { "alias": null, "args": null, "kind": "ScalarField", "name": "buyerAction", "storageKey": null }, -v18 = { +v17 = { "alias": null, "args": [ { @@ -183,7 +182,10 @@ v18 = { "kind": "LinkedField", "name": "node", "plural": false, - "selections": (v12/*: any*/), + "selections": [ + (v1/*: any*/), + (v4/*: any*/) + ], "storageKey": null } ], @@ -192,31 +194,31 @@ v18 = { ], "storageKey": "offers(first:5)" }, -v19 = { +v18 = { "enumValues": null, "nullable": true, "plural": false, "type": "CommerceOrderConnectionWithTotalCount" }, -v20 = { +v19 = { "enumValues": null, "nullable": true, "plural": true, "type": "CommerceOrderEdge" }, -v21 = { +v20 = { "enumValues": null, "nullable": true, "plural": false, "type": "CommerceOrder" }, -v22 = { +v21 = { "enumValues": null, "nullable": false, "plural": false, "type": "String" }, -v23 = { +v22 = { "enumValues": [ "OFFER_ACCEPTED", "OFFER_ACCEPTED_CONFIRM_NEEDED", @@ -229,31 +231,31 @@ v23 = { "plural": false, "type": "CommerceBuyerOfferActionEnum" }, -v24 = { +v23 = { "enumValues": null, "nullable": false, "plural": false, "type": "ID" }, -v25 = { +v24 = { "enumValues": null, "nullable": true, "plural": false, "type": "CommerceOfferConnection" }, -v26 = { +v25 = { "enumValues": null, "nullable": true, "plural": true, "type": "CommerceOfferEdge" }, -v27 = { +v26 = { "enumValues": null, "nullable": true, "plural": false, "type": "CommerceOffer" }, -v28 = { +v27 = { "enumValues": [ "ABANDONED", "APPROVED", @@ -269,37 +271,37 @@ v28 = { "plural": false, "type": "CommerceOrderStateEnum" }, -v29 = { +v28 = { "enumValues": null, "nullable": true, "plural": false, "type": "String" }, -v30 = { +v29 = { "enumValues": null, "nullable": true, "plural": false, "type": "ConversationItemType" }, -v31 = { +v30 = { "enumValues": null, "nullable": true, "plural": false, "type": "ArtworkInfoRow" }, -v32 = { +v31 = { "enumValues": null, "nullable": true, "plural": false, "type": "dimensions" }, -v33 = { +v32 = { "enumValues": null, "nullable": true, "plural": false, "type": "Boolean" }, -v34 = { +v33 = { "enumValues": null, "nullable": true, "plural": false, @@ -327,6 +329,22 @@ return { } ], "storageKey": "conversation(id:\"conversation-id\")" + }, + { + "alias": null, + "args": null, + "concreteType": "Viewer", + "kind": "LinkedField", + "name": "viewer", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "ConversationsContext_viewer" + } + ], + "storageKey": null } ], "type": "Query", @@ -660,7 +678,17 @@ return { (v2/*: any*/), { "kind": "InlineFragment", - "selections": (v12/*: any*/), + "selections": [ + (v1/*: any*/), + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "href", + "storageKey": null + } + ], "type": "Artwork", "abstractKey": null }, @@ -679,7 +707,7 @@ return { "name": "first", "value": 1 }, - (v13/*: any*/) + (v12/*: any*/) ], "concreteType": "CommerceOrderConnectionWithTotalCount", "kind": "LinkedField", @@ -704,9 +732,9 @@ return { "selections": [ (v2/*: any*/), (v1/*: any*/), + (v13/*: any*/), (v14/*: any*/), (v15/*: any*/), - (v16/*: any*/), { "alias": null, "args": null, @@ -717,7 +745,7 @@ return { { "kind": "InlineFragment", "selections": [ - (v17/*: any*/), + (v16/*: any*/), { "alias": null, "args": null, @@ -737,7 +765,7 @@ return { ], "storageKey": null }, - (v18/*: any*/) + (v17/*: any*/) ], "type": "CommerceOfferOrder", "abstractKey": null @@ -760,7 +788,7 @@ return { "name": "first", "value": 10 }, - (v13/*: any*/) + (v12/*: any*/) ], "concreteType": "CommerceOrderConnectionWithTotalCount", "kind": "LinkedField", @@ -785,14 +813,14 @@ return { "selections": [ (v2/*: any*/), (v1/*: any*/), + (v13/*: any*/), (v14/*: any*/), (v15/*: any*/), - (v16/*: any*/), { "kind": "InlineFragment", "selections": [ - (v17/*: any*/), - (v18/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "type": "CommerceOfferOrder", "abstractKey": null @@ -843,11 +871,120 @@ return { (v4/*: any*/) ], "storageKey": "conversation(id:\"conversation-id\")" + }, + { + "alias": null, + "args": null, + "concreteType": "Viewer", + "kind": "LinkedField", + "name": "viewer", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Me", + "kind": "LinkedField", + "name": "me", + "plural": false, + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 100 + }, + { + "kind": "Literal", + "name": "offerType", + "value": [ + "PERSONALIZED" + ] + } + ], + "concreteType": "PartnerOfferToCollectorConnection", + "kind": "LinkedField", + "name": "partnerOffersConnection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PartnerOfferToCollectorEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PartnerOfferToCollector", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "artworkId", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endAt", + "storageKey": null + }, + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "isAvailable", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "note", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Money", + "kind": "LinkedField", + "name": "priceWithDiscount", + "plural": false, + "selections": (v7/*: any*/), + "storageKey": null + }, + (v4/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "partnerOffersConnection(first:100,offerType:[\"PERSONALIZED\"])" + }, + (v4/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null } ] }, "params": { - "cacheID": "34daf05447a2b6c8c6ee7491e9e3d023", + "cacheID": "ff4c982e0182eb5758a2368c94398dbc", "id": null, "metadata": { "relayTestingSelectionTypeInfo": { @@ -857,50 +994,50 @@ return { "plural": false, "type": "Conversation" }, - "conversation.activeOrderCTA": (v19/*: any*/), - "conversation.activeOrderCTA.edges": (v20/*: any*/), - "conversation.activeOrderCTA.edges.node": (v21/*: any*/), - "conversation.activeOrderCTA.edges.node.__typename": (v22/*: any*/), - "conversation.activeOrderCTA.edges.node.buyerAction": (v23/*: any*/), - "conversation.activeOrderCTA.edges.node.id": (v24/*: any*/), - "conversation.activeOrderCTA.edges.node.internalID": (v24/*: any*/), - "conversation.activeOrderCTA.edges.node.offers": (v25/*: any*/), - "conversation.activeOrderCTA.edges.node.offers.edges": (v26/*: any*/), - "conversation.activeOrderCTA.edges.node.offers.edges.node": (v27/*: any*/), - "conversation.activeOrderCTA.edges.node.offers.edges.node.id": (v24/*: any*/), - "conversation.activeOrderCTA.edges.node.offers.edges.node.internalID": (v24/*: any*/), - "conversation.activeOrderCTA.edges.node.state": (v28/*: any*/), - "conversation.activeOrderCTA.edges.node.stateExpiresAt": (v29/*: any*/), - "conversation.activeOrderCTA.edges.node.stateReason": (v29/*: any*/), - "conversation.activeOrders": (v19/*: any*/), - "conversation.activeOrders.edges": (v20/*: any*/), - "conversation.activeOrders.edges.node": (v21/*: any*/), - "conversation.activeOrders.edges.node.__typename": (v22/*: any*/), - "conversation.activeOrders.edges.node.buyerAction": (v23/*: any*/), - "conversation.activeOrders.edges.node.id": (v24/*: any*/), - "conversation.activeOrders.edges.node.internalID": (v24/*: any*/), - "conversation.activeOrders.edges.node.lastOffer": (v27/*: any*/), - "conversation.activeOrders.edges.node.lastOffer.createdAt": (v22/*: any*/), - "conversation.activeOrders.edges.node.lastOffer.id": (v24/*: any*/), - "conversation.activeOrders.edges.node.offers": (v25/*: any*/), - "conversation.activeOrders.edges.node.offers.edges": (v26/*: any*/), - "conversation.activeOrders.edges.node.offers.edges.node": (v27/*: any*/), - "conversation.activeOrders.edges.node.offers.edges.node.id": (v24/*: any*/), - "conversation.activeOrders.edges.node.offers.edges.node.internalID": (v24/*: any*/), - "conversation.activeOrders.edges.node.state": (v28/*: any*/), - "conversation.activeOrders.edges.node.stateExpiresAt": (v29/*: any*/), - "conversation.activeOrders.edges.node.stateReason": (v29/*: any*/), - "conversation.activeOrders.edges.node.stateUpdatedAt": (v29/*: any*/), + "conversation.activeOrderCTA": (v18/*: any*/), + "conversation.activeOrderCTA.edges": (v19/*: any*/), + "conversation.activeOrderCTA.edges.node": (v20/*: any*/), + "conversation.activeOrderCTA.edges.node.__typename": (v21/*: any*/), + "conversation.activeOrderCTA.edges.node.buyerAction": (v22/*: any*/), + "conversation.activeOrderCTA.edges.node.id": (v23/*: any*/), + "conversation.activeOrderCTA.edges.node.internalID": (v23/*: any*/), + "conversation.activeOrderCTA.edges.node.offers": (v24/*: any*/), + "conversation.activeOrderCTA.edges.node.offers.edges": (v25/*: any*/), + "conversation.activeOrderCTA.edges.node.offers.edges.node": (v26/*: any*/), + "conversation.activeOrderCTA.edges.node.offers.edges.node.id": (v23/*: any*/), + "conversation.activeOrderCTA.edges.node.offers.edges.node.internalID": (v23/*: any*/), + "conversation.activeOrderCTA.edges.node.state": (v27/*: any*/), + "conversation.activeOrderCTA.edges.node.stateExpiresAt": (v28/*: any*/), + "conversation.activeOrderCTA.edges.node.stateReason": (v28/*: any*/), + "conversation.activeOrders": (v18/*: any*/), + "conversation.activeOrders.edges": (v19/*: any*/), + "conversation.activeOrders.edges.node": (v20/*: any*/), + "conversation.activeOrders.edges.node.__typename": (v21/*: any*/), + "conversation.activeOrders.edges.node.buyerAction": (v22/*: any*/), + "conversation.activeOrders.edges.node.id": (v23/*: any*/), + "conversation.activeOrders.edges.node.internalID": (v23/*: any*/), + "conversation.activeOrders.edges.node.lastOffer": (v26/*: any*/), + "conversation.activeOrders.edges.node.lastOffer.createdAt": (v21/*: any*/), + "conversation.activeOrders.edges.node.lastOffer.id": (v23/*: any*/), + "conversation.activeOrders.edges.node.offers": (v24/*: any*/), + "conversation.activeOrders.edges.node.offers.edges": (v25/*: any*/), + "conversation.activeOrders.edges.node.offers.edges.node": (v26/*: any*/), + "conversation.activeOrders.edges.node.offers.edges.node.id": (v23/*: any*/), + "conversation.activeOrders.edges.node.offers.edges.node.internalID": (v23/*: any*/), + "conversation.activeOrders.edges.node.state": (v27/*: any*/), + "conversation.activeOrders.edges.node.stateExpiresAt": (v28/*: any*/), + "conversation.activeOrders.edges.node.stateReason": (v28/*: any*/), + "conversation.activeOrders.edges.node.stateUpdatedAt": (v28/*: any*/), "conversation.from": { "enumValues": null, "nullable": false, "plural": false, "type": "ConversationInitiator" }, - "conversation.from.email": (v22/*: any*/), - "conversation.from.id": (v24/*: any*/), - "conversation.id": (v24/*: any*/), - "conversation.inquiryID": (v29/*: any*/), + "conversation.from.email": (v21/*: any*/), + "conversation.from.id": (v23/*: any*/), + "conversation.id": (v23/*: any*/), + "conversation.inquiryID": (v28/*: any*/), "conversation.internalID": { "enumValues": null, "nullable": true, @@ -913,58 +1050,59 @@ return { "plural": true, "type": "ConversationItem" }, - "conversation.items.item": (v30/*: any*/), - "conversation.items.item.__isNode": (v22/*: any*/), - "conversation.items.item.__typename": (v22/*: any*/), - "conversation.items.item.id": (v24/*: any*/), - "conversation.items.item.internalID": (v24/*: any*/), - "conversation.items.liveArtwork": (v30/*: any*/), - "conversation.items.liveArtwork.__isNode": (v22/*: any*/), - "conversation.items.liveArtwork.__typename": (v22/*: any*/), - "conversation.items.liveArtwork.artistNames": (v29/*: any*/), + "conversation.items.item": (v29/*: any*/), + "conversation.items.item.__isNode": (v21/*: any*/), + "conversation.items.item.__typename": (v21/*: any*/), + "conversation.items.item.href": (v28/*: any*/), + "conversation.items.item.id": (v23/*: any*/), + "conversation.items.item.internalID": (v23/*: any*/), + "conversation.items.liveArtwork": (v29/*: any*/), + "conversation.items.liveArtwork.__isNode": (v21/*: any*/), + "conversation.items.liveArtwork.__typename": (v21/*: any*/), + "conversation.items.liveArtwork.artistNames": (v28/*: any*/), "conversation.items.liveArtwork.attributionClass": { "enumValues": null, "nullable": true, "plural": false, "type": "AttributionClass" }, - "conversation.items.liveArtwork.attributionClass.id": (v24/*: any*/), - "conversation.items.liveArtwork.attributionClass.name": (v29/*: any*/), - "conversation.items.liveArtwork.category": (v29/*: any*/), - "conversation.items.liveArtwork.certificateOfAuthenticity": (v31/*: any*/), - "conversation.items.liveArtwork.certificateOfAuthenticity.details": (v29/*: any*/), - "conversation.items.liveArtwork.conditionDescription": (v31/*: any*/), - "conversation.items.liveArtwork.conditionDescription.details": (v29/*: any*/), - "conversation.items.liveArtwork.date": (v29/*: any*/), - "conversation.items.liveArtwork.dimensions": (v32/*: any*/), - "conversation.items.liveArtwork.dimensions.cm": (v29/*: any*/), - "conversation.items.liveArtwork.dimensions.in": (v29/*: any*/), + "conversation.items.liveArtwork.attributionClass.id": (v23/*: any*/), + "conversation.items.liveArtwork.attributionClass.name": (v28/*: any*/), + "conversation.items.liveArtwork.category": (v28/*: any*/), + "conversation.items.liveArtwork.certificateOfAuthenticity": (v30/*: any*/), + "conversation.items.liveArtwork.certificateOfAuthenticity.details": (v28/*: any*/), + "conversation.items.liveArtwork.conditionDescription": (v30/*: any*/), + "conversation.items.liveArtwork.conditionDescription.details": (v28/*: any*/), + "conversation.items.liveArtwork.date": (v28/*: any*/), + "conversation.items.liveArtwork.dimensions": (v31/*: any*/), + "conversation.items.liveArtwork.dimensions.cm": (v28/*: any*/), + "conversation.items.liveArtwork.dimensions.in": (v28/*: any*/), "conversation.items.liveArtwork.editionSets": { "enumValues": null, "nullable": true, "plural": true, "type": "EditionSet" }, - "conversation.items.liveArtwork.editionSets.dimensions": (v32/*: any*/), - "conversation.items.liveArtwork.editionSets.dimensions.cm": (v29/*: any*/), - "conversation.items.liveArtwork.editionSets.dimensions.in": (v29/*: any*/), - "conversation.items.liveArtwork.editionSets.editionOf": (v29/*: any*/), - "conversation.items.liveArtwork.editionSets.id": (v24/*: any*/), - "conversation.items.liveArtwork.editionSets.internalID": (v24/*: any*/), - "conversation.items.liveArtwork.editionSets.isAcquireable": (v33/*: any*/), - "conversation.items.liveArtwork.editionSets.isOfferable": (v33/*: any*/), - "conversation.items.liveArtwork.editionSets.isOfferableFromInquiry": (v33/*: any*/), + "conversation.items.liveArtwork.editionSets.dimensions": (v31/*: any*/), + "conversation.items.liveArtwork.editionSets.dimensions.cm": (v28/*: any*/), + "conversation.items.liveArtwork.editionSets.dimensions.in": (v28/*: any*/), + "conversation.items.liveArtwork.editionSets.editionOf": (v28/*: any*/), + "conversation.items.liveArtwork.editionSets.id": (v23/*: any*/), + "conversation.items.liveArtwork.editionSets.internalID": (v23/*: any*/), + "conversation.items.liveArtwork.editionSets.isAcquireable": (v32/*: any*/), + "conversation.items.liveArtwork.editionSets.isOfferable": (v32/*: any*/), + "conversation.items.liveArtwork.editionSets.isOfferableFromInquiry": (v32/*: any*/), "conversation.items.liveArtwork.editionSets.listPrice": { "enumValues": null, "nullable": true, "plural": false, "type": "ListPrice" }, - "conversation.items.liveArtwork.editionSets.listPrice.__typename": (v22/*: any*/), - "conversation.items.liveArtwork.editionSets.listPrice.display": (v29/*: any*/), - "conversation.items.liveArtwork.framed": (v31/*: any*/), - "conversation.items.liveArtwork.framed.details": (v29/*: any*/), - "conversation.items.liveArtwork.id": (v24/*: any*/), + "conversation.items.liveArtwork.editionSets.listPrice.__typename": (v21/*: any*/), + "conversation.items.liveArtwork.editionSets.listPrice.display": (v28/*: any*/), + "conversation.items.liveArtwork.framed": (v30/*: any*/), + "conversation.items.liveArtwork.framed.details": (v28/*: any*/), + "conversation.items.liveArtwork.id": (v23/*: any*/), "conversation.items.liveArtwork.image": { "enumValues": null, "nullable": true, @@ -977,39 +1115,83 @@ return { "plural": false, "type": "ResizedImageUrl" }, - "conversation.items.liveArtwork.image.resized.height": (v34/*: any*/), - "conversation.items.liveArtwork.image.resized.src": (v22/*: any*/), - "conversation.items.liveArtwork.image.resized.srcSet": (v22/*: any*/), - "conversation.items.liveArtwork.image.resized.width": (v34/*: any*/), - "conversation.items.liveArtwork.internalID": (v24/*: any*/), - "conversation.items.liveArtwork.isAcquireable": (v33/*: any*/), - "conversation.items.liveArtwork.isEdition": (v33/*: any*/), - "conversation.items.liveArtwork.isOfferable": (v33/*: any*/), - "conversation.items.liveArtwork.isOfferableFromInquiry": (v33/*: any*/), - "conversation.items.liveArtwork.manufacturer": (v29/*: any*/), - "conversation.items.liveArtwork.medium": (v29/*: any*/), + "conversation.items.liveArtwork.image.resized.height": (v33/*: any*/), + "conversation.items.liveArtwork.image.resized.src": (v21/*: any*/), + "conversation.items.liveArtwork.image.resized.srcSet": (v21/*: any*/), + "conversation.items.liveArtwork.image.resized.width": (v33/*: any*/), + "conversation.items.liveArtwork.internalID": (v23/*: any*/), + "conversation.items.liveArtwork.isAcquireable": (v32/*: any*/), + "conversation.items.liveArtwork.isEdition": (v32/*: any*/), + "conversation.items.liveArtwork.isOfferable": (v32/*: any*/), + "conversation.items.liveArtwork.isOfferableFromInquiry": (v32/*: any*/), + "conversation.items.liveArtwork.manufacturer": (v28/*: any*/), + "conversation.items.liveArtwork.medium": (v28/*: any*/), "conversation.items.liveArtwork.published": { "enumValues": null, "nullable": false, "plural": false, "type": "Boolean" }, - "conversation.items.liveArtwork.publisher": (v29/*: any*/), - "conversation.items.liveArtwork.saleMessage": (v29/*: any*/), - "conversation.items.liveArtwork.signatureInfo": (v31/*: any*/), - "conversation.items.liveArtwork.signatureInfo.details": (v29/*: any*/), - "conversation.items.liveArtwork.slug": (v24/*: any*/), - "conversation.items.liveArtwork.title": (v29/*: any*/), - "conversation.lastMessageID": (v29/*: any*/) + "conversation.items.liveArtwork.publisher": (v28/*: any*/), + "conversation.items.liveArtwork.saleMessage": (v28/*: any*/), + "conversation.items.liveArtwork.signatureInfo": (v30/*: any*/), + "conversation.items.liveArtwork.signatureInfo.details": (v28/*: any*/), + "conversation.items.liveArtwork.slug": (v23/*: any*/), + "conversation.items.liveArtwork.title": (v28/*: any*/), + "conversation.lastMessageID": (v28/*: any*/), + "viewer": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Viewer" + }, + "viewer.me": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Me" + }, + "viewer.me.id": (v23/*: any*/), + "viewer.me.partnerOffersConnection": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "PartnerOfferToCollectorConnection" + }, + "viewer.me.partnerOffersConnection.edges": { + "enumValues": null, + "nullable": true, + "plural": true, + "type": "PartnerOfferToCollectorEdge" + }, + "viewer.me.partnerOffersConnection.edges.node": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "PartnerOfferToCollector" + }, + "viewer.me.partnerOffersConnection.edges.node.artworkId": (v28/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.endAt": (v28/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.id": (v23/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.internalID": (v23/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.isAvailable": (v32/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.note": (v28/*: any*/), + "viewer.me.partnerOffersConnection.edges.node.priceWithDiscount": { + "enumValues": null, + "nullable": true, + "plural": false, + "type": "Money" + }, + "viewer.me.partnerOffersConnection.edges.node.priceWithDiscount.display": (v28/*: any*/) } }, "name": "ConversationReplyTestQuery", "operationKind": "query", - "text": "query ConversationReplyTestQuery {\n conversation(id: \"conversation-id\") {\n ...ConversationReply_conversation\n id\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationReply_conversation on Conversation {\n ...ConversationCTA_conversation\n from {\n email\n id\n }\n internalID\n inquiryID\n items {\n item {\n __typename\n ... on Artwork {\n id\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n lastMessageID\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" + "text": "query ConversationReplyTestQuery {\n conversation(id: \"conversation-id\") {\n ...ConversationReply_conversation\n id\n }\n viewer {\n ...ConversationsContext_viewer\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationPartnerOfferCTA_artwork on Artwork {\n internalID\n href\n}\n\nfragment ConversationReply_conversation on Conversation {\n ...ConversationCTA_conversation\n from {\n email\n id\n }\n internalID\n inquiryID\n items {\n item {\n __typename\n ... on Artwork {\n id\n ...ConversationPartnerOfferCTA_artwork\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n lastMessageID\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100, offerType: [PERSONALIZED]) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "4d5aab4bef53aaecf5bcdeb6484be827"; +(node as any).hash = "09613682f1b0fe9ff045af80a2573df0"; export default node; diff --git a/src/__generated__/ConversationReply_conversation.graphql.ts b/src/__generated__/ConversationReply_conversation.graphql.ts index 5e88f8056a2..90d4c2d8b06 100644 --- a/src/__generated__/ConversationReply_conversation.graphql.ts +++ b/src/__generated__/ConversationReply_conversation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<680e15471477393d79f124137dc08a61>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -20,6 +20,7 @@ export type ConversationReply_conversation$data = { readonly items: ReadonlyArray<{ readonly item: { readonly id?: string; + readonly " $fragmentSpreads": FragmentRefs<"ConversationPartnerOfferCTA_artwork">; } | null | undefined; } | null | undefined> | null | undefined; readonly lastMessageID: string | null | undefined; @@ -122,7 +123,12 @@ return { { "kind": "InlineFragment", "selections": [ - (v0/*: any*/) + (v0/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "ConversationPartnerOfferCTA_artwork" + } ], "type": "Artwork", "abstractKey": null @@ -146,6 +152,6 @@ return { }; })(); -(node as any).hash = "0d2f6c610b891b6030defa169a4fced8"; +(node as any).hash = "b4060d5aefcc1b137a58e3cc8c1fee86"; export default node; diff --git a/src/__generated__/ConversationsContext_viewer.graphql.ts b/src/__generated__/ConversationsContext_viewer.graphql.ts index a00448978a9..14148a59718 100644 --- a/src/__generated__/ConversationsContext_viewer.graphql.ts +++ b/src/__generated__/ConversationsContext_viewer.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<06e03afca4440032fa2a512879535fa7>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -55,6 +55,13 @@ const node: ReaderFragment = { "kind": "Literal", "name": "first", "value": 100 + }, + { + "kind": "Literal", + "name": "offerType", + "value": [ + "PERSONALIZED" + ] } ], "concreteType": "PartnerOfferToCollectorConnection", @@ -138,7 +145,7 @@ const node: ReaderFragment = { "storageKey": null } ], - "storageKey": "partnerOffersConnection(first:100)" + "storageKey": "partnerOffersConnection(first:100,offerType:[\"PERSONALIZED\"])" } ], "storageKey": null @@ -148,6 +155,6 @@ const node: ReaderFragment = { "abstractKey": null }; -(node as any).hash = "5bdddd04d3159d6b16ce2807b96d0637"; +(node as any).hash = "a29414d4d23a61cab0a39cebaf39ac56"; export default node; diff --git a/src/__generated__/conversationsRoutes_DetailQuery.graphql.ts b/src/__generated__/conversationsRoutes_DetailQuery.graphql.ts index 998413636bd..3525c8dceb8 100644 --- a/src/__generated__/conversationsRoutes_DetailQuery.graphql.ts +++ b/src/__generated__/conversationsRoutes_DetailQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<5a1abd6328aef455000bfcca8ef19048>> * @lightSyntaxTransform * @nogrep */ @@ -704,6 +704,13 @@ return { "kind": "Literal", "name": "first", "value": 100 + }, + { + "kind": "Literal", + "name": "offerType", + "value": [ + "PERSONALIZED" + ] } ], "concreteType": "PartnerOfferToCollectorConnection", @@ -774,7 +781,7 @@ return { "storageKey": null } ], - "storageKey": "partnerOffersConnection(first:100)" + "storageKey": "partnerOffersConnection(first:100,offerType:[\"PERSONALIZED\"])" }, (v8/*: any*/) ], @@ -922,9 +929,6 @@ return { "storageKey": null }, (v13/*: any*/), - (v23/*: any*/), - (v24/*: any*/), - (v25/*: any*/), { "alias": null, "args": null, @@ -932,6 +936,9 @@ return { "name": "href", "storageKey": null }, + (v23/*: any*/), + (v24/*: any*/), + (v25/*: any*/), (v26/*: any*/) ], "type": "Artwork", @@ -1899,12 +1906,12 @@ return { ] }, "params": { - "cacheID": "57b58cecf9e4c92648d79ab5bc21ef82", + "cacheID": "ec043bad31012031139278702c08d7c7", "id": null, "metadata": {}, "name": "conversationsRoutes_DetailQuery", "operationKind": "query", - "text": "query conversationsRoutes_DetailQuery(\n $conversationId: String!\n $first: Int\n) {\n viewer {\n ...ConversationApp_viewer_3ASum4\n }\n conversation(id: $conversationId) {\n ...ConversationApp_conversation\n id\n }\n}\n\nfragment ConversationApp_conversation on Conversation {\n ...ConversationHeader_conversation\n ...ConversationDetails_conversation\n ...ConversationReply_conversation\n ...ConversationMessages_conversation\n}\n\nfragment ConversationApp_viewer_3ASum4 on Viewer {\n ...ConversationsSidebar_viewer_3ASum4\n ...ConversationsContext_viewer\n}\n\nfragment ConversationArtwork_conversation on Conversation {\n items {\n item {\n __typename\n ... on Artwork {\n id\n slug\n date\n title\n isUnlisted\n artist(shallow: true) {\n name\n slug\n id\n }\n image {\n url\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment ConversationAttachments_conversation on Conversation {\n attachmentsConnection: messagesConnection(first: 30, sort: DESC) {\n edges {\n node {\n attachments {\n id\n contentType\n fileName\n downloadURL\n }\n id\n }\n }\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationDetails_conversation on Conversation {\n internalID\n orderConnection(first: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED, CANCELED]) {\n edges {\n node {\n __typename\n ...ConversationOrderInformation_order\n id\n }\n }\n }\n ...ConversationArtwork_conversation\n ...ConversationAttachments_conversation\n}\n\nfragment ConversationHeader_conversation on Conversation {\n from {\n name\n id\n }\n to {\n name\n id\n }\n items {\n item {\n __typename\n ... on Artwork {\n internalID\n id\n slug\n date\n title\n artist(shallow: true) {\n name\n id\n }\n image {\n url\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n orderConnection(first: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED, CANCELED]) {\n edges {\n node {\n __typename\n ...ReviewOrderButton_order\n id\n }\n }\n }\n}\n\nfragment ConversationMessageArtwork_item on ConversationItemType {\n __isConversationItemType: __typename\n __typename\n ... on Artwork {\n internalID\n id\n date\n title\n artistNames\n href\n isOfferableFromInquiry\n image {\n resized(width: 1350) {\n url\n width\n height\n }\n aspectRatio\n }\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n }\n}\n\nfragment ConversationMessage_message on Message {\n __typename\n id\n internalID\n attachments {\n internalID\n contentType\n downloadURL\n fileName\n id\n }\n body\n createdAt\n isMessageSentOnPlatform\n deliveries {\n openedAt\n fullTransformedEmail\n id\n }\n isFromUser\n isFirstMessage\n from {\n name\n }\n to\n cc\n}\n\nfragment ConversationMessages_conversation on Conversation {\n internalID\n fromLastViewedMessageID\n unreadByCollector\n to {\n name\n initials(length: 2)\n id\n }\n messagesConnection(first: 15, sort: DESC) {\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n node {\n id\n internalID\n createdAt\n isFromUser\n ...ConversationMessage_message\n __typename\n }\n cursor\n }\n }\n inquiryRequest {\n formattedFirstMessage\n id\n }\n items {\n item {\n __typename\n ... on Artwork {\n id\n isOfferable\n isOfferableFromInquiry\n internalID\n }\n ...ConversationMessageArtwork_item\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n orderEvents: orderConnection(first: 10, states: [APPROVED, FULFILLED, SUBMITTED, REFUNDED, CANCELED, PROCESSING_APPROVAL], participantType: BUYER) {\n edges {\n node {\n __typename\n internalID\n updatedAt\n ... on CommerceOfferOrder {\n buyerAction\n }\n orderHistory {\n ...ConversationOrderUpdate_event\n __typename\n ... on CommerceOrderStateChangedEvent {\n createdAt\n orderUpdateState\n state\n stateReason\n }\n ... on CommerceOfferSubmittedEvent {\n createdAt\n offer {\n amount\n fromParticipant\n definesTotal\n offerAmountChanged\n respondsTo {\n fromParticipant\n id\n }\n id\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationOrderInformation_order on CommerceOrder {\n __isCommerceOrder: __typename\n code\n state\n ...ConversationOrderState_state\n ...ReviewOrderButton_order\n ... on CommerceOfferOrder {\n lastOffer {\n amount(precision: 2)\n id\n }\n }\n}\n\nfragment ConversationOrderState_state on CommerceOrder {\n __isCommerceOrder: __typename\n state\n mode\n stateReason\n ... on CommerceOfferOrder {\n lastOffer {\n from {\n __typename\n }\n offerAmountChanged\n id\n }\n }\n ...ConversationStatusWithCounter_order\n}\n\nfragment ConversationOrderUpdate_event on CommerceOrderEventUnion {\n __isCommerceOrderEventUnion: __typename\n __typename\n ... on CommerceOrderStateChangedEvent {\n createdAt\n orderUpdateState\n state\n stateReason\n }\n ... on CommerceOfferSubmittedEvent {\n createdAt\n offer {\n amount\n fromParticipant\n definesTotal\n offerAmountChanged\n respondsTo {\n fromParticipant\n id\n }\n id\n }\n }\n}\n\nfragment ConversationReply_conversation on Conversation {\n ...ConversationCTA_conversation\n from {\n email\n id\n }\n internalID\n inquiryID\n items {\n item {\n __typename\n ... on Artwork {\n id\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n lastMessageID\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationStatusWithCounter_order on CommerceOrder {\n __isCommerceOrder: __typename\n stateExpiresAt\n stateUpdatedAt\n formattedStateExpiresAt: stateExpiresAt(format: \"MMM D, h:mm A zz\")\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n\nfragment ConversationsSidebarItem_conversation on Conversation {\n internalID\n unreadByCollector\n to {\n name\n id\n }\n lastMessageAt(format: \"MMM D\")\n orderConnection(last: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED]) {\n edges {\n node {\n __typename\n id\n }\n }\n }\n items {\n item {\n __typename\n ... on Artwork {\n id\n title\n date\n isUnlisted\n artist {\n name\n id\n }\n image {\n url(version: [\"small\", \"square\"])\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment ConversationsSidebar_viewer_3ASum4 on Viewer {\n conversationsConnection(first: $first, type: USER) {\n totalUnreadCount\n edges {\n cursor\n node {\n internalID\n ...ConversationsSidebarItem_conversation\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment ReviewOrderButton_order on CommerceOrder {\n __isCommerceOrder: __typename\n id\n state\n mode\n lineItems {\n edges {\n node {\n artwork {\n id\n }\n id\n }\n }\n }\n ... on CommerceOfferOrder {\n lastOffer {\n from {\n __typename\n }\n offerAmountChanged\n id\n }\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" + "text": "query conversationsRoutes_DetailQuery(\n $conversationId: String!\n $first: Int\n) {\n viewer {\n ...ConversationApp_viewer_3ASum4\n }\n conversation(id: $conversationId) {\n ...ConversationApp_conversation\n id\n }\n}\n\nfragment ConversationApp_conversation on Conversation {\n ...ConversationHeader_conversation\n ...ConversationDetails_conversation\n ...ConversationReply_conversation\n ...ConversationMessages_conversation\n}\n\nfragment ConversationApp_viewer_3ASum4 on Viewer {\n ...ConversationsSidebar_viewer_3ASum4\n ...ConversationsContext_viewer\n}\n\nfragment ConversationArtwork_conversation on Conversation {\n items {\n item {\n __typename\n ... on Artwork {\n id\n slug\n date\n title\n isUnlisted\n artist(shallow: true) {\n name\n slug\n id\n }\n image {\n url\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment ConversationAttachments_conversation on Conversation {\n attachmentsConnection: messagesConnection(first: 30, sort: DESC) {\n edges {\n node {\n attachments {\n id\n contentType\n fileName\n downloadURL\n }\n id\n }\n }\n }\n}\n\nfragment ConversationCTA_conversation on Conversation {\n ...useConversationPurchaseButtonData_conversation\n ...ConversationReviewOfferCTA_conversation\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n ...ConversationConfirmModal_artwork\n __typename\n internalID\n isOfferableFromInquiry\n isAcquireable\n isOfferable\n published\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n item {\n __typename\n ... on Artwork {\n internalID\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n activeOrderCTA: orderConnection(first: 10, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n ... on CommerceOfferOrder {\n buyerAction\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationConfirmModal_artwork on Artwork {\n category\n artistNames\n date\n internalID\n isEdition\n manufacturer\n medium\n publisher\n saleMessage\n title\n isOfferable\n isAcquireable\n isOfferableFromInquiry\n attributionClass {\n name\n id\n }\n image {\n resized(width: 40, height: 40) {\n src\n srcSet\n width\n height\n }\n }\n conditionDescription {\n details\n }\n certificateOfAuthenticity {\n details\n }\n framed {\n details\n }\n dimensions {\n in\n cm\n }\n signatureInfo {\n details\n }\n editionSets {\n internalID\n editionOf\n isOfferableFromInquiry\n isOfferable\n isAcquireable\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n dimensions {\n cm\n in\n }\n id\n }\n}\n\nfragment ConversationDetails_conversation on Conversation {\n internalID\n orderConnection(first: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED, CANCELED]) {\n edges {\n node {\n __typename\n ...ConversationOrderInformation_order\n id\n }\n }\n }\n ...ConversationArtwork_conversation\n ...ConversationAttachments_conversation\n}\n\nfragment ConversationHeader_conversation on Conversation {\n from {\n name\n id\n }\n to {\n name\n id\n }\n items {\n item {\n __typename\n ... on Artwork {\n internalID\n id\n slug\n date\n title\n artist(shallow: true) {\n name\n id\n }\n image {\n url\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n orderConnection(first: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED, CANCELED]) {\n edges {\n node {\n __typename\n ...ReviewOrderButton_order\n id\n }\n }\n }\n}\n\nfragment ConversationMessageArtwork_item on ConversationItemType {\n __isConversationItemType: __typename\n __typename\n ... on Artwork {\n internalID\n id\n date\n title\n artistNames\n href\n isOfferableFromInquiry\n image {\n resized(width: 1350) {\n url\n width\n height\n }\n aspectRatio\n }\n listPrice {\n __typename\n ... on Money {\n display\n }\n ... on PriceRange {\n display\n }\n }\n }\n}\n\nfragment ConversationMessage_message on Message {\n __typename\n id\n internalID\n attachments {\n internalID\n contentType\n downloadURL\n fileName\n id\n }\n body\n createdAt\n isMessageSentOnPlatform\n deliveries {\n openedAt\n fullTransformedEmail\n id\n }\n isFromUser\n isFirstMessage\n from {\n name\n }\n to\n cc\n}\n\nfragment ConversationMessages_conversation on Conversation {\n internalID\n fromLastViewedMessageID\n unreadByCollector\n to {\n name\n initials(length: 2)\n id\n }\n messagesConnection(first: 15, sort: DESC) {\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n node {\n id\n internalID\n createdAt\n isFromUser\n ...ConversationMessage_message\n __typename\n }\n cursor\n }\n }\n inquiryRequest {\n formattedFirstMessage\n id\n }\n items {\n item {\n __typename\n ... on Artwork {\n id\n isOfferable\n isOfferableFromInquiry\n internalID\n }\n ...ConversationMessageArtwork_item\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n orderEvents: orderConnection(first: 10, states: [APPROVED, FULFILLED, SUBMITTED, REFUNDED, CANCELED, PROCESSING_APPROVAL], participantType: BUYER) {\n edges {\n node {\n __typename\n internalID\n updatedAt\n ... on CommerceOfferOrder {\n buyerAction\n }\n orderHistory {\n ...ConversationOrderUpdate_event\n __typename\n ... on CommerceOrderStateChangedEvent {\n createdAt\n orderUpdateState\n state\n stateReason\n }\n ... on CommerceOfferSubmittedEvent {\n createdAt\n offer {\n amount\n fromParticipant\n definesTotal\n offerAmountChanged\n respondsTo {\n fromParticipant\n id\n }\n id\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationOrderInformation_order on CommerceOrder {\n __isCommerceOrder: __typename\n code\n state\n ...ConversationOrderState_state\n ...ReviewOrderButton_order\n ... on CommerceOfferOrder {\n lastOffer {\n amount(precision: 2)\n id\n }\n }\n}\n\nfragment ConversationOrderState_state on CommerceOrder {\n __isCommerceOrder: __typename\n state\n mode\n stateReason\n ... on CommerceOfferOrder {\n lastOffer {\n from {\n __typename\n }\n offerAmountChanged\n id\n }\n }\n ...ConversationStatusWithCounter_order\n}\n\nfragment ConversationOrderUpdate_event on CommerceOrderEventUnion {\n __isCommerceOrderEventUnion: __typename\n __typename\n ... on CommerceOrderStateChangedEvent {\n createdAt\n orderUpdateState\n state\n stateReason\n }\n ... on CommerceOfferSubmittedEvent {\n createdAt\n offer {\n amount\n fromParticipant\n definesTotal\n offerAmountChanged\n respondsTo {\n fromParticipant\n id\n }\n id\n }\n }\n}\n\nfragment ConversationPartnerOfferCTA_artwork on Artwork {\n internalID\n href\n}\n\nfragment ConversationReply_conversation on Conversation {\n ...ConversationCTA_conversation\n from {\n email\n id\n }\n internalID\n inquiryID\n items {\n item {\n __typename\n ... on Artwork {\n id\n ...ConversationPartnerOfferCTA_artwork\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n lastMessageID\n}\n\nfragment ConversationReviewOfferCTA_conversation on Conversation {\n internalID\n activeOrders: orderConnection(first: 1, states: [APPROVED, PROCESSING_APPROVAL, FULFILLED, SUBMITTED, REFUNDED]) {\n edges {\n node {\n __typename\n internalID\n state\n stateReason\n stateExpiresAt\n stateUpdatedAt\n ... on CommerceOfferOrder {\n buyerAction\n lastOffer {\n createdAt\n id\n }\n offers(first: 5) {\n edges {\n node {\n internalID\n id\n }\n }\n }\n }\n id\n }\n }\n }\n}\n\nfragment ConversationStatusWithCounter_order on CommerceOrder {\n __isCommerceOrder: __typename\n stateExpiresAt\n stateUpdatedAt\n formattedStateExpiresAt: stateExpiresAt(format: \"MMM D, h:mm A zz\")\n}\n\nfragment ConversationsContext_viewer on Viewer {\n me {\n partnerOffersConnection(first: 100, offerType: [PERSONALIZED]) {\n edges {\n node {\n artworkId\n endAt\n internalID\n isAvailable\n note\n priceWithDiscount {\n display\n }\n id\n }\n }\n }\n id\n }\n}\n\nfragment ConversationsSidebarItem_conversation on Conversation {\n internalID\n unreadByCollector\n to {\n name\n id\n }\n lastMessageAt(format: \"MMM D\")\n orderConnection(last: 1, states: [APPROVED, FULFILLED, SUBMITTED, PROCESSING_APPROVAL, REFUNDED]) {\n edges {\n node {\n __typename\n id\n }\n }\n }\n items {\n item {\n __typename\n ... on Artwork {\n id\n title\n date\n isUnlisted\n artist {\n name\n id\n }\n image {\n url(version: [\"small\", \"square\"])\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n\nfragment ConversationsSidebar_viewer_3ASum4 on Viewer {\n conversationsConnection(first: $first, type: USER) {\n totalUnreadCount\n edges {\n cursor\n node {\n internalID\n ...ConversationsSidebarItem_conversation\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment ReviewOrderButton_order on CommerceOrder {\n __isCommerceOrder: __typename\n id\n state\n mode\n lineItems {\n edges {\n node {\n artwork {\n id\n }\n id\n }\n }\n }\n ... on CommerceOfferOrder {\n lastOffer {\n from {\n __typename\n }\n offerAmountChanged\n id\n }\n }\n}\n\nfragment useConversationPurchaseButtonData_conversation on Conversation {\n internalID\n items {\n liveArtwork {\n __typename\n ... on Artwork {\n __typename\n isAcquireable\n isEdition\n internalID\n slug\n editionSets {\n internalID\n id\n }\n }\n ... on Node {\n __isNode: __typename\n id\n }\n }\n }\n}\n" } }; })();