feat(ux): implement sprint 11 user experience module
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, map, of } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { CategoriesWidgetComponent, FooterNavigationWidgetComponent, HeroWidgetComponent, ProductCarouselWidgetComponent } from '../ui';
|
||||
import { CategoriesWidgetComponent, FooterNavigationWidgetComponent, HeroWidgetComponent, ProductCarouselWidgetComponent, RecentlyViewedWidgetComponent } from '../ui';
|
||||
import { RegisteredWidget } from '../contracts/widget-component.contract';
|
||||
import { WidgetRegistryService } from './widget-registry.service';
|
||||
import { WidgetManifestService } from './widget-manifest.service';
|
||||
@@ -12,7 +12,8 @@ const APPROVED_WIDGET_COMPONENTS: Record<string, RegisteredWidget['component']>
|
||||
'footer': FooterNavigationWidgetComponent,
|
||||
'footer-navigation': FooterNavigationWidgetComponent,
|
||||
'product-carousel': ProductCarouselWidgetComponent,
|
||||
'product-collection': ProductCarouselWidgetComponent
|
||||
'product-collection': ProductCarouselWidgetComponent,
|
||||
'recently-viewed': RecentlyViewedWidgetComponent
|
||||
};
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
|
||||
@@ -42,6 +42,8 @@ export class DataSourceResolverService {
|
||||
case 'footer':
|
||||
case 'footer-navigation':
|
||||
return of(this.toFooterData(section, settings));
|
||||
case 'recently-viewed':
|
||||
return of({ section, settings });
|
||||
default:
|
||||
return of({ section, settings });
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { CategoriesWidgetData } from '../contracts/widget-data.contract';
|
||||
@if (widgetData.categories.length) {
|
||||
<app-catalog-category-grid
|
||||
[categories]="widgetData.categories"
|
||||
(categorySelected)="onCategorySelected($event)"
|
||||
(categorySelected)="handleCategorySelected($event)"
|
||||
/>
|
||||
} @else if (widgetData.emptyMessage) {
|
||||
<p class="categories-widget__empty">{{ widgetData.emptyMessage }}</p>
|
||||
@@ -37,9 +37,11 @@ import { CategoriesWidgetData } from '../contracts/widget-data.contract';
|
||||
export class CategoriesWidgetComponent {
|
||||
@Input() section: SectionConfig | null = null;
|
||||
@Input() data: CategoriesWidgetData | null = null;
|
||||
@Input() categorySelectedCallback: ((category: unknown) => void) | null = null;
|
||||
@Output() categorySelected = new EventEmitter<unknown>();
|
||||
|
||||
onCategorySelected(category: unknown): void {
|
||||
handleCategorySelected(category: unknown): void {
|
||||
this.categorySelectedCallback?.(category);
|
||||
this.categorySelected.emit(category);
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,5 @@ export * from './categories-widget.component';
|
||||
export * from './footer-navigation-widget.component';
|
||||
export * from './hero-widget.component';
|
||||
export * from './product-carousel-widget.component';
|
||||
export * from './recently-viewed-widget.component';
|
||||
export * from './unknown-widget.component';
|
||||
|
||||
36
src/app/widgets/ui/recently-viewed-widget.component.ts
Normal file
36
src/app/widgets/ui/recently-viewed-widget.component.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { SectionConfig } from '../../shared/models/config';
|
||||
import { RecentlyViewedStripComponent } from '../../features/website/user-experience/components/recently-viewed-strip/recently-viewed-strip.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-recently-viewed-widget',
|
||||
standalone: true,
|
||||
imports: [RecentlyViewedStripComponent],
|
||||
template: `
|
||||
<app-recently-viewed-strip
|
||||
[title]="title"
|
||||
[maxItems]="maxItems"
|
||||
[showClear]="showClear"
|
||||
/>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class RecentlyViewedWidgetComponent {
|
||||
@Input() section: SectionConfig | null = null;
|
||||
@Input() data: { settings?: Record<string, unknown> } | null = null;
|
||||
|
||||
get title(): string {
|
||||
const raw = this.data?.settings?.['title'];
|
||||
return typeof raw === 'string' && raw.trim().length > 0 ? raw : 'Recently Viewed';
|
||||
}
|
||||
|
||||
get maxItems(): number {
|
||||
const raw = this.data?.settings?.['maxItems'];
|
||||
const value = typeof raw === 'number' ? raw : Number(raw);
|
||||
return Number.isFinite(value) ? Math.max(1, value) : 8;
|
||||
}
|
||||
|
||||
get showClear(): boolean {
|
||||
return this.data?.settings?.['showClear'] === true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user