Skip to content

Commit

Permalink
docs: Add docs on custom fields on custom entities
Browse files Browse the repository at this point in the history
Relates to #1848
  • Loading branch information
michaelbromley committed Jan 25, 2024
1 parent 74aeb86 commit 33d8e28
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 0 deletions.
63 changes: 63 additions & 0 deletions docs/docs/guides/developer-guide/database-entity/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,66 @@ The full list of TypeORM decorators can be found in the [TypeORM decorator refer
## Corresponding GraphQL type

Once you have defined a new DB entity, it is likely that you want to expose it in your GraphQL API. Here's how to [define a new type in your GraphQL API](/guides/developer-guide/extend-graphql-api/#defining-a-new-type).

## Supporting custom fields

From Vendure v2.2, it is possible to add support for [custom fields](/guides/developer-guide/custom-fields/) to your custom entities. This
is useful when you are defining a custom entity as part of a plugin which is intended to be used by other developers. For example, a plugin
which defines a new entity for storing product reviews might want to allow the developer to add custom fields to the review entity.

First you need to update your entity class to implement the `HasCustomFields` interface, and provide an empty class
which will be used to store the custom field values:

```ts title="src/plugins/reviews/entities/product-review.entity.ts"
import {
DeepPartial,
HasCustomFields,
Product,
VendureEntity,
} from '@vendure/core';
import { Column, Entity, ManyToOne } from 'typeorm';

// highlight-next-line
export class CustomProductReviewFields {}

@Entity()
// highlight-next-line
export class ProductReview extends VendureEntity implements HasCustomFields {
constructor(input?: DeepPartial<ProductReview>) {
super(input);
}

// highlight-start
@Column(type => CustomProductReviewFields)
customFields: CustomProductReviewFields;
// highlight-end

@ManyToOne(type => Product)
product: Product;

@EntityId()
productId: ID;

@Column()
text: string;

@Column()
rating: number;
}
```

Now you'll be able to add custom fields to the `ProductReview` entity via the VendureConfig:

```ts title="src/vendure-config.ts"
import { VendureConfig } from '@vendure/core';

export const config: VendureConfig = {
// ...
customFields: {
ProductReview: [
{ name: 'reviewerName', type: 'string' },
{ name: 'reviewerLocation', type: 'string' },
],
},
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,98 @@ export default [
// highlight-end
]
```

## Supporting custom fields

From Vendure v2.2, it is possible for your [custom entities to support custom fields](/guides/developer-guide/database-entity/#supporting-custom-fields).

If you have set up your entity to support custom fields, and you want custom fields to be available in the Admin UI detail view,
you need to add the following to your detail component:

```ts title="src/plugins/reviews/ui/components/review-detail/review-detail.component.ts"
// highlight-next-line
import { getCustomFieldsDefaults } from '@vendure/admin-ui/core';

@Component({
selector: 'review-detail',
templateUrl: './review-detail.component.html',
styleUrls: ['./review-detail.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [SharedModule],
})
export class ReviewDetailComponent extends TypedBaseDetailComponent<typeof getReviewDetailDocument, 'review'> implements OnInit, OnDestroy {

// highlight-next-line
customFields = this.getCustomFieldConfig('ProductReview');

detailForm = this.formBuilder.group({
title: [''],
rating: [1],
authorName: [''],
// highlight-next-line
customFields: this.formBuilder.group(getCustomFieldsDefaults(this.customFields)),
});

protected setFormValues(entity: NonNullable<ResultOf<typeof getReviewDetailDocument>['review']>, languageCode: LanguageCode): void {
this.detailForm.patchValue({
title: entity.name,
rating: entity.rating,
authorName: entity.authorName,
productId: entity.productId,
});
// highlight-start
if (this.customFields.length) {
this.setCustomFieldFormValues(this.customFields, this.detailForm.get('customFields'), entity);
}
// highlight-end
}
}
```

Then add a card for your custom fields to the template:

```html title="src/plugins/reviews/ui/components/review-detail/review-detail.component.html"
<form class="form" [formGroup]="detailForm">
<vdr-page-detail-layout>
<!-- The sidebar is used for displaying "metadata" type information about the entity -->
<vdr-page-detail-sidebar>
<vdr-card *ngIf="entity$ | async as entity">
<vdr-page-entity-info [entity]="entity" />
</vdr-card>
</vdr-page-detail-sidebar>

<!-- The main content area is used for displaying the entity's fields -->
<vdr-page-block>
<!-- The vdr-card is the container for grouping items together on a page -->
<!-- it can also take an optional [title] property to display a title -->
<vdr-card>
<!-- the form-grid class is used to lay out the form fields -->
<div class="form-grid">
<vdr-form-field label="Title" for="title">
<input id="title" type="text" formControlName="title" />
</vdr-form-field>
<vdr-form-field label="Rating" for="rating">
<input id="rating" type="number" min="1" max="5" formControlName="rating" />
</vdr-form-field>

<!-- etc -->
</div>
</vdr-card>
// highlight-start
<vdr-card
formGroupName="customFields"
*ngIf="customFields.length"
[title]="'common.custom-fields' | translate"
>
<vdr-tabbed-custom-fields
entityName="ProductReview"
[customFields]="customFields"
[customFieldsFormGroup]="detailForm.get('customFields')"
></vdr-tabbed-custom-fields>
</vdr-card>
// highlight-end
</vdr-page-block>
</vdr-page-detail-layout>
</form>
```
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,88 @@ export default [
// highlight-end
]
```

## Supporting custom fields

From Vendure v2.2, it is possible for your [custom entities to support custom fields](/guides/developer-guide/database-entity/#supporting-custom-fields).

If you have set up your entity to support custom fields, and you want custom fields to be available in the Admin UI list view,
you need to add the following to your list component:

```ts title="src/plugins/reviews/ui/components/review-list/review-list.component.ts"
@Component({
selector: 'review-list',
templateUrl: './review-list.component.html',
styleUrls: ['./review-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [SharedModule],
})
export class ReviewListComponent extends TypedBaseListComponent<typeof getReviewListDocument, 'reviews'> {

// highlight-next-line
customFields = this.getCustomFieldConfig('ProductReview');

readonly filters = this.createFilterCollection()
.addIdFilter()
.addDateFilters()
.addFilter({
name: 'title',
type: {kind: 'text'},
label: 'Title',
filterField: 'title',
})
.addFilter({
name: 'rating',
type: {kind: 'number'},
label: 'Rating',
filterField: 'rating',
})
.addFilter({
name: 'authorName',
type: {kind: 'text'},
label: 'Author',
filterField: 'authorName',
})
// highlight-next-line
.addCustomFieldFilters(this.customFields)
.connectToRoute(this.route);

readonly sorts = this.createSortCollection()
.defaultSort('createdAt', 'DESC')
.addSort({name: 'createdAt'})
.addSort({name: 'updatedAt'})
.addSort({name: 'title'})
.addSort({name: 'rating'})
.addSort({name: 'authorName'})
// highlight-next-line
.addCustomFieldSorts(this.customFields)
.connectToRoute(this.route);

// rest of class omitted for brevity
}
```

and then add the `vdr-dt2-custom-field-column` component to your data table:

```html title="src/plugins/reviews/ui/components/review-list/review-list.component.html"
<vdr-data-table-2
id="review-list"
[items]="items$ | async"
[itemsPerPage]="itemsPerPage$ | async"
[totalItems]="totalItems$ | async"
[currentPage]="currentPage$ | async"
[filters]="filters"
(pageChange)="setPageNumber($event)"
(itemsPerPageChange)="setItemsPerPage($event)"
>
<!-- rest of data table omitted for brevity -->
// highlight-start
<vdr-dt2-custom-field-column
*ngFor="let customField of customFields"
[customField]="customField"
[sorts]="sorts"
/>
// highlight-end
</vdr-data-table-2>
```

0 comments on commit 33d8e28

Please sign in to comment.