Skip to content

Commit

Permalink
feat(core): Add OrderInterceptor API (#3233)
Browse files Browse the repository at this point in the history
Closes #2123
  • Loading branch information
michaelbromley authored Nov 26, 2024
1 parent fb80ee3 commit 7706e35
Show file tree
Hide file tree
Showing 113 changed files with 27,610 additions and 57,619 deletions.
12 changes: 12 additions & 0 deletions docs/docs/guides/core-concepts/orders/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,15 @@ If you have defined custom order states, the Admin UI will allow you to manually
order from one state to another:

![./custom-order-ui.webp](./custom-order-ui.webp)

## Order Interceptors

Vendure v3.1 introduces the concept of [Order Interceptors](/reference/typescript-api/orders/order-interceptor/).
These are a way to intercept operations that add, modify or remove order lines. Examples use-cases include:

* Preventing certain products from being added to the order based on some criteria, e.g. if the product is already in another active order.
* Enforcing a minimum or maximum quantity of a given product in the order
* Using a CAPTCHA to prevent automated order creation

Check the [Order Interceptor](/reference/typescript-api/orders/order-interceptor/) docs for more information as well as a complete
example of how to implement an interceptor.
82 changes: 41 additions & 41 deletions docs/docs/reference/admin-ui-api/bulk-actions/bulk-action.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ import MemberDescription from '@site/src/components/MemberDescription';

<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/providers/bulk-action-registry/bulk-action-types.ts" sourceLine="99" packageName="@vendure/admin-ui" since="1.8.0" />

Configures a bulk action which can be performed on all selected items in a list view.

Configures a bulk action which can be performed on all selected items in a list view.

For a full example, see the <a href='/reference/admin-ui-api/bulk-actions/register-bulk-action#registerbulkaction'>registerBulkAction</a> docs.

```ts title="Signature"
interface BulkAction<ItemType = any, ComponentType = any> {
location: BulkActionLocationId;
label: string;
getTranslationVars?: (
context: BulkActionFunctionContext<ItemType, ComponentType>,
getTranslationVars?: (
context: BulkActionFunctionContext<ItemType, ComponentType>,
) => Record<string, string | number> | Promise<Record<string, string | number>>;
icon?: string;
iconClass?: string;
Expand All @@ -46,26 +46,26 @@ interface BulkAction<ItemType = any, ComponentType = any> {

### getTranslationVars

<MemberInfo kind="property" type={`( context: <a href='/reference/admin-ui-api/bulk-actions/bulk-action#bulkactionfunctioncontext'>BulkActionFunctionContext</a>&#60;ItemType, ComponentType&#62;, ) =&#62; Record&#60;string, string | number&#62; | Promise&#60;Record&#60;string, string | number&#62;&#62;`} />
<MemberInfo kind="property" type={`( context: <a href='/reference/admin-ui-api/bulk-actions/bulk-action#bulkactionfunctioncontext'>BulkActionFunctionContext</a>&#60;ItemType, ComponentType&#62;, ) =&#62; Record&#60;string, string | number&#62; | Promise&#60;Record&#60;string, string | number&#62;&#62;`} />

An optional function that should resolve to a map of translation variables which can be
An optional function that should resolve to a map of translation variables which can be
used when translating the `label` string.
### icon

<MemberInfo kind="property" type={`string`} />

A valid [Clarity Icons](https://core.clarity.design/foundation/icons/shapes/) icon shape, e.g.
A valid [Clarity Icons](https://core.clarity.design/foundation/icons/shapes/) icon shape, e.g.
"cog", "user", "info-standard".
### iconClass

<MemberInfo kind="property" type={`string`} />

A class to be added to the icon element. Examples:

- is-success
- is-danger
- is-warning
- is-info
A class to be added to the icon element. Examples:

- is-success
- is-danger
- is-warning
- is-info
- is-highlight
### onClick

Expand All @@ -76,10 +76,10 @@ Defines the logic that executes when the bulk action button is clicked.

<MemberInfo kind="property" type={`(context: <a href='/reference/admin-ui-api/bulk-actions/bulk-action#bulkactionfunctioncontext'>BulkActionFunctionContext</a>&#60;ItemType, ComponentType&#62;) =&#62; boolean | Promise&#60;boolean&#62;`} />

A function that determines whether this bulk action item should be displayed in the menu.
If not defined, the item will always be displayed.

This function will be invoked each time the selection is changed, so try to avoid expensive code
A function that determines whether this bulk action item should be displayed in the menu.
If not defined, the item will always be displayed.

This function will be invoked each time the selection is changed, so try to avoid expensive code
running here.

*Example*
Expand Down Expand Up @@ -130,25 +130,25 @@ registerBulkAction({
A valid location of a list view that supports the bulk actions API.

```ts title="Signature"
type BulkActionLocationId = | 'product-list'
| 'facet-list'
| 'collection-list'
| 'customer-list'
| 'customer-group-list'
| 'customer-group-members-list'
| 'customer-group-members-picker-list'
| 'promotion-list'
| 'seller-list'
| 'channel-list'
| 'administrator-list'
| 'role-list'
| 'shipping-method-list'
| 'stock-location-list'
| 'payment-method-list'
| 'tax-category-list'
| 'tax-rate-list'
| 'zone-list'
| 'zone-members-list'
type BulkActionLocationId = | 'product-list'
| 'facet-list'
| 'collection-list'
| 'customer-list'
| 'customer-group-list'
| 'customer-group-members-list'
| 'customer-group-members-picker-list'
| 'promotion-list'
| 'seller-list'
| 'channel-list'
| 'administrator-list'
| 'role-list'
| 'shipping-method-list'
| 'stock-location-list'
| 'payment-method-list'
| 'tax-category-list'
| 'tax-rate-list'
| 'zone-list'
| 'zone-members-list'
| string
```
Expand All @@ -157,7 +157,7 @@ type BulkActionLocationId = | 'product-list'
<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/providers/bulk-action-registry/bulk-action-types.ts" sourceLine="43" packageName="@vendure/admin-ui" since="1.8.0" />
This is the argument which gets passed to the `getTranslationVars` and `isVisible` functions
This is the argument which gets passed to the `getTranslationVars` and `isVisible` functions
of the BulkAction definition.
```ts title="Signature"
Expand All @@ -180,15 +180,15 @@ An array of the selected items from the list.

<MemberInfo kind="property" type={`ComponentType`} />

The component instance that is hosting the list view. For instance,
`ProductListComponent`. This can be used to call methods on the instance,
e.g. calling `hostComponent.refresh()` to force a list refresh after
The component instance that is hosting the list view. For instance,
`ProductListComponent`. This can be used to call methods on the instance,
e.g. calling `hostComponent.refresh()` to force a list refresh after
deleting the selected items.
### injector

<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/injector#injector'>Injector</a>`} />

The Angular [Injector](https://angular.io/api/core/Injector) which can be used
The Angular [Injector](https://angular.io/api/core/Injector) which can be used
to get service instances which might be needed in the click handler.
### route

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import MemberDescription from '@site/src/components/MemberDescription';

<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/base-detail.component.ts" sourceLine="256" packageName="@vendure/admin-ui" />

A helper function for creating tabs that point to a <a href='/reference/admin-ui-api/list-detail-views/typed-base-detail-component#typedbasedetailcomponent'>TypedBaseDetailComponent</a>. This takes
care of the route resolver parts so that the detail component automatically has access to the
A helper function for creating tabs that point to a <a href='/reference/admin-ui-api/list-detail-views/typed-base-detail-component#typedbasedetailcomponent'>TypedBaseDetailComponent</a>. This takes
care of the route resolver parts so that the detail component automatically has access to the
correct resolved detail data.

*Example*
Expand All @@ -40,17 +40,17 @@ export class ProductSpecsUiExtensionModule {}
```
```ts title="Signature"
function detailComponentWithResolver<T extends TypedDocumentNode<any, { id: string }>, Field extends keyof ResultOf<T>, R extends Field>(config: {
component: Type<TypedBaseDetailComponent<T, Field>>;
query: T;
entityKey: R;
getBreadcrumbs?: (entity: ResultOf<T>[R]) => BreadcrumbValue;
variables?: T extends TypedDocumentNode<any, infer V> ? Omit<V, 'id'> : never;
function detailComponentWithResolver<T extends TypedDocumentNode<any, { id: string }>, Field extends keyof ResultOf<T>, R extends Field>(config: {
component: Type<TypedBaseDetailComponent<T, Field>>;
query: T;
entityKey: R;
getBreadcrumbs?: (entity: ResultOf<T>[R]) => BreadcrumbValue;
variables?: T extends TypedDocumentNode<any, infer V> ? Omit<V, 'id'> : never;
}): void
```
Parameters
### config
<MemberInfo kind="parameter" type={`{ component: Type&#60;<a href='/reference/admin-ui-api/list-detail-views/typed-base-detail-component#typedbasedetailcomponent'>TypedBaseDetailComponent</a>&#60;T, Field&#62;&#62;; query: T; entityKey: R; getBreadcrumbs?: (entity: ResultOf&#60;T&#62;[R]) =&#62; BreadcrumbValue; variables?: T extends TypedDocumentNode&#60;any, infer V&#62; ? Omit&#60;V, 'id'&#62; : never; }`} />
<MemberInfo kind="parameter" type={`{ component: Type&#60;<a href='/reference/admin-ui-api/list-detail-views/typed-base-detail-component#typedbasedetailcomponent'>TypedBaseDetailComponent</a>&#60;T, Field&#62;&#62;; query: T; entityKey: R; getBreadcrumbs?: (entity: ResultOf&#60;T&#62;[R]) =&#62; BreadcrumbValue; variables?: T extends TypedDocumentNode&#60;any, infer V&#62; ? Omit&#60;V, 'id'&#62; : never; }`} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';

<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/base-list.component.ts" sourceLine="217" packageName="@vendure/admin-ui" />

A version of the <a href='/reference/admin-ui-api/list-detail-views/base-list-component#baselistcomponent'>BaseListComponent</a> which is designed to be used with a
A version of the <a href='/reference/admin-ui-api/list-detail-views/base-list-component#baselistcomponent'>BaseListComponent</a> which is designed to be used with a
[TypedDocumentNode](https://the-guild.dev/graphql/codegen/plugins/typescript/typed-document-node).

```ts title="Signature"
Expand All @@ -27,11 +27,11 @@ class TypedBaseListComponent<T extends TypedDocumentNode<any, Vars>, Field exten
protected dataTableConfigService = inject(DataTableConfigService);
protected dataTableListId: string | undefined;
constructor()
configure(config: {
document: T;
getItems: (data: ResultOf<T>) => { items: Array<ItemOf<ResultOf<T>, Field>>; totalItems: number };
setVariables?: (skip: number, take: number) => VariablesOf<T>;
refreshListOnChanges?: Array<Observable<any>>;
configure(config: {
document: T;
getItems: (data: ResultOf<T>) => { items: Array<ItemOf<ResultOf<T>, Field>>; totalItems: number };
setVariables?: (skip: number, take: number) => VariablesOf<T>;
refreshListOnChanges?: Array<Observable<any>>;
}) => ;
ngOnInit() => ;
createFilterCollection() => DataTableFilterCollection<NonNullable<NonNullable<Vars['options']>['filter']>>;
Expand Down Expand Up @@ -96,7 +96,7 @@ class TypedBaseListComponent<T extends TypedDocumentNode<any, Vars>, Field exten

### configure

<MemberInfo kind="method" type={`(config: { document: T; getItems: (data: ResultOf&#60;T&#62;) =&#62; { items: Array&#60;ItemOf&#60;ResultOf&#60;T&#62;, Field&#62;&#62;; totalItems: number }; setVariables?: (skip: number, take: number) =&#62; VariablesOf&#60;T&#62;; refreshListOnChanges?: Array&#60;Observable&#60;any&#62;&#62;; }) => `} />
<MemberInfo kind="method" type={`(config: { document: T; getItems: (data: ResultOf&#60;T&#62;) =&#62; { items: Array&#60;ItemOf&#60;ResultOf&#60;T&#62;, Field&#62;&#62;; totalItems: number }; setVariables?: (skip: number, take: number) =&#62; VariablesOf&#60;T&#62;; refreshListOnChanges?: Array&#60;Observable&#60;any&#62;&#62;; }) => `} />


### ngOnInit
Expand Down
14 changes: 7 additions & 7 deletions docs/docs/reference/admin-ui-api/react-components/form-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ export function MyReactComponent() {
```

```ts title="Signature"
function FormField(props: PropsWithChildren<{
for?: string;
label?: string;
tooltip?: string;
invalid?: boolean;
errorMessage?: string;
function FormField(props: PropsWithChildren<{
for?: string;
label?: string;
tooltip?: string;
invalid?: boolean;
errorMessage?: string;
}>): void
```
Parameters

### props

<MemberInfo kind="parameter" type={`PropsWithChildren&#60;{ for?: string; label?: string; tooltip?: string; invalid?: boolean; errorMessage?: string; }&#62;`} />
<MemberInfo kind="parameter" type={`PropsWithChildren&#60;{ for?: string; label?: string; tooltip?: string; invalid?: boolean; errorMessage?: string; }&#62;`} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ interface AssetServerOptions {
presets?: ImageTransformPreset[];
namingStrategy?: AssetNamingStrategy;
previewStrategy?: AssetPreviewStrategy;
storageStrategyFactory?: (
options: AssetServerOptions,
storageStrategyFactory?: (
options: AssetServerOptions,
) => AssetStorageStrategy | Promise<AssetStorageStrategy>;
cacheHeader?: CacheConfig | string;
}
Expand All @@ -48,12 +48,12 @@ The local directory to which assets will be uploaded when using the <a href='/re

<MemberInfo kind="property" type={`string | ((ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, identifier: string) =&#62; string)`} />

The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/". A
function can also be provided to handle more complex cases, such as serving multiple domains
from a single server. In this case, the function should return a string url prefix.

If not provided, the plugin will attempt to guess based off the incoming
request and the configured route. However, in all but the simplest cases,
The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/". A
function can also be provided to handle more complex cases, such as serving multiple domains
from a single server. In this case, the function should return a string url prefix.

If not provided, the plugin will attempt to guess based off the incoming
request and the configured route. However, in all but the simplest cases,
this guess may not yield correct results.
### previewMaxWidth

Expand All @@ -79,19 +79,19 @@ Defines how asset files and preview images are named before being saved.

<MemberInfo kind="property" type={`<a href='/reference/typescript-api/assets/asset-preview-strategy#assetpreviewstrategy'>AssetPreviewStrategy</a>`} since="1.7.0" />

Defines how previews are generated for a given Asset binary. By default, this uses
Defines how previews are generated for a given Asset binary. By default, this uses
the <a href='/reference/core-plugins/asset-server-plugin/sharp-asset-preview-strategy#sharpassetpreviewstrategy'>SharpAssetPreviewStrategy</a>
### storageStrategyFactory

<MemberInfo kind="property" type={`( options: <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>, ) =&#62; <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a> | Promise&#60;<a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>&#62;`} default={`() =&#62; <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a>`} />
<MemberInfo kind="property" type={`( options: <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>, ) =&#62; <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a> | Promise&#60;<a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>&#62;`} default={`() =&#62; <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a>`} />

A function which can be used to configure an <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>. This is useful e.g. if you wish to store your assets
A function which can be used to configure an <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>. This is useful e.g. if you wish to store your assets
using a cloud storage provider. By default, the <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a> is used.
### cacheHeader

<MemberInfo kind="property" type={`<a href='/reference/core-plugins/asset-server-plugin/cache-config#cacheconfig'>CacheConfig</a> | string`} default={`'public, max-age=15552000'`} since="1.9.3" />

Configures the `Cache-Control` directive for response to control caching in browsers and shared caches (e.g. Proxies, CDNs).
Configures the `Cache-Control` directive for response to control caching in browsers and shared caches (e.g. Proxies, CDNs).
Defaults to publicly cached for 6 months.


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ Using type `any` in order to avoid the need to include `aws-sdk` dependency in g

<GenerationInfo sourceFile="packages/asset-server-plugin/src/s3-asset-storage-strategy.ts" sourceLine="119" packageName="@vendure/asset-server-plugin" />

Returns a configured instance of the <a href='/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy#s3assetstoragestrategy'>S3AssetStorageStrategy</a> which can then be passed to the <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>`storageStrategyFactory` property.
Returns a configured instance of the <a href='/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy#s3assetstoragestrategy'>S3AssetStorageStrategy</a> which can then be passed to the <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>
`storageStrategyFactory` property.

Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:

Expand Down
Loading

0 comments on commit 7706e35

Please sign in to comment.