Skip to content

Commit

Permalink
feat: PX-5157 - Add Bulk Edit endpoint (#4269)
Browse files Browse the repository at this point in the history
* feat: initial setup of bulk edit endpoint

* fix: updating to correctly read from the rest endpoint

* feat: adding some beginner friendly documentation on how to add a REST endpoint from gravity to metaphysics

* fix: use async / await instead of .then structure

* fix: ensuring loader method is always available

* fix: removing doc addition from this PR into its own PR

* fix: re-adding null check as typecheck failed

* fix: Rename variables to better match the response. Readded loader check. Removed unused internal fields
  • Loading branch information
Mitch-Henson committed Aug 3, 2022
1 parent 1865d19 commit f45c867
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 1 deletion.
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 @@ -15473,6 +15483,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

# 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

0 comments on commit f45c867

Please sign in to comment.