Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PX-5157 - Add Bulk Edit endpoint #4269

Merged
merged 9 commits into from
Aug 3, 2022
53 changes: 53 additions & 0 deletions _schemaV2.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -10905,6 +10905,11 @@ type Mutation {
updateNotificationPreferences(
input: updateNotificationPreferencesMutationInput!
): updateNotificationPreferencesMutationPayload

# Update all artworks that belong to the partner
updatePartnerArtworks(
input: UpdatePartnerArtworksMutationInput!
): UpdatePartnerArtworksMutationPayload
updateSavedSearch(input: UpdateSavedSearchInput!): UpdateSavedSearchPayload
updateSmsSecondFactor(
input: UpdateSmsSecondFactorInput!
Expand Down Expand Up @@ -11712,6 +11717,11 @@ type PartnerArtworkGrid implements ArtworkContextGrid {
title: String
}

type PartnerArtworksError {
Mitch-Henson marked this conversation as resolved.
Show resolved Hide resolved
count: Int
ids: [String]
}

type PartnerCategory {
cached: Int
categoryType: PartnerCategoryType
Expand Down Expand Up @@ -15458,6 +15468,49 @@ type updateNotificationPreferencesMutationPayload {
): [NotificationPreference!]!
}

type UpdatePartnerArtworksMutationFailure {
mutationError: GravityMutationError
}

input UpdatePartnerArtworksMutationInput {
# Whether Artsy domestic shipping should be enabled
artsyShippingDomestic: Boolean

# Whether Artsy international shipping should be enabled
artsyShippingInternational: Boolean
clientMutationId: String
mzikherman marked this conversation as resolved.
Show resolved Hide resolved

# ID of the partner
id: String!

# The partner location ID to assign
location: String
}

type UpdatePartnerArtworksMutationPayload {
clientMutationId: String
partnerArtworksOrError: UpdatePartnerArtworksMutationType
}

type UpdatePartnerArtworksMutationSuccess {
partnerArtworks: UpdatePartnerArtworksMutationSuccessDetails
Mitch-Henson marked this conversation as resolved.
Show resolved Hide resolved
}

type UpdatePartnerArtworksMutationSuccessDetails {
errors: PartnerArtworksError

# A globally unique ID.
id: ID!

# A type-specific ID likely used as a database ID.
internalID: ID!
Mitch-Henson marked this conversation as resolved.
Show resolved Hide resolved
success: Int
}

union UpdatePartnerArtworksMutationType =
UpdatePartnerArtworksMutationFailure
| UpdatePartnerArtworksMutationSuccess

# Autogenerated input type of UpdateSavedSearch
input UpdateSavedSearchInput {
attributes: SearchCriteriaAttributes
Expand Down
2 changes: 1 addition & 1 deletion src/data/complete.queryMap.json
Original file line number Diff line number Diff line change
Expand Up @@ -4196,4 +4196,4 @@
"d946be33628c0d36dbd53e5ce5b9b779": "query OnboardingSearchResultsQuery(\n $term: String!\n $entities: [SearchEntity!]!\n) {\n viewer {\n ...OnboardingSearchResults_viewer_plJt2\n }\n}\n\nfragment ArtistListItemNew_artist on Artist {\n id\n internalID\n slug\n name\n initials\n href\n isFollowed\n nationality\n birthday\n deathday\n image {\n url\n }\n}\n\nfragment OnboardingSearchResults_viewer_plJt2 on Viewer {\n matchConnection(term: $term, entities: $entities, first: 10, mode: AUTOSUGGEST) {\n edges {\n node {\n __typename\n ... on Artist {\n internalID\n ...ArtistListItemNew_artist\n }\n ... on Profile {\n internalID\n owner {\n __typename\n ... on Partner {\n ...PartnerListItem_partner\n }\n ... on Node {\n __isNode: __typename\n id\n }\n ... on FairOrganizer {\n id\n }\n }\n id\n }\n ... on Node {\n __isNode: __typename\n id\n }\n ... on Feature {\n id\n }\n ... on Page {\n id\n }\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment PartnerListItem_partner on Partner {\n internalID\n name\n initials\n locationsConnection(first: 15) {\n edges {\n node {\n city\n id\n }\n }\n }\n profile {\n id\n slug\n name\n internalID\n isFollowed\n icon {\n url(version: \"square140\")\n }\n }\n}\n",
"fd64643e7e25470528b89bd5ee333596": "query OnboardingSearchResults_viewerRefetch(\n $after: String\n $count: Int = 10\n $entities: [SearchEntity!]!\n $term: String!\n) {\n viewer {\n ...OnboardingSearchResults_viewer_2Hfuwj\n }\n}\n\nfragment ArtistListItemNew_artist on Artist {\n id\n internalID\n slug\n name\n initials\n href\n isFollowed\n nationality\n birthday\n deathday\n image {\n url\n }\n}\n\nfragment OnboardingSearchResults_viewer_2Hfuwj on Viewer {\n matchConnection(term: $term, entities: $entities, first: $count, after: $after, mode: AUTOSUGGEST) {\n edges {\n node {\n __typename\n ... on Artist {\n internalID\n ...ArtistListItemNew_artist\n }\n ... on Profile {\n internalID\n owner {\n __typename\n ... on Partner {\n ...PartnerListItem_partner\n }\n ... on Node {\n __isNode: __typename\n id\n }\n ... on FairOrganizer {\n id\n }\n }\n id\n }\n ... on Node {\n __isNode: __typename\n id\n }\n ... on Feature {\n id\n }\n ... on Page {\n id\n }\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment PartnerListItem_partner on Partner {\n internalID\n name\n initials\n locationsConnection(first: 15) {\n edges {\n node {\n city\n id\n }\n }\n }\n profile {\n id\n slug\n name\n internalID\n isFollowed\n icon {\n url(version: \"square140\")\n }\n }\n}\n",
"febc099cc4662fec4ed976e797c73c55": "query NewBuyNowArtworksRailTestsQuery(\n $id: String!\n) {\n sale(id: $id) {\n ...NewBuyNowArtworksRail_sale\n id\n }\n}\n\nfragment ArtworkRailCard_artwork_hl5k2 on Artwork {\n id\n slug\n internalID\n href\n artistNames\n date\n image {\n resized(width: 155) {\n src\n srcSet\n width\n height\n }\n aspectRatio\n }\n sale {\n isAuction\n isClosed\n endAt\n id\n }\n saleMessage\n saleArtwork {\n counts {\n bidderPositions\n }\n currentBid {\n display\n }\n id\n }\n partner {\n name\n id\n }\n title\n realizedPrice\n}\n\nfragment NewBuyNowArtworksRail_sale on Sale {\n internalID\n promotedSale {\n artworksConnection(first: 20) {\n edges {\n node {\n ...SmallArtworkRail_artworks\n id\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n }\n}\n\nfragment SmallArtworkRail_artworks on Artwork {\n ...ArtworkRailCard_artwork_hl5k2\n internalID\n href\n slug\n}\n"
}
}
5 changes: 5 additions & 0 deletions src/lib/loaders/loaders_with_authentication/gravity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,11 @@ export default (accessToken, userID, opts) => {
{},
{ headers: true }
),
updatePartnerArtworksLoader: gravityLoader(
(id) => `partner/${id}/artworks`,
{},
{ method: "PUT" }
),
partnerInquirerCollectorProfileLoader: gravityLoader<
any,
{ partnerId: string; inquiryId: string }
Expand Down
134 changes: 134 additions & 0 deletions src/schema/v2/partnerArtworksMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
GraphQLBoolean,
GraphQLInt,
GraphQLList,
GraphQLNonNull,
GraphQLString,
} from "graphql"
import { mutationWithClientMutationId } from "graphql-relay"
import { ResolverContext } from "types/graphql"
import {
GravityMutationErrorType,
formatGravityError,
} from "lib/gravityErrorHandler"
import { GraphQLObjectType } from "graphql"
import { InternalIDFields } from "./object_identification"
import { GraphQLUnionType } from "graphql"
interface Input {
id: string
artsyShippingDomestic: boolean | null
artsyShippingInternational: boolean | null
location: string | null
}

