From 33d8e28869faaef006fcb00e04dd4d4db6d95126 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Thu, 25 Jan 2024 14:20:39 +0100 Subject: [PATCH] docs: Add docs on custom fields on custom entities Relates to #1848 --- .../developer-guide/database-entity/index.md | 63 ++++++++++++ .../creating-detail-views/index.md | 95 +++++++++++++++++++ .../creating-list-views/index.md | 85 +++++++++++++++++ 3 files changed, 243 insertions(+) diff --git a/docs/docs/guides/developer-guide/database-entity/index.md b/docs/docs/guides/developer-guide/database-entity/index.md index 4d44b5b03c..52c9bbe77c 100644 --- a/docs/docs/guides/developer-guide/database-entity/index.md +++ b/docs/docs/guides/developer-guide/database-entity/index.md @@ -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) { + 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' }, + ], + }, +}; +``` \ No newline at end of file diff --git a/docs/docs/guides/extending-the-admin-ui/creating-detail-views/index.md b/docs/docs/guides/extending-the-admin-ui/creating-detail-views/index.md index 79c4c5b809..236e8a5f99 100644 --- a/docs/docs/guides/extending-the-admin-ui/creating-detail-views/index.md +++ b/docs/docs/guides/extending-the-admin-ui/creating-detail-views/index.md @@ -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 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['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" +
+ + + + + + + + + + + + + + +
+ + + + + + + + +
+
+ // highlight-start + + + + // highlight-end +
+
+
+``` \ No newline at end of file diff --git a/docs/docs/guides/extending-the-admin-ui/creating-list-views/index.md b/docs/docs/guides/extending-the-admin-ui/creating-list-views/index.md index d4138134a1..3c845254bd 100644 --- a/docs/docs/guides/extending-the-admin-ui/creating-list-views/index.md +++ b/docs/docs/guides/extending-the-admin-ui/creating-list-views/index.md @@ -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 { + + // 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" + + + // highlight-start + + // highlight-end + +``` \ No newline at end of file