Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(cart): clean up verbiage and remove dependencies from installation code #3008

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 9 additions & 99 deletions libs/cart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,113 +3,23 @@ Building and maintaining a model and code for an ecommerce store is complex and
provides clear interfaces, models, and factories for the frontend of an ecommerce store so that you don't have to.

## Installation
To install `@daffodil/cart` and its dependencies, use the following commands in the terminal.
To install `@daffodil/cart`, use the following commands in your terminal.

Install with npm:
```
npm install @daffodil/cart @daffodil/core @ngrx/store @ngrx/effects --save
npm install @daffodil/cart --save
```

Install with yarn:
```
yarn add @daffodil/cart @daffodil/core @ngrx/store @ngrx/effects
yarn add @daffodil/cart
```

## Getting started
`@daffodil/cart` includes multiple layers of functionality that build on each other. The models can be used on their own. The driver layers can be used with the models but also allow custom extensions to those models to be passed as generics. A state layer sits on top of the driver layer. Individual drivers can be overridden through driver injection tokens and custom extensions to models can be passed into the state layer's generics.
`@daffodil/cart` includes multiple layers of functionality that build on each other. The models can be used on their own. The recommended way to use Daffodil is with the state layer.

The recommended way to use Daffodil is with the state layer.

- [State guide](/libs/cart/guides/state.md)
- [Drivers guide](/libs/cart/guides/drivers.md)
- [Extension guide](/libs/cart/guides/extension.md)

## Usage

