Browse Source

feat(admin-ui): Add 'groups' field to Customer type in Admin API

Relates to #330
Michael Bromley 5 years ago
parent
commit
9635677498

+ 1 - 0
packages/admin-ui/src/lib/core/src/common/generated-types.ts

@@ -927,6 +927,7 @@ export type CurrentUserChannelInput = {
 
 export type Customer = Node & {
    __typename?: 'Customer';
+  groups: Array<CustomerGroup>;
   id: Scalars['ID'];
   createdAt: Scalars['DateTime'];
   updatedAt: Scalars['DateTime'];

+ 6 - 6
packages/admin-ui/src/lib/core/src/common/introspection-result.ts

@@ -66,6 +66,9 @@ const result: IntrospectionResultData = {
                     {
                         name: 'Customer',
                     },
+                    {
+                        name: 'CustomerGroup',
+                    },
                     {
                         name: 'Address',
                     },
@@ -96,9 +99,6 @@ const result: IntrospectionResultData = {
                     {
                         name: 'TaxCategory',
                     },
-                    {
-                        name: 'CustomerGroup',
-                    },
                     {
                         name: 'ProductOption',
                     },
@@ -136,13 +136,13 @@ const result: IntrospectionResultData = {
                         name: 'ProductVariantList',
                     },
                     {
-                        name: 'OrderList',
+                        name: 'CustomerList',
                     },
                     {
-                        name: 'HistoryEntryList',
+                        name: 'OrderList',
                     },
                     {
-                        name: 'CustomerList',
+                        name: 'HistoryEntryList',
                     },
                     {
                         name: 'CollectionList',

+ 1 - 0
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -919,6 +919,7 @@ export type CurrentUserChannel = {
 
 export type Customer = Node & {
     __typename?: 'Customer';
+    groups: Array<CustomerGroup>;
     id: Scalars['ID'];
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];

+ 1 - 0
packages/common/src/generated-types.ts

@@ -919,6 +919,7 @@ export type CurrentUserChannel = {
 
 export type Customer = Node & {
    __typename?: 'Customer';
+  groups: Array<CustomerGroup>;
   id: Scalars['ID'];
   createdAt: Scalars['DateTime'];
   updatedAt: Scalars['DateTime'];

+ 24 - 0
packages/core/e2e/customer-group.e2e-spec.ts

@@ -20,6 +20,7 @@ import {
     GetCustomerGroup,
     GetCustomerGroups,
     GetCustomerList,
+    GetCustomerWithGroups,
     RemoveCustomersFromGroup,
     UpdateCustomerGroup,
 } from './graphql/generated-e2e-admin-types';
@@ -140,6 +141,17 @@ describe('CustomerGroup resolver', () => {
         ]);
     });
 
+    it('customer.groups field resolver', async () => {
+        const { customer } = await adminClient.query<
+            GetCustomerWithGroups.Query,
+            GetCustomerWithGroups.Variables
+        >(GET_CUSTOMER_WITH_GROUPS, {
+            id: customers[0].id,
+        });
+
+        expect(customer?.groups).toEqual([{ id: 'T_1', name: 'group 1 updated' }]);
+    });
+
     it(
         'removeCustomersFromGroup with invalid customerId',
         assertThrowsWithMessage(async () => {
@@ -268,3 +280,15 @@ export const REMOVE_CUSTOMERS_FROM_GROUP = gql`
     }
     ${CUSTOMER_GROUP_FRAGMENT}
 `;
+
+export const GET_CUSTOMER_WITH_GROUPS = gql`
+    query GetCustomerWithGroups($id: ID!) {
+        customer(id: $id) {
+            id
+            groups {
+                id
+                name
+            }
+        }
+    }
+`;

+ 20 - 0
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -919,6 +919,7 @@ export type CurrentUserChannel = {
 
 export type Customer = Node & {
     __typename?: 'Customer';
+    groups: Array<CustomerGroup>;
     id: Scalars['ID'];
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];
@@ -3907,6 +3908,18 @@ export type RemoveCustomersFromGroupMutation = { __typename?: 'Mutation' } & {
     removeCustomersFromGroup: { __typename?: 'CustomerGroup' } & CustomerGroupFragment;
 };
 
+export type GetCustomerWithGroupsQueryVariables = {
+    id: Scalars['ID'];
+};
+
+export type GetCustomerWithGroupsQuery = { __typename?: 'Query' } & {
+    customer?: Maybe<
+        { __typename?: 'Customer' } & Pick<Customer, 'id'> & {
+                groups: Array<{ __typename?: 'CustomerGroup' } & Pick<CustomerGroup, 'id' | 'name'>>;
+            }
+    >;
+};
+
 export type DeleteCustomerAddressMutationVariables = {
     id: Scalars['ID'];
 };
@@ -5813,6 +5826,13 @@ export namespace RemoveCustomersFromGroup {
     export type RemoveCustomersFromGroup = CustomerGroupFragment;
 }
 
+export namespace GetCustomerWithGroups {
+    export type Variables = GetCustomerWithGroupsQueryVariables;
+    export type Query = GetCustomerWithGroupsQuery;
+    export type Customer = NonNullable<GetCustomerWithGroupsQuery['customer']>;
+    export type Groups = NonNullable<NonNullable<GetCustomerWithGroupsQuery['customer']>['groups'][0]>;
+}
+
 export namespace DeleteCustomerAddress {
     export type Variables = DeleteCustomerAddressMutationVariables;
     export type Mutation = DeleteCustomerAddressMutation;

+ 9 - 2
packages/core/src/api/api-internal-modules.ts

@@ -31,7 +31,10 @@ import { TaxCategoryResolver } from './resolvers/admin/tax-category.resolver';
 import { TaxRateResolver } from './resolvers/admin/tax-rate.resolver';
 import { ZoneResolver } from './resolvers/admin/zone.resolver';
 import { CollectionEntityResolver } from './resolvers/entity/collection-entity.resolver';
-import { CustomerEntityResolver } from './resolvers/entity/customer-entity.resolver';
+import {
+    CustomerAdminEntityResolver,
+    CustomerEntityResolver,
+} from './resolvers/entity/customer-entity.resolver';
 import { CustomerGroupEntityResolver } from './resolvers/entity/customer-group-entity.resolver';
 import { FulfillmentEntityResolver } from './resolvers/entity/fulfillment-entity.resolver';
 import { OrderEntityResolver } from './resolvers/entity/order-entity.resolver';
@@ -103,7 +106,11 @@ export const entityResolvers = [
     RoleEntityResolver,
 ];
 
-export const adminEntityResolvers = [ProductVariantAdminEntityResolver, ProductAdminEntityResolver];
+export const adminEntityResolvers = [
+    CustomerAdminEntityResolver,
+    ProductVariantAdminEntityResolver,
+    ProductAdminEntityResolver,
+];
 
 /**
  * The internal module containing some shared providers used by more than

+ 13 - 0
packages/core/src/api/resolvers/entity/customer-entity.resolver.ts

@@ -56,3 +56,16 @@ export class CustomerEntityResolver {
         return this.userService.getUserByEmailAddress(customer.emailAddress);
     }
 }
+
+@Resolver('Customer')
+export class CustomerAdminEntityResolver {
+    constructor(private customerService: CustomerService) {}
+
+    @ResolveField()
+    groups(@Ctx() ctx: RequestContext, @Parent() customer: Customer) {
+        if (customer.groups) {
+            return customer.groups;
+        }
+        return this.customerService.getCustomerGroups(customer.id);
+    }
+}

+ 4 - 0
packages/core/src/api/schema/admin-api/customer.api.graphql

@@ -23,6 +23,10 @@ type Mutation {
     deleteCustomerAddress(id: ID!): Boolean!
 }
 
+type Customer implements Node {
+    groups: [CustomerGroup!]!
+}
+
 input UpdateCustomerInput {
     id: ID!
     title: String

+ 17 - 5
packages/core/src/service/services/customer.service.ts

@@ -18,6 +18,7 @@ import { ListQueryOptions } from '../../common/types/common-types';
 import { assertFound, idsAreEqual, normalizeEmailAddress } from '../../common/utils';
 import { ConfigService } from '../../config/config.service';
 import { Address } from '../../entity/address/address.entity';
+import { CustomerGroup } from '../../entity/customer-group/customer-group.entity';
 import { Customer } from '../../entity/customer/customer.entity';
 import { User } from '../../entity/user/user.entity';
 import { EventBus } from '../../event-bus/event-bus';
@@ -72,14 +73,25 @@ export class CustomerService {
             .leftJoinAndSelect('country.translations', 'countryTranslation')
             .where('address.customer = :id', { id: customerId })
             .getMany()
-            .then(addresses => {
-                addresses.forEach(address => {
+            .then((addresses) => {
+                addresses.forEach((address) => {
                     address.country = translateDeep(address.country, ctx.languageCode);
                 });
                 return addresses;
             });
     }
 
+    async getCustomerGroups(customerId: ID): Promise<CustomerGroup[]> {
+        const customerWithGroups = await this.connection
+            .getRepository(Customer)
+            .findOne(customerId, { relations: ['groups'] });
+        if (customerWithGroups) {
+            return customerWithGroups.groups;
+        } else {
+            return [];
+        }
+    }
+
     async create(ctx: RequestContext, input: CreateCustomerInput, password?: string): Promise<Customer> {
         input.emailAddress = normalizeEmailAddress(input.emailAddress);
         const customer = new Customer(input);
@@ -328,8 +340,8 @@ export class CustomerService {
             .findOne(addressId, { relations: ['customer', 'customer.addresses'] });
         if (result) {
             const customerAddressIds = result.customer.addresses
-                .map(a => a.id)
-                .filter(id => !idsAreEqual(id, addressId)) as string[];
+                .map((a) => a.id)
+                .filter((id) => !idsAreEqual(id, addressId)) as string[];
 
             if (customerAddressIds.length) {
                 if (input.defaultBillingAddress === true) {
@@ -362,7 +374,7 @@ export class CustomerService {
             const customerAddresses = result.customer.addresses;
             if (1 < customerAddresses.length) {
                 const otherAddresses = customerAddresses
-                    .filter(address => !idsAreEqual(address.id, addressToDelete.id))
+                    .filter((address) => !idsAreEqual(address.id, addressToDelete.id))
                     .sort((a, b) => (a.id < b.id ? -1 : 1));
                 if (addressToDelete.defaultShippingAddress) {
                     otherAddresses[0].defaultShippingAddress = true;

+ 1 - 0
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -919,6 +919,7 @@ export type CurrentUserChannel = {
 
 export type Customer = Node & {
     __typename?: 'Customer';
+    groups: Array<CustomerGroup>;
     id: Scalars['ID'];
     createdAt: Scalars['DateTime'];
     updatedAt: Scalars['DateTime'];

File diff suppressed because it is too large
+ 0 - 0
schema-admin.json


Some files were not shown because too many files changed in this diff