const UpdatePartnerArtworksMutationSuccessDetails = new GraphQLObjectType<
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutationSuccessDetails",
fields: () => ({
...InternalIDFields,
Mitch-Henson marked this conversation as resolved.
Show resolved Hide resolved
success: { type: GraphQLInt },
errors: {
type: new GraphQLObjectType({
name: "PartnerArtworksError",
fields: {
count: { type: GraphQLInt },
ids: { type: GraphQLList(GraphQLString) },
},
}),
},
}),
})

const UpdatePartnerArtworksMutationSuccessType = new GraphQLObjectType<
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutationSuccess",
isTypeOf: (data) => data.success || data.errors,
Mitch-Henson marked this conversation as resolved.
Show resolved Hide resolved
fields: () => ({
partnerArtworks: {
type: UpdatePartnerArtworksMutationSuccessDetails,
resolve: (partnerArtworks) => partnerArtworks,
},
}),
})

const UpdatePartnerArtworksMutationFailureType = new GraphQLObjectType<
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutationFailure",
isTypeOf: (data) => {
return data._type === "GravityMutationError"
},
fields: () => ({
mutationError: {
type: GravityMutationErrorType,
resolve: (err) => err,
},
}),
})

const UpdatePartnerArtworksMutationType = new GraphQLUnionType({
name: "UpdatePartnerArtworksMutationType",
types: [
UpdatePartnerArtworksMutationSuccessType,
UpdatePartnerArtworksMutationFailureType,
],
})

