## Widgets ### Old (Angular) ```ts title="src/plugins/reviews/ui/components/reviews-widget/reviews-widget.component.ts" import { Component, OnInit } from '@angular/core'; import { DataService, SharedModule } from '@vendure/admin-ui/core'; import { Observable } from 'rxjs'; @Component({ selector: 'reviews-widget', template: ` `, standalone: true, imports: [SharedModule], }) export class ReviewsWidgetComponent implements OnInit { pendingReviews$: Observable; constructor(private dataService: DataService) {} ngOnInit() { this.pendingReviews$ = this.dataService.query(gql` query GetAllReviews($options: ProductReviewListOptions) { productReviews(options: $options) { items { id createdAt authorName summary rating } } }`, { options: { filter: { state: { eq: 'new' } }, take: 10, }, }) .mapStream(data => data.productReviews.items); } } ``` ```ts title="src/plugins/reviews/ui/providers.ts" import { registerDashboardWidget } from '@vendure/admin-ui/core'; export default [ registerDashboardWidget('reviews', { title: 'Latest reviews', supportedWidths: [4, 6, 8, 12], requiresPermissions: ['ReadReview'], loadComponent: () => import('./reviews-widget/reviews-widget.component').then( m => m.ReviewsWidgetComponent, ), }), ]; ``` ### New (React Dashboard) ```tsx title="custom-widget.tsx" import { Badge, DashboardBaseWidget, useLocalFormat, useWidgetFilters } from '@vendure/dashboard'; export function CustomWidget() { const { dateRange } = useWidgetFilters(); const { formatDate } = useLocalFormat(); return (
Displaying results from {formatDate(dateRange.from)} to {formatDate(dateRange.to)}
); } ``` ```tsx title="index.tsx" import { defineDashboardExtension } from '@vendure/dashboard'; import { CustomWidget } from './custom-widget'; defineDashboardExtension({ widgets: [ { id: 'custom-widget', name: 'Custom Widget', component: CustomWidget, defaultSize: { w: 3, h: 3 }, }, ], }); ```