Skip to content

Commit

Permalink
feat(cart)!: use operation entity state for item entities (#2794)
Browse files Browse the repository at this point in the history
BREAKING CHANGES: removes many selectors and facade fields
  • Loading branch information
griest024 committed May 14, 2024
1 parent 589a06c commit b2c1e90
Show file tree
Hide file tree
Showing 92 changed files with 789 additions and 2,303 deletions.
4 changes: 2 additions & 2 deletions apps/demo/src/app/cart/components/cart/cart.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ describe('Cart', () => {

fixture = TestBed.createComponent(WrapperComponent);
wrapper = fixture.componentInstance;
daffCartFacade.items$ = new BehaviorSubject(cart.items);
daffCartFacade.isCartEmpty$ = new BehaviorSubject(true);
daffCartFacade.cart$.next(cart);
daffCartFacade.isCartEmpty$.next(true);
wrapper.cartValue = cart;
component = fixture.debugElement.query(By.css('demo-cart')).componentInstance;

Expand Down
4 changes: 2 additions & 2 deletions apps/demo/src/app/cart/components/cart/cart.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export class CartComponent implements OnInit {
) {}

ngOnInit(): void {
this.itemCount$ = this.facade.items$.pipe(
map(items => items.length),
this.itemCount$ = this.facade.cart$.pipe(
map((cart) => cart?.items.length),
);
this.isCartEmpty$ = this.facade.isCartEmpty$;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DaffCartAddressServiceInterface } from '@daffodil/cart/driver';
@Injectable({
providedIn: 'root',
})
export class DaffInMemoryCartAddressService implements DaffCartAddressServiceInterface<DaffCartAddress, DaffCart> {
export class DaffInMemoryCartAddressService implements DaffCartAddressServiceInterface {
/**
* The URL with which the driver makes calls to the backend.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DaffCartBillingAddressServiceInterface } from '@daffodil/cart/driver';
@Injectable({
providedIn: 'root',
})
export class DaffInMemoryCartBillingAddressService implements DaffCartBillingAddressServiceInterface<DaffCartAddress, DaffCart> {
export class DaffInMemoryCartBillingAddressService implements DaffCartBillingAddressServiceInterface {
/**
* The URL with which the driver makes calls to the backend.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import { DaffCartItemServiceInterface } from '@daffodil/cart/driver';
@Injectable({
providedIn: 'root',
})
export class DaffInMemoryCartItemService implements DaffCartItemServiceInterface<
DaffCartItem,
DaffCartItemInput,
DaffCart
> {
export class DaffInMemoryCartItemService implements DaffCartItemServiceInterface {
/**
* The URL with which the driver makes calls to the backend.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DaffCartShippingAddressServiceInterface } from '@daffodil/cart/driver';
@Injectable({
providedIn: 'root',
})
export class DaffInMemoryCartShippingAddressService implements DaffCartShippingAddressServiceInterface<DaffCartAddress, DaffCart> {
export class DaffInMemoryCartShippingAddressService implements DaffCartShippingAddressServiceInterface {
/**
* The URL with which the driver makes calls to the backend.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import { DaffCartShippingInformationServiceInterface } from '@daffodil/cart/driv
@Injectable({
providedIn: 'root',
})
export class DaffInMemoryCartShippingInformationService implements DaffCartShippingInformationServiceInterface<
DaffCartShippingRate,
DaffCart
> {
export class DaffInMemoryCartShippingInformationService implements DaffCartShippingInformationServiceInterface {
/**
* The URL with which the driver makes calls to the backend.
*/
Expand Down
6 changes: 1 addition & 5 deletions libs/cart/driver/magento/src/cart.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,7 @@ export class DaffMagentoCartService implements DaffCartServiceInterface<DaffCart
private apollo: Apollo,
@Inject(DAFF_MAGENTO_CART_MUTATION_QUEUE) private mutationQueue: DaffQueuedApollo,
private cartTransformer: DaffMagentoCartTransformer,
@Inject(DaffCartItemDriver) private cartItemDriver: DaffCartItemServiceInterface<
DaffCartItem,
DaffCartItemInput,
DaffCart
>,
@Inject(DaffCartItemDriver) private cartItemDriver: DaffCartItemServiceInterface,
@Inject(DAFF_CART_MAGENTO_EXTRA_CART_FRAGMENTS) private extraCartFragments: DocumentNode[],
) {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCartAddress,
DaffCart,
} from '@daffodil/cart';
import { DaffCart } from '@daffodil/cart';

/**
* The interface responsible for managing the address of a cart.
*/
export interface DaffCartAddressServiceInterface<
T extends DaffCartAddress = DaffCartAddress,
V extends DaffCart = DaffCart
> {
export interface DaffCartAddressServiceInterface<T extends DaffCart = DaffCart> {
/**
* Update the billing and shipping address of a cart
*/
update(cartId: V['id'], address: Partial<T>): Observable<Partial<V>>;
update(cartId: T['id'], address: Partial<T['shipping_address'] | T['billing_address']>): Observable<Partial<T>>;
}

export const DaffCartAddressDriver = new InjectionToken<
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCartAddress,
DaffCart,
} from '@daffodil/cart';
import { DaffCart } from '@daffodil/cart';

/**
* The interface responsible for managing the billing address of a cart.
*/
export interface DaffCartBillingAddressServiceInterface<
T extends DaffCartAddress = DaffCartAddress,
V extends DaffCart = DaffCart
> {
export interface DaffCartBillingAddressServiceInterface<T extends DaffCart = DaffCart> {
/**
* Retrieve the billing address of a cart
*/
get(cartId: V['id']): Observable<T>;
get(cartId: T['id']): Observable<T['billing_address']>;

/**
* Update the billing address of a cart
*/
update(cartId: V['id'], address: Partial<T>): Observable<Partial<V>>;
update(cartId: T['id'], address: Partial<T['billing_address']>): Observable<Partial<T>>;
}

export const DaffCartBillingAddressDriver = new InjectionToken<
Expand Down
13 changes: 5 additions & 8 deletions libs/cart/driver/src/interfaces/cart-coupon-service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCart,
DaffCartCoupon,
} from '@daffodil/cart';
import { DaffCart } from '@daffodil/cart';

/**
* The interface responsible for applying a coupon to a cart.
*/
export interface DaffCartCouponServiceInterface<T extends DaffCart = DaffCart, V extends DaffCartCoupon = DaffCartCoupon> {
export interface DaffCartCouponServiceInterface<T extends DaffCart = DaffCart> {
/**
* Apply a coupon to the cart and return a partial of the cart.
*/
apply(cartId: T['id'], coupon: V): Observable<Partial<T>>;
apply(cartId: T['id'], coupon: T['coupons'][number]): Observable<Partial<T>>;

/**
* List coupon codes applied to a cart.
*/
list(cartId: T['id']): Observable<V[]>;
list(cartId: T['id']): Observable<T['coupons']>;

/**
* Remove a coupon from the cart and return a partial of the cart.
*/
remove(cartId: T['id'], coupon: V): Observable<Partial<T>>;
remove(cartId: T['id'], coupon: T['coupons'][number]): Observable<Partial<T>>;

/**
* Remove all coupons from the cart and return a partial of the cart.
Expand Down
19 changes: 9 additions & 10 deletions libs/cart/driver/src/interfaces/cart-item-service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,37 @@ import {
* The interface responsible for managing the items of a cart.
*/
export interface DaffCartItemServiceInterface<
T extends DaffCartItem = DaffCartItem,
T extends DaffCart = DaffCart,
U extends DaffCartItemInput = DaffCartItemInput,
V extends DaffCart = DaffCart
> {
/**
* List all of the available items of a cart
*/
list(cartId: V['id']): Observable<T[]>;
list(cartId: T['id']): Observable<T['items']>;

/**
* Get a specific cart item of a cart.
*/
get(cartId: V['id'], item_id: DaffCartItem['id']): Observable<T>;
get(cartId: T['id'], item_id: DaffCartItem['id']): Observable<T['items'][number]>;

/**
* Add something to a cart.
*/
add(id: V['id'], product: U): Observable<Partial<V>>;
add(id: T['id'], product: U): Observable<Partial<T>>;

/**
* Update an existing item in a cart
*/
update(
cartId: V['id'],
itemId: T['id'],
changes: Partial<T>,
): Observable<Partial<V>>;
cartId: T['id'],
itemId: T['items'][number]['id'],
changes: Partial<T['items'][number]>,
): Observable<Partial<T>>;

/**
* Remove an item from a cart.
*/
delete(cartId: V['id'], itemId: T['id']): Observable<Partial<V>>;
delete(cartId: T['id'], itemId: T['items'][number]['id']): Observable<Partial<T>>;
}

export const DaffCartItemDriver = new InjectionToken<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Observable } from 'rxjs';

import {
DaffCart,
DaffCartPaymentMethod,
DaffCartOrderResult,
} from '@daffodil/cart';

Expand All @@ -12,13 +11,12 @@ import {
*/
export interface DaffCartOrderServiceInterface<
T extends DaffCart = DaffCart,
V extends DaffCartPaymentMethod = DaffCartPaymentMethod,
R extends DaffCartOrderResult = DaffCartOrderResult
> {
/**
* Place an order and return the order ID.
*/
placeOrder(id: T['id'], payment?: V): Observable<R>;
placeOrder(id: T['id'], payment?: T['payment']): Observable<R>;
}

export const DaffCartOrderDriver = new InjectionToken<DaffCartOrderServiceInterface>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,30 @@ import {
/**
* The interface responsible for managing the selected payment method of a cart.
*/
export interface DaffCartPaymentServiceInterface<
T extends DaffCartPaymentMethod = DaffCartPaymentMethod,
V extends DaffCart = DaffCart,
R extends DaffCartAddress = DaffCartAddress
> {
export interface DaffCartPaymentServiceInterface<T extends DaffCart = DaffCart> {
/**
* Get the currently applied payment method of a cart.
*/
get(cartId: V['id']): Observable<T>;
get(cartId: T['id']): Observable<T['payment']>;

/**
* Update the payment method applied to a cart.
*
* If a billing address is provided, the driver will update that simultaneously.
*/
update(cartId: V['id'], payment: Partial<T>, billingAddress?: Partial<R>): Observable<Partial<V>>;
update(cartId: T['id'], payment: Partial<T['payment']>, billingAddress?: Partial<T['billing_address']>): Observable<Partial<T>>;

/**
* Update the billing address and payment method applied to a cart.
*
* @deprecated use `update` with the `billingAddress` parameter instead.
*/
updateWithBilling(cartId: V['id'], payment: Partial<T>, address: Partial<R>): Observable<Partial<V>>;
updateWithBilling(cartId: T['id'], payment: Partial<T['payment']>, address: Partial<T['billing_address']>): Observable<Partial<T>>;

/**
* Remove the payment method applied to a cart.
*/
remove(cartId: V['id']): Observable<void>;
remove(cartId: T['id']): Observable<void>;
}

export const DaffCartPaymentDriver = new InjectionToken<
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCartAddress,
DaffCart,
} from '@daffodil/cart';
import { DaffCart } from '@daffodil/cart';

/**
* The interface responsible for managing the shipping address of a cart.
*/
export interface DaffCartShippingAddressServiceInterface<
T extends DaffCartAddress = DaffCartAddress,
V extends DaffCart = DaffCart
> {
export interface DaffCartShippingAddressServiceInterface<T extends DaffCart = DaffCart> {
/**
* Retrieve the shipping address of a cart.
*/
get(cartId: V['id']): Observable<T>;
get(cartId: T['id']): Observable<T['shipping_address']>;

/**
* Update the shipping address of a cart.
*/
update(cartId: V['id'], address: Partial<T>): Observable<Partial<V>>;
update(cartId: T['id'], address: Partial<T['shipping_address']>): Observable<Partial<T>>;
}

export const DaffCartShippingAddressDriver = new InjectionToken<
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCartShippingRate,
DaffCart,
} from '@daffodil/cart';
import { DaffCart } from '@daffodil/cart';

/**
* The interface responsible for mediating the interaction of the shipping
* information of a cart with a given platform.
*/
export interface DaffCartShippingInformationServiceInterface<
T extends DaffCartShippingRate = DaffCartShippingRate,
V extends DaffCart = DaffCart
>{
export interface DaffCartShippingInformationServiceInterface<T extends DaffCart = DaffCart>{
/**
* Get the currently selected shipping method of a cart.
*/
get(cartId: V['id']): Observable<T>;
get(cartId: T['id']): Observable<T['shipping_information']>;

/**
* Update the currently selected shipping method of a cart.
*/
update(cartId: V['id'], shippingInfo: Partial<T>): Observable<Partial<V>>;
update(cartId: T['id'], shippingInfo: Partial<T['shipping_information']>): Observable<Partial<T>>;

/**
* Remove the currently selected shipping method from a cart.
*/
delete(cartId: V['id'], id?: T['id']): Observable<Partial<V>>;
delete(cartId: T['id'], id?: T['shipping_information']['id']): Observable<Partial<T>>;
}

export const DaffCartShippingInformationDriver = new InjectionToken<
Expand Down
14 changes: 14 additions & 0 deletions libs/cart/src/helpers/get-affected-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { DaffCartItem } from '../models/public_api';

/**
* Finds the IDs of any affected cart items between two carts.
*/
export function daffCartGetAffectedItems<T extends DaffCartItem = DaffCartItem>(oldItems: Array<T>, newItems: Array<T>): Array<T['id']> {
return newItems.reduce((acc, newItem) => {
const oldItem = oldItems.find(({ id }) => id === newItem.id);
if (!oldItem || oldItem.qty !== newItem.qty) {
acc.push(newItem.id);
}
return acc;
}, <Array<T['id']>>[]);
}
21 changes: 21 additions & 0 deletions libs/cart/src/helpers/input-to-item-transform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
DaffCartItem,
DaffCartItemInput,
} from '../models/public_api';

export const daffCartItemInputToItemTransform = (input: DaffCartItemInput): DaffCartItem => ({
type: input.type,
product_id: input.productId,
qty: input.qty,

item_id: null,
id: null,
parent_item_id: null,
sku: null,
name: null,
price: null,
row_total: null,
in_stock: false,
discounts: [],
url: null,
});
Loading

0 comments on commit b2c1e90

Please sign in to comment.