export const updatePartnerArtworksMutation = mutationWithClientMutationId<
Input,
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutation",
description: "Update all artworks that belong to the partner",
inputFields: {
id: {
type: new GraphQLNonNull(GraphQLString),
description: "ID of the partner",
},
artsyShippingDomestic: {
type: GraphQLBoolean,
description: "Whether Artsy domestic shipping should be enabled",
},
artsyShippingInternational: {
type: GraphQLBoolean,
description: "Whether Artsy international shipping should be enabled",
},
location: {
type: GraphQLString,
description: "The partner location ID to assign",
},
},
outputFields: {
partnerArtworksOrError: {
type: UpdatePartnerArtworksMutationType,
resolve: (result) => result,
},
},
mutateAndGetPayload: async (
{ id, artsyShippingDomestic, artsyShippingInternational, location },
{ updatePartnerArtworksLoader }
) => {
const gravityOptions = {
artsy_shipping_domestic: artsyShippingDomestic,
artsy_shipping_international: artsyShippingInternational,
location,
}

try {
return await updatePartnerArtworksLoader?.(id, gravityOptions)
} catch (error) {
const formattedErr = formatGravityError(error)
if (formattedErr) {
return { ...formattedErr, _type: "GravityMutationError" }
} else {
throw new Error(error)
}
}
},
})
2 changes: 2 additions & 0 deletions src/schema/v2/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ import { toggleFeatureFlagMutation } from "./admin/mutations/toggleFeatureFlagMu
import { MatchConnection } from "./Match"
import { PartnerArtistDocumentsConnection } from "./partnerArtistDocumentsConnection"
import { PartnerShowDocumentsConnection } from "./partnerShowDocumentsConnection"
import { updatePartnerArtworksMutation } from "./partnerArtworksMutation"

const PrincipalFieldDirective = new GraphQLDirective({
name: "principalField",
Expand Down Expand Up @@ -313,6 +314,7 @@ export default new GraphQLSchema({
updateUserSaleProfile: updateUserSaleProfileMutation,
updateMyUserProfile: UpdateMyUserProfileMutation,
updateNotificationPreferences: updateNotificationPreferencesMutation,
updatePartnerArtworks: updatePartnerArtworksMutation,
deleteMyUserProfileIcon: deleteCollectorProfileIconMutation,
requestPriceEstimate: requestPriceEstimateMutation,
},
Expand Down