Skip to content

Commit

Permalink
feat(admin-ui): Allow groups admin from CustomerDetailComponent
Browse files Browse the repository at this point in the history
Relates to #330
  • Loading branch information
michaelbromley committed May 21, 2020
1 parent 9635677 commit 8dca9a3
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 9 deletions.
6 changes: 5 additions & 1 deletion packages/admin-ui/src/lib/core/src/common/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4272,7 +4272,10 @@ export type GetCustomerQuery = (
{ __typename?: 'Query' }
& { customer?: Maybe<(
{ __typename?: 'Customer' }
& { orders: (
& { groups: Array<(
{ __typename?: 'CustomerGroup' }
& Pick<CustomerGroup, 'id' | 'name'>
)>, orders: (
{ __typename?: 'OrderList' }
& Pick<OrderList, 'totalItems'>
& { items: Array<(
Expand Down Expand Up @@ -6787,6 +6790,7 @@ export namespace GetCustomer {
export type Variables = GetCustomerQueryVariables;
export type Query = GetCustomerQuery;
export type Customer = CustomerFragment;
export type Groups = (NonNullable<(NonNullable<GetCustomerQuery['customer']>)['groups'][0]>);
export type Orders = (NonNullable<GetCustomerQuery['customer']>)['orders'];
export type Items = (NonNullable<(NonNullable<GetCustomerQuery['customer']>)['orders']['items'][0]>);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export const GET_CUSTOMER = gql`
query GetCustomer($id: ID!, $orderListOptions: OrderListOptions) {
customer(id: $id) {
...Customer
groups {
id
name
}
orders(options: $orderListOptions) {
items {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<vdr-action-bar-items locationId="customer-detail"></vdr-action-bar-items>
<button
class="btn btn-primary"
*ngIf="(isNew$ | async); else updateButton"
*ngIf="isNew$ | async; else updateButton"
(click)="create()"
[disabled]="!(addressDefaultsUpdated || (detailForm.valid && detailForm.dirty))"
>
Expand Down Expand Up @@ -53,7 +53,7 @@
>
<input id="emailAddress" type="text" formControlName="emailAddress" />
</vdr-form-field>
<vdr-form-field [label]="'customer.password' | translate" for="password" *ngIf="(isNew$ | async)">
<vdr-form-field [label]="'customer.password' | translate" for="password" *ngIf="isNew$ | async">
<input id="password" type="password" formControlName="password" />
</vdr-form-field>

Expand All @@ -70,6 +70,28 @@
</section>
</form>

<div class="groups" *ngIf="(entity$ | async)?.groups as groups">
<label class="clr-control-label">{{ 'customer.customer-groups' | translate }}</label>
<ng-container *ngIf="groups.length; else noGroups">
<vdr-chip
*ngFor="let group of groups"
[colorFrom]="group.id"
icon="times"
(iconClick)="removeFromGroup(group)"
>{{ group.name }}</vdr-chip
>
</ng-container>
<ng-template #noGroups>
{{ 'customer.not-a-member-of-any-groups' | translate }}
</ng-template>
<div>
<button class="btn btn-sm btn-secondary" (click)="addToGroup()">
<clr-icon shape="plus"></clr-icon>
{{ 'customer.add-customer-to-group' | translate }}
</button>
</div>
</div>

<div class="clr-row" *ngIf="!(isNew$ | async)">
<div class="clr-col-md-4">
<h3>{{ 'customer.addresses' | translate }}</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnIni
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BaseDetailComponent } from '@vendure/admin-ui/core';
import {
BaseDetailComponent,
CreateAddressInput,
CreateCustomerInput,
Customer,
CustomFieldConfig,
DataService,
GetAvailableCountries,
GetCustomer,
GetCustomerQuery,
ModalService,
NotificationService,
ServerConfigService,
UpdateCustomerInput,
} from '@vendure/admin-ui/core';
import { NotificationService } from '@vendure/admin-ui/core';
import { DataService } from '@vendure/admin-ui/core';
import { ServerConfigService } from '@vendure/admin-ui/core';
import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
import { forkJoin, Observable, Subject } from 'rxjs';
import { filter, map, merge, mergeMap, shareReplay, take } from 'rxjs/operators';
import { EMPTY, forkJoin, from, Observable, Subject } from 'rxjs';
import { concatMap, filter, map, merge, mergeMap, shareReplay, switchMap, take } from 'rxjs/operators';

import { SelectCustomerGroupDialogComponent } from '../select-customer-group-dialog/select-customer-group-dialog.component';

type CustomerWithOrders = NonNullable<GetCustomerQuery['customer']>;

Expand Down Expand Up @@ -49,6 +52,7 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
private changeDetector: ChangeDetectorRef,
private formBuilder: FormBuilder,
protected dataService: DataService,
private modalService: ModalService,
private notificationService: NotificationService,
) {
super(route, router, serverConfigService, dataService);
Expand Down Expand Up @@ -243,6 +247,53 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
);
}

addToGroup() {
this.modalService
.fromComponent(SelectCustomerGroupDialogComponent, {
size: 'md',
})
.pipe(
switchMap((groupIds) => (groupIds ? from(groupIds) : EMPTY)),
concatMap((groupId) => this.dataService.customer.addCustomersToGroup(groupId, [this.id])),
)
.subscribe({
next: (res) => {
this.notificationService.success(_(`customer.add-customers-to-group-success`), {
customerCount: 1,
groupName: res.addCustomersToGroup.name,
});
},
complete: () => {
this.dataService.customer.getCustomer(this.id, { take: 0 }).single$.subscribe();
},
});
}

removeFromGroup(group: GetCustomer.Groups) {
this.modalService
.dialog({
title: _('customer.confirm-remove-customer-from-group'),
buttons: [
{ type: 'secondary', label: _('common.cancel') },
{ type: 'danger', label: _('common.delete'), returnValue: true },
],
})
.pipe(
switchMap((response) =>
response
? this.dataService.customer.removeCustomersFromGroup(group.id, [this.id])
: EMPTY,
),
switchMap(() => this.dataService.customer.getCustomer(this.id, { take: 0 }).single$),
)
.subscribe((result) => {
this.notificationService.success(_(`customer.remove-customers-from-group-success`), {
customerCount: 1,
groupName: group.name,
});
});
}

protected setFormValues(entity: Customer.Fragment): void {
const customerGroup = this.detailForm.get('customer');
if (customerGroup) {
Expand Down Expand Up @@ -283,6 +334,7 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
}
}
}
this.changeDetector.markForCheck();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<ng-template vdrDialogTitle>
{{ 'customer.add-customer-to-group' }}
</ng-template>

<ng-select
[items]="groups$ | async"
appendTo="body"
[addTag]="false"
[multiple]="true"
bindValue="id"
[(ngModel)]="selectedGroupIds"
[clearable]="true"
[searchable]="false"
>
<ng-template ng-label-tmp let-item="item" let-clear="clear">
<span aria-hidden="true" class="ng-value-icon left" (click)="clear(item)"> × </span>
<vdr-chip [colorFrom]="item.id">{{ item.name }}</vdr-chip>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<vdr-chip [colorFrom]="item.id">{{ item.name }}</vdr-chip>
</ng-template>
</ng-select>


<ng-template vdrDialogButtons>
<button type="button" class="btn" (click)="cancel()">{{ 'common.cancel' | translate }}</button>
<button type="submit" (click)="add()" [disabled]="!selectedGroupIds.length" class="btn btn-primary">
{{ 'customer.add-customer-to-groups-with-count' | translate: {count: selectedGroupIds.length} }}
</button>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { DataService, Dialog, GetCustomerGroups, GetCustomerList } from '@vendure/admin-ui/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';

@Component({
selector: 'vdr-select-customer-group-dialog',
templateUrl: './select-customer-group-dialog.component.html',
styleUrls: ['./select-customer-group-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SelectCustomerGroupDialogComponent implements Dialog<string[]>, OnInit {
resolveWith: (result?: string[]) => void;
groups$: Observable<GetCustomerGroups.Items[]>;
selectedGroupIds: string[] = [];

constructor(private dataService: DataService) {}

ngOnInit() {
this.groups$ = this.dataService.customer
.getCustomerGroupList()
.mapStream((res) => res.customerGroups.items);
}

cancel() {
this.resolveWith();
}

add() {
this.resolveWith(this.selectedGroupIds);
}
}
2 changes: 2 additions & 0 deletions packages/admin-ui/src/lib/customer/src/customer.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CustomerGroupListComponent } from './components/customer-group-list/cus
import { CustomerGroupMemberListComponent } from './components/customer-group-member-list/customer-group-member-list.component';
import { CustomerListComponent } from './components/customer-list/customer-list.component';
import { CustomerStatusLabelComponent } from './components/customer-status-label/customer-status-label.component';
import { SelectCustomerGroupDialogComponent } from './components/select-customer-group-dialog/select-customer-group-dialog.component';
import { customerRoutes } from './customer.routes';

@NgModule({
Expand All @@ -23,6 +24,7 @@ import { customerRoutes } from './customer.routes';
CustomerGroupDetailDialogComponent,
AddCustomerToGroupDialogComponent,
CustomerGroupMemberListComponent,
SelectCustomerGroupDialogComponent,
],
exports: [AddressCardComponent],
})
Expand Down
5 changes: 5 additions & 0 deletions packages/admin-ui/src/lib/static/i18n-messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,22 @@
"with-selected": "With selected..."
},
"customer": {
"add-customer-to-group": "Add customer to group",
"add-customer-to-groups-with-count": "Add customer to {count, plural, one {1 group} other {{count} groups}}",
"add-customers-to-group": "Add customers to group",
"add-customers-to-group-success": "Added {customerCount, plural, one {1 customer} other {{customerCount} customers}} to \"{ groupName }\"",
"add-customers-to-group-with-count": "Add {count, plural, one {1 customer} other {{count} customers}}",
"add-customers-to-group-with-name": "Add customers to \"{ groupName }\"",
"addresses": "Addresses",
"city": "City",
"confirm-delete-customer-group": "Delete customer group?",
"confirm-remove-customer-from-group": "Remove customer from group?",
"country": "Country",
"create-customer-group": "Create customer group",
"create-new-address": "Create new address",
"create-new-customer": "Create new customer",
"create-new-customer-group": "Create new customer group",
"customer-groups": "Customer groups",
"customer-type": "Customer type",
"default-billing-address": "Default billing",
"default-shipping-address": "Default shipping",
Expand All @@ -219,6 +223,7 @@
"last-name": "Last name",
"name": "Name",
"no-orders-placed": "No orders placed",
"not-a-member-of-any-groups": "This customer is not a member of any groups",
"orders": "Orders",
"password": "Password",
"phone-number": "Phone number",
Expand Down

0 comments on commit 8dca9a3

Please sign in to comment.