@@ -9,8 +9,10 @@ import {
99 Output ,
1010 QueryList
1111} from '@angular/core' ;
12+ import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
1213import { IconType } from '@hypertrace/assets-library' ;
13- import { queryListAndChanges$ } from '@hypertrace/common' ;
14+ import { queryListAndChanges$ , SubscriptionLifecycle } from '@hypertrace/common' ;
15+ import { isEqual } from 'lodash-es' ;
1416import { BehaviorSubject , combineLatest , EMPTY , Observable , of , Subject } from 'rxjs' ;
1517import { map } from 'rxjs/operators' ;
1618import { ButtonRole , ButtonStyle } from '../button/button' ;
@@ -19,11 +21,18 @@ import { SearchBoxDisplayMode } from '../search-box/search-box.component';
1921import { SelectOptionComponent } from '../select/select-option.component' ;
2022import { SelectSize } from '../select/select-size' ;
2123import { MultiSelectJustify } from './multi-select-justify' ;
22-
2324@Component ( {
2425 selector : 'ht-multi-select' ,
2526 styleUrls : [ './multi-select.component.scss' ] ,
2627 changeDetection : ChangeDetectionStrategy . OnPush ,
28+ providers : [
29+ SubscriptionLifecycle ,
30+ {
31+ provide : NG_VALUE_ACCESSOR ,
32+ useExisting : MultiSelectComponent ,
33+ multi : true
34+ }
35+ ] ,
2736 template : `
2837 <div
2938 class="multi-select"
@@ -120,7 +129,7 @@ import { MultiSelectJustify } from './multi-select-justify';
120129 </div>
121130 `
122131} )
123- export class MultiSelectComponent < V > implements AfterContentInit , OnChanges {
132+ export class MultiSelectComponent < V > implements ControlValueAccessor , AfterContentInit , OnChanges {
124133 @Input ( )
125134 public size : SelectSize = SelectSize . Medium ;
126135
@@ -167,6 +176,9 @@ export class MultiSelectComponent<V> implements AfterContentInit, OnChanges {
167176 public popoverOpen : boolean = false ;
168177 public triggerValues$ : Observable < TriggerValues > = new Observable ( ) ;
169178
179+ private propagateControlValueChange ?: ( value : V [ ] | undefined ) => void ;
180+ private propagateControlValueChangeOnTouch ?: ( value : V [ ] | undefined ) => void ;
181+
170182 public ngAfterContentInit ( ) : void {
171183 this . allOptions$ = this . allOptionsList !== undefined ? queryListAndChanges$ ( this . allOptionsList ) : EMPTY ;
172184 this . filteredOptions$ = combineLatest ( [ this . allOptions$ , this . searchSubject ] ) . pipe (
@@ -215,24 +227,37 @@ export class MultiSelectComponent<V> implements AfterContentInit, OnChanges {
215227 }
216228
217229 const selected = this . isSelectedItem ( item )
218- ? this . selected ?. filter ( value => value !== item . value )
230+ ? this . selected ?. filter ( value => ! isEqual ( value , item . value ) )
219231 : ( this . selected ?? [ ] ) . concat ( item . value ) ;
220232
221233 this . setSelection ( selected ?? [ ] ) ;
222234 }
223235
224236 public isSelectedItem ( item : SelectOptionComponent < V > ) : boolean {
225- return this . selected !== undefined && this . selected . filter ( value => value === item . value ) . length > 0 ;
237+ return this . selected !== undefined && this . selected . filter ( value => isEqual ( value , item . value ) ) . length > 0 ;
226238 }
227239
228240 public preventClickDefault ( event : Event ) : void {
229241 event . preventDefault ( ) ;
230242 }
231243
244+ public writeValue ( value ?: V [ ] ) : void {
245+ this . setSelection ( value ?? [ ] ) ;
246+ }
247+
248+ public registerOnChange ( onChange : ( value : V [ ] | undefined ) => void ) : void {
249+ this . propagateControlValueChange = onChange ;
250+ }
251+
252+ public registerOnTouched ( onTouch : ( value : V [ ] | undefined ) => void ) : void {
253+ this . propagateControlValueChangeOnTouch = onTouch ;
254+ }
255+
232256 private setSelection ( selected : V [ ] ) : void {
233257 this . selected = selected ;
234258 this . setTriggerLabel ( ) ;
235259 this . selectedChange . emit ( this . selected ) ;
260+ this . propagateValueChangeToFormControl ( this . selected ) ;
236261 }
237262
238263 private setTriggerLabel ( ) : void {
@@ -256,6 +281,11 @@ export class MultiSelectComponent<V> implements AfterContentInit, OnChanges {
256281 } )
257282 ) ;
258283 }
284+
285+ private propagateValueChangeToFormControl ( value : V [ ] | undefined ) : void {
286+ this . propagateControlValueChange ?.( value ) ;
287+ this . propagateControlValueChangeOnTouch ?.( value ) ;
288+ }
259289}
260290
261291interface TriggerValues {
0 commit comments