src/app/search/search.page.ts
OnInit
AfterViewInit
OnDestroy
OnTabViewWillEnter
selector | app-search |
styleUrls | ./search.page.scss |
templateUrl | ./search.page.html |
constructor(contentService: ContentService, pageService: PageAssembleService, eventsBusService: EventsBusService, preferences: SharedPreferences, profileService: ProfileService, frameworkService: FrameworkService, frameworkUtilService: FrameworkUtilService, courseService: CourseService, searchHistoryService: SearchHistoryService, appVersion: AppVersion, changeDetectionRef: ChangeDetectorRef, zone: NgZone, event: Events, events: Events, appGlobalService: AppGlobalService, platform: Platform, formAndFrameworkUtilService: FormAndFrameworkUtilService, commonUtilService: CommonUtilService, telemetryGeneratorService: TelemetryGeneratorService, translate: TranslateService, headerService: AppHeaderService, popoverCtrl: PopoverController, location: Location, router: Router, navCtrl: NavController, sbProgressLoader: SbProgressLoader, groupHandlerService: GroupHandlerService, navService: NavigationService, profileHandler: ProfileHandler, onboardingConfigurationService: OnboardingConfigurationService)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in src/app/search/search.page.ts:171
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Parameters :
|
Async addActivityToGroup |
addActivityToGroup()
|
Defined in src/app/search/search.page.ts:1742
|
Returns :
any
|
Private addCorRelation |
addCorRelation(id: string, type: string)
|
Defined in src/app/search/search.page.ts:1623
|
Returns :
void
|
Private addSearchHistoryEntry |
addSearchHistoryEntry()
|
Defined in src/app/search/search.page.ts:1054
|
Returns :
void
|
applyFilter | ||||||
applyFilter(offset?: number)
|
||||||
Defined in src/app/search/search.page.ts:861
|
||||||
Parameters :
Returns :
void
|
cancelDownload |
cancelDownload()
|
Defined in src/app/search/search.page.ts:1601
|
Returns :
void
|
checkParent | ||||||
checkParent(parent, child)
|
||||||
Defined in src/app/search/search.page.ts:1429
|
||||||
Parameters :
Returns :
void
|
checkProfileData | ||||||
checkProfileData(data, profile)
|
||||||
Defined in src/app/search/search.page.ts:686
|
||||||
Parameters :
Returns :
void
|
Private Async checkRetiredOpenBatch |
checkRetiredOpenBatch(content: any, layoutName?: string)
|
Defined in src/app/search/search.page.ts:1066
|
Returns :
any
|
checkUserSession |
checkUserSession()
|
Defined in src/app/search/search.page.ts:1619
|
Returns :
void
|
Private disableHeaderEvents |
disableHeaderEvents()
|
Defined in src/app/search/search.page.ts:1878
|
Returns :
void
|
downloadParentContent | ||||
downloadParentContent(parent)
|
||||
Defined in src/app/search/search.page.ts:1463
|
||||
Parameters :
Returns :
void
|
editProfile |
editProfile()
|
Defined in src/app/search/search.page.ts:787
|
Returns :
void
|
Private enableHeaderEvents |
enableHeaderEvents()
|
Defined in src/app/search/search.page.ts:1870
|
Returns :
void
|
fetchPrimaryCategoryFilters | ||||
fetchPrimaryCategoryFilters(facetFilters)
|
||||
Defined in src/app/search/search.page.ts:1822
|
||||
Parameters :
Returns :
void
|
findCode | ||||||||||||
findCode(categoryList: Array
|
||||||||||||
Defined in src/app/search/search.page.ts:650
|
||||||||||||
Parameters :
Returns :
any
|
Private generateImpressionEvent | ||||
generateImpressionEvent(dialCodeResult?)
|
||||
Defined in src/app/search/search.page.ts:1633
|
||||
Parameters :
Returns :
void
|
generateInteractEvent | ||||||||||
generateInteractEvent(identifier, contentType, pkgVersion, index)
|
||||||||||
Defined in src/app/search/search.page.ts:1240
|
||||||||||
Parameters :
Returns :
void
|
Private generateLogEvent | ||||
generateLogEvent(searchResult)
|
||||
Defined in src/app/search/search.page.ts:1657
|
||||
Parameters :
Returns :
void
|
generateQRScanSuccessInteractEvent | ||||||
generateQRScanSuccessInteractEvent(dialCodeResultCount, dialCode)
|
||||||
Defined in src/app/search/search.page.ts:1384
|
||||||
Parameters :
Returns :
void
|
generateQRSessionEndEvent |
generateQRSessionEndEvent(pageId: string, qrData: string)
|
Defined in src/app/search/search.page.ts:1266
|
Returns :
void
|
Private Async getAppName |
getAppName()
|
Defined in src/app/search/search.page.ts:350
|
Returns :
unknown
|
getContentCount | ||||
getContentCount(displayDialCodeResult)
|
||||
Defined in src/app/search/search.page.ts:1725
|
||||
Parameters :
Returns :
number
|
Async getContentForDialCode |
getContentForDialCode()
|
Defined in src/app/search/search.page.ts:1178
|
Returns :
any
|
Private getEnrolledCourses | ||||||||
getEnrolledCourses(returnRefreshedCourses: boolean)
|
||||||||
Defined in src/app/search/search.page.ts:1678
|
||||||||
To get enrolled course(s) of logged-in user. It internally calls course handler of genie sdk
Parameters :
Returns :
Promise<any>
|
getFrameworkId |
getFrameworkId()
|
Defined in src/app/search/search.page.ts:357
|
Returns :
void
|
getImportContentRequestBody | ||||||||||||
getImportContentRequestBody(identifiers: Array
|
||||||||||||
Defined in src/app/search/search.page.ts:1585
|
||||||||||||
Function to get import content api request params
Parameters :
Returns :
Array<ContentImport>
|
goBack |
goBack()
|
Defined in src/app/search/search.page.ts:1711
|
Returns :
void
|
handleCancel |
handleCancel()
|
Defined in src/app/search/search.page.ts:914
|
Returns :
void
|
handleDeviceBackButton |
handleDeviceBackButton()
|
Defined in src/app/search/search.page.ts:406
|
Returns :
void
|
handleFilterSelect | ||||
handleFilterSelect(event)
|
||||
Defined in src/app/search/search.page.ts:1835
|
||||
Parameters :
Returns :
void
|
handleHeaderEvents | ||||
handleHeaderEvents($event)
|
||||
Defined in src/app/search/search.page.ts:1799
|
||||
Parameters :
Returns :
void
|
handleSearch | ||||||||||||
handleSearch(shouldApplyProfileFilter, offset?: number)
|
||||||||||||
Defined in src/app/search/search.page.ts:922
|
||||||||||||
Parameters :
Returns :
void
|
hideRefresher | ||||
hideRefresher(hide)
|
||||
Defined in src/app/search/search.page.ts:280
|
||||
Parameters :
Returns :
void
|
init |
init()
|
Defined in src/app/search/search.page.ts:1162
|
Returns :
void
|
ionViewDidEnter |
ionViewDidEnter()
|
Defined in src/app/search/search.page.ts:266
|
Returns :
void
|
Async ionViewWillEnter |
ionViewWillEnter()
|
Defined in src/app/search/search.page.ts:247
|
Returns :
any
|
ionViewWillLeave |
ionViewWillLeave()
|
Defined in src/app/search/search.page.ts:332
|
Returns :
void
|
loadData |
loadData()
|
Defined in src/app/search/search.page.ts:423
|
Returns :
void
|
Async navigateToBatchListPopup |
navigateToBatchListPopup(content: any, layoutName?: string, retiredBatched?: any)
|
Defined in src/app/search/search.page.ts:1094
|
Returns :
any
|
Async navigateToPreviousPage |
navigateToPreviousPage()
|
Defined in src/app/search/search.page.ts:367
|
Returns :
any
|
ngAfterViewInit |
ngAfterViewInit()
|
Defined in src/app/search/search.page.ts:284
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Defined in src/app/search/search.page.ts:343
|
Returns :
void
|
Async ngOnInit |
ngOnInit()
|
Defined in src/app/search/search.page.ts:241
|
Returns :
any
|
onSearchHistoryTap | ||||||
onSearchHistoryTap(searchEntry: SearchEntry)
|
||||||
Defined in src/app/search/search.page.ts:314
|
||||||
Parameters :
Returns :
void
|
openCollection | ||||
openCollection(collection)
|
||||
Defined in src/app/search/search.page.ts:434
|
||||
Parameters :
Returns :
void
|
Async openContent | ||||||||||||
openContent(collection, content, index?, isQrCodeLinkToSingleContent?, markAsSelected?)
|
||||||||||||
Defined in src/app/search/search.page.ts:448
|
||||||||||||
Parameters :
Returns :
any
|
openSelectedContent |
openSelectedContent()
|
Defined in src/app/search/search.page.ts:1760
|
Returns :
void
|
popCurrentPage |
popCurrentPage()
|
Defined in src/app/search/search.page.ts:402
|
Returns :
void
|
processDialCodeResult | ||||
processDialCodeResult(dialResult)
|
||||
Defined in src/app/search/search.page.ts:1280
|
||||
Parameters :
Returns :
void
|
redirectToNotifications |
redirectToNotifications()
|
Defined in src/app/search/search.page.ts:1861
|
Returns :
void
|
scrollToTop |
scrollToTop()
|
Defined in src/app/search/search.page.ts:1707
|
Returns :
void
|
searchOnFocus |
searchOnFocus()
|
Defined in src/app/search/search.page.ts:1792
|
Returns :
void
|
setCurrentProfile | ||||||
setCurrentProfile(index, data)
|
||||||
Defined in src/app/search/search.page.ts:658
|
||||||
Parameters :
Returns :
void
|
setGrade | ||||||
setGrade(reset, grades)
|
||||||
Defined in src/app/search/search.page.ts:619
|
||||||
Parameters :
Returns :
void
|
setMedium | ||||||
setMedium(reset, mediums)
|
||||||
Defined in src/app/search/search.page.ts:635
|
||||||
Parameters :
Returns :
void
|
Private Async showContentDetails | ||||||||||||||||
showContentDetails(content, isRootContent: boolean, isAvailableLocally: boolean)
|
||||||||||||||||
Defined in src/app/search/search.page.ts:474
|
||||||||||||||||
Parameters :
Returns :
any
|
showFilter |
showFilter()
|
Defined in src/app/search/search.page.ts:828
|
Returns :
void
|
subscribeSdkEvent |
subscribeSdkEvent()
|
Defined in src/app/search/search.page.ts:1519
|
Subscribe Sunbird-SDK event to get content download progress
Returns :
void
|
tabViewWillEnter |
tabViewWillEnter()
|
Defined in src/app/search/search.page.ts:1885
|
Returns :
void
|
Private updateCsGroupAddableBloc | ||||||
updateCsGroupAddableBloc(params, pageId)
|
||||||
Defined in src/app/search/search.page.ts:1772
|
||||||
Parameters :
Returns :
void
|
updateFilterIcon |
updateFilterIcon()
|
Defined in src/app/search/search.page.ts:1400
|
Returns :
void
|
activityList |
Type : GroupActivity[]
|
Default value : []
|
Defined in src/app/search/search.page.ts:104
|
activityTypeData |
Type : any
|
Defined in src/app/search/search.page.ts:103
|
appName |
Type : string
|
Defined in src/app/search/search.page.ts:96
|
appPrimaryColor |
Type : string
|
Defined in src/app/search/search.page.ts:164
|
backButtonFunc |
Type : Subscription
|
Defined in src/app/search/search.page.ts:130
|
batches |
Type : any
|
Defined in src/app/search/search.page.ts:138
|
boardList |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:143
|
categories |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:142
|
childContent |
Type : any
|
Default value : undefined
|
Defined in src/app/search/search.page.ts:123
|
Public commonUtilService |
Type : CommonUtilService
|
Defined in src/app/search/search.page.ts:191
|
contentData |
Type : any
|
Defined in src/app/search/search.page.ts:122
|
contentView |
Type : IonContent
|
Decorators :
@ViewChild('contentView', {static: false})
|
Defined in src/app/search/search.page.ts:158
|
Private corRelationList |
Type : Array<CorrelationData>
|
Defined in src/app/search/search.page.ts:134
|
currentCount |
Type : number
|
Default value : 0
|
Defined in src/app/search/search.page.ts:120
|
currentFrameworkId |
Type : string
|
Default value : ''
|
Defined in src/app/search/search.page.ts:132
|
defaultAppIcon |
Type : string
|
Defined in src/app/search/search.page.ts:116
|
dialCode |
Type : string
|
Defined in src/app/search/search.page.ts:106
|
dialCodeContentResult |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:108
|
dialCodeResult |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:107
|
discoverCmp |
Type : DiscoverComponent
|
Decorators :
@ViewChild(DiscoverComponent, {static: false})
|
Defined in src/app/search/search.page.ts:93
|
displayDialCodeResult |
Type : any
|
Defined in src/app/search/search.page.ts:126
|
downloadProgress |
Type : any
|
Defined in src/app/search/search.page.ts:98
|
enableSearch |
Default value : false
|
Defined in src/app/search/search.page.ts:154
|
enrolledCourses |
Type : any
|
Defined in src/app/search/search.page.ts:136
|
Optional eventSubscription |
Type : Subscription
|
Defined in src/app/search/search.page.ts:125
|
filterIcon |
Defined in src/app/search/search.page.ts:111
|
gradeList |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:145
|
groupId |
Type : string
|
Defined in src/app/search/search.page.ts:102
|
guestUser |
Type : any
|
Defined in src/app/search/search.page.ts:137
|
headerObservable |
Type : Subscription
|
Defined in src/app/search/search.page.ts:159
|
hideSearchOption |
Default value : false
|
Defined in src/app/search/search.page.ts:168
|
identifier |
Type : string
|
Defined in src/app/search/search.page.ts:141
|
initialFilterCriteria |
Type : any
|
Defined in src/app/search/search.page.ts:149
|
isDialCodeSearch |
Default value : false
|
Defined in src/app/search/search.page.ts:114
|
isDownloadStarted |
Default value : false
|
Defined in src/app/search/search.page.ts:119
|
isEmptyResult |
Default value : false
|
Defined in src/app/search/search.page.ts:117
|
isFilterApplied |
Type : boolean
|
Default value : false
|
Defined in src/app/search/search.page.ts:170
|
isFirstLaunch |
Default value : false
|
Defined in src/app/search/search.page.ts:128
|
isFromGroupFlow |
Default value : false
|
Defined in src/app/search/search.page.ts:105
|
isProfileUpdated |
Type : boolean
|
Defined in src/app/search/search.page.ts:146
|
isQrCodeLinkToContent |
Type : any
|
Defined in src/app/search/search.page.ts:147
|
isSingleContent |
Default value : false
|
Defined in src/app/search/search.page.ts:131
|
layoutName |
Type : string
|
Default value : 'search'
|
Defined in src/app/search/search.page.ts:135
|
LibraryCardTypes |
Default value : LibraryCardTypes
|
Defined in src/app/search/search.page.ts:148
|
Optional loader |
Type : any
|
Defined in src/app/search/search.page.ts:139
|
loadingDisplayText |
Default value : this.commonUtilService.translateMessage('LOADING_CONTENT')
|
Defined in src/app/search/search.page.ts:124
|
mediumList |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:144
|
parentContent |
Type : any
|
Default value : undefined
|
Defined in src/app/search/search.page.ts:121
|
PillBorder |
Default value : PillBorder
|
Defined in src/app/search/search.page.ts:162
|
PillsViewType |
Default value : PillsViewType
|
Defined in src/app/search/search.page.ts:161
|
preAppliedFilter |
Type : any
|
Defined in src/app/search/search.page.ts:153
|
primaryCategories |
Type : Array<string>
|
Default value : []
|
Defined in src/app/search/search.page.ts:100
|
primaryCategoryFilters |
Defined in src/app/search/search.page.ts:160
|
profile |
Type : Profile
|
Defined in src/app/search/search.page.ts:127
|
queuedIdentifiers |
Type : []
|
Default value : []
|
Defined in src/app/search/search.page.ts:118
|
refresh |
Type : boolean
|
Default value : false
|
Defined in src/app/search/search.page.ts:156
|
refresher |
Type : IonRefresher
|
Decorators :
@ViewChild('refresher', {static: false})
|
Defined in src/app/search/search.page.ts:92
|
responseData |
Type : any
|
Defined in src/app/search/search.page.ts:113
|
rootOrgId |
Type : string
|
Defined in src/app/search/search.page.ts:171
|
searchBar |
Decorators :
@ViewChild('searchInput', {static: false})
|
Defined in src/app/search/search.page.ts:99
|
searchContentResult |
Type : Array<any>
|
Default value : []
|
Defined in src/app/search/search.page.ts:109
|
searchFilterConfig |
Type : Array<any>
|
Defined in src/app/search/search.page.ts:152
|
Public searchHistory$ |
Type : Observable<SearchEntry[]>
|
Defined in src/app/search/search.page.ts:95
|
searchInfolVisibility |
Type : string
|
Default value : 'show'
|
Defined in src/app/search/search.page.ts:155
|
searchKeywords |
Type : string
|
Default value : ''
|
Defined in src/app/search/search.page.ts:112
|
searchWithBackButton |
Default value : false
|
Defined in src/app/search/search.page.ts:166
|
selectedLanguageCode |
Type : string
|
Default value : ''
|
Defined in src/app/search/search.page.ts:133
|
selectedPrimaryCategoryFilter |
Type : any
|
Defined in src/app/search/search.page.ts:165
|
Private selectedSwitchableTab |
Type : string
|
Defined in src/app/search/search.page.ts:167
|
SelectMode |
Default value : SelectMode
|
Defined in src/app/search/search.page.ts:163
|
shouldGenerateEndTelemetry |
Default value : false
|
Defined in src/app/search/search.page.ts:129
|
showAddToGroupButtons |
Default value : false
|
Defined in src/app/search/search.page.ts:150
|
showEmptyMessage |
Type : boolean
|
Defined in src/app/search/search.page.ts:115
|
showLoader |
Default value : false
|
Defined in src/app/search/search.page.ts:110
|
showLoading |
Type : boolean
|
Defined in src/app/search/search.page.ts:97
|
source |
Type : string
|
Defined in src/app/search/search.page.ts:101
|
supportedUserTypesConfig |
Type : Array<any>
|
Defined in src/app/search/search.page.ts:151
|
totalCount |
Type : number
|
Defined in src/app/search/search.page.ts:169
|
userId |
Type : any
|
Defined in src/app/search/search.page.ts:140
|
import { Component, Inject, NgZone, OnDestroy, ViewChild, ChangeDetectorRef, OnInit, AfterViewInit } from '@angular/core';
import { Router, NavigationExtras } from '@angular/router';
import { Platform, PopoverController, IonContent, NavController, IonRefresher } from '@ionic/angular';
import { Events } from '@app/util/events';
import { TranslateService } from '@ngx-translate/core';
import { Location } from '@angular/common';
import each from 'lodash/each';
import find from 'lodash/find';
import map from 'lodash/map';
import {
CachedItemRequestSourceFrom, Content, ContentDetailRequest, ContentEventType, ContentImport, ContentImportRequest,
ContentImportResponse, ContentImportStatus, ContentSearchCriteria, ContentSearchResult, ContentService,
CorrelationData, DownloadEventType, DownloadProgress, EventsBusEvent, EventsBusService, PageAssembleCriteria,
PageAssembleFilter, PageAssembleService, PageName, SearchType, SharedPreferences, TelemetryObject,
NetworkError, CourseService, CourseBatchesRequest, CourseEnrollmentType, CourseBatchStatus, Course, Batch,
FetchEnrolledCourseRequest, Profile,
ProfileService, Framework,
FrameworkCategoryCodesGroup,
FrameworkDetailsRequest,
FrameworkService,
FrameworkUtilService,
GetSuggestedFrameworksRequest, SearchEntry,
SearchHistoryService, SortOrder,
GroupActivity
} from 'sunbird-sdk';
import { Map } from '@app/app/telemetryutil';
import {
BatchConstants,
RouterLinks, Search, ContentCard,
ContentFilterConfig,
PreferenceKey,
SwitchableTabsConfig
} from '@app/app/app.constant';
import { AppGlobalService } from '@app/services/app-global-service.service';
import { FormAndFrameworkUtilService } from '@app/services/formandframeworkutil.service';
import { CommonUtilService } from '@app/services/common-util.service';
import { TelemetryGeneratorService } from '@app/services/telemetry-generator.service';
import {
Environment, ImpressionType, InteractSubtype,
InteractType, LogLevel, Mode, PageId, CorReleationDataType,
AuditType, ImpressionSubtype, ObjectType
} from '@app/services/telemetry-constants';
import { AppHeaderService } from '@app/services/app-header.service';
import { AppVersion } from '@ionic-native/app-version/ngx';
import { SearchHistoryNamespaces } from '@app/config/search-history-namespaces';
import { featureIdMap } from '@app/app/feature-id-map';
import { EnrollmentDetailsComponent } from '../components/enrollment-details/enrollment-details.component';
import { ContentUtil } from '@app/util/content-util';
import { LibraryCardTypes, PillBorder, PillsViewType, SelectMode } from '@project-sunbird/common-consumption';
import { Subscription, Observable, from } from 'rxjs';
import { switchMap, tap, map as rxjsMap, share, startWith, debounceTime } from 'rxjs/operators';
import { SbProgressLoader } from '../../services/sb-progress-loader.service';
import { applyProfileFilter, updateFilterInSearchQuery } from '@app/util/filter.util';
import { GroupHandlerService, OnboardingConfigurationService } from '@app/services';
import { NavigationService } from '@app/services/navigation-handler.service';
import { CsGroupAddableBloc } from '@project-sunbird/client-services/blocs';
import { CsContentType } from '@project-sunbird/client-services/services/content';
import { ProfileHandler } from '@app/services/profile-handler';
import { FormConstants } from '../form.constants';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { DiscoverComponent } from '../components/discover/discover.page';
import { OnTabViewWillEnter } from './../tabs/on-tab-view-will-enter';
declare const cordova;
@Component({
selector: 'app-search',
templateUrl: './search.page.html',
styleUrls: ['./search.page.scss'],
animations: [
trigger('labelVisibility', [
state(
'show',
style({
maxHeight: '50vh',
overflow: 'hidden'
})
),
state(
'hide',
style({
maxHeight: '0',
overflow: 'hidden'
})
),
transition('* => show', [animate('500ms ease-out')]),
transition('show => hide', [animate('500ms ease-in')])
])
],
})
export class SearchPage implements OnInit, AfterViewInit, OnDestroy, OnTabViewWillEnter {
@ViewChild('refresher', { static: false }) refresher: IonRefresher;
@ViewChild(DiscoverComponent, { static: false }) discoverCmp: DiscoverComponent;
public searchHistory$: Observable<SearchEntry[]>;
appName: string;
showLoading: boolean;
downloadProgress: any;
@ViewChild('searchInput', { static: false }) searchBar;
primaryCategories: Array<string> = [];
source: string;
groupId: string;
activityTypeData: any;
activityList: GroupActivity[] = [];
isFromGroupFlow = false;
dialCode: string;
dialCodeResult: Array<any> = [];
dialCodeContentResult: Array<any> = [];
searchContentResult: Array<any> = [];
showLoader = false;
filterIcon;
searchKeywords = '';
responseData: any;
isDialCodeSearch = false;
showEmptyMessage: boolean;
defaultAppIcon: string;
isEmptyResult = false;
queuedIdentifiers = [];
isDownloadStarted = false;
currentCount = 0;
parentContent: any = undefined;
contentData: any;
childContent: any = undefined;
loadingDisplayText = this.commonUtilService.translateMessage('LOADING_CONTENT');
eventSubscription?: Subscription;
displayDialCodeResult: any;
profile: Profile;
isFirstLaunch = false;
shouldGenerateEndTelemetry = false;
backButtonFunc: Subscription;
isSingleContent = false;
currentFrameworkId = '';
selectedLanguageCode = '';
private corRelationList: Array<CorrelationData>;
layoutName = 'search';
enrolledCourses: any;
guestUser: any;
batches: any;
loader?: any;
userId: any;
identifier: string;
categories: Array<any> = [];
boardList: Array<any> = [];
mediumList: Array<any> = [];
gradeList: Array<any> = [];
isProfileUpdated: boolean;
isQrCodeLinkToContent: any;
LibraryCardTypes = LibraryCardTypes;
initialFilterCriteria: any;
showAddToGroupButtons = false;
supportedUserTypesConfig: Array<any>;
searchFilterConfig: Array<any>;
preAppliedFilter: any;
enableSearch = false;
searchInfolVisibility = 'show';
refresh: boolean = false;
@ViewChild('contentView', { static: false }) contentView: IonContent;
headerObservable: Subscription;
primaryCategoryFilters;
PillsViewType = PillsViewType;
PillBorder = PillBorder;
SelectMode = SelectMode;
appPrimaryColor: string;
selectedPrimaryCategoryFilter: any;
searchWithBackButton = false;
private selectedSwitchableTab: string;
hideSearchOption = false;
totalCount: number;
isFilterApplied: boolean = false;
rootOrgId: string;
constructor(
@Inject('CONTENT_SERVICE') private contentService: ContentService,
@Inject('PAGE_ASSEMBLE_SERVICE') private pageService: PageAssembleService,
@Inject('EVENTS_BUS_SERVICE') private eventsBusService: EventsBusService,
@Inject('SHARED_PREFERENCES') private preferences: SharedPreferences,
@Inject('PROFILE_SERVICE') private profileService: ProfileService,
@Inject('FRAMEWORK_SERVICE') private frameworkService: FrameworkService,
@Inject('FRAMEWORK_UTIL_SERVICE') private frameworkUtilService: FrameworkUtilService,
@Inject('COURSE_SERVICE') private courseService: CourseService,
@Inject('SEARCH_HISTORY_SERVICE') private searchHistoryService: SearchHistoryService,
private appVersion: AppVersion,
private changeDetectionRef: ChangeDetectorRef,
private zone: NgZone,
private event: Events,
private events: Events,
private appGlobalService: AppGlobalService,
private platform: Platform,
private formAndFrameworkUtilService: FormAndFrameworkUtilService,
public commonUtilService: CommonUtilService,
private telemetryGeneratorService: TelemetryGeneratorService,
private translate: TranslateService,
private headerService: AppHeaderService,
private popoverCtrl: PopoverController,
private location: Location,
private router: Router,
private navCtrl: NavController,
private sbProgressLoader: SbProgressLoader,
private groupHandlerService: GroupHandlerService,
private navService: NavigationService,
private profileHandler: ProfileHandler,
private onboardingConfigurationService: OnboardingConfigurationService
) {
const extras = this.router.getCurrentNavigation().extras.state;
if (extras) {
this.dialCode = extras.dialCode;
this.primaryCategories = extras.primaryCategories;
this.corRelationList = extras.corRelation;
this.source = extras.source;
this.searchWithBackButton = extras.searchWithBackButton;
this.hideSearchOption = extras.hideSearchOption;
if (this.source === PageId.GROUP_DETAIL) {
this.isFromGroupFlow = true;
this.searchOnFocus();
}
this.groupId = extras.groupId;
this.activityTypeData = extras.activityTypeData;
this.activityList = extras.activityList;
this.enrolledCourses = extras.enrolledCourses;
this.guestUser = extras.guestUser;
this.userId = extras.userId;
this.shouldGenerateEndTelemetry = extras.shouldGenerateEndTelemetry;
this.preAppliedFilter = extras.preAppliedFilter;
if (this.preAppliedFilter) {
this.enableSearch = true;
this.searchKeywords = this.preAppliedFilter.query || '';
}
}
this.rootOrgId = this.onboardingConfigurationService.getAppConfig().overriddenDefaultChannelId
this.checkUserSession();
this.isFirstLaunch = true;
this.init();
this.defaultAppIcon = 'assets/imgs/ic_launcher.png';
this.getFrameworkId();
this.selectedLanguageCode = this.translate.currentLang;
}
async ngOnInit() {
this.getAppName();
this.supportedUserTypesConfig = await this.profileHandler.getSupportedUserTypes();
this.appPrimaryColor = getComputedStyle(document.querySelector('html')).getPropertyValue('--app-primary-medium');
}
async ionViewWillEnter() {
if (this.dialCode) {
this.enableSearch = true;
}
this.enableHeaderEvents();
if (this.isFromGroupFlow || this.searchWithBackButton) {
this.headerService.showHeaderWithBackButton(null, this.commonUtilService.translateMessage('SEARCH_IN_APP', { 'app_name': this.appName}));
} else {
this.headerService.showHeaderWithHomeButton(['download', 'notification']);
}
this.handleDeviceBackButton();
this.searchFilterConfig = await this.formAndFrameworkUtilService.getFormFields(FormConstants.SEARCH_FILTER);
if ((this.source === PageId.GROUP_DETAIL && this.isFirstLaunch) || this.preAppliedFilter) {
this.isFirstLaunch = false;
this.handleSearch(true);
}
this.selectedSwitchableTab = await this.preferences.getString(PreferenceKey.SELECTED_SWITCHABLE_TABS_CONFIG).toPromise()
}
ionViewDidEnter() {
if (!this.dialCode && this.isFirstLaunch && this.source !== PageId.GROUP_DETAIL) {
setTimeout(() => {
this.isFirstLaunch = false;
}, 100);
}
this.sbProgressLoader.hide({ id: this.dialCode });
this.checkUserSession();
if (this.refresher) {
this.refresher.disabled = false;
}
}
hideRefresher(hide) {
this.refresh = hide;
}
ngAfterViewInit() {
this.searchHistory$ = this.searchBar && (this.searchBar as any).ionChange.pipe(
rxjsMap((e: CustomEvent) => e.target['value']),
share(),
startWith(''),
debounceTime(500),
switchMap((v: string) => {
if (v) {
return from(this.searchHistoryService.getEntries({
like: v,
limit: 5,
namespace: SearchHistoryNamespaces.LIBRARY
}).toPromise());
}
return from(this.searchHistoryService.getEntries({
limit: 10,
namespace: SearchHistoryNamespaces.LIBRARY
}).toPromise());
}),
tap(() => {
setTimeout(() => {
this.showAddToGroupButtons = false;
this.changeDetectionRef.detectChanges();
});
}) as any
);
}
onSearchHistoryTap(searchEntry: SearchEntry) {
this.searchKeywords = searchEntry.query;
this.handleSearch();
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.SEARCH_HISTORY_CLICKED,
Environment.HOME,
PageId.SEARCH,
undefined,
{
selectedSearchHistory: searchEntry.query
},
undefined,
featureIdMap.searchHistory.SEARCH_HISTORY_QUERY_FROM_HISTORY
);
}
ionViewWillLeave() {
if (this.backButtonFunc) {
this.backButtonFunc.unsubscribe();
}
if (this.eventSubscription) {
this.eventSubscription.unsubscribe();
}
this.disableHeaderEvents();
this.refresher.disabled = true;
}
ngOnDestroy() {
if (this.eventSubscription) {
this.eventSubscription.unsubscribe();
}
this.disableHeaderEvents();
}
private async getAppName() {
return this.appVersion.getAppName()
.then((appName: any) => {
this.appName = appName;
});
}
getFrameworkId() {
this.preferences.getString('current_framework_id').toPromise()
.then(value => {
this.currentFrameworkId = value;
})
.catch(() => {
});
}
async navigateToPreviousPage() {
if (this.shouldGenerateEndTelemetry) {
this.generateQRSessionEndEvent(this.source, this.dialCode);
}
if (this.appGlobalService.isGuestUser) {
if ((this.source === PageId.PERMISSION || this.source === PageId.ONBOARDING_PROFILE_PREFERENCES)
&& this.appGlobalService.isOnBoardingCompleted) {
if (this.appGlobalService.isProfileSettingsCompleted) {
if (await this.commonUtilService.isDeviceLocationAvailable()) {
this.router.navigate([`/${RouterLinks.TABS}`], { state: { loginMode: 'guest' }, replaceUrl: true });
} else {
const navigationExtras: NavigationExtras = {
state: {
isShowBackButton: false
}
};
this.navCtrl.navigateForward([`/${RouterLinks.DISTRICT_MAPPING}`], navigationExtras);
}
} else {
this.router.navigate([`/${RouterLinks.PROFILE_SETTINGS}`],
{ state: { isCreateNavigationStack: false, hideBackButton: true, showFrameworkCategoriesMenu: true } });
}
} else {
if (this.source === PageId.ONBOARDING_PROFILE_PREFERENCES) {
this.router.navigate([`/${RouterLinks.PROFILE_SETTINGS}`], { state: { showFrameworkCategoriesMenu: true }, replaceUrl: true });
} else {
this.popCurrentPage();
}
}
} else {
this.popCurrentPage();
}
}
popCurrentPage() {
this.location.back();
}
handleDeviceBackButton() {
this.backButtonFunc = this.platform.backButton.subscribeWithPriority(10, () => {
this.navigateToPreviousPage();
if (this.displayDialCodeResult && this.displayDialCodeResult[0].dialCodeResult &&
this.displayDialCodeResult[0].dialCodeResult.length) {
this.telemetryGeneratorService.generateBackClickedNewTelemetry(
true,
this.source === PageId.ONBOARDING ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_BOOK_RESULT
);
} else {
this.telemetryGeneratorService.generateBackClickedTelemetry(ImpressionType.SEARCH,
Environment.HOME, false, undefined, this.corRelationList);
}
});
}
loadData() {
setTimeout(() => {
let offset = this.searchContentResult == undefined ? 0 : this.searchContentResult.length;
if(this.isFilterApplied) {
this.applyFilter(offset);
} else {
this.handleSearch(true, offset);
}
}, 500);
}
openCollection(collection) {
const values = new Map();
values.root = true;
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
InteractSubtype.CONTENT_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_SEARCH,
ContentUtil.getTelemetryObject(collection),
values,
undefined,
this.corRelationList);
this.showContentDetails(collection, true);
}
async openContent(collection, content, index?, isQrCodeLinkToSingleContent?, markAsSelected?) {
if (markAsSelected && this.isFromGroupFlow) {
this.searchContentResult.forEach((element, idx) => {
if (idx === index) {
element.selected = true;
} else {
element.selected = false;
}
});
this.showAddToGroupButtons = true;
} else {
this.showLoader = false;
this.parentContent = collection;
this.isQrCodeLinkToContent = isQrCodeLinkToSingleContent;
this.generateInteractEvent(content.identifier, content.contentType, content.pkgVersion, index ? index : 0);
if (collection !== undefined) {
this.parentContent = collection;
this.childContent = content;
this.checkParent(collection, content);
} else {
this.showLoader = false;
await this.checkRetiredOpenBatch(content);
}
}
}
private async showContentDetails(content, isRootContent: boolean = false, isAvailableLocally: boolean = true) {
this.showLoader = false;
let params;
if (this.shouldGenerateEndTelemetry) {
params = {
content,
corRelation: this.corRelationList,
source: this.source,
shouldGenerateEndTelemetry: this.shouldGenerateEndTelemetry,
parentContent: this.parentContent,
isSingleContent: this.isSingleContent,
onboarding: this.appGlobalService.isOnBoardingCompleted,
isProfileUpdated: this.isProfileUpdated,
isQrCodeLinkToContent: this.isQrCodeLinkToContent,
isAvailableLocally
};
} else {
params = {
content,
corRelation: this.corRelationList,
parentContent: this.parentContent,
isSingleContent: this.isSingleContent,
onboarding: this.appGlobalService.isOnBoardingCompleted,
isProfileUpdated: this.isProfileUpdated,
isQrCodeLinkToContent: this.isQrCodeLinkToContent,
isAvailableLocally
};
}
if (this.loader) {
this.loader.dismiss();
}
if (this.isDialCodeSearch && !this.appGlobalService.isOnBoardingCompleted && await this.appGlobalService.getProfileSettingsStatus()) {
this.appGlobalService.setOnBoardingCompleted();
}
switch (ContentUtil.isTrackable(content)) {
case 1:
if (!this.guestUser) {
this.enrolledCourses = await this.getEnrolledCourses(false);
} else {
this.enrolledCourses = [];
}
if (this.enrolledCourses && this.enrolledCourses.length) {
for (let i = 0; i < this.enrolledCourses.length; i++) {
if (content.identifier === this.enrolledCourses[i].courseId) {
params.content = this.enrolledCourses[i];
}
}
}
const correlationData: CorrelationData = new CorrelationData();
if (this.source === PageId.GROUP_DETAIL) {
correlationData.id = PageId.GROUP_DETAIL;
correlationData.type = CorReleationDataType.FROM_PAGE;
if (params && params.corRelation) {
params.corRelation.push(correlationData);
}
}
if (CsGroupAddableBloc.instance.initialised) {
this.updateCsGroupAddableBloc(params, PageId.COURSE_DETAIL);
}
this.navService.navigateToTrackableCollection(
{
source: this.source,
groupId: this.groupId,
activityList: this.activityList,
content: params.content,
corRelation: params.corRelation,
isSingleContent: params.isSingleContent,
onboarding: params.onboarding,
parentContent: params.parentContent,
isQrCodeLinkToContent: params.isQrCodeLinkToContent,
isOnboardingSkipped: !this.appGlobalService.isOnBoardingCompleted
}
);
if (this.isSingleContent) {
this.isSingleContent = false;
}
break;
case 0:
if (this.isDialCodeSearch && !isRootContent) {
params.isCreateNavigationStack = true;
const corRelationList: Array<CorrelationData> = [];
corRelationList.push({ id: this.dialCode, type: CorReleationDataType.QR });
const telemetryObject = new TelemetryObject(content.identifier, ObjectType.TEXTBOOK, undefined);
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.SELECT_BOOK, '',
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_BOOK_RESULT,
telemetryObject,
undefined, undefined,
corRelationList
);
this.navCtrl.navigateForward([RouterLinks.QRCODERESULT], {
state: {
content: params.content,
corRelation: params.corRelation,
isSingleContent: params.isSingleContent,
onboarding: params.onboarding,
parentContent: params.parentContent,
isProfileUpdated: params.isProfileUpdated,
isQrCodeLinkToContent: params.isQrCodeLinkToContent,
isAvailableLocally: params.isAvailableLocally,
source: params.source,
dialCode: this.dialCode
}
});
if (this.isSingleContent) {
this.isSingleContent = false;
}
} else {
if (CsGroupAddableBloc.instance.initialised) {
this.updateCsGroupAddableBloc(params, PageId.COLLECTION_DETAIL);
}
this.navService.navigateToCollection({
source: this.source,
groupId: this.groupId,
activityList: this.activityList,
content: params.content,
corRelation: params.corRelation,
isSingleContent: params.isSingleContent,
onboarding: params.onboarding,
parentContent: params.parentContent
});
}
break;
case -1:
if (CsGroupAddableBloc.instance.initialised) {
this.updateCsGroupAddableBloc(params, PageId.CONTENT_DETAIL);
}
this.navService.navigateToContent({
content: params.content,
corRelation: params.corRelation,
isSingleContent: params.isSingleContent,
onboarding: params.onboarding,
parentContent: params.parentContent
});
break;
}
this.disableHeaderEvents();
}
setGrade(reset, grades) {
if (reset) {
this.profile.grade = [];
this.profile.gradeValue = {};
}
each(grades, (grade) => {
if (grade && this.profile.grade.indexOf(grade) === -1) {
if (this.profile.grade && this.profile.grade.length) {
this.profile.grade.push(grade);
} else {
this.profile.grade = [grade];
}
}
});
}
setMedium(reset, mediums) {
if (reset) {
this.profile.medium = [];
}
each(mediums, (medium) => {
if (medium && this.profile.medium.indexOf(medium) === -1) {
if (this.profile.medium && this.profile.medium.length) {
this.profile.medium.push(medium);
} else {
this.profile.medium = [medium];
}
}
});
}
findCode(categoryList: Array<any>, data, categoryType) {
if (find(categoryList, (category) => category.name === data[categoryType])) {
return find(categoryList, (category) => category.name === data[categoryType]).code;
} else {
return undefined;
}
}
setCurrentProfile(index, data) {
if (!this.profile.medium || !this.profile.medium.length) {
this.profile.medium = [];
}
switch (index) {
case 0:
this.profile.syllabus = [data.framework];
this.profile.board = [data.board];
this.setMedium(true, data.medium);
this.profile.subject = [];
this.setGrade(true, data.gradeLevel);
break;
case 1:
this.profile.board = [data.board];
this.setMedium(true, data.medium);
this.profile.subject = [];
this.setGrade(true, data.gradeLevel);
break;
case 2:
this.setMedium(false, data.medium);
break;
case 3:
this.setGrade(false, data.gradeLevel);
break;
}
this.editProfile();
}
checkProfileData(data, profile) {
if (data && data.framework) {
const getSuggestedFrameworksRequest: GetSuggestedFrameworksRequest = {
language: this.translate.currentLang,
requiredCategories: FrameworkCategoryCodesGroup.DEFAULT_FRAMEWORK_CATEGORIES
};
// Auto update the profile if that board/framework is listed in custodian framework list.
this.frameworkUtilService.getActiveChannelSuggestedFrameworkList(getSuggestedFrameworksRequest).toPromise()
.then((res: Framework[]) => {
this.isProfileUpdated = false;
res.forEach(element => {
// checking whether content data framework Id exists/valid in syllabus list
if (data.framework === element.identifier || data.board.indexOf(element.name) !== -1) {
data.framework = element.identifier;
this.isProfileUpdated = true;
const frameworkDetailsRequest: FrameworkDetailsRequest = {
frameworkId: element.identifier,
requiredCategories: FrameworkCategoryCodesGroup.DEFAULT_FRAMEWORK_CATEGORIES
};
this.frameworkService.getFrameworkDetails(frameworkDetailsRequest).toPromise()
.then((framework: Framework) => {
this.categories = framework.categories;
this.boardList = find(this.categories, (category) => category.code === 'board').terms;
this.mediumList = find(this.categories, (category) => category.code === 'medium').terms;
this.gradeList = find(this.categories, (category) => category.code === 'gradeLevel').terms;
if (data.board) {
data.board = this.findCode(this.boardList, data, 'board');
}
if (data.medium) {
if (typeof data.medium === 'string') {
data.medium = [this.findCode(this.mediumList, data, 'medium')];
} else {
data.medium = map(data.medium, (dataMedium) => {
return find(this.mediumList, (medium) => medium.name === dataMedium).code;
});
}
}
if (data.gradeLevel && data.gradeLevel.length) {
data.gradeLevel = map(data.gradeLevel, (dataGrade) => {
return find(this.gradeList, (grade) => grade.name === dataGrade).code;
});
}
if (profile && profile.syllabus && profile.syllabus[0] && data.framework === profile.syllabus[0]) {
if (data.board) {
if (profile.board && !(profile.board.length > 1) && data.board === profile.board[0]) {
if (data.medium) {
let existingMedium = false;
for (let i = 0; i < data.medium.length; i++) {
const mediumExists = find(profile.medium, (medium) => {
return medium === data.medium[i];
});
if (!mediumExists) {
break;
}
existingMedium = true;
}
if (!existingMedium) {
this.setCurrentProfile(2, data);
}
if (data.gradeLevel && data.gradeLevel.length) {
let existingGrade = false;
for (let i = 0; i < data.gradeLevel.length; i++) {
const gradeExists = find(profile.grade, (grade) => {
return grade === data.gradeLevel[i];
});
if (!gradeExists) {
break;
}
existingGrade = true;
}
if (!existingGrade) {
this.setCurrentProfile(3, data);
}
}
}
} else {
this.setCurrentProfile(1, data);
}
}
} else {
this.setCurrentProfile(0, data);
}
}).catch((err) => {
if (NetworkError.isInstance(err)) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
}
});
return;
}
});
})
.catch((err) => {
if (NetworkError.isInstance(err)) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
}
});
}
}
editProfile() {
const req: Profile = {
board: this.profile.board,
grade: this.profile.grade,
medium: this.profile.medium,
subject: this.profile.subject,
uid: this.profile.uid,
handle: this.profile.handle,
profileType: this.profile.profileType,
source: this.profile.source,
createdAt: this.profile.createdAt,
syllabus: this.profile.syllabus
};
if (this.profile.grade && this.profile.grade.length > 0) {
this.profile.grade.forEach(gradeCode => {
for (let i = 0; i < this.gradeList.length; i++) {
if (this.gradeList[i].code === gradeCode) {
req.gradeValue = this.profile.gradeValue;
req.gradeValue[this.gradeList[i].code] = this.gradeList[i].name;
break;
}
}
});
}
this.profileService.updateProfile(req).toPromise()
.then((res: any) => {
if (res.syllabus && res.syllabus.length && res.board && res.board.length
&& res.grade && res.grade.length && res.medium && res.medium.length) {
this.events.publish(AppGlobalService.USER_INFO_UPDATED);
this.events.publish('refresh:profile');
this.appGlobalService.setOnBoardingCompleted();
}
this.commonUtilService.handleToTopicBasedNotification();
this.appGlobalService.guestUserProfile = res;
this.telemetryGeneratorService.generateProfilePopulatedTelemetry(PageId.DIAL_CODE_SCAN_RESULT,
req, 'auto');
})
.catch(() => {
});
}
showFilter() {
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
InteractSubtype.FILTER_BUTTON_CLICKED,
Environment.HOME,
this.source || PageId.SEARCH);
const filterCriteriaData = this.responseData.filterCriteria;
filterCriteriaData.facetFilters.forEach(element => {
this.searchFilterConfig.forEach(item => {
if (element.name === item.code) {
element.translatedName = this.commonUtilService.getTranslatedValue(item.translations, item.name);
return;
}
});
this.initialFilterCriteria.facetFilters.forEach(newElement => {
this.searchFilterConfig.forEach(item => {
if (newElement.name === item.code) {
newElement.translatedName = this.commonUtilService.getTranslatedValue(item.translations, item.name);
return;
}
});
});
this.router.navigate(['/filters'], {
state: {
filterCriteria: this.responseData.filterCriteria,
initialfilterCriteria: this.initialFilterCriteria,
supportedUserTypesConfig: this.supportedUserTypesConfig,
source: this.source
}
});
});
}
applyFilter(offset?: number) {
this.showAddToGroupButtons = false;
this.showLoader = true;
this.responseData.filterCriteria.mode = 'hard';
this.responseData.filterCriteria.searchType = SearchType.FILTER;
const modifiedCriteria = JSON.parse(JSON.stringify(this.responseData.filterCriteria));
modifiedCriteria.facetFilters.forEach(facet => {
if (facet.values && facet.values.length > 0) {
if (facet.name === 'audience') {
facet.values = ContentUtil.getAudienceFilter(facet, this.supportedUserTypesConfig);
}
}
});
modifiedCriteria.offset = offset ? offset : 0;
this.contentService.searchContent(modifiedCriteria).toPromise()
.then((responseData: ContentSearchResult) => {
this.totalCount = responseData.count
this.zone.run(() => {
this.responseData = responseData;
if (responseData) {
if (this.isDialCodeSearch) {
this.processDialCodeResult(responseData.contentDataList);
} else {
if (this.searchContentResult && this.searchContentResult.length > 0 && modifiedCriteria.offset > 0 && responseData.contentDataList.length > 0) {
responseData.contentDataList.forEach(ele => {
this.searchContentResult.push(ele);
})
} else {
this.searchContentResult = responseData.contentDataList;
}
this.isEmptyResult = !(this.searchContentResult && this.searchContentResult.length > 0);
const values = new Map();
values.from = this.source;
values.searchCount = this.responseData.length;
values.searchCriteria = this.responseData.filterCriteria;
this.telemetryGeneratorService.generateExtraInfoTelemetry(values, PageId.SEARCH);
}
if (this.responseData.filterCriteria && this.responseData.filterCriteria.facetFilters) {
this.fetchPrimaryCategoryFilters(this.responseData.filterCriteria.facetFilters);
}
this.updateFilterIcon();
} else {
this.isEmptyResult = true;
}
this.showLoader = false;
});
}).catch(() => {
this.zone.run(() => {
this.showLoader = false;
});
});
}
handleCancel() {
this.searchKeywords = '';
this.searchBar.setFocus();
this.searchContentResult = undefined;
this.filterIcon = false;
this.isEmptyResult = false;
}
handleSearch(shouldApplyProfileFilter = false, offset?: number) {
if (offset == undefined) {
this.scrollToTop();
}
if (this.searchKeywords.length < 3 && this.source !== PageId.GROUP_DETAIL && !this.preAppliedFilter) {
return;
}
this.showAddToGroupButtons = false;
this.addSearchHistoryEntry();
this.showLoader = true;
(window as any).Keyboard.hide();
const facets = this.searchFilterConfig.reduce((acc, filterConfig) => {
acc.push(filterConfig.code);
return acc;
}, []);
const contentSearchRequest: ContentSearchCriteria = {
searchType: SearchType.SEARCH,
query: this.searchKeywords,
primaryCategories: this.primaryCategories,
facets: facets ? facets : Search.FACETS,
mode: 'soft',
framework: this.currentFrameworkId,
languageCode: this.selectedLanguageCode,
limit: 10,
offset: offset
};
if(this.rootOrgId){
contentSearchRequest.channel = [this.rootOrgId]
}
if (this.profile && this.source === PageId.GROUP_DETAIL && shouldApplyProfileFilter) {
if (this.profile.board && this.profile.board.length) {
contentSearchRequest.board = applyProfileFilter(this.appGlobalService, this.profile.board,
contentSearchRequest.board, 'board');
}
if (this.profile.medium && this.profile.medium.length) {
contentSearchRequest.medium = applyProfileFilter(this.appGlobalService, this.profile.medium,
contentSearchRequest.medium, 'medium');
}
if (this.profile.grade && this.profile.grade.length) {
contentSearchRequest.grade = applyProfileFilter(this.appGlobalService, this.profile.grade,
contentSearchRequest.grade, 'gradeLevel');
}
}
this.isDialCodeSearch = false;
this.dialCodeContentResult = undefined;
this.dialCodeResult = undefined;
if (!this.corRelationList) {
this.corRelationList = [];
}
let searchQuery;
if (this.activityTypeData || this.preAppliedFilter) {
const query = this.activityTypeData ? this.activityTypeData.searchQuery :
JSON.stringify({ request: this.preAppliedFilter });
searchQuery = updateFilterInSearchQuery(query, undefined, false);
searchQuery.request.query = this.searchKeywords;
searchQuery.request.facets = contentSearchRequest.facets;
if (this.activityTypeData) {
searchQuery.request.mode = contentSearchRequest.mode;
}
searchQuery.request.searchType = SearchType.FILTER;
const profileFilters = {
board: contentSearchRequest.board || [],
medium: contentSearchRequest.medium || [],
gradeLevel: contentSearchRequest.grade || []
};
if (this.activityTypeData) {
searchQuery.request.filters = {
...searchQuery.request.filters,
...profileFilters,
board: [...(searchQuery.request.filters.board || []), ...(profileFilters.board || [])],
medium: [...(searchQuery.request.filters.medium || []), ...(profileFilters.medium || [])],
gradeLevel: [...(searchQuery.request.filters.gradeLevel || []), ...(profileFilters.gradeLevel || [])]
};
} else {
searchQuery.request.filters = {
...searchQuery.request.filters
};
}
}
this.contentService.searchContent(contentSearchRequest, searchQuery).toPromise()
.then((response: ContentSearchResult) => {
this.totalCount = response.count;
this.zone.run(() => {
this.responseData = response;
this.preAppliedFilter = undefined;
if (response) {
if (!this.initialFilterCriteria) {
this.initialFilterCriteria = JSON.parse(JSON.stringify(this.responseData.filterCriteria));
}
this.addCorRelation(response.responseMessageId, 'API');
if (this.searchContentResult && this.searchContentResult.length > 0 && contentSearchRequest.offset > 0 && this.responseData.contentDataList.length > 0) {
this.responseData.contentDataList.forEach(ele => {
this.searchContentResult.push(ele);
})
} else {
this.searchContentResult = response.contentDataList;
}
this.isEmptyResult = !this.searchContentResult || this.searchContentResult.length === 0;
this.updateFilterIcon();
this.generateLogEvent(response);
const values = new Map();
values.from = this.source;
values.searchCount = this.searchContentResult ? this.searchContentResult.length : 0;
values.searchCriteria = response.request;
this.telemetryGeneratorService.generateExtraInfoTelemetry(values, PageId.SEARCH);
if (response.filterCriteria && response.filterCriteria.facetFilters) {
this.fetchPrimaryCategoryFilters(response.filterCriteria.facetFilters);
}
} else {
this.isEmptyResult = true;
}
this.showEmptyMessage = this.searchContentResult.length === 0;
this.showLoader = false;
});
}).catch(() => {
this.zone.run(() => {
this.showLoader = false;
if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
}
});
});
}
private addSearchHistoryEntry() {
if (!this.searchKeywords) {
return;
}
this.searchHistoryService
.addEntry({
query: this.searchKeywords,
namespace: SearchHistoryNamespaces.LIBRARY
})
.toPromise();
}
private async checkRetiredOpenBatch(content: any, layoutName?: string) {
this.showLoader = false;
this.loader = await this.commonUtilService.getLoader();
await this.loader.present();
this.loader.onDidDismiss(() => { this.loader = undefined; });
let retiredBatches: Array<any> = [];
let anyOpenBatch = false;
await this.getEnrolledCourses(true);
this.enrolledCourses = this.enrolledCourses || [];
if (layoutName !== ContentCard.LAYOUT_INPROGRESS) {
retiredBatches = this.enrolledCourses.filter((element) => {
if (element.contentId === content.identifier && element.batch.status === 1 && element.cProgress !== 100) {
anyOpenBatch = true;
content.batch = element.batch;
}
if (element.contentId === content.identifier && element.batch.status === 2 && element.cProgress !== 100) {
return element;
}
});
}
if (anyOpenBatch || !retiredBatches.length) {
// open the batch directly
await this.showContentDetails(content, true);
} else if (retiredBatches.length) {
await this.navigateToBatchListPopup(content, layoutName, retiredBatches);
}
}
async navigateToBatchListPopup(content: any, layoutName?: string, retiredBatched?: any) {
const ongoingBatches = [];
const courseBatchesRequest: CourseBatchesRequest = {
filters: {
courseId: layoutName === ContentCard.LAYOUT_INPROGRESS ? content.contentId : content.identifier,
enrollmentType: CourseEnrollmentType.OPEN,
status: [CourseBatchStatus.IN_PROGRESS]
},
sort_by: { createdDate: SortOrder.DESC },
fields: BatchConstants.REQUIRED_FIELDS
};
const reqvalues = new Map();
reqvalues.enrollReq = courseBatchesRequest;
if (this.commonUtilService.networkInfo.isNetworkAvailable) {
if (!this.guestUser) {
this.courseService.getCourseBatches(courseBatchesRequest).toPromise()
.then((res: Batch[]) => {
this.zone.run(async () => {
this.batches = res;
if (this.batches.length) {
this.batches.forEach((batch) => {
if (batch.status === 1) {
ongoingBatches.push(batch);
}
});
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
'ongoing-batch-popup',
Environment.HOME,
PageId.SEARCH, undefined,
reqvalues);
const popover = await this.popoverCtrl.create({
component: EnrollmentDetailsComponent,
componentProps: {
upcommingBatches: [],
ongoingBatches,
retiredBatched,
content
},
cssClass: 'enrollement-popover'
});
await this.loader.dismiss();
await popover.present();
const { data } = await popover.onDidDismiss();
if (data && data.isEnrolled) {
this.getEnrolledCourses();
}
if (data && typeof data.isEnrolled === 'function') {
(data.isEnrolled as Function).call(this);
}
} else {
await this.loader.dismiss();
this.showContentDetails(content, true);
}
});
})
.catch((error: any) => {
console.log('error while fetching course batches ==>', error);
});
}
} else {
if (this.loader) {
this.loader.dismiss();
}
this.commonUtilService.showToast('ERROR_NO_INTERNET_MESSAGE');
}
}
init() {
this.generateImpressionEvent();
const values = new Map();
values.from = this.source;
this.telemetryGeneratorService.generateExtraInfoTelemetry(values, PageId.SEARCH);
if (this.dialCode !== undefined && this.dialCode.length > 0) {
this.getContentForDialCode();
}
this.event.subscribe('search.applyFilter', (filterCriteria) => {
this.responseData.filterCriteria = filterCriteria;
this.primaryCategoryFilters = undefined;
this.applyFilter();
});
}
async getContentForDialCode() {
if (this.dialCode === undefined || this.dialCode.length === 0) {
return;
}
this.isDialCodeSearch = true;
this.showLoader = true;
const primaryCategories = await this.formAndFrameworkUtilService.getSupportedContentFilterConfig(
ContentFilterConfig.NAME_DIALCODE);
this.primaryCategories = primaryCategories;
// Page API START
const pageAssemblefilter: PageAssembleFilter = {};
pageAssemblefilter.dialcodes = this.dialCode;
pageAssemblefilter.primaryCategory = this.primaryCategories;
const pageAssembleCriteria: PageAssembleCriteria = {
name: PageName.DIAL_CODE,
filters: pageAssemblefilter,
source: 'app',
from: CachedItemRequestSourceFrom.SERVER
};
if (this.profile && this.profile.board && this.profile.board.length) {
pageAssembleCriteria.userProfile = { board: applyProfileFilter(this.appGlobalService, this.profile.board, [], 'board') };
}
this.pageService.getPageAssemble(pageAssembleCriteria).toPromise()
.then((res: any) => {
this.zone.run(() => {
const sections = res.sections;
if (sections && sections.length) {
this.addCorRelation(sections[0].resmsgId, 'API');
this.processDialCodeResult(sections);
}
this.showLoader = false;
});
}).catch(() => {
this.zone.run(() => {
this.showLoader = false;
if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
const corRelationList: Array<CorrelationData> = [];
corRelationList.push({ id: this.dialCode, type: CorReleationDataType.QR });
this.telemetryGeneratorService.generateImpressionTelemetry(
AuditType.TOAST_SEEN,
ImpressionSubtype.OFFLINE_MODE,
PageId.SCAN_OR_MANUAL,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
undefined, undefined, undefined, undefined,
corRelationList
);
} else {
this.commonUtilService.showToast('SOMETHING_WENT_WRONG');
}
this.location.back();
});
});
}
generateInteractEvent(identifier, contentType, pkgVersion, index) {
const values = new Map();
values.SearchPhrase = this.searchKeywords;
values.PositionClicked = index;
values.source = this.source;
if (this.isDialCodeSearch) {
values.root = false;
}
const telemetryObject = new TelemetryObject(identifier, contentType, pkgVersion);
if (!this.corRelationList) {
this.corRelationList = [];
}
this.corRelationList.push({
id: 'SearchResult',
type: 'Section'
});
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
InteractSubtype.CONTENT_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
this.isDialCodeSearch ? PageId.DIAL_SEARCH : (this.source || PageId.SEARCH),
telemetryObject,
values,
ContentUtil.generateRollUp(undefined, identifier),
this.corRelationList);
}
generateQRSessionEndEvent(pageId: string, qrData: string) {
if (pageId !== undefined) {
const telemetryObject = new TelemetryObject(qrData, 'qr', '');
this.telemetryGeneratorService.generateEndTelemetry(
'qr',
Mode.PLAY,
pageId,
Environment.HOME,
telemetryObject,
undefined,
this.corRelationList);
}
}
processDialCodeResult(dialResult) {
console.log('dialresult', dialResult);
const displayDialCodeResult = [];
dialResult.forEach(searchResult => {
const collectionArray: Array<any> = searchResult.collections;
const contentArray: Array<any> = searchResult.contents;
const addedContent = new Array<any>();
const dialCodeResultObj = {
isCourse: false,
dialCodeResult: [],
dialCodeContentResult: []
};
const dialCodeCourseResultObj = {
isCourse: true,
dialCodeResult: [],
dialCodeContentResult: []
};
// Handle localization
if (searchResult.display) {
dialCodeResultObj['name'] = this.commonUtilService.getTranslatedValue(searchResult.display, searchResult.name);
} else {
dialCodeResultObj['name'] = searchResult.name;
}
if (collectionArray && collectionArray.length > 0) {
collectionArray.forEach((collection) => {
contentArray.forEach((content) => {
if (collection.childNodes.includes(content.identifier)) {
if (collection.content === undefined) {
collection.content = [];
}
collection.content.push(content);
addedContent.push(content.identifier);
}
});
dialCodeResultObj.dialCodeResult.push(collection);
});
displayDialCodeResult.push(dialCodeResultObj);
}
let isAllContentMappedToCollection = false;
if (contentArray) {
isAllContentMappedToCollection = contentArray.length === addedContent.length;
}
if (!isAllContentMappedToCollection && contentArray && contentArray.length > 1) {
const dialCodeContentResult = [];
const dialCodeContentCourseResult = []; // content type course
contentArray.forEach((content) => {
if (content.contentType === CsContentType.COURSE) {
dialCodeContentCourseResult.push(content);
} else if (addedContent.indexOf(content.identifier) < 0) {
dialCodeContentResult.push(content);
}
});
if (dialCodeContentCourseResult.length) {
dialCodeCourseResultObj.dialCodeContentResult = dialCodeContentCourseResult;
if (displayDialCodeResult && !(displayDialCodeResult.length > 0)) {
displayDialCodeResult.push(dialCodeCourseResultObj);
} else {
displayDialCodeResult[0].dialCodeContentResult = dialCodeContentCourseResult;
}
}
if (dialCodeContentResult.length) {
dialCodeResultObj.dialCodeContentResult = dialCodeContentResult;
displayDialCodeResult.push(dialCodeResultObj);
}
}
if (displayDialCodeResult.length && displayDialCodeResult[0].dialCodeResult) {
this.generateImpressionEvent(displayDialCodeResult[0].dialCodeResult);
}
let isParentCheckStarted = false;
if (dialCodeResultObj.dialCodeResult.length === 1 && dialCodeResultObj.dialCodeResult[0].content.length === 1
&& isAllContentMappedToCollection) {
this.parentContent = dialCodeResultObj.dialCodeResult[0];
this.childContent = dialCodeResultObj.dialCodeResult[0].content[0];
this.checkParent(dialCodeResultObj.dialCodeResult[0], dialCodeResultObj.dialCodeResult[0].content[0]);
isParentCheckStarted = true;
}
this.generateQRScanSuccessInteractEvent((contentArray ? contentArray.length : 0), this.dialCode);
if (contentArray && contentArray.length === 1 && !isParentCheckStarted) {
this.isSingleContent = true;
this.openContent(contentArray[0], contentArray[0], 0, true);
// return;
}
});
this.displayDialCodeResult = displayDialCodeResult;
if (this.displayDialCodeResult.length === 0 && !this.isSingleContent) {
this.location.back();
if (this.shouldGenerateEndTelemetry) {
this.generateQRSessionEndEvent(this.source, this.dialCode);
}
this.telemetryGeneratorService.generateImpressionTelemetry(ImpressionType.VIEW,
'',
PageId.DIAL_NOT_LINKED,
Environment.HOME);
this.commonUtilService.showContentComingSoonAlert(this.source, undefined, this.dialCode);
}
}
generateQRScanSuccessInteractEvent(dialCodeResultCount, dialCode) {
const values = new Map();
values.networkAvailable = this.commonUtilService.networkInfo.isNetworkAvailable ? 'Y' : 'N';
values.scannedData = dialCode;
values.count = dialCodeResultCount;
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.OTHER,
InteractSubtype.DIAL_SEARCH_RESULT_FOUND,
this.source ? this.source : PageId.SEARCH,
PageId.SEARCH,
undefined,
values
);
}
updateFilterIcon() {
if (!this.responseData.filterCriteria) {
return;
}
this.responseData.filterCriteria.facetFilters.forEach(facet => {
if (facet.values && facet.values.length > 0) {
facet.values.forEach(value => {
if (value.apply) {
this.isFilterApplied = true;
}
});
}
});
if (this.isFilterApplied) {
this.filterIcon = './assets/imgs/ic_action_filter_applied.png';
this.corRelationList.push({
id: 'filter',
type: CorReleationDataType.DISCOVERY_TYPE
});
} else {
this.filterIcon = './assets/imgs/ic_action_filter.png';
}
if (this.isEmptyResult) {
this.filterIcon = undefined;
}
}
checkParent(parent, child) {
const identifier = parent.identifier;
const contentRequest: ContentDetailRequest = {
contentId: identifier,
objectType: parent.objectType
};
this.contentService.getContentDetails(contentRequest).toPromise()
.then((data: Content) => {
if (data) {
if (data.isAvailableLocally) {
this.zone.run(() => {
this.showContentDetails(child, false, true);
});
} else {
this.subscribeSdkEvent();
this.downloadParentContent(parent);
this.profile = this.appGlobalService.getCurrentUser();
this.checkProfileData(data.contentData, this.profile);
setTimeout(() => {
this.showContentDetails(this.childContent, false, false);
}, 400);
}
} else {
this.zone.run(() => {
this.showContentDetails(child);
});
}
}).catch((err) => {
if (NetworkError.isInstance(err)) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
}
});
}
downloadParentContent(parent) {
this.zone.run(() => {
this.downloadProgress = 0;
this.isDownloadStarted = true;
});
const option: ContentImportRequest = {
contentImportArray: this.getImportContentRequestBody([parent.identifier], false),
contentStatusArray: ['Live'],
fields: ['appIcon', 'name', 'subject', 'size', 'gradeLevel']
};
// Call content service
this.contentService.importContent(option).toPromise()
.then((data: ContentImportResponse[]) => {
this.zone.run(() => {
if (data && data.length && this.isDownloadStarted) {
data.forEach((value) => {
if (value.status === ContentImportStatus.ENQUEUED_FOR_DOWNLOAD) {
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.OTHER,
InteractSubtype.LOADING_SPINE,
this.source === PageId.USER_TYPE_SELECTION ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_SEARCH,
undefined,
undefined,
undefined,
this.corRelationList
);
this.queuedIdentifiers.push(value.identifier);
}
});
}
if (this.queuedIdentifiers.length === 0) {
this.showLoading = false;
this.isDownloadStarted = false;
if (this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_CONTENT_NOT_AVAILABLE');
} else {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
}
}
});
})
.catch((err) => {
if (NetworkError.isInstance(err)) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
this.showLoading = false;
this.isDownloadStarted = false;
}
});
}
/**
* Subscribe Sunbird-SDK event to get content download progress
*/
subscribeSdkEvent() {
this.eventSubscription = this.eventsBusService.events()
.subscribe((event: EventsBusEvent) => {
this.zone.run(() => {
if (event.type === DownloadEventType.PROGRESS && event.payload.progress) {
const downloadEvent = event as DownloadProgress;
this.downloadProgress = downloadEvent.payload.progress === -1 ? 0 : downloadEvent.payload.progress;
this.loadingDisplayText = this.commonUtilService.translateMessage('LOADING_CONTENT') + ' ' + this.downloadProgress + ' %';
if (this.downloadProgress === 100) {
this.loadingDisplayText = this.commonUtilService.translateMessage('LOADING_CONTENT') + ' ';
}
}
if (event.type === ContentEventType.IMPORT_PROGRESS) {
const totalCountMsg = Math.floor((event.payload.currentCount / event.payload.totalCount) * 100) +
'% (' + event.payload.currentCount + ' / ' + event.payload.totalCount + ')';
this.loadingDisplayText = this.commonUtilService.translateMessage('EXTRACTING_CONTENT', totalCountMsg);
if (event.payload.currentCount === event.payload.totalCount) {
let timer = 30;
const interval = setInterval(() => {
this.loadingDisplayText = `Getting things ready in ${timer--} seconds`;
if (timer === 0) {
this.loadingDisplayText = 'Getting things ready';
clearInterval(interval);
}
}, 1000);
}
}
if (event.payload && event.type === ContentEventType.IMPORT_COMPLETED) {
if (this.queuedIdentifiers.length && this.isDownloadStarted) {
if (this.queuedIdentifiers.includes(event.payload.contentId)) {
this.currentCount++;
}
if (this.queuedIdentifiers.length === this.currentCount) {
this.showLoading = false;
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.OTHER,
InteractSubtype.LOADING_SPINE_COMPLETED,
this.source === PageId.USER_TYPE_SELECTION ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_SEARCH,
undefined,
undefined,
undefined,
this.corRelationList
);
this.events.publish('savedResources:update', {
update: true
});
}
} else {
this.events.publish('savedResources:update', {
update: true
});
}
}
});
}) as any;
}
/**
* Function to get import content api request params
*
* @param {Array<string>} identifiers contains list of content identifier(s)
* @param {boolean} isChild
*/
getImportContentRequestBody(identifiers: Array<string>, isChild: boolean): Array<ContentImport> {
const requestParams = [];
const folderPath = this.platform.is('ios') ? cordova.file.documentsDirectory : cordova.file.externalDataDirectory;
identifiers.forEach((value) => {
requestParams.push({
isChildContent: isChild,
// TODO - check with Anil for destination path
destinationFolder: folderPath,
contentId: value,
correlationData: this.corRelationList !== undefined ? this.corRelationList : []
});
});
return requestParams;
}
cancelDownload() {
this.contentService.cancelDownload(this.parentContent.identifier).toPromise().then(() => {
this.zone.run(() => {
this.showLoading = false;
if (this.isSingleContent) {
this.location.back();
}
});
}).catch(() => {
this.zone.run(() => {
this.showLoading = false;
if (this.isSingleContent) {
this.location.back();
}
});
});
}
checkUserSession() {
this.profile = this.appGlobalService.getCurrentUser();
}
private addCorRelation(id: string, type: string) {
if (this.corRelationList === undefined || this.corRelationList === null) {
this.corRelationList = new Array<CorrelationData>();
}
const corRelation: CorrelationData = new CorrelationData();
corRelation.id = id || '';
corRelation.type = type;
this.corRelationList.push(corRelation);
}
private generateImpressionEvent(dialCodeResult?) {
if (this.dialCode) {
const corRelationList: Array<CorrelationData> = [];
corRelationList.push({ id: this.dialCode, type: CorReleationDataType.QR });
corRelationList.push({ id: dialCodeResult ? dialCodeResult.length.toString() : '1', type: CorReleationDataType.COUNT_BOOK });
this.telemetryGeneratorService.generatePageLoadedTelemetry(
PageId.QR_BOOK_RESULT,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
undefined,
undefined,
undefined,
undefined,
corRelationList
);
} else {
this.telemetryGeneratorService.generateImpressionTelemetry(
ImpressionType.SEARCH, '',
this.source ? this.source : PageId.SEARCH,
Environment.HOME, '', '', '',
undefined,
this.corRelationList);
}
}
private generateLogEvent(searchResult) {
if (searchResult != null) {
const contentArray: Array<any> = searchResult.contentDataList;
const params = new Array<any>();
const paramsMap = new Map();
paramsMap.SearchResults = contentArray ? contentArray.length : 0;
paramsMap.SearchCriteria = searchResult.request;
params.push(paramsMap);
this.telemetryGeneratorService.generateLogEvent(LogLevel.INFO,
this.source ? this.source : PageId.SEARCH,
Environment.HOME,
ImpressionType.SEARCH,
params);
}
}
/**
* To get enrolled course(s) of logged-in user.
*
* It internally calls course handler of genie sdk
*/
private getEnrolledCourses(returnRefreshedCourses: boolean = false): Promise<any> {
this.showLoader = true;
const option: FetchEnrolledCourseRequest = {
userId: this.userId,
returnFreshCourses: returnRefreshedCourses
};
return this.courseService.getEnrolledCourses(option).toPromise()
.then((enrolledCourses) => {
if (enrolledCourses) {
this.zone.run(() => {
this.enrolledCourses = enrolledCourses ? enrolledCourses : [];
if (this.enrolledCourses.length > 0) {
const courseList: Array<Course> = [];
for (const course of this.enrolledCourses) {
courseList.push(course);
}
this.appGlobalService.setEnrolledCourseList(courseList);
}
this.showLoader = false;
});
return enrolledCourses;
}
}, () => {
this.showLoader = false;
return [];
});
}
scrollToTop() {
this.contentView.scrollToTop();
}
goBack() {
if (this.displayDialCodeResult && this.displayDialCodeResult[0].dialCodeResult && this.displayDialCodeResult[0].dialCodeResult.length) {
this.telemetryGeneratorService.generateBackClickedNewTelemetry(
false,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_BOOK_RESULT
);
} else {
this.telemetryGeneratorService.generateBackClickedTelemetry(ImpressionType.SEARCH,
Environment.HOME, true, undefined, this.corRelationList);
}
this.navigateToPreviousPage();
}
getContentCount(displayDialCodeResult) {
let totalCount = 0;
displayDialCodeResult.forEach(resultlist => {
if (resultlist.dialCodeResult.length) {
for (let i = 0; i < resultlist.dialCodeResult.length; i++) {
if (resultlist.dialCodeResult[i].content && resultlist.dialCodeResult[i].content.length) {
totalCount += resultlist.dialCodeResult[i].content.length;
}
}
}
if (resultlist.dialCodeContentResult.length) {
totalCount += resultlist.dialCodeContentResult.length;
}
});
return totalCount;
}
async addActivityToGroup() {
const content = this.searchContentResult.find((c) => c.selected);
if (this.activityList) {
const activityExist = this.activityList.find(activity => activity.id === content.identifier);
if (activityExist) {
this.commonUtilService.showToast('ACTIVITY_ALREADY_ADDED_IN_GROUP');
return;
}
}
this.groupHandlerService.addActivityToGroup(
this.groupId,
content.identifier,
(this.activityTypeData && this.activityTypeData.activityType) || {},
PageId.SEARCH,
this.corRelationList,
-2);
}
openSelectedContent() {
let index = 0;
let content;
this.searchContentResult.forEach((element, idx) => {
if (element.selected) {
index = idx;
content = element;
}
});
this.openContent(undefined, content, index, undefined, false);
}
private updateCsGroupAddableBloc(params, pageId) {
const cData = {
type: CorReleationDataType.GROUP_ID,
id: CsGroupAddableBloc.instance.state.groupId
}
params.corRelation.push(cData)
CsGroupAddableBloc.instance.updateState(
{
pageIds: [pageId],
groupId: CsGroupAddableBloc.instance.state.groupId,
params: {
...CsGroupAddableBloc.instance.state.params,
corRelation: params.corRelation,
noOfPagesToRevertOnSuccess: -3,
activityType: (this.activityTypeData && this.activityTypeData.activityType) || {}
}
}
);
}
searchOnFocus() {
this.enableSearch = true;
this.searchInfolVisibility = 'hide';
this.headerService.showHeaderWithBackButton(null, this.commonUtilService.translateMessage('SEARCH_IN_APP', { 'app_name': this.appName}));
this.appGlobalService.isDiscoverBackEnabled = true;
}
handleHeaderEvents($event) {
switch ($event.name) {
case 'back':
if (this.isFromGroupFlow) {
this.location.back()
} else if(this.enableSearch) {
this.enableSearch = false;
this.searchInfolVisibility = 'show';
this.headerService.showHeaderWithHomeButton(['download', 'notification']);
this.appGlobalService.isDiscoverBackEnabled = false;
} else if (this.selectedSwitchableTab === SwitchableTabsConfig.HOME_DISCOVER_TABS_CONFIG) {
break;
} else {
this.location.back()
}
break;
case 'notification':
this.redirectToNotifications();
break;
default: console.warn('Use Proper Event name');
}
}
fetchPrimaryCategoryFilters(facetFilters) {
if (!this.primaryCategoryFilters) {
setTimeout(() => {
for (let index = 0; index < facetFilters.length; index++) {
if (facetFilters[index].name === 'primaryCategory') {
this.primaryCategoryFilters = facetFilters[index].values;
break;
}
}
});
}
}
handleFilterSelect(event) {
if (!event || !event.data || !event.data.length) {
return;
}
if (this.initialFilterCriteria) {
this.responseData.filterCriteria = JSON.parse(JSON.stringify(this.initialFilterCriteria));
}
let primaryCategoryFilter = (this.responseData.filterCriteria as ContentSearchCriteria).facetFilters.find(facet => {
return facet.name === 'primaryCategory'
});
if (!primaryCategoryFilter) {
return;
}
let primaryCategoryFilterValue = primaryCategoryFilter.values.find(f => {
return f.name === (event.data[0].value && event.data[0].value.name);
})
if (!primaryCategoryFilterValue) {
return
}
if (!primaryCategoryFilterValue.apply) {
this.selectedPrimaryCategoryFilter = primaryCategoryFilterValue;
primaryCategoryFilterValue.apply = true;
this.applyFilter();
}
}
redirectToNotifications() {
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.NOTIFICATION_CLICKED,
Environment.HOME,
PageId.SEARCH);
this.router.navigate([RouterLinks.NOTIFICATION]);
}
private enableHeaderEvents(){
if(!this.headerObservable){
this.headerObservable = this.headerService.headerEventEmitted$.subscribe(eventName => {
this.handleHeaderEvents(eventName);
});
}
}
private disableHeaderEvents(){
if (this.headerObservable) {
this.headerObservable.unsubscribe();
this.headerObservable = undefined;
}
}
tabViewWillEnter() {
if (this.isFromGroupFlow || this.searchWithBackButton) {
this.headerService.showHeaderWithBackButton
(null, this.commonUtilService.translateMessage('SEARCH_IN_APP', { 'app_name': this.appName}));
} else {
this.headerService.showHeaderWithHomeButton(['download', 'notification']);
}
this.enableHeaderEvents();
}
}
<ion-content #contentView class="search-bg">
<div class="spinner-div" *ngIf="refresh">
<ion-spinner icon="spiral" class="refreshspinner"></ion-spinner>
</div>
<ion-refresher #refresher slot="fixed" (ionRefresh)="discoverCmp.doRefresh($event)">
<ion-refresher-content refreshingSpinner="circles"></ion-refresher-content>
</ion-refresher>
<div class="container-focus sticky-position" *ngIf="!hideSearchOption" [ngClass]="{'pt-0': searchInfolVisibility==='hide', '': searchInfolVisibility==='show'}">
<div class="search-info pt-8 mx-24">
<div [@labelVisibility]="searchInfolVisibility" [attr.aria-hidden] = "searchInfolVisibility === 'hide'">
<strong class="title" role="heading" aria-level="1">{{'SEARCH_IN_APP' | translate: {'app_name': appName} }}</strong>
<p class="description">{{'SEARCH_IN_APP_DESCRIPTION' | translate: {'app_name': appName} }}</p>
</div>
</div>
<div class="search-container" [ngClass]="{'search-filter': filterIcon, '': !filterIcon}">
<div class="search-input d-flex">
<ion-input type="search" *ngIf="!dialCode" #searchInput dir="{{commonUtilService.getAppDirection()}}"
(keyup.enter)="handleSearch()" (ionFocus)="searchOnFocus()"
(ngModelChange)="searchContentResult = undefined; filterIcon = false; isEmptyResult = false"
[(ngModel)]="searchKeywords" [placeholder]="'SEARCH_HINT' | translate">
</ion-input>
<button (click)="handleSearch()" aria-label="search" *ngIf="!filterIcon || isFromGroupFlow">
<img src="assets/imgs/search.svg" alt="search">
</button>
<button (click)="handleCancel()" aria-label="clear search" *ngIf="filterIcon && searchKeywords">
<img src="assets/imgs/ic_action_close.svg" alt="clear search">
</button>
</div>
<div class="filter-btn" *ngIf="filterIcon">
<button (click)="showFilter()" aria-label="search filter">
<img src="assets/imgs/filter.svg" alt="search filter">
</button>
</div>
</div>
</div>
<ng-container *ngIf="enableSearch">
<ng-container *ngIf="searchHistory$">
<ng-container *ngIf="searchHistory$ | async as searchHistory">
<ng-container *ngIf="!(
showLoader ||
isEmptyResult ||
displayDialCodeResult ||
(dialCodeContentResult && dialCodeContentResult.length) ||
(searchContentResult && searchContentResult.length) ||
(!showLoader && showEmptyMessage)
)">
<ng-container *ngIf="!searchHistory.length && !searchKeywords">
<div class="sb-no-search-history text-center">
<span>
{{'SEARCH_TO_FIND_CONTENT' | translate: {'%s': appName} }}
</span>
</div>
</ng-container>
<ng-container *ngIf="searchKeywords">
<div class="sb-search-history-entry sb-search-header-meta row">
<div class="col-auto invisible">
<img src="assets/imgs/icon_recent.svg" alt="recent">
</div>
<div class="col" (click)="handleSearch()">
{{'FRMELEMENTS_LBL_SEARCH_SUB_HEADING' | translate: {'appName': appName, 'searchText': searchKeywords} }}
</div>
<div class="col-auto">
<img style="width: 0.875rem; height: 0.875rem" src="./assets/imgs/ic_action_search.svg" alt="search">
</div>
</div>
</ng-container>
<ng-container *ngIf="searchHistory.length">
<div (click)="onSearchHistoryTap(searchEntry)" *ngFor="let searchEntry of searchHistory"
class="sb-search-history-entry row">
<div class="col-auto">
<img style="width: 0.875rem; height: 0.875rem" src="./assets/imgs/icon_recent.svg" alt="recent">
</div>
<div class="col">
{{searchEntry.query}}
</div>
<div class="col-auto">
<img style="width: 0.875rem; height: 0.875rem" src="./assets/imgs/ic_action_search_grey.svg" alt="search">
</div>
</div>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngIf="isEmptyResult">
<div class="sb-no-search-history">
<span>
{{ 'EMPTY_SEARCH_RESULTS' | translate }}
</span>
</div>
</ng-container>
<div class="m-n" *ngIf="showLoader">
<div class="skeleton-header">
<app-skeleton-item height="0.75rem" width="75%" style="height:0.75rem; width:75%;"></app-skeleton-item>
<app-skeleton-item height="0.75rem" width="40%" style="height:0.75rem; width:40%; margin-top:8px;"></app-skeleton-item>
</div>
<div class="skeleton-search-card" *ngFor="let i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13]">
<ion-avatar slot="end" class="skleton-avatar">
<app-skeleton-item height="3.5rem" width="3.5rem" style="height:3.5rem; width:3.5rem;"></app-skeleton-item>
</ion-avatar>
<div style=" flex: 22 auto;">
<app-skeleton-item height="0.75rem" width="40%" style="height:0.75rem; width:100%; padding-bottom: 8px;">
</app-skeleton-item>
<app-skeleton-item height="0.75rem" width="30%"
style="height:0.75rem; width:100%; padding-bottom: 8px;margin-top:8px;"></app-skeleton-item>
</div>
</div>
</div>
<!-- Testing here -->
<ion-list no-lines *ngIf="displayDialCodeResult" class="collection-list" class="search-bg">
<div *ngFor="let resultlist of displayDialCodeResult">
<!-- Course -->
<div
*ngIf="resultlist && resultlist.isCourse && resultlist.dialCodeContentResult && resultlist.dialCodeContentResult.length">
<div class="pt-8 px-8">
<p class="results-count" *ngIf="resultlist.dialCodeContentResult || resultlist.dialCodeResult">
{{'SHOWING_MULTIPLE_BOOK_RESULT' | translate:{'%s': getContentCount(displayDialCodeResult)} }}
<strong>{{ totalCount }} </strong>
</p>
</div>
<div class="sb-textbook-container">
<div class="sb-textbook-items">
<div class="sb-textbook-title-container">
<span class="textbook-title">
{{'COURSES' | translate}}
</span>
</div>
<div class="sb-card-container sb-card-textbook-container">
<div *ngFor="let content of resultlist.dialCodeContentResult; let last = last, let i = index">
<sb-course-card appContentDirection class="sb-card-grid__item" [course]="content"
(click)="openContent(undefined, content, i);" [cardImg]="content?.appIcon || content?.courseLogoUrl || defaultAppIcon" [section]="null">
</sb-course-card>
</div>
</div>
</div>
</div>
</div>
<div *ngIf="resultlist && !resultlist.isCourse">
<div>
<!-- Collection List -->
<div class="sb-textbook-title-container px-8">
<span class="textbook-title">{{'TEXTBOOK' | translate}}</span>
</div>
<div *ngFor="let result of resultlist.dialCodeResult" class="ion-no-padding ion-no-margin">
<div *ngIf="result && result.content && result.content.length">
<div *ngFor="let content of result.content; let last = last, let i = index"
class="content-list ion-no-padding">
<sb-library-card [content]="result" [type]="LibraryCardTypes.QRCODE_RESULT"
[layoutConfig]="{layout: 'v4'}"
(click)="openContent(result, content, i);" [cardImg]="result?.appIcon || defaultAppIcon"
[moreInfoLabel]="'Section'" [section]="content.name">
</sb-library-card>
<div *ngIf="!last" class="inner-divider"></div>
</div>
</div>
</div>
<!-- Content List -->
<div no-lines *ngIf="resultlist.dialCodeContentResult && resultlist.dialCodeContentResult.length">
<div *ngFor="let content of resultlist.dialCodeContentResult; let last = last, let i = index"
class="content-list">
<sb-library-card [content]="content" [type]="LibraryCardTypes.QRCODE_RESULT"
[layoutConfig]="{layout: 'v4'}"
(click)="openContent(content, content, i + ((resultlist && resultlist.dialCodeResult) ? resultlist.dialCodeResult.length : 0) )"
[cardImg]="content?.appIcon || defaultAppIcon" [moreInfoLabel]="'Section'">
</sb-library-card>
<div *ngIf="!last" class="inner-divider"></div>
</div>
</div>
</div>
</div>
</div>
</ion-list>
<div *ngIf="searchContentResult && searchContentResult.length">
<div class="pills-filter" [ngClass]="{'mt-32': hideSearchOption, '': !hideSearchOption}">
<sb-pills-grid *ngIf="primaryCategoryFilters && primaryCategoryFilters.length" (select)="handleFilterSelect($event)"
[pillsViewType]="PillsViewType.SCROLL"
[pillBorder]="PillBorder.ROUND">
<sb-pill-item *ngFor="let filter of primaryCategoryFilters"
[name]="filter?.name | titlecase"
[theme]="(filter?.name === selectedPrimaryCategoryFilter?.name) ? {pillBgColor:appPrimaryColor, pillTextColor:'white'} : {pillBgColor:'white'}"
[value]="filter">
</sb-pill-item>
</sb-pills-grid>
</div>
<div class="sb-search-history-entry fixed-counter row" [ngClass]="{'scc-container': searchInfolVisibility === 'hide', 'sbc-container':searchInfolVisibility === 'show'}">
<div class="col" *ngIf="searchKeywords">
{{'SHOWING_RESULT_OUTOF_TOTAL' | translate: {'%count': searchContentResult.length, '%query': totalCount} }}
</div>
<div class="col" *ngIf="!searchKeywords">
{{'RECOMMENDATION_BASED_ON_PROFILE' | translate }}
</div>
</div>
<div [ngClass]="{'scc-container':searchInfolVisibility === 'show', 'sbcc-container': searchInfolVisibility === 'hide'}">
<div class="sc-content" *ngFor="let content of searchContentResult; let i = index; let last = last">
<sb-library-card [content]="content" [type]="'mobile_textbook'" [isSelected]="content.selected"
[layoutConfig]="{layout: 'v4'}"
(click)="openContent(undefined, content, i, undefined, true)" [cardImg]="content?.appIcon || defaultAppIcon">
</sb-library-card>
</div>
</div>
<ion-button class="view-more custom-btn-txt-transform-none" expand="block" (click)="loadData($event)" *ngIf="searchContentResult?.length > 0 && searchContentResult.length < totalCount">
{{ 'VIEW_MORE' | translate }}
</ion-button>
</div>
<div class="empty-search-result ion-text-center ion-padding-top" *ngIf="!showLoader && showEmptyMessage">
{{ 'EMPTY_SEARCH_RESULTS' | translate }}
</div>
</ng-container>
<ng-container *ngIf="!enableSearch">
<app-discover (hideRefresher)="hideRefresher($event)"></app-discover>
</ng-container>
<!-- scroll top -->
<!-- <div class="scroll_up" (click)="scrollToTop()" *ngIf="searchContentResult && searchContentResult.length">
<ion-icon name="arrow-up-circle-outline"></ion-icon>
</div> -->
</ion-content>
<div class="add-to-group-btn-container" *ngIf="showAddToGroupButtons">
<button class="open-btn add-to-group-btn" (click)="openSelectedContent()">{{'VIEW_ACTIVITY' | translate}}</button>
<button class="add-btn add-to-group-btn" (click)="addActivityToGroup()">{{'ADD_TO_GROUP_ACTIVITY' | translate}}</button>
</div>
<div class="loading-backdrop ion-text-center" *ngIf="showLoading">
<div class="backdrop-container">
<ion-label>{{ loadingDisplayText }}</ion-label>
<app-pb-horizontal [progress]="downloadProgress" isOnBoardCard="false"></app-pb-horizontal>
</div>
<div class="backdrop-footer">
<ion-button size="small" class="cancel-btn" (click)="cancelDownload()">{{'CANCEL' | translate}}</ion-button>
</div>
</div>
./search.page.scss
@import "src/assets/styles/variables";
@import "src/assets/styles/_custom-mixins";
@import "src/assets/styles/fonts";
@import "src/assets/styles/_variables.scss";
:host{
.search-buttons-group {
margin-right: 1rem;
}
.sb-no-search-history {
display: flex;
height: 100%;
color: map-get($colors, granite_gray);
justify-content: center;
align-items: center;
background-color: map-get($colors, white_fa);
}
.sb-search-history-entry {
align-items: center;
.invisible {
visibility: hidden;
}
> div {
font-size: 0.75rem;
@include padding(8px, 16px);
// padding: 8px 16px;
img {
vertical-align: baseline;
}
}
}
.sb-search-header-meta {
color: $blue;
font-size: 0.75rem;
padding-top: 0.5rem;
}
.text-input-clear-icon {
display: block !important;
}
.collection-list {
margin-bottom: 0 !important;
}
.item-inner {
.label {
margin-right: 0 !important;
}
padding-right: 0 !important;
}
.spinner-container {
width: 100%;
height: 100%;
display: block;
.loader {
display: block;
margin: auto;
top: 48%;
}
}
.divider {
width: 100%;
height: 0.375rem;
background-color: map-get($colors, $gray-0);
margin: 20px 0 0 0;
}
.inner-divider{
width: 90%;
height: 0.188rem;
background-color: map-get($colors, $gray-0);
margin: 0 5%;
}
.sb-textbook-title-container{
height: ($base-block-space * 3);
@include margin(null, null, $base-block-space, null);
margin-top: 16px;
.textbook-icon {
height: 1.063rem;
transform: scaleX(-1);
@include margin(0, ($base-block-space * 1), 0, 0);
color: $tertiary-color;
}
.textbook-title {
height: ($base-block-space * 3);
color: $blue;
font-size: 1.125rem;
font-weight: bold;
text-transform: capitalize;
line-height: ($base-block-space * 3);
}
}
ion-item {
.collection-header {
margin-bottom: 0 !important;
}
margin-top: unset !important;
margin-bottom: 0 !important;
}
.collection-header {
margin-top: 16px;
}
.content-list {
margin-bottom: 0 !important;
margin-top: 16px;
.label {
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-right: 0 !important;
}
}
.dial-section-header{
@extend .NotoSans-bold;
font-size: 1.350rem;
padding: 11px;
margin: 0;
background-color: map-get($colors, $gray-0);
}
.view-collection {
margin: 0 !important;
padding: 0 !important;
right: 0 !important;
text-transform: none;
font-weight: 600;
font-size: $font-size-base;
line-height: 0.875rem;
span.button-inner{
color: map-get($colors, vivid_blue);
}
}
.collection-name {
font-size: $font-size-base;
color: black;
}
span {
color: grey;
@extend .font-weight-600;
font-size: $font-size-base;
}
.cancel-btn span {
color: map-get($colors, white) !important;
}
.empty-search-result {
font-size: 1.2rem;
}
.ellipsis{
overflow: hidden !important;
text-overflow: ellipsis !important;
color: grey;
}
.subject{
color: grey;
@extend .font-weight-600;
font-size: 1.3rem;
}
.inline-block{
display: inline-block;
}
.width{
max-width: 60%;
vertical-align: top;
}
.loading-backdrop {
.backdrop-container {
width: 100%;
padding: 16px;
text-align: center;
position: absolute;
top: 50%;
margin-top: -50px;
}
.backdrop-footer {
position: absolute;
width: 100%;
bottom: 0;
padding-bottom: 16px;
}
background-color: map-get($colors, white);
height: 100%;
z-index: 1000;
opacity: 1 !important;
}
.tb-border-btm{
border-bottom: 0.5px solid rgba(151, 151, 151, 0.5);
}
ion-header .button-native {
--color : #{$primary-color};
}
.sb-textbook-container {
@include padding(($base-block-space * 1));
width: 100%;
&:last-child{
margin-bottom: ($base-block-space * 2);
}
.sb-view-all-container
{
.sb-card-container .sb-search-card .sb-card
{
padding: 8px 16px;
}
.sb-view-all-items.sb-search-items
{
padding: 0px;
background-color: transparent;
}
.sb-card-result.sb-card-details
{
@include padding($base-block-space * 2);
.sb-card-res-count{
color: map-get($colors, dark_gray);
font-size: ($font-size-base - 0.125);
line-height: 0.938rem;
}
.sb-card-result-content{
color: map-get($colors, dark_gray);
font-size: ($font-size-base + 0.125);
font-weight: 500;
line-height: 1.375rem;
}
}
}
.sb-separator-line{
margin: 0;
}
.sb-card{
@include margin(0);
border-radius: 2px 2px 0 0;
// border-bottom: 0.5px solid rgba(94, 94, 94, 0.75);
}
.sb-card-textbook-container{
app-text-book-card {
.sb-card.reverse{
border-bottom: 0.5px solid rgba(151, 151, 151, 0.40) !important;
&:last-child{
border-bottom: 0.5px solid rgba(151, 151, 151, 0.40) !important;
}
}
&:last-child{
.sb-card.reverse{
border-bottom: none;
}
}
}
}
}
.row{
display: flex;
justify-content: space-between;
align-items: center;
}
.col {
flex: 1 1 auto;
min-height: 2rem !important;
}
.skeleton-header{
border-bottom: 1px solid map-get($colors, empty_color);
@include padding(8px);
}
.skeleton-search-card{
@include padding(8px);
display: flex;
flex-direction: row-reverse;
border-bottom: 1px solid map-get($colors, empty_color);
box-shadow: 0 -1px 5px 0px rgba(0,0,0,0.1);
}
.skleton-avatar {
display: inline-block; flex: 1 auto;
}
}
.results-count {
margin: 0;
@include padding(8px, null, null, 8px !important);
}
.add-to-group-btn-container {
text-align: center;
.add-to-group-btn{
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 1rem;
cursor: pointer;
outline: none;
margin: 4px 0 8px;
width: 45%;
padding: 16px 0 16px 0;
}
.open-btn {
border: 1px solid $blue;
background-color: white;
color: $blue;
margin: 8px;
}
.add-btn {
background-color: $blue;
border: none;
margin: 8px;
}
}
.sc-container{
.sc-content{
margin: 1px 0;
}
}
.search-info {
display: flex;
.title {
font-size: 1.125rem;
}
.description {
color: #333333;
font-size: 0.75rem;
margin-bottom: 0;
}
}
.search-container {
margin: 1rem;
margin-bottom: 0.25rem;
.search-input {
background-color: var(--app-white);
border-radius: 1rem;
padding: 0.25rem 0.75rem;
ion-input {
border: none;
width: 90%;
display: inline-block;
padding: 0.25rem;
font-size: 1.125rem;
}
button{
background-color: transparent;
box-shadow: none !important;
}
}
}
.search-filter{
display: flex;
.search-input {
width: 85%;
}
.filter-btn{
display: flex;
width: 15%;
vertical-align: middle;
margin-left: 0.5rem;
button{
width: 100%;
box-shadow: 0 0 50px 0 rgba(0,0,0,0.1) !important;
background-color: var(--app-primary-header-light);
}
}
}
.spinner-div {
padding: 40px;
background-color: map-get($colors, light_gray);
text-align: center;
border: none !important;
}
.sticky-position {
position: sticky;
z-index: 9;
top: 0px;
}
::ng-deep {
.sb--card__img.sb--card__image-pos {
z-index: 8 !important;
}
}
.scroll_up {
position: fixed;
bottom: 0.6rem;
right: 0.6rem;
ion-icon {
color: lightblue;
zoom: 2;
}
}
.pills-filter {
position: fixed;
z-index: 1;
top: 6rem;
padding-bottom: 0.5rem;
background-color: var(--app-tertiary-background);
}
.fixed-counter {
color: $blue;
font-size: 0.75rem;
position: fixed;
z-index: 1;
background-color: var(--app-tertiary-background);
width: 100%;
top: 9rem;
height: 3rem;
div {
background-color: var(--app-white);
border-radius: 1rem;
width: 94%;
margin: 0 0.625rem;
}
}
.fixed-counter + .sc-container {
margin-top: 7rem;
}
.fixed-counter + .scc-container {
margin-top: 4rem;
}
.pills-filter+ .sbc-container {
margin-top: 6rem;
}
.sb-search-history-entry+ .sbcc-container {
margin-top: 3rem;
}