### Interacting with platforms
Interacting with platforms through the [cart facade](/libs/cart/guides/state.md#using-the-facade) is the recommended method.

It is possible to interact with platforms by directly calling the drivers. While this requires more work to integrate into components, it offers greater flexibility. See the [drivers guide](/libs/cart/guides/drivers.md) for more information.

### Using routing guards
`@daffodil/cart` provides a number of routing guards to prevent access to certain pages until specific data becomes available.

The following example illustrates using the `DaffShippingAddressGuard` to prevent accessing the shipping method page of checkout until a shipping address has been set.

```ts
import {
DaffShippingAddressGuard,
DaffCartShippingAddressGuardRedirectUrl
} from '@daffodil/cart';

@NgModule({
imports: [
...,
RouterModule.forRoot([
{
path: 'checkout/shipping',
component: CheckoutShippingComponent,
canActivate: [DaffShippingAddressGuard]
},
{
path: '',
component: HomepageComponent,
},
])
],
providers: [
{
provide: DaffCartShippingAddressGuardRedirectUrl,
useValue: '/'
}
]
})
class AppModule {}
```

> The `'checkout/shipping'` route's activation was guarded with the `DaffShippingAddressGuard`, ensuring that page cannot be accessed unless the cart has a valid shipping address set. The `DaffCartShippingAddressGuardRedirectUrl` token is used to configure the path to which the user is redirected when and if the activation fails.

### Providing platform-agnostic payment IDs
`DaffCartFacade` provides a field (`paymentId$`) for agnostic payment IDs. The IDs must be user-supplied to prevent circular package dependencies. Provide an object for the `DaffCartPaymentMethodIdMap` token. The keys of this object should be cart payment methods and the values should be strings.

```ts
import {
DaffCartPaymentMethodIdMap,
DaffCartFacade,
DaffCartPaymentMethod
} from '@daffodil/cart';

@NgModule({
...,
providers: [
{
provide: DaffCartPaymentMethodIdMap,
useValue: {
authorizenet_accept_js: 'authorizenet',
payflowpro: 'paypal'
}
}
]
})
class AppModule {}

@Component({})
class CartComponent implements OnInit {
paymentID$: Observable<string>;

constructor(private cartFacade: DaffCartFacade) {}

ngOnInit() {
this.paymentID$ = this.cartFacade.paymentId$;
}

setPayment(info) {
this.cartFacade.dispatch(new DaffCartPaymentUpdate({
method: 'authorizenet_accept_js',
payment_info: info
}));
}
}
```

> When `setPayment` is called, the cart payment method will be updated. After this update is finished, the `this.paymentID$` stream will emit `'authorizenet'`.
| Layer | Description |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [State](/libs/cart/guides/state.md) | Can be used with the models but also allow custom extensions to those models to be passed as generics |
| [Drivers](/libs/cart/guides/drivers.md) | Sits on top of the driver layer |
| [Extensions](/libs/cart/guides/extension.md) | Individual drivers can be overridden through driver injection tokens and custom extensions to models can be passed into the state layer's generics |
10 changes: 4 additions & 6 deletions libs/cart/guides/drivers.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Drivers
`@daffodil/cart` can interface with supported platforms through drivers. Choose the driver that corresponds to the platform of choice and follow the linked guide to set it up.

## Supported drivers

### In-memory web API
The in-memory driver is for rapid development without the need to set up a magento/shopify/etc backend. It will mock out the management of a cart and operate like a functional backend. It is intended for development and testing purposes and not meant to be used in production.
## In-memory web API
The in-memory driver is for rapid development without the need to set up a platform-specific backend. It will mock out the management of a cart and operate like a functional backend. It is intended for development and testing purposes and not meant to be used in production.

To set up in the root component:
1. Import the `DaffCartInMemoryDriverModule` from `@daffodil/cart/testing`
Expand All @@ -28,7 +26,7 @@ Now this `DaffCart` implementation will have access to the in-memory driver to u

> Note: It is important to only have one `daffodil/cart` driver set up at a time in the root component. To set up a driver configuration to make switching between different backend drivers simple, follow the [advanced setup guide](). <!-- TODO: add multiple drivers guide -->

### Magento
## Magento
The Magento driver communicates with the Magento backend through the GraphQL API.

To set up in the root component:
Expand All @@ -53,7 +51,7 @@ This `DaffCart` implementation will now be able to interact with Magento.

> Note: It is important to only have one `@daffodil/cart` driver set up in the root component at a time. To set up a driver configuration to make switching between different backend drivers simple, follow the [advanced setup guide](). <!-- TODO: add multiple drivers guide -->

#### Fragment introspection
### Fragment introspection
You should set up fragment introspection with the Magento backend. Refer to the [fragment introspection guide](../../../../tools/builders/guides/fragment-introspection.md) for more information.

## Usage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Extension
# Extensions
`@daffodil/cart` provides a number of extension mechanisms so that it can be customized to fit specific needs.

## Custom drivers
Expand Down
21 changes: 13 additions & 8 deletions libs/cart/guides/state.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# State
`@daffodil/cart` provides a fully featured state library to streamline the management of an application's state as well as driver interaction. The facade is an abstraction that provides all the functionality needed for standard use. It is the recommended way to interact with the Daffodil state layer.
`@daffodil/cart` provides a fully featured state library to streamline the management of an application's state as well as driver interaction.

## Overview
The facade is an abstraction that provides all the functionality needed for standard use. It's the recommended way to interact with the Daffodil state layer.

## Set up the root component
1. Import the `DaffCartStateModule`
2. Import `StoreModule.forRoot({})`, which will be relevant later on when using the redux and state management features `@daffodil/cart`.
1. Import the `DaffCartStateModule` in the root component.
2. Import `StoreModule.forRoot({})`. This will be relevant later on when using the redux and state management features of `@daffodil/cart`.

```typescript
```ts
@ngModule({
imports:[
StoreModule.forRoot({}),
Expand Down Expand Up @@ -33,9 +36,11 @@ Once the `DaffCartFacade` has been set up in the component, it can now be used t

Additionally, the Daffodil cart facade provides three different loading states for each section of the cart:

- `mutating$` tracks when an update to a cart property is occurring.
- `resolving$` tracks when new data is being fetched but no updates are taking place.
- `loading$` emits `true` when either `mutating$` or `resolving$` is `true`.
| State | Description |
| ------------ | --------------------------------------------------------------------- |
| `mutating$` | Tracks when an update to a cart property is occurring |
| `resolving$` | Tracks when new data is being fetched but no updates are taking place |
| `loading$` | Emits `true` when either `mutating$` or `resolving$` is `true` |

There is also overall `featureLoading$`, `featureMutating$`, and `featureResolving$` streams to track loading for any section of the cart. These can be used to enhance the application's UI.

Expand Down Expand Up @@ -136,7 +141,7 @@ This tutorial will walk you through the cart resolution process, which is respon
### Supported scenarios
At the moment, the following scenarios are handled by the `DaffResolvedCartGuard`.

> For customer cart support, use the [@daffodil/cart-customer](/libs/cart-customer/README.md) package.
> For customer cart support, use [@daffodil/cart-customer](/libs/cart-customer/README.md).

- Generating a new cart when a user visits the application for the very first time.
- Retrieving a previously existing cart for a user upon page reload.
Expand Down
4 changes: 2 additions & 2 deletions libs/cart/guides/testing.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Testing
`@daffodil/cart` provides a testing package accessible at `@daffodil/cart/testing`. This package provides model factories, facade mocks, and driver mocks to facilitate unit testing.
`@daffodil/cart` provides a testing package accessible at `@daffodil/cart/testing`. It provides model factories, facade mocks, and driver mocks to facilitate unit testing.

## Example
The following example demonstrates how to unit test a component using Daffodil model factories and the mock facade with the Jasmine testing framework and the `jasmine-marbles` library.
The following example demonstrates how to unit test a component using Daffodil model factories, the mock facade with the Jasmine testing framework, and the `jasmine-marbles` library.

`cart.component.ts`
```ts
Expand Down
89 changes: 89 additions & 0 deletions libs/cart/guides/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Usage

## Interacting with platforms
Interacting with platforms through the [cart facade](/libs/cart/guides/state.md#using-the-facade) is the recommended method.

It is possible to interact with platforms by directly calling the drivers. While this requires more work to integrate into components, it offers greater flexibility. See the [drivers guide](/libs/cart/guides/drivers.md) for more information.

## Using routing guards
`@daffodil/cart` provides a number of routing guards to prevent access to certain pages until specific data becomes available.

The following example illustrates using the `DaffShippingAddressGuard` to prevent accessing the shipping method page of checkout until a shipping address has been set.

```ts
import {
DaffShippingAddressGuard,
DaffCartShippingAddressGuardRedirectUrl
} from '@daffodil/cart';

@NgModule({
imports: [
...,
RouterModule.forRoot([
{
path: 'checkout/shipping',
component: CheckoutShippingComponent,
canActivate: [DaffShippingAddressGuard]
},
{
path: '',
component: HomepageComponent,
},
])
],
providers: [
{
provide: DaffCartShippingAddressGuardRedirectUrl,
useValue: '/'
}
]
})
class AppModule {}
```

> The `'checkout/shipping'` route's activation was guarded with the `DaffShippingAddressGuard`, ensuring that page cannot be accessed unless the cart has a valid shipping address set. The `DaffCartShippingAddressGuardRedirectUrl` token is used to configure the path to which the user is redirected when and if the activation fails.

## Providing platform-agnostic payment IDs
`DaffCartFacade` provides a field (`paymentId$`) for agnostic payment IDs. The IDs must be user-supplied to prevent circular package dependencies. Provide an object for the `DaffCartPaymentMethodIdMap` token. The keys of this object should be cart payment methods and the values should be strings.

```ts
import {
DaffCartPaymentMethodIdMap,
DaffCartFacade,
DaffCartPaymentMethod
} from '@daffodil/cart';

@NgModule({
...,
providers: [
{
provide: DaffCartPaymentMethodIdMap,
useValue: {
authorizenet_accept_js: 'authorizenet',
payflowpro: 'paypal'
}
}
]
})
class AppModule {}

@Component({})
class CartComponent implements OnInit {
paymentID$: Observable<string>;

constructor(private cartFacade: DaffCartFacade) {}

ngOnInit() {
this.paymentID$ = this.cartFacade.paymentId$;
}

setPayment(info) {
this.cartFacade.dispatch(new DaffCartPaymentUpdate({
method: 'authorizenet_accept_js',
payment_info: info
}));
}
}
```

> When `setPayment` is called, the cart payment method will be updated. After this update is finished, the `this.paymentID$` stream will emit `'authorizenet'`.
Loading