src/app/modules/content-search/components/data-driven-filter/data-driven-filter.component.ts
OnInit
OnChanges
OnDestroy
selector | app-data-driven-filter |
styleUrls | ./data-driven-filter.component.scss |
templateUrl | ./data-driven-filter.component.html |
Properties |
|
Methods |
|
Inputs |
Outputs |
constructor(configService: ConfigService, resourceService: ResourceService, router: Router, activatedRoute: ActivatedRoute, cacheService: CacheService, cdr: ChangeDetectorRef, frameworkService: FrameworkService, formService: FormService, userService: UserService, permissionService: PermissionService, utilService: UtilService, browserCacheTtlService: BrowserCacheTtlService, orgDetailsService: OrgDetailsService, layoutService: LayoutService)
|
|||||||||||||||||||||||||||||||||||||||||||||
Parameters :
|
accordionDefaultOpen | |
Type : boolean
|
|
enrichFilters | |
Type : object
|
|
filterEnv | |
Type : string
|
|
formAction | |
Type : string
|
|
frameworkName | |
Type : string
|
|
hashTagId | |
Type : string
|
|
ignoreQuery | |
Type : {}
|
|
Default value : []
|
|
isOpen | |
Type : any
|
|
isShowFilterLabel | |
Type : boolean
|
|
layoutConfiguration | |
Type : any
|
|
pageId | |
Type : string
|
|
showSearchedParam | |
Type : boolean
|
|
Default value : true
|
|
viewAllMode | |
Type : boolean
|
|
Default value : false
|
|
dataDrivenFilter | |
Type : EventEmitter
|
|
Public applyFilters |
applyFilters()
|
Returns :
void
|
Private enrichFiltersOnInputChange |
enrichFiltersOnInputChange()
|
Returns :
void
|
Private fetchFrameWorkDetails |
fetchFrameWorkDetails()
|
Returns :
any
|
getFormatedFilterDetails |
getFormatedFilterDetails()
|
Returns :
any
|
Private getFormDetails |
getFormDetails()
|
Returns :
any
|
getOrgSearch |
getOrgSearch()
|
Returns :
any
|
Public handleTopicChange | ||||
handleTopicChange(topicsSelected)
|
||||
Parameters :
Returns :
void
|
Private hardRefreshFilter |
hardRefreshFilter()
|
Returns :
void
|
Private modelChange | ||||
modelChange(data)
|
||||
Parameters :
Returns :
void
|
ngOnChanges |
ngOnChanges()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
Public removeFilterSelection | ||||||
removeFilterSelection(field, item)
|
||||||
Parameters :
Returns :
void
|
Public resetFilters |
resetFilters()
|
Returns :
void
|
Private setFilterInteractData |
setFilterInteractData()
|
Returns :
void
|
Private subscribeToQueryParams |
subscribeToQueryParams()
|
Returns :
void
|
Public applyFilterInteractEdata |
Type : IInteractEventEdata
|
Public categoryMasterList |
Type : Array<any>
|
Public channelInputLabel |
Type : any
|
Public configService |
Type : ConfigService
|
Public filterInteractEdata |
Type : IInteractEventEdata
|
Public filtersDetails |
Type : Array<any>
|
Public formFieldProperties |
Type : Array<any>
|
Public formInputData |
Type : any
|
Public formService |
Type : FormService
|
Public framework |
Type : string
|
Public frameworkService |
Type : FrameworkService
|
Public isShowFilterPlaceholder |
Default value : true
|
Public layoutService |
Type : LayoutService
|
Public permissionService |
Type : PermissionService
|
Public refresh |
Default value : true
|
Public resetFilterInteractEdata |
Type : IInteractEventEdata
|
resourceDataSubscription |
Type : Subscription
|
Public resourceService |
Type : ResourceService
|
Public router |
Type : Router
|
Private selectedLanguage |
Type : string
|
Public showFilters |
Default value : false
|
telemetryCdata |
Type : Array<literal type>
|
Public unsubscribe |
Default value : new Subject<void>()
|
Public userService |
Type : UserService
|
import { of, throwError, Subscription, Subject } from 'rxjs';
import { first, mergeMap, map, catchError, filter } from 'rxjs/operators';
import {
ConfigService, ResourceService, Framework, BrowserCacheTtlService, UtilService, LayoutService} from '@sunbird/shared';
import { Component, OnInit, Input, Output, EventEmitter, ChangeDetectorRef, OnChanges, OnDestroy, ViewRef } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FrameworkService, FormService, PermissionService, UserService, OrgDetailsService } from '@sunbird/core';
import * as _ from 'lodash-es';
import { CacheService } from '../../../shared/services/cache-service/cache.service';
import { IInteractEventEdata } from '@sunbird/telemetry';
@Component({
selector: 'app-data-driven-filter',
templateUrl: './data-driven-filter.component.html',
styleUrls: ['./data-driven-filter.component.scss']
})
export class DataDrivenFilterComponent implements OnInit, OnChanges, OnDestroy {
@Input() filterEnv: string;
@Input() accordionDefaultOpen: boolean;
@Input() isShowFilterLabel: boolean;
@Input() hashTagId: string;
@Input() ignoreQuery = [];
@Input() showSearchedParam = true;
@Input() enrichFilters: object;
@Input() viewAllMode = false;
@Input() pageId: string;
@Input() frameworkName: string;
@Input() formAction: string;
@Output() dataDrivenFilter = new EventEmitter();
@Input() layoutConfiguration;
@Input() isOpen;
public showFilters = false;
public formFieldProperties: Array<any>;
public filtersDetails: Array<any>;
public categoryMasterList: Array<any>;
public framework: string;
public channelInputLabel: any;
public formInputData: any;
public unsubscribe = new Subject<void>();
public refresh = true;
public isShowFilterPlaceholder = true;
public filterInteractEdata: IInteractEventEdata;
public applyFilterInteractEdata: IInteractEventEdata;
public resetFilterInteractEdata: IInteractEventEdata;
telemetryCdata: Array<{}>;
private selectedLanguage: string;
resourceDataSubscription: Subscription;
// add langauge default value en
constructor(public configService: ConfigService, public resourceService: ResourceService, public router: Router,
private activatedRoute: ActivatedRoute, private cacheService: CacheService, private cdr: ChangeDetectorRef,
public frameworkService: FrameworkService, public formService: FormService,
public userService: UserService, public permissionService: PermissionService, private utilService: UtilService,
private browserCacheTtlService: BrowserCacheTtlService, private orgDetailsService: OrgDetailsService,
public layoutService: LayoutService) {
this.router.onSameUrlNavigation = 'reload';
}
ngOnInit() {
// screen size
if (window.innerWidth <= 992 ) {
this.isOpen = false;
}
this.resourceDataSubscription = this.resourceService.languageSelected$
.subscribe(item => {
this.selectedLanguage = item.value;
if (this.formFieldProperties && this.formFieldProperties.length > 0) {
_.forEach(this.formFieldProperties, (data, index) => {
this.formFieldProperties[index] = this.utilService.translateLabel(data, this.selectedLanguage);
this.formFieldProperties[index].range = this.utilService.translateValues(data.range, this.selectedLanguage);
});
this.filtersDetails = _.cloneDeep(this.formFieldProperties);
this.formInputData = this.utilService.convertSelectedOption(this.formInputData,
this.formFieldProperties, 'en', this.selectedLanguage);
}
}
);
this.frameworkService.initialize(this.frameworkName, this.hashTagId);
this.getFormatedFilterDetails().subscribe((formFieldProperties) => {
this.formFieldProperties = formFieldProperties;
this.filtersDetails = _.cloneDeep(formFieldProperties);
this.dataDrivenFilter.emit(formFieldProperties);
this.subscribeToQueryParams();
}, (err) => {
this.dataDrivenFilter.emit([]);
});
this.setFilterInteractData();
}
getFormatedFilterDetails() {
const formAction = this.formAction ? this.formAction : 'search';
return this.fetchFrameWorkDetails().pipe(
mergeMap((frameworkDetails: any) => {
this.categoryMasterList = frameworkDetails.categoryMasterList;
this.framework = frameworkDetails.code;
return this.getFormDetails();
}),
mergeMap((formData: any) => {
if (_.find(formData, { code: 'channel' })) {
return this.getOrgSearch().pipe(map((channelData: any) => {
const data = _.filter(channelData, 'hashTagId');
return { formData: formData, channelData: data };
}));
} else {
return of({ formData: formData });
}
}),
map((formData: any) => {
let formFieldProperties = _.filter(formData.formData, (formFieldCategory) => {
if (!_.isEmpty(formFieldCategory.allowedRoles)
&& !this.permissionService.checkRolesPermissions(formFieldCategory.allowedRoles)) {
return false;
}
if (formFieldCategory.code === 'channel') {
formFieldCategory.range = _.map(formData.channelData, (value) => {
return {
category: 'channel',
identifier: value.hashTagId,
name: value.orgName,
};
});
} else {
const loggedInUserRoles = _.get(this.userService, 'userProfile.userRoles');
const frameworkTerms = _.get(_.find(this.categoryMasterList, { code: formFieldCategory.code }), 'terms');
formFieldCategory.range = _.union(formFieldCategory.range, frameworkTerms);
if (this.filterEnv === 'upforreview' && formFieldCategory.code === 'contentType' &&
(_.includes(loggedInUserRoles, 'CONTENT_REVIEWER') && _.includes(loggedInUserRoles, 'BOOK_REVIEWER') &&
!_.find(formFieldCategory.range, { name: 'TextBook' }))) {
formFieldCategory.range.push({ name: 'TextBook' });
}
}
if (this.selectedLanguage !== 'en') {
formFieldCategory = this.utilService.translateLabel(formFieldCategory, this.selectedLanguage);
formFieldCategory.range = this.utilService.translateValues(formFieldCategory.range, this.selectedLanguage);
}
return true;
});
formFieldProperties = _.sortBy(_.uniqBy(formFieldProperties, 'code'), 'index');
return formFieldProperties;
}));
}
private fetchFrameWorkDetails() {
return this.frameworkService.frameworkData$.pipe(filter((frameworkDetails) => { // wait to get the framework name if passed as input
if (!frameworkDetails.err) {
const framework = this.frameworkName ? this.frameworkName : 'defaultFramework';
const frameworkData = _.get(frameworkDetails.frameworkdata, framework);
if (frameworkData) {
return true;
} else {
return false;
}
}
return true;
}), first(),
mergeMap((frameworkDetails: Framework) => {
if (!frameworkDetails.err) {
const framework = this.frameworkName ? this.frameworkName : 'defaultFramework';
const frameworkData = _.get(frameworkDetails.frameworkdata, framework);
if (frameworkData) {
return of({ categoryMasterList: frameworkData.categories, framework: frameworkData.code });
} else {
return throwError('no result for ' + this.frameworkName); // framework error need to handle this
}
} else {
return throwError(frameworkDetails.err); // framework error
}
}));
}
private subscribeToQueryParams() {
this.activatedRoute.queryParams.subscribe((params) => {
this.formInputData = {};
_.forIn(params, (value, key) => this.formInputData[key] = typeof value === 'string' && key !== 'key' ? [value] : value);
this.formInputData = this.utilService.convertSelectedOption(this.formInputData,
this.formFieldProperties, 'en', this.selectedLanguage);
if (params.channel) {
this.modelChange(this.formInputData.channel);
this.channelInputLabel = this.orgDetailsService.getOrg();
}
this.showFilters = true;
this.hardRefreshFilter();
});
}
private getFormDetails() {
const formServiceInputParams = {
formType: 'content',
formAction: this.formAction ? this.formAction : 'search',
contentType: this.filterEnv,
framework: this.framework
};
return this.formService.getFormConfig(formServiceInputParams, this.hashTagId);
}
public resetFilters() {
this.formInputData = _.pick(this.formInputData, this.ignoreQuery);
if (this.viewAllMode) {
const data = this.cacheService.get('viewAllQuery');
_.forIn(data, (value, key) => this.formInputData[key] = value);
}
let redirectUrl; // if pageNumber exist then go to first page every time when filter changes, else go exact path
if (this.activatedRoute.snapshot.params.pageNumber) { // when using dataDriven filter should this should be verified
redirectUrl = this.router.url.split('?')[0].replace(/[^\/]+$/, '1');
} else {
redirectUrl = this.router.url.split('?')[0];
}
redirectUrl = decodeURI(redirectUrl);
this.router.navigate([redirectUrl], { relativeTo: this.activatedRoute.parent, queryParams: this.formInputData });
this.hardRefreshFilter();
this.setFilterInteractData();
}
public applyFilters() {
this.formInputData = this.utilService.convertSelectedOption(this.formInputData, this.formFieldProperties, this.selectedLanguage, 'en');
const queryParams: any = {};
_.forIn(this.formInputData, (eachInputs: Array<any | object>, key) => {
const formatedValue = typeof eachInputs === 'string' ? eachInputs :
_.compact(_.map(eachInputs, value => typeof value === 'string' ? value : _.get(value, 'identifier')));
if (formatedValue.length) {
queryParams[key] = formatedValue;
}
});
let redirectUrl; // if pageNumber exist then go to first page every time when filter changes, else go exact path
if (this.activatedRoute.snapshot.params.pageNumber) { // when using dataDriven filter should this should be verified
redirectUrl = this.router.url.split('?')[0].replace(/[^\/]+$/, '1');
} else {
redirectUrl = this.router.url.split('?')[0];
}
redirectUrl = decodeURI(redirectUrl);
if (!_.isEmpty(queryParams)) {
queryParams['appliedFilters'] = true;
this.router.navigate([redirectUrl], { queryParams: queryParams });
}
this.setFilterInteractData();
}
public removeFilterSelection(field, item) {
const itemIndex = this.formInputData[field].indexOf(item);
if (itemIndex !== -1) {
this.formInputData[field].splice(itemIndex, 1);
if (field === 'channel') {
this.channelInputLabel.splice(itemIndex, 1);
}
this.formInputData = _.pickBy(this.formInputData);
this.hardRefreshFilter();
}
}
ngOnChanges() {
if (this.formFieldProperties && this.enrichFilters) {
this.enrichFiltersOnInputChange();
}
}
private enrichFiltersOnInputChange() {
if (this.activatedRoute.snapshot.queryParams.appliedFilters === 'false') {
this.filtersDetails = this.formFieldProperties; // show all filters as implicit filters are applied
return;
}
this.filtersDetails = _.map(this.formFieldProperties, (eachFields) => {
const enrichField = _.cloneDeep(eachFields);
if (!_.includes(['channel', 'contentType', 'topic'], enrichField.code)) {
enrichField.range = _.filter(this.enrichFilters[enrichField.code],
(field) => {
return _.find(eachFields.range, { name: _.get(field, 'name')});
});
}
return enrichField;
});
this.hardRefreshFilter();
}
public handleTopicChange(topicsSelected) {
this.formInputData['topic'] = [];
_.forEach(topicsSelected, (value, index) => {
this.formInputData['topic'].push(value.name);
});
this.cdr.detectChanges();
}
private modelChange(data) {
this.channelInputLabel = [];
const orgDetails = _.find(this.formFieldProperties, ['code', 'channel']);
if (orgDetails) {
_.forEach(data, (value, key) => {
this.channelInputLabel.push(_.find(orgDetails['range'], { identifier: value }));
this.orgDetailsService.setOrg(this.channelInputLabel);
});
}
}
private setFilterInteractData() {
setTimeout(() => { // wait for model to change
const filters = _.pickBy(this.formInputData, (val, key) =>
(!_.isEmpty(val) || typeof val === 'number')
&& _.map(this.formFieldProperties, field => field.code).includes(key));
this.applyFilterInteractEdata = {
id: 'apply-filter',
type: 'click',
pageid: _.get(this.activatedRoute, 'snapshot.data.telemetry.pageid'),
extra: {filters: filters}
};
this.resetFilterInteractEdata = {
id: 'reset-filter',
type: 'click',
pageid: _.get(this.activatedRoute, 'snapshot.data.telemetry.pageid'),
extra: {filters: filters}
};
this.filterInteractEdata = {
id: 'filter-accordion',
type: 'click',
pageid: _.get(this.activatedRoute, 'snapshot.data.telemetry.pageid')
};
}, 5);
const pageSection = this.cacheService.get('pageSection');
if (_.get(pageSection, 'id' )) {
this.telemetryCdata = [{ 'type': 'page-section', 'id': pageSection.id }];
}
}
private hardRefreshFilter() {
this.refresh = false;
if (!(this.cdr as ViewRef).destroyed ) {
this.cdr.detectChanges();
}
this.refresh = true;
}
getOrgSearch() {
return this.orgDetailsService.searchOrg().pipe(map(data => (data.content)),
catchError(err => {
return [];
}));
}
ngOnDestroy() {
if (this.resourceDataSubscription) {
this.resourceDataSubscription.unsubscribe();
}
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
<ng-container *ngIf="!layoutConfiguration">
<div class="sb-prominent-filter pb-8 px-16" *ngIf="showFilters">
<div class="ui container">
<!--Selected Filters list-->
<div class="mb-16" *ngIf="filtersDetails && formInputData && showSearchedParam">
<ng-container *ngFor="let field of filtersDetails">
<div class="d-inline-block" *ngIf='formInputData[field.code] && formInputData[field.code].length > 0'>
<label>{{field.label}} : </label>
<ng-container *ngFor="let item of formInputData[field.code]">
<a class="ui label mt-8 mr-8" *ngIf='!item?.name && field.code !== "channel"'>
{{item}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item)" tabindex="0"></i>
</a>
<a class="ui label mt-8 mr-8" *ngIf='item?.name && field.code !== "channel"'>
{{item.name}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item)" tabindex="0"></i>
</a>
</ng-container>
<ng-container *ngFor="let item of channelInputLabel">
<a class="ui label mt-8 mr-8" *ngIf='item?.name && field.code === "channel"'>
{{item.name}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item.identifier)" tabindex="0"></i>
</a>
</ng-container>
</div>
</ng-container>
</div>
<!--/Selected Filters list-->
<!--Filters-->
<div class="sb-prominent-filter-container" *ngIf="refresh && filtersDetails">
<div class="sb-prominent-filter-field" *ngFor="let field of filtersDetails">
<div *ngIf="(field.inputType==='select' || field.inputType === 'multi-select') && field.code !== 'channel'">
<sui-multi-select (ngModelChange)="setFilterInteractData()" id={{field.code}} name={{field.code}}
defaultSelectionText={{field.label}} zeroSelectionText={{resourceService.frmelmnts.lbl.Select}}
class="ui selection dropdown multiple" [(ngModel)]="formInputData[field.code]" [options]="options"
[hasLabels]="false" #multiSelect *ngIf="field.code !== 'gradeLevel'">
<sui-select-option *ngFor="let option of field.range | sortBy:'name':'asc'" [value]="option.name">
</sui-select-option>
</sui-multi-select>
<sui-multi-select (ngModelChange)="setFilterInteractData()" id={{field.code}} name={{field.code}}
defaultSelectionText={{field.label}} zeroSelectionText={{resourceService.frmelmnts.lbl.Select}}
class="ui selection dropdown multiple" [(ngModel)]="formInputData[field.code]" [options]="options"
[hasLabels]="false" #multiSelect *ngIf="field.code === 'gradeLevel'">
<sui-select-option *ngFor="let option of field.range" [value]="option.name"></sui-select-option>
</sui-multi-select>
</div>
<div *ngIf="field.code === 'channel'">
<sui-multi-select (ngModelChange)="modelChange($event);setFilterInteractData()" id={{field.code}}
name={{field.code}} defaultSelectionText={{field.name}}
zeroSelectionText={{resourceService.frmelmnts.lbl.Select}} class="ui selection dropdown multiple"
[(ngModel)]="formInputData[field.code]" [options]="options" [hasLabels]="false" labelField="name"
valueField="identifier" #multiSelect>
<sui-select-option *ngFor="let option of field.range | sortBy:'name':'asc'" [value]="option">
</sui-select-option>
</sui-multi-select>
</div>
<div *ngIf="field.code==='topic'">
<app-topic-picker [selectedTopics]="formInputData[field.code]" [formTopic]="field"
(topicChange)="handleTopicChange($event);setFilterInteractData()"></app-topic-picker>
</div>
</div>
<div class="sb-prominent-filter-field">
<button class="sb-btn sb-btn-normal sb-btn-outline-primary" (click)="resetFilters()" tabindex="0"
appTelemetryInteract [telemetryInteractEdata]="resetFilterInteractEdata">
{{resourceService.frmelmnts?.btn?.reset}}
</button>
<button class="sb-btn sb-btn-normal sb-btn-primary ml-8" (click)="applyFilters()" tabindex="0"
appTelemetryInteract [telemetryInteractEdata]="applyFilterInteractEdata">
{{resourceService.frmelmnts?.btn?.apply}}
</button>
</div>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="layoutConfiguration">
<div class="sbt-filter">
<div class="sbt-filter-overlay"></div>
<div class="sbt-filter-switcher-container cursor-pointer mobile only" appTelemetryInteract
[telemetryInteractEdata]="filterInteractEdata" [telemetryInteractCdata]="telemetryCdata"
(click)="isOpen = !isOpen" tabindex="0">
<div class="sbt-filter-switcher"><i class="sliders horizontal icon"></i></div>
<div class="sbt-filter-text">{{resourceService.frmelmnts?.lbl?.filters}}</div>
</div>
<div class="sbt-filter-switcher-container cursor-pointer computer only" appTelemetryInteract
[telemetryInteractEdata]="filterInteractEdata" [telemetryInteractCdata]="telemetryCdata">
<div class="sbt-filter-switcher"><i class="sliders horizontal icon"></i></div>
<div class="sbt-filter-text">{{resourceService.frmelmnts?.lbl?.filters}}</div>
</div>
<mat-accordion class="sb-mat-accordion mb-16 sbt-filter-accordion">
<mat-expansion-panel [expanded]="isOpen">
<div class="sb-mat-accordion__content sbt-filter-bar mr-16 pl-24" tabindex="0">
<div class="sbt-reset-bar d-flex flex-ai-center flex-ai-jc-center">
<button class="sb-btn sb-btn-xs sb-btn-link-primary pull-right sbt-btn-reset cursor-pointer"
(click)="resetFilters()" tabindex="0" appTelemetryInteract
[telemetryInteractEdata]="resetFilterInteractEdata">{{resourceService.frmelmnts?.btn?.reset}} <i
class="icon undo"></i></button>
<span class="sbt-filter-close"><i class="icon-svg icon-svg--xxs icon-close cursor-pointer"
(click)="isOpen = !isOpen" tabindex="0" attr.aria-label="{{resourceService.frmelmnts?.btn?.close}}">
<svg class="icon icon-svg--red">
<use xlink:href="./assets/images/sprite.svg#close"></use>
</svg>
</i>
</span>
</div>
<div class="sbt-filter-scrollable relative pr-24">
<!--Selected Filters list-->
<div class="mb-16" *ngIf="filtersDetails && formInputData && showSearchedParam">
<ng-container *ngFor="let field of filtersDetails">
<div class="d-inline-block" *ngIf='formInputData[field.code] && formInputData[field.code].length > 0'>
<label>{{field.label}} : </label>
<ng-container *ngFor="let item of formInputData[field.code]">
<a class="ui label mt-8 mr-8" *ngIf='!item?.name && field.code !== "channel"'>
{{item}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item)"></i>
</a>
<a class="ui label mt-8 mr-8" *ngIf='item?.name && field.code !== "channel"'>
{{item.name}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item)"></i>
</a>
</ng-container>
<ng-container *ngFor="let item of channelInputLabel">
<a class="ui label mt-8 mr-8" *ngIf='item?.name && field.code === "channel"'>
{{item.name}}
<i class="delete icon" (click)="removeFilterSelection(field.code,item.identifier)"></i>
</a>
</ng-container>
</div>
</ng-container>
</div>
<!--/Selected Filters list-->
<!--Filters-->
<div class="" *ngIf="refresh && filtersDetails">
<div class="" *ngFor="let field of filtersDetails">
<div
*ngIf="(field.inputType==='select' || field.inputType === 'multi-select') && field.code !== 'channel'">
<sui-multi-select (ngModelChange)="setFilterInteractData()" id={{field.code}} name={{field.code}}
defaultSelectionText={{field.label}} zeroSelectionText={{resourceService.frmelmnts.lbl.Select}}
class="ui selection dropdown multiple selection sbt-dropdown sbt-dropdown-bold sbt-dropdown--sm sbt-purple--lbg w-100 mb-16"
[(ngModel)]="formInputData[field.code]" [options]="options" [hasLabels]="false" #multiSelect
*ngIf="field.code !== 'gradeLevel'">
<sui-select-option *ngFor="let option of field.range | sortBy:'name':'asc'" [value]="option.name">
</sui-select-option>
</sui-multi-select>
<sui-multi-select (ngModelChange)="setFilterInteractData()" id={{field.code}} name={{field.code}}
defaultSelectionText={{field.label}} zeroSelectionText={{resourceService.frmelmnts.lbl.Select}}
class="ui selection dropdown multiple selection sbt-dropdown sbt-dropdown-bold sbt-dropdown--sm sbt-purple--lbg w-100 mb-16"
[(ngModel)]="formInputData[field.code]" [options]="options" [hasLabels]="false" #multiSelect
*ngIf="field.code === 'gradeLevel'">
<sui-select-option *ngFor="let option of field.range" [value]="option.name"></sui-select-option>
</sui-multi-select>
</div>
<div *ngIf="field.code === 'channel'">
<sui-multi-select (ngModelChange)="modelChange($event);setFilterInteractData()" id={{field.code}}
name={{field.code}} defaultSelectionText={{field.name}}
zeroSelectionText={{resourceService.frmelmnts.lbl.Select}}
class="selection sbt-dropdown sbt-dropdown-bold sbt-dropdown--sm sbt-purple--lbg w-100 mb-16"
[(ngModel)]="formInputData[field.code]" [options]="options" [hasLabels]="false" labelField="name"
valueField="identifier" #multiSelect>
<sui-select-option *ngFor="let option of field.range | sortBy:'name':'asc'" [value]="option">
</sui-select-option>
</sui-multi-select>
</div>
<div *ngIf="field.code==='topic'">
<app-topic-picker [selectedTopics]="formInputData[field.code]" [formTopic]="field"
(topicChange)="handleTopicChange($event);setFilterInteractData()"></app-topic-picker>
</div>
</div>
<div class="text-right">
<!-- <button class="sb-btn sb-btn-normal sb-btn-outline-primary" (click)="resetFilters()" appTelemetryInteract
[telemetryInteractEdata]="resetFilterInteractEdata">
{{resourceService.frmelmnts?.btn?.reset}}
</button> -->
<button class="sb-btn sb-btn-normal sb-btn-primary ml-8" (click)="applyFilters()" appTelemetryInteract
[telemetryInteractEdata]="applyFilterInteractEdata">
{{resourceService.frmelmnts?.btn?.apply}}
</button>
</div>
</div>
<!--Filters-->
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</ng-container>
./data-driven-filter.component.scss
@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
@use "pages/sbt-filter" as *;
// state dropdown css
.ui.selection.dropdown .menu>.item {
font-size: calculateRem(12px);
padding: 1em 1em !important;
}
.ui.selection.dropdown.state-medium {
color: var(--primary-400);
display: flex;
align-items: center;
border: none;
background: none;
min-width: calculateRem(100px);
margin: 0;
.medium-selection {
min-width: calculateRem(120px);
}
&:hover {
background: var(--rc-E0F1FD);
}
}
.ui.selection.dropdown.state-selection {
color: var(--primary-400);
font-weight: bold;
display: flex;
align-items: center;
min-width: calculateRem(208px);
@include respond-below(sm) {
min-width: 10rem;
}
border-radius: calculateRem(2px);
border: calculateRem(0.5px) solid var(--primary-400);
&.active {
background: var(--rc-E0F1FD) !important;
color: var(--primary-400) !important;
border-color: var(--primary-400);
box-shadow: none;
}
&:hover {
color: var(--primary-400) !important;
box-sizing: border-box;
border-radius: calculateRem(2px);
background-color: var(--rc-E0F1FD);
box-shadow: none;
}
}
.ui.selection.dropdown .menu {
max-height: 20em;
}
.ui.default.dropdown:not(.button)>.text,
.ui.dropdown:not(.button)>.default.text {
color: var(--red-400);
}
:host ::ng-deep .dropdown:not(.button)>.default.text {
color: var(--primary-400) !important;
}
:host ::ng-deep .sb-slider-pills-container .sb-pills-container {
padding: 0.5rem 0 !important;
}