Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 20x 20x 20x 20x 20x | import { Directive, Input, OnInit, Optional, Output, SkipSelf } from '@angular/core'; import { ReplaySubject, combineLatest, debounceTime, distinctUntilChanged, pairwise, startWith } from 'rxjs'; import { ProductContext, ProductContextDisplayProperties, ProductContextFacade, } from 'ish-core/facades/product-context.facade'; import { ProductCompletenessLevel, SkuQuantityType } from 'ish-core/models/product/product.model'; declare type IdType = number | string; @Directive({ selector: '[ishProductContext]', providers: [ProductContextFacade], exportAs: 'ishProductContext', }) export class ProductContextDirective implements OnInit { @Input() completeness: 'List' | 'Detail' = 'List'; @Output() skuChange = this.context.select('sku'); @Output() quantityChange = this.context.select('quantity'); private propIndex$ = new ReplaySubject<IdType>(1); constructor(@SkipSelf() @Optional() parentContext: ProductContextFacade, private context: ProductContextFacade) { Iif (parentContext) { function removeFromParent(parent: ProductContext['children'], id: IdType) { delete parent[id]; } function addToParent(parent: ProductContext['children'], id: IdType, context: ProductContext) { parent[id] = context; } function isId(id: IdType): boolean { return id !== undefined; } parentContext.connect( 'children', combineLatest([ this.propIndex$.pipe(startWith(undefined), distinctUntilChanged(), pairwise()), this.context.select().pipe(debounceTime(0)), ]), (parent, [[prevId, currId], context]) => { let newChildren: ProductContext['children']; // remove previous entry if ID changed Iif (context.propagateActive && isId(prevId) && prevId !== currId) { newChildren = { ...parent.children }; removeFromParent(newChildren, prevId); } // propagate current entry Iif (isId(currId)) { newChildren ??= { ...parent.children }; if (context.propagateActive) { addToParent(newChildren, currId, context); } else { removeFromParent(newChildren, currId); } } return newChildren ?? parent.children; } ); } } @Input() set log(log: boolean) { this.context.log(log); } @Input() set sku(sku: string) { this.context.set('sku', () => sku); } @Input() set categoryId(categoryId: string) { this.context.set('categoryId', () => categoryId); } @Input() set quantity(quantity: number) { this.context.set('quantity', () => quantity); } @Input() set allowZeroQuantity(allowZeroQuantity: boolean) { this.context.set('allowZeroQuantity', () => allowZeroQuantity); } @Input() set propagateActive(propagateActive: boolean) { this.context.set('propagateActive', () => propagateActive); } @Input() set propagateIndex(index: number | string) { this.propIndex$.next(index); } @Input() set parts(parts: SkuQuantityType[]) { this.context.set('parts', () => parts); } @Input() set configuration(config: Partial<ProductContextDisplayProperties>) { this.context.config = config; } ngOnInit() { this.context.set('requiredCompletenessLevel', () => this.completeness === 'List' ? ProductCompletenessLevel.List : ProductCompletenessLevel.Detail ); } } |