diff --git a/apps/console/src/pages/VendorListPage.tsx b/apps/console/src/pages/VendorListPage.tsx index e2546114b..04901a8c7 100644 --- a/apps/console/src/pages/VendorListPage.tsx +++ b/apps/console/src/pages/VendorListPage.tsx @@ -27,7 +27,12 @@ import { VendorListPage_vendors$key } from "./__generated__/VendorListPage_vendo const ITEMS_PER_PAGE = 25; const vendorListPageQuery = graphql` - query VendorListPageQuery($first: Int, $after: CursorKey, $last: Int, $before: CursorKey) { + query VendorListPageQuery( + $first: Int + $after: CursorKey + $last: Int + $before: CursorKey + ) { currentOrganization: node(id: "AZSfP_xAcAC5IAAAAAAltA") { id ... on Organization { @@ -38,15 +43,11 @@ const vendorListPageQuery = graphql` `; const vendorListFragment = graphql` - fragment VendorListPage_vendors on Organization + fragment VendorListPage_vendors on Organization @refetchable(queryName: "VendorListPagePaginationQuery") { id - vendors( - first: $first - after: $after - last: $last - before: $before - ) @connection(key: "VendorListPage_vendors") { + vendors(first: $first, after: $after, last: $last, before: $before) + @connection(key: "VendorListPage_vendors") { edges { node { id @@ -66,7 +67,10 @@ const vendorListFragment = graphql` `; const createVendorMutation = graphql` - mutation VendorListPageCreateVendorMutation($input: CreateVendorInput!, $connections: [ID!]!) { + mutation VendorListPageCreateVendorMutation( + $input: CreateVendorInput! + $connections: [ID!]! + ) { createVendor(input: $input) { vendorEdge @prependEdge(connections: $connections) { node { @@ -81,8 +85,13 @@ const createVendorMutation = graphql` `; const deleteVendorMutation = graphql` - mutation VendorListPageDeleteVendorMutation($input: DeleteVendorInput!) { - deleteVendor(input: $input) + mutation VendorListPageDeleteVendorMutation( + $input: DeleteVendorInput! + $connections: [ID!]! + ) { + deleteVendor(input: $input) { + deletedVendorId @deleteEdge(connections: $connections) + } } `; @@ -162,13 +171,18 @@ function VendorListContent({ }: { queryRef: PreloadedQuery; }) { - const data = usePreloadedQuery(vendorListPageQuery, queryRef); + const data = usePreloadedQuery( + vendorListPageQuery, + queryRef, + ); const [searchParams, setSearchParams] = useSearchParams(); const [isPending, startTransition] = useTransition(); const [searchTerm, setSearchTerm] = useState(""); const [filteredVendors, setFilteredVendors] = useState>([]); - const [createVendor] = useMutation(createVendorMutation); - const [deleteVendor] = useMutation(deleteVendorMutation); + const [createVendor] = + useMutation(createVendorMutation); + const [deleteVendor] = + useMutation(deleteVendorMutation); const { data: vendorsConnection, @@ -178,9 +192,13 @@ function VendorListContent({ hasPrevious, isLoadingNext, isLoadingPrevious, - } = usePaginationFragment(vendorListFragment, data.currentOrganization); + } = usePaginationFragment< + VendorListPagePaginationQuery, + VendorListPage_vendors$key + >(vendorListFragment, data.currentOrganization); - const vendors = vendorsConnection.vendors.edges.map((edge) => edge.node) ?? []; + const vendors = + vendorsConnection.vendors.edges.map((edge) => edge.node) ?? []; const pageInfo = vendorsConnection.vendors.pageInfo; const fuse = new Fuse(vendorsList, { @@ -239,7 +257,12 @@ function VendorListContent({ onClick={() => { createVendor({ variables: { - connections: [ConnectionHandler.getConnectionID(data.currentOrganization.id, "VendorListPageQuery_vendors")], + connections: [ + ConnectionHandler.getConnectionID( + data.currentOrganization.id, + "VendorListPageQuery_vendors", + ), + ], input: { organizationId: data.currentOrganization.id, name: vendor.name, @@ -254,7 +277,8 @@ function VendorListContent({ setFilteredVendors([]); toast({ title: "Vendor added", - description: "The vendor has been added successfully", + description: + "The vendor has been added successfully", }); }, }); @@ -343,6 +367,12 @@ function VendorListContent({ ) { deleteVendor({ variables: { + connections: [ + ConnectionHandler.getConnectionID( + data.currentOrganization.id, + "VendorListPage_vendors", + ), + ], input: { vendorId: vendor.id, }, @@ -350,7 +380,8 @@ function VendorListContent({ onCompleted() { toast({ title: "Vendor deleted", - description: "The vendor has been deleted successfully", + description: + "The vendor has been deleted successfully", }); }, }); diff --git a/apps/console/src/pages/__generated__/VendorListPageDeleteVendorMutation.graphql.ts b/apps/console/src/pages/__generated__/VendorListPageDeleteVendorMutation.graphql.ts index a1fa746bd..6e495f7fe 100644 --- a/apps/console/src/pages/__generated__/VendorListPageDeleteVendorMutation.graphql.ts +++ b/apps/console/src/pages/__generated__/VendorListPageDeleteVendorMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -13,10 +13,13 @@ export type DeleteVendorInput = { vendorId: string; }; export type VendorListPageDeleteVendorMutation$variables = { + connections: ReadonlyArray; input: DeleteVendorInput; }; export type VendorListPageDeleteVendorMutation$data = { - readonly deleteVendor: any; + readonly deleteVendor: { + readonly deletedVendorId: string; + }; }; export type VendorListPageDeleteVendorMutation = { response: VendorListPageDeleteVendorMutation$data; @@ -24,56 +27,106 @@ export type VendorListPageDeleteVendorMutation = { }; const node: ConcreteRequest = (function(){ -var v0 = [ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "connections" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" +}, +v2 = [ { - "defaultValue": null, - "kind": "LocalArgument", - "name": "input" + "kind": "Variable", + "name": "input", + "variableName": "input" } ], -v1 = [ - { - "alias": null, - "args": [ - { - "kind": "Variable", - "name": "input", - "variableName": "input" - } - ], - "kind": "ScalarField", - "name": "deleteVendor", - "storageKey": null - } -]; +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "deletedVendorId", + "storageKey": null +}; return { "fragment": { - "argumentDefinitions": (v0/*: any*/), + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/) + ], "kind": "Fragment", "metadata": null, "name": "VendorListPageDeleteVendorMutation", - "selections": (v1/*: any*/), + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteVendorPayload", + "kind": "LinkedField", + "name": "deleteVendor", + "plural": false, + "selections": [ + (v3/*: any*/) + ], + "storageKey": null + } + ], "type": "Mutation", "abstractKey": null }, "kind": "Request", "operation": { - "argumentDefinitions": (v0/*: any*/), + "argumentDefinitions": [ + (v1/*: any*/), + (v0/*: any*/) + ], "kind": "Operation", "name": "VendorListPageDeleteVendorMutation", - "selections": (v1/*: any*/) + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteVendorPayload", + "kind": "LinkedField", + "name": "deleteVendor", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "filters": null, + "handle": "deleteEdge", + "key": "", + "kind": "ScalarHandle", + "name": "deletedVendorId", + "handleArgs": [ + { + "kind": "Variable", + "name": "connections", + "variableName": "connections" + } + ] + } + ], + "storageKey": null + } + ] }, "params": { - "cacheID": "6b9ec06210106cc8f8905fbfda5c60b0", + "cacheID": "278e42c6c988a64d4c863198f02df901", "id": null, "metadata": {}, "name": "VendorListPageDeleteVendorMutation", "operationKind": "mutation", - "text": "mutation VendorListPageDeleteVendorMutation(\n $input: DeleteVendorInput!\n) {\n deleteVendor(input: $input)\n}\n" + "text": "mutation VendorListPageDeleteVendorMutation(\n $input: DeleteVendorInput!\n) {\n deleteVendor(input: $input) {\n deletedVendorId\n }\n}\n" } }; })(); -(node as any).hash = "a435b00067d595fc8a1dec393ed1d0b6"; +(node as any).hash = "20a320191535706246ae00aa05df991e"; export default node; diff --git a/pkg/api/console/v1/schema.graphql b/pkg/api/console/v1/schema.graphql index 13ce3ab2c..40f0a2ea4 100644 --- a/pkg/api/console/v1/schema.graphql +++ b/pkg/api/console/v1/schema.graphql @@ -316,7 +316,7 @@ type Query { type Mutation { createVendor(input: CreateVendorInput!): CreateVendorPayload! updateVendor(input: UpdateVendorInput!): Vendor! - deleteVendor(input: DeleteVendorInput!): Void! + deleteVendor(input: DeleteVendorInput!): DeleteVendorPayload! createPeople(input: CreatePeopleInput!): CreatePeoplePayload! updatePeople(input: UpdatePeopleInput!): People! deletePeople(input: DeletePeopleInput!): Void! @@ -392,4 +392,9 @@ type CreatePeoplePayload { type CreateVendorPayload { vendorEdge: VendorEdge! -} \ No newline at end of file +} + +type DeleteVendorPayload { + vendorEdge: VendorEdge! + deletedVendorId: ID! +} diff --git a/pkg/api/console/v1/schema/schema.go b/pkg/api/console/v1/schema/schema.go index f0253e173..1131277ef 100644 --- a/pkg/api/console/v1/schema/schema.go +++ b/pkg/api/console/v1/schema/schema.go @@ -104,6 +104,11 @@ type ComplexityRoot struct { VendorEdge func(childComplexity int) int } + DeleteVendorPayload struct { + DeletedVendorID func(childComplexity int) int + VendorEdge func(childComplexity int) int + } + Evidence struct { CreatedAt func(childComplexity int) int FileURL func(childComplexity int) int @@ -295,7 +300,7 @@ type FrameworkResolver interface { type MutationResolver interface { CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.Vendor, error) - DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error) + DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error) UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.People, error) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (string, error) @@ -517,6 +522,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CreateVendorPayload.VendorEdge(childComplexity), true + case "DeleteVendorPayload.deletedVendorId": + if e.complexity.DeleteVendorPayload.DeletedVendorID == nil { + break + } + + return e.complexity.DeleteVendorPayload.DeletedVendorID(childComplexity), true + + case "DeleteVendorPayload.vendorEdge": + if e.complexity.DeleteVendorPayload.VendorEdge == nil { + break + } + + return e.complexity.DeleteVendorPayload.VendorEdge(childComplexity), true + case "Evidence.createdAt": if e.complexity.Evidence.CreatedAt == nil { break @@ -1730,7 +1749,7 @@ type Query { type Mutation { createVendor(input: CreateVendorInput!): CreateVendorPayload! updateVendor(input: UpdateVendorInput!): Vendor! - deleteVendor(input: DeleteVendorInput!): Void! + deleteVendor(input: DeleteVendorInput!): DeleteVendorPayload! createPeople(input: CreatePeopleInput!): CreatePeoplePayload! updatePeople(input: UpdatePeopleInput!): People! deletePeople(input: DeletePeopleInput!): Void! @@ -1806,7 +1825,13 @@ type CreatePeoplePayload { type CreateVendorPayload { vendorEdge: VendorEdge! -}`, BuiltIn: false}, +} + +type DeleteVendorPayload { + vendorEdge: VendorEdge! + deletedVendorId: ID! +} +`, BuiltIn: false}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) @@ -3789,6 +3814,88 @@ func (ec *executionContext) fieldContext_CreateVendorPayload_vendorEdge(_ contex return fc, nil } +func (ec *executionContext) _DeleteVendorPayload_vendorEdge(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteVendorPayload_vendorEdge(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.VendorEdge, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorEdge) + fc.Result = res + return ec.marshalNVendorEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorEdge(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteVendorPayload_vendorEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteVendorPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_VendorEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_VendorEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _DeleteVendorPayload_deletedVendorId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteVendorPayload_deletedVendorId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeletedVendorID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteVendorPayload_deletedVendorId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteVendorPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Evidence_id(ctx context.Context, field graphql.CollectedField, obj *types.Evidence) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Evidence_id(ctx, field) if err != nil { @@ -5253,9 +5360,9 @@ func (ec *executionContext) _Mutation_deleteVendor(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(string) + res := resTmp.(*types.DeleteVendorPayload) fc.Result = res - return ec.marshalNVoid2string(ctx, field.Selections, res) + return ec.marshalNDeleteVendorPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorPayload(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Mutation_deleteVendor(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5265,7 +5372,13 @@ func (ec *executionContext) fieldContext_Mutation_deleteVendor(ctx context.Conte IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Void does not have child fields") + switch field.Name { + case "vendorEdge": + return ec.fieldContext_DeleteVendorPayload_vendorEdge(ctx, field) + case "deletedVendorId": + return ec.fieldContext_DeleteVendorPayload_deletedVendorId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteVendorPayload", field.Name) }, } ctx = graphql.WithFieldContext(ctx, fc) @@ -10566,6 +10679,50 @@ func (ec *executionContext) _CreateVendorPayload(ctx context.Context, sel ast.Se return out } +var deleteVendorPayloadImplementors = []string{"DeleteVendorPayload"} + +func (ec *executionContext) _DeleteVendorPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteVendorPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteVendorPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DeleteVendorPayload") + case "vendorEdge": + out.Values[i] = ec._DeleteVendorPayload_vendorEdge(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deletedVendorId": + out.Values[i] = ec._DeleteVendorPayload_deletedVendorId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var evidenceImplementors = []string{"Evidence", "Node"} func (ec *executionContext) _Evidence(ctx context.Context, sel ast.SelectionSet, obj *types.Evidence) graphql.Marshaler { @@ -12720,6 +12877,20 @@ func (ec *executionContext) unmarshalNDeleteVendorInput2githubᚗcomᚋgetprobo return res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) marshalNDeleteVendorPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteVendorPayload) graphql.Marshaler { + return ec._DeleteVendorPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteVendorPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteVendorPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteVendorPayload(ctx, sel, v) +} + func (ec *executionContext) marshalNEvidence2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐEvidence(ctx context.Context, sel ast.SelectionSet, v *types.Evidence) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { diff --git a/pkg/api/console/v1/types/types.go b/pkg/api/console/v1/types/types.go index 5685241d2..684d75033 100644 --- a/pkg/api/console/v1/types/types.go +++ b/pkg/api/console/v1/types/types.go @@ -96,6 +96,11 @@ type DeleteVendorInput struct { VendorID gid.GID `json:"vendorId"` } +type DeleteVendorPayload struct { + VendorEdge *VendorEdge `json:"vendorEdge"` + DeletedVendorID gid.GID `json:"deletedVendorId"` +} + type Evidence struct { ID gid.GID `json:"id"` FileURL string `json:"fileUrl"` diff --git a/pkg/api/console/v1/v1_resolver.go b/pkg/api/console/v1/v1_resolver.go index 571982700..9dd36eea1 100644 --- a/pkg/api/console/v1/v1_resolver.go +++ b/pkg/api/console/v1/v1_resolver.go @@ -110,13 +110,15 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV } // DeleteVendor is the resolver for the deleteVendor field. -func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (string, error) { +func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) { err := r.svc.DeleteVendor(ctx, input.VendorID) if err != nil { - return "", fmt.Errorf("cannot delete vendor: %w", err) + return nil, fmt.Errorf("cannot delete vendor: %w", err) } - return "", nil + return &types.DeleteVendorPayload{ + DeletedVendorID: input.VendorID, + }, nil } // CreatePeople is the resolver for the createPeople field.