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
47 changes: 47 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 PartnerArtworksBulkEditErrors {
count: Int
ids: [String]
}

type PartnerCategory {
cached: Int
categoryType: PartnerCategoryType
Expand Down Expand Up @@ -15458,6 +15468,43 @@ 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
partnerArtworksBulkEditOrError: UpdatePartnerArtworksMutationType
}

type UpdatePartnerArtworksMutationSuccess {
partnerArtworksBulkEdit: UpdatePartnerArtworksMutationSuccessDetails
}

type UpdatePartnerArtworksMutationSuccessDetails {
errors: PartnerArtworksBulkEditErrors
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
137 changes: 137 additions & 0 deletions src/schema/v2/partnerArtworksMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
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 { GraphQLUnionType } from "graphql"
import { isExisty } from "lib/helpers"
interface Input {
id: string
artsyShippingDomestic: boolean | null
artsyShippingInternational: boolean | null
location: string | null
}

const UpdatePartnerArtworksMutationSuccessDetails = new GraphQLObjectType<
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutationSuccessDetails",
fields: () => ({
success: { type: GraphQLInt },
errors: {
type: new GraphQLObjectType({
name: "PartnerArtworksBulkEditErrors",
fields: {
count: { type: GraphQLInt },
ids: { type: GraphQLList(GraphQLString) },
},
}),
},
}),
})

const UpdatePartnerArtworksMutationSuccessType = new GraphQLObjectType<
any,
ResolverContext
>({
name: "UpdatePartnerArtworksMutationSuccess",
isTypeOf: (data) => isExisty(data.success),
fields: () => ({
partnerArtworksBulkEdit: {
type: UpdatePartnerArtworksMutationSuccessDetails,
resolve: (partnerArtworksBulkEdit) => partnerArtworksBulkEdit,
},
}),
})

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: {
partnerArtworksBulkEditOrError: {
type: UpdatePartnerArtworksMutationType,
resolve: (result) => result,
},
},
mutateAndGetPayload: async (
{ id, artsyShippingDomestic, artsyShippingInternational, location },
{ updatePartnerArtworksLoader }
) => {
const gravityOptions = {
artsy_shipping_domestic: artsyShippingDomestic,
artsy_shipping_international: artsyShippingInternational,
location,
}

if (!updatePartnerArtworksLoader) {
throw new Error("You need to be signed in to perform this action")
}

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