@clickview/lite 0.103.2 → 0.103.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/.vite/manifest.json +407 -407
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{BeW5XQTb2.chunk.js → BBwi4FOJ2.chunk.js} +2 -2
  5. package/dist/scripts/{BeW5XQTb2.chunk.js.map → BBwi4FOJ2.chunk.js.map} +1 -1
  6. package/dist/scripts/{D8mi6CVp2.chunk.js → BYJa-jEI2.chunk.js} +2 -2
  7. package/dist/scripts/{D8mi6CVp2.chunk.js.map → BYJa-jEI2.chunk.js.map} +1 -1
  8. package/dist/scripts/{Drh1bb9z.chunk.js → BbJGjXBH.chunk.js} +2 -2
  9. package/dist/scripts/{Drh1bb9z.chunk.js.map → BbJGjXBH.chunk.js.map} +1 -1
  10. package/dist/scripts/BcVxkWsW.chunk.js +1 -0
  11. package/dist/scripts/{DOYyhXN-.chunk.js → BjtsulNM.chunk.js} +2 -2
  12. package/dist/scripts/{DOYyhXN-.chunk.js.map → BjtsulNM.chunk.js.map} +1 -1
  13. package/dist/scripts/{QVwuOts3.chunk.js → C3eIGNDs.chunk.js} +2 -2
  14. package/dist/scripts/{QVwuOts3.chunk.js.map → C3eIGNDs.chunk.js.map} +1 -1
  15. package/dist/scripts/{CfrfHGSh.chunk.js → CT3yl0jK.chunk.js} +2 -2
  16. package/dist/scripts/{CfrfHGSh.chunk.js.map → CT3yl0jK.chunk.js.map} +1 -1
  17. package/dist/scripts/{wpRpI9h02.chunk.js → CbPqWgxm2.chunk.js} +2 -2
  18. package/dist/scripts/{wpRpI9h02.chunk.js.map → CbPqWgxm2.chunk.js.map} +1 -1
  19. package/dist/scripts/{CsCjBSq62.chunk.js → Cj6PScU52.chunk.js} +2 -2
  20. package/dist/scripts/{CsCjBSq62.chunk.js.map → Cj6PScU52.chunk.js.map} +1 -1
  21. package/dist/scripts/{BD_YlxPJ.chunk.js → Cl0Kjmj6.chunk.js} +2 -2
  22. package/dist/scripts/{BD_YlxPJ.chunk.js.map → Cl0Kjmj6.chunk.js.map} +1 -1
  23. package/dist/scripts/{yfjVyowY.chunk.js → DAed0ji9.chunk.js} +2 -2
  24. package/dist/scripts/{yfjVyowY.chunk.js.map → DAed0ji9.chunk.js.map} +1 -1
  25. package/dist/scripts/{CIzlhCeS.chunk.js → Dl-8A2m-.chunk.js} +2 -2
  26. package/dist/scripts/{CIzlhCeS.chunk.js.map → Dl-8A2m-.chunk.js.map} +1 -1
  27. package/dist/scripts/{BFH_tnSb2.chunk.js → RaLi1Skr2.chunk.js} +3 -3
  28. package/dist/scripts/{BFH_tnSb2.chunk.js.map → RaLi1Skr2.chunk.js.map} +1 -1
  29. package/dist/scripts/{app-DvYKGw_S.js → app-BYLHZF74.js} +4 -4
  30. package/dist/scripts/{app-DvYKGw_S.js.map → app-BYLHZF74.js.map} +1 -1
  31. package/dist/scripts/{kLCNzxrH2.chunk.js → hWjV2SVN2.chunk.js} +2 -2
  32. package/dist/scripts/{kLCNzxrH2.chunk.js.map → hWjV2SVN2.chunk.js.map} +1 -1
  33. package/package.json +1 -1
  34. package/dist/scripts/C2s0ZcC4.chunk.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"D8mi6CVp2.chunk.js","names":[],"sources":["../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/components/search-widget-tooltip/SearchWidgetTooltip.tsx","../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/mixed-widget-search-results.module.scss","../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults.tsx","../../../../libs/shared/src/apps/search/constants/SearchOGQL.ts","../../../../libs/shared/src/apps/search/flight-requests/SharedSearchRequests.ts","../../src/apps/search/hooks/useFetchSchoolLevels.ts","../../src/apps/search/hooks/useFetchSearchData.tsx","../../../../libs/shared/src/images/svg/objects/FilterSvg.tsx","../../../../libs/shared/src/hooks/useDialogKeyboardNavigation.ts","../../../../libs/shared/src/components/action-sheet/action-sheet.module.scss","../../../../libs/shared/src/components/action-sheet/ActionSheet.tsx","../../src/apps/search/components/sm-screen-search-filter/SmScreenSearchFilterItem.tsx","../../src/apps/search/components/sm-screen-search-filter/SmScreenSearchFilter.tsx","../../src/apps/search/views/search-results-v2/components/search-results-filter/search-results-filter.module.scss","../../src/apps/search/views/search-results-v2/components/search-results-filter/SearchResultsFilter.tsx","../../src/apps/search/views/search-results-v2/components/search-results-request-video/SearchResultsRequestVideo.tsx","../../src/apps/search/views/search-results-v2/components/search-results-empty-state/SearchResultsEmptyState.tsx","../../src/apps/search/views/search-results-v2/transformations/on-load/detectCurriculumCodeSearch.ts","../../src/apps/search/views/search-results-v2/transformations/on-load/fetchVideoAssocsObjects.ts","../../src/apps/search/views/search-results-v2/transformations/on-load/OnLoadWidgets.ts","../../src/apps/search/views/search-results-v2/transformations/results/mergeSearchResults.ts","../../src/apps/search/views/search-results-v2/transformations/results/SearchResultsTransformations.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchRelevantTopics.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchTags.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/WidgetItemTransformations.ts","../../src/apps/search/views/search-results-v2/utils/SearchResultsFilterHelper.ts","../../src/apps/search/views/search-results-v2/utils/SearchResultsAppLinkHelper.ts","../../src/apps/search/views/search-results-v2/SearchResultsViewV2.tsx"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { InfoSvg } from 'libs/shared/images/svg/status/InfoSvg';\n\nconst namespace = 'search.searchWidgetTooltip';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchWidgetTooltipProps {\n widgetId: WidgetTypeId;\n isTertiary: boolean;\n}\n\nfunction getWidgetPhrase(widgetId: WidgetTypeId, isTertiary: boolean) {\n const widgetTooltipPhraseMap: {[key in WidgetTypeId]?: string } = {\n [WidgetTypeId.SearchRelevantTopics]: 'relevantTopicsTooltip',\n [WidgetTypeId.SearchCompanies]: 'studiosAndChannelsTooltip',\n [WidgetTypeId.SearchTopResults]: 'topResultsTooltip',\n [WidgetTypeId.SearchSeries]: 'seriesTooltip',\n [WidgetTypeId.SearchPlaylists]: 'playlistsTooltip',\n [WidgetTypeId.SearchMyVideosFolder]: 'myVideosFoldersTooltip',\n [WidgetTypeId.SearchMySchoolLibraryFolder]: isTertiary ? 'mySchoolFoldersTooltipTertiary' : 'mySchoolFoldersTooltip',\n [WidgetTypeId.SearchMyVideos]: 'myVideosTooltip',\n [WidgetTypeId.SearchMySchoolLibraryVideos]: isTertiary ? 'mySchoolVideosTooltipTertiary' : 'mySchoolVideosTooltip',\n [WidgetTypeId.SearchExchangeArchive]: 'exchangeArchiveTooltip',\n [WidgetTypeId.SearchClickViewLive]: 'clickViewLiveTooltip',\n [WidgetTypeId.SearchRelatedResults]: 'relatedResultsTooltip',\n [WidgetTypeId.SearchContentPartners]: 'channelsTooltip'\n };\n\n return widgetTooltipPhraseMap[widgetId];\n}\n\nexport function SearchWidgetTooltip(props: SearchWidgetTooltipProps): JSX.Element {\n const phrase = getWidgetPhrase(props.widgetId, props.isTertiary);\n\n if (!phrase)\n return <></>;\n\n return (\n <SvgContainer\n className='svg-container text-secondary'\n svg={InfoSvg}\n title={getPhrase(phrase)}\n tooltipPlacement='top'\n tooltipSpanHack\n tooltipSpanHackClassName='ms-2'\n />\n );\n}\n",":local {\n $seriesWidget: 'search-series-widget';\n $posterTemplate: 'poster-fixed-list-large-widget-template';\n $thumbnailTemplate: 'thumbnail-fixed-list-media-small-widget-template';\n $tagSlidingListTemplate: 'tag-sliding-list-widget-template';\n\n .searchResultsWidgetsContainer {\n :global {\n .#{$seriesWidget}.#{$thumbnailTemplate} {\n\n // If a series poster widget with heading is a immediate sibling of series thumbnail widget\n +.#{$seriesWidget}.#{$posterTemplate}.curated-widget.has-heading .curated-widget-header {\n display: none;\n }\n }\n\n .#{$seriesWidget}.#{$posterTemplate} {\n\n // If a series thumbnail widget with heading is a immediate sibling of series poster widget\n +.#{$seriesWidget}.#{$thumbnailTemplate}.curated-widget.has-heading .curated-widget-header {\n display: none;\n }\n }\n\n .#{$tagSlidingListTemplate}.curated-widget {\n padding-bottom: map-get($spacers, 3); // 1rem (16px)\n margin-bottom: map-get($spacers, 4); // 1.5rem (24px)\n border-bottom: 1px solid $gray-300;\n }\n }\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport type { SearchDashboard, SearchDashboardItem, WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { AllSearchWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, type CurrentUser, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { SearchWidgetTooltip } from './components/search-widget-tooltip/SearchWidgetTooltip';\n\nimport styles from './mixed-widget-search-results.module.scss';\n\nconst namespace = 'search.mixedWidgetSearchResults';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getName(widget: WidgetSearchItem, isTertiary: boolean): string {\n if (widget.widgetId === WidgetTypeId.SearchMySchoolLibraryFolder)\n return isTertiary ? getPhrase('tertiaryFolderHeading') : widget.name;\n\n if (widget.widgetId === WidgetTypeId.SearchMySchoolLibraryVideos)\n return isTertiary ? getPhrase('tertiaryLibraryVideoHeading') : widget.name;\n\n return widget.name;\n}\n\nfunction getWidgetMetadata(widget: WidgetSearchItem): Partial<WidgetMetadata> {\n if (widget.widgetId === WidgetTypeId.SearchCurriculumCode) {\n return {\n curriculumLeafName: widget.content?.name,\n curriculumLeafDescription: widget.content?.description\n };\n }\n\n return {};\n}\n\nfunction getWidgetClassName(widget: WidgetSearchItem): string {\n /**\n * This is to uniquely idenfity the widget in search results when\n * search playlist widget comes after search series widget which\n * causes the search playlist widget header to be hidden.\n */\n if (widget.widgetId === WidgetTypeId.SearchSeries) {\n return 'search-series-widget';\n }\n return;\n}\n\n/**\n * Partial loading components can have different behavior depending on\n * if the predicate returns true or false.\n */\nfunction getPartialLoadingPredicate(item: SearchDashboardItem): boolean {\n return [WidgetTypeId.SearchTags].includes(item.widgetId);\n}\n\nexport interface MixedWidgetSearchResultsProps {\n data: SearchDashboard;\n widgetAppLinks: AllSearchWidgetTemplates['appLinks'];\n widgetAppLinkOptions?: AllSearchWidgetTemplates['appLinkOptions'];\n audiences: PresentationAudience[];\n availablePresentations: Presentation[];\n currentUser: CurrentUser;\n commonVideoProps: CommonVideoProps;\n isTertiary: boolean;\n settingsHash: SettingsHash;\n\n getAnalyticsData?: (widget: SearchDashboardItem, yIndex: number, xIndex: number) => HashObject;\n \n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n\n getRequest: (widgetTypeId: WidgetTypeId, cursor?: string) => Flight.Request;\n setIsEmpty?: (widget: WidgetTypeId, isEmpty: boolean) => void;\n\n getSeeMoreAppLink: (widget: WidgetSearchItem, isLastItem: boolean) => Core.AppLink;\n /**\n * Array of transformers to be applied to search results before rendering\n */\n searchResultsTransformers?: Array<UseTransformerFunc<WidgetSearchItem[]>>;\n /**\n * Array of transformers to be applied to each search widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<WidgetSearchItem>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: WidgetSearchItem[]) => void>;\n}\n\nexport function MixedWidgetSearchResults(props: React.PropsWithChildren<MixedWidgetSearchResultsProps>): JSX.Element {\n if (!props.data || !props.data.length)\n return <></>;\n\n return (\n <div className={styles.searchResultsWidgetsContainer}>\n {props.data.map((item, idx) => {\n const isLastWidget = props.data.length - 1 === idx;\n return (\n <React.Fragment key={item.widgetId}>\n <InfiniteWidgetContainerView<SearchDashboardItem, WidgetSearchItem, AllSearchWidgetTemplates>\n index={idx}\n item={item}\n dashboardTarget={DashboardTargetType.Search}\n \n getName={widget => getName(widget, props.isTertiary)}\n getWidgetMetadata={widget => getWidgetMetadata(widget)}\n \n infiniteFetch={isLastWidget}\n getCursor={widget => widget.content?.cursor}\n getRequest={cursor => props.getRequest(item.widgetId, cursor)}\n getPartialLoadingPredicate={() => getPartialLoadingPredicate(item)}\n \n getBadgeComponent={widget => (\n <SearchWidgetTooltip\n widgetId={widget.widgetId}\n isTertiary={props.isTertiary}\n />\n )}\n \n audiences={props.audiences}\n currentUser={props.currentUser}\n appLinks={props.widgetAppLinks}\n appLinkOptions={props.widgetAppLinkOptions}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n settingsHash={props.settingsHash}\n\n hasPermissions={props.hasPermissions}\n getWidgetClassName={getWidgetClassName}\n getAnalyticsData={props.getAnalyticsData}\n getSelectedItems={props.getSelectedItems}\n hasLocalPermissions={props.hasLocalPermissions}\n getSeeMoreAppLink={widget => props.getSeeMoreAppLink(widget, isLastWidget)}\n setIsEmpty={isEmpty => props.setIsEmpty(item.widgetId, isEmpty)}\n\n resultsTransformers={props.searchResultsTransformers}\n widgetItemTransformers={props.widgetItemTransformers}\n onLoadWidgetsTriggers={props.onLoadWidgetsTriggers}\n />\n {item.name === 'Tags' && props.children}\n </React.Fragment>\n );\n })}\n </div>\n );\n}\n","import { SharedWithStatements } from 'libs/shared/constants/WithStatements';\nimport { TagType } from 'libs/shared/enums/TagType';\n\n/**\n * OGQL used for search V5 endpoint\n */\nexport const SearchOGQL = {\n video: SharedWithStatements.VIDEO_COLLECTION,\n series: 'rating,tallPoster',\n playlist:\n 'videos[count(),thumbnail]{limit:1},interactives[count(),_thumbnail]{limit:1},' +\n 'clips[count(),_thumbnail]{limit:1}',\n classification: `_theme[banner,cover,tallposter,thumbnail,icon],cover,thumbnail,tags{tagtype:${TagType.Curation}}`,\n clip: SharedWithStatements.CLIP_COLLECTION,\n interactive: SharedWithStatements.INTERACTIVE_COLLECTION,\n company: 'logo',\n category: 'libraries[_logo],thumbnail',\n partner_profile: SharedWithStatements.PARTNER_PROFILE\n};\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { SearchOGQL } from 'libs/shared/apps/search/constants/SearchOGQL';\nimport { SearchIndices, SearchResultObjectTypes, SearchResults, SearchResultsObject } from 'libs/shared/apps/search/interfaces';\nimport type { WidgetFilter } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SharedSearchHelper } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport type { Playlist, Series } from 'libs/shared/interfaces';\nimport { ThemeAssetHelper } from 'libs/shared/utils/ThemeAssetHelper';\n\nfunction formatSearchResponse(response: SearchResults<SearchResultObjectTypes>) {\n /**\n * Until playlists and series are regionalised, search will always return every series/playlist that exists\n * even if the current user doesn't have access to the content inside (which will happen for example when playlists/series)\n * contain all UK library content but is being searched for by an AU user.\n *\n * For some search queries, this may result in search showing a bunch of \"empty\" playlists/series, which sucks.\n * This will filter all empty collections out and decrement the `totalResults` to avoid this and make search a better\n * experience.\n *\n * Ideally this will be removed one day when this regionalisation is no longer an issue.\n */\n let totalResults = response.totalResults;\n\n const results = response?.results?.filter(result => {\n if (result._index !== 'series' && result._index !== 'playlist')\n return true;\n\n if (result._index === 'playlist') {\n const playlist = result as SearchResultsObject<Playlist>;\n\n if (playlist.clips?.data?.length ||\n playlist.interactives?.data?.length ||\n playlist.videos?.data?.length)\n return true;\n\n totalResults--;\n return false;\n }\n\n if ((result as SearchResultsObject<Series>).videos?.data?.length === 0) {\n totalResults--;\n return false;\n }\n\n return true;\n }) ?? [];\n\n response.results = results;\n response.totalResults = totalResults;\n\n // The first search result will always have the highest score value.\n // We store it so that we can access it for subsequent results pages\n const resultMaxScore = results[0]?._score;\n\n return {\n ...response,\n results: SharedSearchHelper.mapMaxScoreToSearchResults(results, resultMaxScore)\n };\n}\n\nfunction stringifyObject(obj: HashObject): string {\n return Object.entries(obj).reduce((prev, [ , value ]) => {\n let stringifiedValue = value;\n\n if (typeof value === 'object') {\n stringifiedValue = stringifyObject(value);\n } else if ([ 'number', 'boolean', 'string' ].includes(typeof value)) {\n stringifiedValue = value.toString();\n }\n\n if (!prev.length)\n return stringifiedValue;\n\n return `${prev},${stringifiedValue}`;\n }, '');\n}\n\n/**\n * We want to map the filters to the global filters object but we need to remove the filter prefix\n * and exclude the presentation filter\n */\nfunction getGlobalFilters(filters: HashObject, widgetTypeId: WidgetTypeId | null): Record<string, any> {\n return Object.entries(filters)\n .reduce((prev, [ key, value ]) => {\n const actualKey = key.replace(FilterConstants.FILTER_PARAM_PREFIX, '');\n if (actualKey === 'presentation' &&\n widgetTypeId !== WidgetTypeId.SearchTopResults &&\n widgetTypeId !== WidgetTypeId.SearchRelatedResults &&\n widgetTypeId !== WidgetTypeId.SearchSeries\n ) {\n return prev;\n }\n\n return { ...prev, [actualKey]: value };\n }, {});\n}\n\nexport const SharedSearchRequests = {\n searchDashboard(\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:dashboard:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: getGlobalFilters(genericFilters, null),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner\n };\n\n return {\n url: '{gateway}/v5/search/widgets',\n publicUrl: '/api/search/v5/widgets',\n type: HttpVerbs.POST,\n data,\n key\n };\n },\n\n searchDashboardWidget(\n widgetTypeId: WidgetTypeId,\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:dashboard:${widgetTypeId}:widget:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n excludeVideoIds,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: getGlobalFilters(genericFilters, widgetTypeId),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner,\n ogql: SearchOGQL,\n excludeVideoIds\n };\n\n return {\n url: `{gateway}/v5/search/widgets/${widgetTypeId}`,\n publicUrl: `/api/search/v5/widgets/${widgetTypeId}`,\n type: HttpVerbs.POST,\n data,\n key,\n formatData: (data: HashObject) => {\n if (!data)\n return data;\n\n return {\n ...data,\n content: data.content?.data ?\n { ...data.content, data: data.content.data.map(ThemeAssetHelper.applyThemeToClassification) } :\n data.content\n };\n }\n };\n },\n\n searchV5(\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner,\n ogql: SearchOGQL\n };\n\n return {\n url: '{gateway}/v5/search',\n publicUrl: '/api/search/v5',\n type: HttpVerbs.POST,\n data,\n key\n };\n },\n \n searchV4(options: {\n query: string,\n indices: SearchIndices[],\n filters: HashObject,\n sorts?: HashObject,\n allowSubstitute: boolean,\n cursor?: string,\n limit?: number\n }): Flight.PublicRequest {\n const { query, indices, filters = {}, sorts = {}, allowSubstitute = true, cursor, limit } = options;\n\n let key = `search:v4:${query}:${allowSubstitute}:${indices}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}excludeLibraryExclusive`]: excludeLibraryExclusive,\n isLearner,\n ...genericFilters\n } = filters;\n\n const indexObjects = indices.map(index => {\n if (index !== 'video' || !excludeLibraryExclusive)\n return { index };\n\n return { index, filters: { excludeLibraryExclusive } };\n });\n\n const data = {\n searchType: 'content',\n indices: indexObjects,\n filters: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\n sorts,\n query,\n allowSubstitute,\n cursor: cursor ?? undefined,\n isLearner: !!isLearner,\n limit\n };\n\n return {\n url: '{gateway}/v4/search',\n publicUrl: '/api/search/v4',\n type: HttpVerbs.POST,\n data,\n key,\n formatData: formatSearchResponse\n };\n },\n\n search(options: {\n query: string,\n indices: SearchIndices[],\n filters?: HashObject,\n allowSubstitute?: boolean,\n cursor?: string,\n limit?: number,\n success?: (results: SearchResults) => void,\n error?: (xhr: Xhr) => void\n }): Flight.PublicRequest {\n const { query, indices, filters, allowSubstitute, cursor, limit, success, error } = options;\n\n let key = `search:${query}:${allowSubstitute}:${indices}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n const params = Object.assign({}, {\n index: indices,\n cursor: cursor ?? undefined,\n query,\n allowSubstitute,\n limit,\n ...filters\n });\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v3/search', params),\n publicUrl: UrlHelper.urlBuilder('/api/search', params),\n key,\n formatData: formatSearchResponse,\n success,\n error\n };\n },\n\n tagsAndClassifications(\n query: string,\n indices: SearchIndices[],\n filters: HashObject = {},\n cursor?: string,\n success?: (results: string[]) => void,\n error?: () => void\n ): Flight.PublicRequest {\n const params = {\n index: indices,\n cursor,\n query,\n ...filters\n };\n\n let key = `filter:options:${query}:${indices.join(':')}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v3/search/tags-and-classifications', params),\n publicUrl: UrlHelper.urlBuilder('/api/search/tags-and-classifications', params),\n key,\n success,\n error,\n normalize: false\n };\n }\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Presentation, SchoolLevels } from 'libs/shared/interfaces';\n\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\n\nimport { SearchRequests } from 'apps/search/flight-requests/SearchRequests';\n\nexport function useFetchSchoolLevels(presentation: Presentation) {\n const { hasPermissions } = usePermissions();\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n function getPresentationIds() {\n if (isLearner)\n return presentation ? [presentation?.id] : null;\n\n return availablePresentations?.map(o => o.id);\n }\n\n const presentationIds = getPresentationIds();\n\n return Flight.useBasicFetch<SchoolLevels>(\n hasPresentationsLoaded &&\n presentationIds &&\n SearchRequests.schoolLevels(presentationIds)\n );\n}\n","import { Flight } from 'libs/common/flight';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { TopicResults } from 'libs/shared/apps/search/interfaces';\nimport { MasterObjectTypes } from 'libs/shared/enums/MasterObjectTypes';\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DomainMasterCollectionType, LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser, DashboardTargetType, Library, Rating, User, YearGroup } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { RatingRequests } from 'shared/flight-requests/RatingRequests';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\n\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { useFetchSchoolLevels } from 'apps/search/hooks/useFetchSchoolLevels';\nimport { useSearchCompanies } from 'apps/search/hooks/useSearchCompanies';\nimport { useSearchTopics } from 'apps/search/hooks/useSearchTopics';\n\n/**\n * We need to fetch libraries in order to support the sources filter. \n * However we need to exclude the streamable library, and additionally we need to exclude\n * the exchange library if the user has decided they don't want to see exchange results.\n * \n * We then need to return both of these ids so that the FilterHelper.getBackendFilters()\n * can add them as excludeLibraryExclusive filters\n * \n * - Sha\n */\nfunction useGetLibraries() {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const products = useProducts();\n const settings = useSettings(null);\n const { upsellPresentationType } = useUpsellContext();\n\n const streamableLibrary = Flight.useBasicFetch<HashObject>(LibraryRequests.streamableLearning());\n const streamableLibraryId = streamableLibrary.data?.objectId;\n const showStreamableSearchResults = settings.clickViewLive\n && upsellPresentationType !== PresentationType.StreamableLearning;\n\n const showExchangeSearchResults = products.hasProduct(ProductId.Exchange) && settings.showExchangeSearchResults;\n\n const libraryTypes: DomainMasterCollectionType[] = [ 'sharedLibrary', 'customLibrary', 'workspace', 'hostedLibrary', 'exchange' ];\n const librariesRequest = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated && LibraryRequests.domainLibraries(libraryTypes)\n );\n\n let libraries = librariesRequest.data ?? [];\n const exchangeLibraryIndex = libraries?.findIndex(l => l.type === MasterObjectTypes.Exchange);\n const exchangeLibraryId = libraries[exchangeLibraryIndex]?.id;\n\n if (!showExchangeSearchResults)\n libraries = [ ...libraries.slice(0, exchangeLibraryIndex), ...libraries.slice(exchangeLibraryIndex + 1) ];\n\n if (streamableLibraryId && !showStreamableSearchResults) {\n const streamableIndex = libraries?.findIndex(l => l.id.toString() === streamableLibraryId.toString());\n libraries = [ ...libraries.slice(0, streamableIndex), ...libraries.slice(streamableIndex + 1) ];\n }\n\n const hasLibrariesCompleted = (\n streamableLibrary.hasCompleted &&\n (!currentUser.data?.isAuthenticated || librariesRequest.hasCompleted)\n );\n\n return {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n };\n}\n\nfunction useGetRatings() {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const ratings = Flight.useBasicFetch<Rating[]>(RatingRequests.ratings(currentUser.data?.countryCode));\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n if (!hasPresentationsLoaded)\n return ratings;\n\n if (availablePresentations?.length > 1 || !activePresentation)\n return ratings;\n\n const learningLevel = TopicsHelper.getMappedPresentationLevel(activePresentation.learningLevel);\n if (learningLevel !== PresentationLearningLevel.Level_1)\n return ratings;\n\n return {\n ...ratings,\n data: ratings.data?.filter(rating => {\n // Primary schools shouldn't see ratings higher than PG\n return rating.code && rating.value < 64;\n })\n };\n}\n\n/**\n * This hook contains all the simple data fetching that normally sits in the view.\n * I've done this to help promote readability of of the SearchResultsView - Sha\n */\nexport function useFetchSearchData(\n queryParams: HashObject\n) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const userDetails = Flight.useBasicFetch<User>(currentUser.data?.id && UserRequests.user(currentUser.data.id));\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n const products = useProducts();\n const settings = useSettings(null);\n\n const {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n } = useGetLibraries();\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n const currentPresentationId = activePresentation?.id;\n\n const curriculums = useCurriculums();\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(activePresentation);\n const schoolLevelIds = schoolLevels.data?.schoolLevels?.map(o => o.id);\n const availableTopics = Flight.useBasicFetch<TopicResults>(schoolLevels?.data &&\n ClassificationRequests.topicsFromAllAvailablePresentations(schoolLevelIds));\n\n const ratings = useGetRatings();\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n const canUseSeriesActions = hasLocalPermissions(LocalPermissionName.UseSeriesActions);\n const hasCustomLibraries = hasPermissions(PermissionName.ViewLibraries);\n const hasMoviesAndTv = hasPermissions(PermissionName.ViewMoviesTv);\n\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n const topics = useSearchTopics(\n queryParams,\n ratings.data,\n currentPresentationId,\n availablePresentations,\n isLearner\n );\n\n const companies = useSearchCompanies(\n queryParams,\n ratings.data,\n availablePresentations,\n hasMoviesAndTv\n );\n\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams\n });\n\n const hasDataLoaded = (\n audiences.hasCompleted &&\n hasPresentationsLoaded &&\n currentUser.hasCompleted &&\n (!currentUser.data?.isAuthenticated || userDetails.hasCompleted) &&\n ratings.hasCompleted &&\n config.hasCompleted &&\n availablePresentations &&\n (!currentUser.data?.isAuthenticated || !products.isLoadingProducts) &&\n !settings.isLoadingSettings &&\n hasLibrariesCompleted\n );\n\n return {\n queryParams,\n currentUser,\n userDetails,\n config,\n yearGroups,\n products,\n settings,\n curriculums,\n audiences,\n schoolLevels,\n currentPresentation: activePresentation,\n availablePresentations,\n availableTopics,\n ratings,\n topics,\n companies,\n moviesAndTvDashboard,\n currentPresentationId,\n isLearner,\n isGuest,\n canUseSeriesActions,\n libraries,\n hasDataLoaded,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n hasPermissions,\n hasLocalPermissions,\n hasCustomLibraries,\n hasMoviesAndTv,\n showStreamableSearchResults\n };\n}\n\nexport function useFetchSearchDataV2(\n queryParams: HashObject\n) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const userDetails = Flight.useBasicFetch<User>(currentUser.data?.id && UserRequests.user(currentUser.data.id));\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n const products = useProducts();\n const settings = useSettings(null);\n const isTertiary = useIsTertiary();\n\n const {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n } = useGetLibraries();\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n const currentPresentationId = activePresentation?.id;\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(activePresentation);\n const schoolLevelIds = schoolLevels.data?.schoolLevels?.map(o => o.id);\n const availableTopics = Flight.useBasicFetch<TopicResults>(schoolLevels?.data &&\n ClassificationRequests.topicsFromAllAvailablePresentations(schoolLevelIds));\n\n const ratings = useGetRatings();\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n const hasCustomLibraries = hasPermissions(PermissionName.ViewLibraries);\n const hasMoviesAndTv = hasPermissions(PermissionName.ViewMoviesTv);\n \n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams\n });\n\n const hasDataLoaded = (\n audiences.hasCompleted &&\n hasPresentationsLoaded &&\n currentUser.hasCompleted &&\n (!currentUser.data?.isAuthenticated || userDetails.hasCompleted) &&\n ratings.hasCompleted &&\n config.hasCompleted &&\n availablePresentations &&\n (!currentUser.data?.isAuthenticated || !products.isLoadingProducts) &&\n !settings.isLoadingSettings &&\n hasLibrariesCompleted\n );\n\n return {\n queryParams,\n currentUser,\n userDetails,\n yearGroups,\n products,\n settings,\n audiences,\n schoolLevels,\n currentPresentation: activePresentation,\n availablePresentations,\n availableTopics,\n ratings,\n moviesAndTvDashboard,\n currentPresentationId,\n isLearner,\n isGuest,\n libraries,\n hasDataLoaded,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n hasPermissions,\n hasLocalPermissions,\n hasCustomLibraries,\n showStreamableSearchResults,\n hasMoviesAndTv,\n isTertiary\n };\n}\n","import React from 'react';\n\nexport function FilterSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M17.437 8.5a2 2 0 0 0-3.874 0H4.5a.5.5 0 0 0 0 1h9.063a2 2 0 0 0 3.874 0H19.5a.5.5 0 0 0 0-1zM16.5 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-12 5.5a.5.5 0 0 0 0 1h3.063a2 2 0 0 0 3.874 0H19.5a.5.5 0 0 0 0-1h-8.063a2 2 0 0 0-3.874 0zm5-.5a1 1 0 1 1 0 2 1 1 0 0 1 0-2'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])'\n].join(',');\n\nexport function useDialogKeyboardNavigation(onClose: () => void) {\n const focusRef = React.useRef<HTMLDivElement>(null);\n const [ hasFocused, setHasFocused ] = React.useState(false);\n\n function shouldFocusCheck(): boolean {\n return !!focusRef.current;\n }\n \n function focus(): void {\n if (!focusRef.current)\n return;\n \n focusRef.current.focus();\n setHasFocused(true);\n }\n \n function onKeyDown(event: React.KeyboardEvent<HTMLDivElement>): void {\n if (event.key === 'Escape') {\n onClose();\n return;\n }\n \n if (event.key !== 'Tab' || !focusRef.current)\n return;\n \n const focusable = Array.from(\n focusRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n \n if (focusable.length === 0) {\n event.preventDefault();\n focusRef.current.focus();\n return;\n }\n \n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n \n if (event.shiftKey && active === first) { // navigating backwards\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n }\n \n React.useEffect(() => {\n if (!shouldFocusCheck() || hasFocused) return;\n focus();\n }, [ focusRef.current, hasFocused ]);\n\n return {\n focusRef,\n onKeyDown\n };\n}\n",":local {\n .openInAppPrompt {\n z-index: 5000;\n max-height: 75vh;\n animation: slideUp 0.20s ease-out;\n }\n\n .mask {\n z-index: 4999;\n }\n\n @keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n}\n","import React from 'react';\n\nimport { useDialogKeyboardNavigation } from 'libs/shared/hooks/useDialogKeyboardNavigation';\n\nimport styles from './action-sheet.module.scss';\n\ninterface ActionSheetProps {\n onClose: () => void;\n}\n\nexport function ActionSheet(props: React.PropsWithChildren<ActionSheetProps>) {\n const { focusRef, onKeyDown } = useDialogKeyboardNavigation(props.onClose);\n\n return (\n <div>\n <div className={`modal-backdrop show ${styles.mask}`} onClick={props.onClose}/>\n <div\n className={`position-fixed w-100 bg-white pb-3 px-3 bottom-0 start-0 rounded-top-3 overflow-auto ${styles.openInAppPrompt}`}\n ref={focusRef}\n role='dialog'\n aria-label='Action sheet'\n aria-modal='true'\n tabIndex={-1}\n onKeyDown={onKeyDown}\n >\n {props.children}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { FilterIds, FilterState, FilterStateHash, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\ninterface SmScreenSearchFilterItemProps {\n filter: SearchFilter;\n filterState: FilterStateHash;\n hideCaret?: boolean;\n className?: string;\n isMoreFilter?: boolean;\n setParentDraftState?: (id: FilterIds, val: FilterState) => void;\n}\n\nexport function SmScreenSearchFilterItem(props: SmScreenSearchFilterItemProps) {\n const { filterState } = props;\n\n const currentFilterState = props.isMoreFilter ?\n filterState.moreFilters[props.filter.id] :\n filterState[props.filter.id];\n const [ draftState, setDraftState ] = React.useState<FilterState>(currentFilterState);\n \n function onSelectItem(state: FilterState): void {\n setDraftState(state);\n props.setParentDraftState(props.filter.id, state);\n }\n\n const FilterComponent = React.useMemo(() => {\n return props.filter.customComponent ?\n props.filter.customComponent :\n FilterHelper.mapTypeToComponent(props.filter.type);\n }, [props.filter.type]);\n\n return (\n <div className={props.className || ''}>\n <hr className='hr' />\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n filterState={filterState}\n isExpandable={true}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { ResetButton } from 'libs/shared/apps/search/components/reset-button/ResetButton';\nimport { DraftState, FilterIds, FilterState, FilterStateHash, MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { ActionSheet } from 'libs/shared/components/action-sheet/ActionSheet';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { LanguageNamespaceContext } from 'libs/shared/components/text/Text';\n\nimport { SmScreenSearchFilterItem } from 'apps/search/components/sm-screen-search-filter/SmScreenSearchFilterItem';\n\ntype SearchFiltersProps = {\n queryParams: HashObject,\n mainFilters: SearchFilter[],\n appLink: Core.AppLink,\n moreFilters?: MoreFilters,\n isFetchingOptions?: boolean,\n constantIndices?: SearchIndices[],\n analyticsOptions?: AnalyticsOptions,\n\n alignResetButtonLeft?: boolean,\n closeFilter: () => void,\n\n /**\n * Incremental changes flag for partner profiles\n */\n _hasPartnerProfiles?: boolean\n};\n\nconst namespace = 'search.smallScreenSearchFilters';\n\nexport function SmScreenSearchFilter(props: SearchFiltersProps) {\n const { queryParams, appLink, isFetchingOptions, constantIndices = []} = props;\n \n const currentState = React.useMemo(() => {\n return FilterHelper.deriveInitialStateFromQuery(queryParams, props.mainFilters, props.moreFilters, appLink);\n }, [ queryParams, isFetchingOptions, props.mainFilters, props.moreFilters, appLink ]);\n\n // use ref here to create a draft state intermediary holding state within the parent component\n const draftStateRef = React.useRef<FilterStateHash>(ObjectHelper.deepClone(currentState));\n const setDraftState = (id: FilterIds, val: FilterState) => draftStateRef.current[id] = val;\n const setMoreFilterDraftState = (id: FilterIds, val: FilterState) => draftStateRef.current['moreFilters'][id] = val;\n\n const indices = ArrayHelper.uniq([\n ...FilterHelper.getAppliedIndices(queryParams, true, props._hasPartnerProfiles),\n ...constantIndices\n ]);\n \n const { mainFilters, moreFilters } = FilterHelper.mixinDisabledFields(\n currentState,\n indices,\n props.mainFilters,\n props.moreFilters\n );\n \n // Separate the tag filter as it's rendered differently\n const mainFiltersWithoutTags = mainFilters.filter(f => f.type !== 'tag');\n\n function applyFilters() {\n const mainFilterState: DraftState = ObjectHelper.omit(draftStateRef.current, [ 'appLink', 'moreFilters' ]);\n const moreFilterState: Omit<FilterStateHash, 'moreFilters' | 'appLink'> = ObjectHelper.omit(draftStateRef.current?.moreFilters, ['appLink']);\n\n FilterHelper.applyFilter(\n [ ...mainFiltersWithoutTags, ...(moreFilters?.filters ?? []) ],\n currentState,\n { ...mainFilterState, ...moreFilterState },\n appLink\n );\n\n if (props.analyticsOptions) {\n FilterHelper.logFilterEvent(\n props.mainFilters,\n props.moreFilters,\n currentState,\n queryParams.query,\n props.analyticsOptions\n );\n }\n\n props.closeFilter();\n }\n\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => { document.body.style.overflow = ''; };\n }, []);\n\n return (\n <ActionSheet onClose={props.closeFilter}>\n <LanguageNamespaceContext.Provider value={namespace}>\n <div className='pt-3 mb-0 h4'>\n <Text phrase='heading'/>\n </div>\n {mainFiltersWithoutTags.map(filter => (\n <SmScreenSearchFilterItem\n key={filter.id}\n className='mb-4'\n filter={filter}\n filterState={currentState}\n setParentDraftState={setDraftState}\n />\n ))}\n {moreFilters && moreFilters.filters?.map(filter => (\n <SmScreenSearchFilterItem\n key={filter.id}\n className='mb-4'\n filter={filter}\n filterState={currentState}\n setParentDraftState={setMoreFilterDraftState}\n isMoreFilter={true}\n />\n ))}\n <div\n className='position-fixed bottom-0 start-0 p-3 d-flex justify-content-between flex-row-reverse bg-white w-100'\n >\n <button className='btn btn-dark justify-item-end' onClick={applyFilters}>\n {LanguageService.getPhrase(namespace, 'apply')}\n </button>\n {FilterHelper.hasActiveFilters(queryParams) && (\n <ResetButton\n mainFilters={props.mainFilters}\n moreFilters={props.moreFilters}\n currentQueryParam={queryParams.query}\n analyticsOptions={props.analyticsOptions}\n alignLeft={props.alignResetButtonLeft}\n filterState={currentState}\n onClick={props.closeFilter}\n />\n )}\n </div>\n </LanguageNamespaceContext.Provider>\n </ActionSheet>\n );\n}\n",":local {\n .filterButtonContainer {\n top: 5rem;\n z-index: 1020;\n margin-left: -1.5rem;\n margin-right: -1.5rem;\n padding: 0.75rem 1.5rem 0;\n\n &::before {\n content: '';\n position: absolute;\n bottom: 100%;\n left: 0;\n right: 0;\n height: 5rem;\n background-color: inherit;\n }\n }\n\n .filterButton {\n line-height: 1.5rem;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { EntityType, LocationContext } from 'libs/analytics/interfaces';\n\nimport { SearchFilters } from 'libs/shared/apps/search/components/search-filters/SearchFilters';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { FilterSvg } from 'libs/shared/images/svg/objects/FilterSvg';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { SmScreenSearchFilter } from 'apps/search/components/sm-screen-search-filter/SmScreenSearchFilter';\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\n\nimport styles from './search-results-filter.module.scss';\n\nconst namespace = 'search.searchResultsFilter';\n\ninterface SearchResultsFilterProps {\n searchData: ReturnType<typeof useFetchSearchDataV2>;\n queryParams: HashObject;\n filters: ReturnType<typeof SearchHelper.getFilters>;\n hideDivider: boolean;\n}\n\nexport function SearchResultsFilter(props: SearchResultsFilterProps) {\n const { searchData, queryParams, filters, hideDivider } = props;\n\n const breakpoint = useBreakpoints();\n const [ isSmScreenFilterOpen, setIsSmScreenFilterOpen ] = React.useState(false);\n\n const hasSearchData = !!searchData.audiences.data && !!searchData.ratings.data && !!searchData.availableTopics.data;\n\n return (\n <>\n {hasSearchData && (\n !breakpoint.xs ?\n <SearchFilters\n queryParams={queryParams}\n mainFilters={filters?.mainFilters}\n moreFilters={filters?.moreFilters}\n analyticsOptions={{\n entity: EntityType.SearchResults,\n location: LocationContext.SearchFilters\n }}\n appLink={{ application: AppChannels.SEARCH, action: Actions.Search.HOME }}\n hideDivider={hideDivider}\n _hasPartnerProfiles={searchData.settings.hasPartnerProfiles}\n /> :\n <div className={`position-sticky bg-white ${styles.filterButtonContainer}`}>\n <button className={`btn btn-dark w-100 mb-3 ${styles.filterButton}`} onClick={() => setIsSmScreenFilterOpen(true)}>\n <SvgContainer svg={FilterSvg}/>\n <span className='ms-1'>{LanguageService.getPhrase(namespace, 'filterText')}</span>\n </button>\n </div>\n )}\n {breakpoint.xs && isSmScreenFilterOpen &&\n <SmScreenSearchFilter\n queryParams={queryParams}\n mainFilters={filters?.mainFilters}\n moreFilters={filters?.moreFilters}\n analyticsOptions={{\n entity: EntityType.SearchResults,\n location: LocationContext.SearchFilters\n }}\n appLink={{ application: AppChannels.SEARCH, action: Actions.Search.HOME }}\n closeFilter={() => setIsSmScreenFilterOpen(false)}\n _hasPartnerProfiles={searchData.settings?.hasPartnerProfiles}\n />\n }\n </>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { FeedbackOption } from 'libs/shared/views/feedback/enums/FeedbackOption';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'search.searchResultsRequestVideo';\n\ninterface SearchResultsRequestVideo {\n skipBeforeRequestingVideoStep?: boolean;\n description?: string;\n}\n\nexport function SearchResultsRequestVideo(props: SearchResultsRequestVideo): JSX.Element {\n const { skipBeforeRequestingVideoStep = true } = props;\n \n return (\n <div className='d-flex flex-column align-items-center justify-content-center gap-3 mb-3'>\n {props.description ?\n <span>{props.description}</span> :\n <Text phrase='description' namespace={namespace} />\n }\n <AppLink\n appLink={{\n application: AppChannels.DEFAULT,\n action: Actions.Default.GIVE_FEEDBACK,\n params: {\n selectedOption: FeedbackOption.REQUEST_VIDEO,\n skipBeforeRequestingVideoStep: !!skipBeforeRequestingVideoStep\n }\n }}\n className='btn btn-outline-dark'\n >\n <Text phrase='requestVideo' namespace={namespace} />\n </AppLink>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { SearchResultsRequestVideo } from '../search-results-request-video/SearchResultsRequestVideo';\n\nconst namespace = 'search.searchResultsEmptyStateV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchResultsEmptyStateProps {\n query?: string;\n scotland?: boolean;\n hideRequestVideo?: boolean;\n}\n\nexport function SearchResultsEmptyState(props: SearchResultsEmptyStateProps): JSX.Element {\n const imageUrl = (props.scotland && props.query?.trim()?.toLowerCase() === 'nessie') ?\n ImageUrls.EmptyStates.Search.RESULTS_SCOTLAND :\n ImageUrls.EmptyStates.Search.RESULTS;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={imageUrl} />\n\n <EmptyState.Heading>\n {props.query ?\n <Text phrase='headingWithQuery' options={{ query: props.query }} /> :\n <Text phrase='headingWithoutQuery' />\n }\n </EmptyState.Heading>\n\n <EmptyState.Info className='w-50 m-0'>\n <Text phrase='info' />\n <AppLink\n className='info-link'\n appLink={{\n application: AppChannels.SUBJECT,\n action: Actions.Subjects.PRESENTATION_TOPICS,\n args: [null]\n }}\n >\n <Text phrase='topicsAppLink' />\n </AppLink>\n </EmptyState.Info>\n </EmptyState>\n \n {!props.hideRequestVideo &&\n <SearchResultsRequestVideo description={getPhrase('requestVideoInfo')} />\n }\n </LanguageNamespaceContext.Provider>\n );\n}\n","import { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SEARCH_CURRICULUM_CODE_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nexport interface DetectCurriculumCodeSearchOptions {\n isCurriculumCodeSearch: boolean;\n data: WidgetSearchItem[];\n}\n\n/**\n * Detect if we are dealing with a curriculum code search widget\n * Update the search bar UI when we detect that a curriculum code has been searched for\n * and trigger applink to update url params\n */\nexport function detectCurriculumCodeSearch(\n options: DetectCurriculumCodeSearchOptions\n): void {\n const widgets = options.data;\n\n if (!widgets || !widgets.length)\n return;\n \n widgets.forEach(widget => {\n if (widget.widgetId !== WidgetTypeId.SearchCurriculumCode)\n return;\n \n const hasSearchedCode = !!widget?.content?.name && !!widget?.content?.description;\n \n if (options.isCurriculumCodeSearch && !hasSearchedCode) {\n Core.AppLinkHelper.trigger({\n ...Core.AppLinkHelper.getCurrentAppLink(),\n params: {\n ...((Core.AppLinkHelper.getCurrentAppLink().params || {}) as HashObject),\n [SEARCH_CURRICULUM_CODE_PARAM]: undefined\n }\n }, { replace: true });\n return;\n }\n if (!options.isCurriculumCodeSearch && hasSearchedCode) {\n Core.AppLinkHelper.trigger({\n ...Core.AppLinkHelper.getCurrentAppLink(),\n params: {\n ...((Core.AppLinkHelper.getCurrentAppLink().params || {}) as HashObject),\n [SEARCH_CURRICULUM_CODE_PARAM]: true\n }\n }, { replace: true });\n return;\n }\n });\n}\n","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { BaseObject } from 'libs/shared/interfaces';\n\nexport interface FetchVideoAssocsObjectsOptions {\n fetchObjects: (objects: BaseObject[]) => void;\n data: WidgetSearchItem[];\n}\n\nexport function fetchVideoAssocsObjects(options: FetchVideoAssocsObjectsOptions): void {\n const widgets = options.data;\n\n if (!widgets || !widgets.length)\n return;\n \n const objects = widgets.reduce((outer, widget) => {\n return widget.content.data.reduce((inner, video) => ([ ...inner, video ]), outer);\n }, []);\n \n if (!objects.length)\n return;\n \n options.fetchObjects(objects);\n}\n","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { detectCurriculumCodeSearch, DetectCurriculumCodeSearchOptions } from './detectCurriculumCodeSearch';\nimport { fetchVideoAssocsObjects, FetchVideoAssocsObjectsOptions } from './fetchVideoAssocsObjects';\n\ntype AllOnLoadWidgetTriggerOptions =\n & DetectCurriculumCodeSearchOptions &\n FetchVideoAssocsObjectsOptions;\ntype GetOnLoadWidgetTriggersOptions = Omit<AllOnLoadWidgetTriggerOptions, 'data'>;\n\nexport function getOnLoadWidgetTriggers(\n options: GetOnLoadWidgetTriggersOptions\n): Array<(data: WidgetSearchItem[]) => void> {\n return [\n data => detectCurriculumCodeSearch({ data, ...options }),\n data => fetchVideoAssocsObjects({ data, ...options })\n ];\n}\n","import { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\nexport function mergeSearchResults(options: SearchResultsTransformOptions): SearchResultsTransformOptions {\n const { data } = options;\n\n if (!data) return options;\n \n const mergedWidgets = WidgetHelper.mergeWidgets(data, (target, source) => {\n target.content.data = [\n ...(target.content.data || []),\n ...source.content.data\n ];\n });\n\n return {\n ...options,\n data: mergedWidgets\n };\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\nimport { mergeSearchResults } from './mergeSearchResults';\n\nfunction getData(options: SearchResultsTransformOptions): WidgetSearchItem[] {\n if (!options.data) {\n throw new DevError('Data is not defined in the options');\n }\n\n return options.data;\n}\n\nexport function getSearchResultsTransformers(): Array<UseTransformerFunc<WidgetSearchItem[]>> {\n return [\n data => getData(mergeSearchResults({ data }))\n ];\n}\n","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport type { Classification } from 'libs/shared/interfaces';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\n/**\n * Sort first six Relevant topics widget by Exact matches and then by presentation level \n */\nexport function transformSearchRelevantTopics(\n options: WidgetSearchItemTransformOptions\n): WidgetSearchItemTransformOptions {\n if (options.data.widgetId !== WidgetTypeId.SearchRelevantTopics)\n return options;\n\n function sortByLearningLevel(a: Classification, b: Classification) {\n return TopicsHelper.sortByLearningLevel(a, b, options.availablePresentations);\n }\n\n /**\n * We only want to sort the first 6 items.\n * Anything after that are items added\n * through pagination.\n */\n const relevantTopicsData = options.data.content.data.slice(0, 6);\n const remainingTopicsData = options.data.content.data.slice(6);\n \n const exactMatchSortedTopics: Classification[] = [];\n const remainingSortedTopics: Classification[] = [];\n \n relevantTopicsData.forEach(topic => {\n if (!MasterTypeHelper.isClassification(topic))\n return;\n \n if (topic?.name?.toLowerCase() === options.query?.toLowerCase()) {\n exactMatchSortedTopics.push(topic);\n return;\n }\n \n remainingSortedTopics.push(topic);\n });\n \n exactMatchSortedTopics.sort(sortByLearningLevel);\n remainingSortedTopics.sort(sortByLearningLevel);\n \n const sortedItem = {\n ...options.data,\n content: {\n ...options.data.content,\n data: [\n ...exactMatchSortedTopics,\n ...remainingSortedTopics,\n ...remainingTopicsData\n ]\n }\n };\n \n options = {\n ...options,\n data: sortedItem\n };\n\n return options;\n}\n","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\n/**\n * Transform search tag data so that its id is its name\n */\nexport function transformSearchTags(options: WidgetSearchItemTransformOptions): WidgetSearchItemTransformOptions {\n if (options.data.widgetId !== WidgetTypeId.SearchTags)\n return options;\n\n const normalizedItemData = options.data.content.data.map(x => ({\n id: x.name,\n ...x\n }));\n\n options.data = {\n ...options.data,\n content: {\n ...options.data.content,\n data: normalizedItemData\n }\n };\n\n return options;\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\nimport { transformSearchRelevantTopics } from './transformSearchRelevantTopics';\nimport { transformSearchTags } from './transformSearchTags';\n\nfunction getData(options: WidgetSearchItemTransformOptions): WidgetSearchItem {\n if (!options.data) {\n throw new DevError('Data is not defined in the options');\n }\n\n return options.data;\n}\n\ntype GetSearchWidgetItemTransformersOptions = Omit<WidgetSearchItemTransformOptions, 'data'>;\n\nexport function getSearchWidgetItemTransformers(\n options: GetSearchWidgetItemTransformersOptions\n): Array<UseTransformerFunc<WidgetSearchItem>> {\n return [\n data => getData(transformSearchTags({ data, ...options })),\n data => getData(transformSearchRelevantTopics({ data, ...options }))\n ];\n}\n","import { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { SourceFilterOptions, TypeFilterOptions } from 'libs/shared/apps/search/interfaces';\nimport { WidgetFilter } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { BaseObject, DashboardTargetType } from 'libs/shared/interfaces';\n\ninterface HasQueryParamOptions {\n queryParams: HashObject;\n key: string;\n value: string;\n}\n\ninterface GetWidgetIdsFromQueryParamsOptions {\n settingsHash: SettingsHash;\n}\n\ninterface GetWidgetFiltersOptions {\n queryParams: HashObject;\n widgetTypeId: WidgetTypeId;\n cursor?: string;\n options?: GetWidgetIdsFromQueryParamsOptions;\n}\n\nconst SupportedSearchWidgetTypeIds: WidgetTypeId[] = [\n WidgetTypeId.SearchRelevantTopics,\n WidgetTypeId.SearchCompanies,\n WidgetTypeId.SearchPlaylists,\n WidgetTypeId.SearchSeries,\n WidgetTypeId.SearchTopResults,\n WidgetTypeId.SearchMyVideos,\n WidgetTypeId.SearchMyVideosFolder,\n WidgetTypeId.SearchMySchoolLibraryVideos,\n WidgetTypeId.SearchMySchoolLibraryFolder,\n WidgetTypeId.SearchExchangeArchive,\n WidgetTypeId.SearchClickViewLive,\n WidgetTypeId.SearchRelatedResults,\n WidgetTypeId.SearchCurriculumCode,\n WidgetTypeId.SearchContentPartners\n];\n\nfunction hasQueryParam(options: HasQueryParamOptions) {\n const targetParam = options.queryParams?.[options.key];\n \n if (typeof targetParam === 'string') {\n return targetParam === options.value;\n }\n\n if (!Array.isArray(targetParam)) {\n return false;\n }\n\n return targetParam.includes(options.value);\n}\n\nfunction getValidFocusedWidget(queryParams: HashObject, options: GetWidgetIdsFromQueryParamsOptions): WidgetTypeId {\n if (!queryParams?.focus)\n return;\n\n let widgetTypeId: WidgetTypeId;\n\n if (typeof queryParams.focus === 'string') {\n widgetTypeId = SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus);\n }\n\n if (Array.isArray(queryParams.focus) && queryParams.focus.length === 1) {\n widgetTypeId = SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus[0]);\n }\n\n if (!widgetTypeId)\n return;\n\n const widgetTypeIdConfig = WidgetTypeIdConfig[widgetTypeId];\n\n if (!widgetTypeIdConfig?.predicate?.({ targetType: DashboardTargetType.Search, settingsHash: options.settingsHash }))\n return;\n\n return widgetTypeId;\n}\n\nfunction getWidgetIdsFromQueryParams(\n queryParams: HashObject,\n options?: GetWidgetIdsFromQueryParamsOptions\n): WidgetTypeId[] {\n const widgets: WidgetTypeId[] = [];\n\n const focusedWidget = getValidFocusedWidget(queryParams, options);\n\n if (focusedWidget) {\n return [ focusedWidget, WidgetTypeId.SearchTags ];\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Classification, queryParams })) {\n widgets.push(WidgetTypeId.SearchRelevantTopics);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Company, queryParams })) {\n widgets.push(WidgetTypeId.SearchCompanies);\n }\n\n if (options.settingsHash?.hasPartnerProfiles && hasQueryParam({ key: 'type', value: TypeFilterOptions.PartnerProfile, queryParams })) {\n widgets.push(WidgetTypeId.SearchContentPartners);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Series, queryParams })) {\n widgets.push(WidgetTypeId.SearchSeries);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Playlist, queryParams })) {\n widgets.push(WidgetTypeId.SearchPlaylists);\n }\n\n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Category, queryParams })) {\n widgets.push(WidgetTypeId.SearchMySchoolLibraryFolder, WidgetTypeId.SearchMyVideosFolder);\n }\n \n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.ExchangeArchive, queryParams })) {\n widgets.push(WidgetTypeId.SearchExchangeArchive);\n }\n\n if (options?.settingsHash?.clickViewLive && hasQueryParam({ key: 'source', value: SourceFilterOptions.LiveStreams, queryParams })) {\n widgets.push(WidgetTypeId.SearchClickViewLive);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.MyVideos, queryParams })) {\n widgets.push(WidgetTypeId.SearchMyVideos, WidgetTypeId.SearchMyVideosFolder);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.ClickView, queryParams })) {\n widgets.push(WidgetTypeId.SearchTopResults, WidgetTypeId.SearchRelatedResults);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.School, queryParams })) {\n widgets.push(WidgetTypeId.SearchMySchoolLibraryVideos, WidgetTypeId.SearchMySchoolLibraryFolder);\n }\n\n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Video, queryParams }) ||\n hasQueryParam({ key: 'type', value: TypeFilterOptions.Clip, queryParams }) ||\n hasQueryParam({ key: 'type', value: TypeFilterOptions.Interactive, queryParams })) {\n widgets.push(\n WidgetTypeId.SearchTopResults,\n WidgetTypeId.SearchRelatedResults,\n WidgetTypeId.SearchMySchoolLibraryVideos,\n WidgetTypeId.SearchMyVideos,\n WidgetTypeId.SearchExchangeArchive,\n WidgetTypeId.SearchClickViewLive,\n WidgetTypeId.SearchCurriculumCode\n );\n }\n\n if (widgets.length) {\n widgets.push(WidgetTypeId.SearchTopResults);\n widgets.push(WidgetTypeId.SearchTags);\n }\n\n return ArrayHelper.uniq(widgets);\n}\n\nexport const SearchResultsFilterHelper = {\n isOnlyActiveWidget(widgetId: WidgetTypeId, queryParams: HashObject): boolean {\n const targetParam = queryParams?.['focus'];\n \n if (typeof targetParam === 'string')\n return targetParam.toLowerCase() === widgetId.toLowerCase();\n \n if (!Array.isArray(targetParam))\n return false;\n \n if (targetParam.length !== 1)\n return false;\n \n return !!targetParam.find(p => p.toLowerCase() === widgetId.toLowerCase());\n },\n\n getActiveWidgetFilters(\n queryParams: HashObject,\n options?: GetWidgetIdsFromQueryParamsOptions\n ): WidgetFilter[] {\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams, options);\n \n return widgets.map(w => ({ id: w }));\n },\n\n getWidgetFilters(params: GetWidgetFiltersOptions): WidgetFilter[] {\n const { queryParams, widgetTypeId, cursor, options } = params;\n \n if (cursor) {\n return [{\n id: widgetTypeId,\n cursor\n }];\n }\n\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams, options);\n return widgets.map(w => ({ id: w }));\n },\n\n getSelectedTagOrClassification(queryParams: HashObject): BaseObject[] {\n if (typeof queryParams?.tagOrClassification === 'string')\n return [{ id: queryParams.tagOrClassification, name: queryParams.tagOrClassification }];\n\n if (Array.isArray(queryParams?.tagOrClassification))\n return queryParams.tagOrClassification.map((tag: string) => ({\n id: tag,\n name: tag\n }));\n\n return [];\n },\n\n getSearchWidgetSelectedItems(queryParams: HashObject, widgetTypeId: WidgetTypeId): BaseObject[] {\n if (widgetTypeId !== WidgetTypeId.SearchTags)\n return [];\n\n return SearchResultsFilterHelper.getSelectedTagOrClassification(queryParams);\n }\n};\n","import { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { MixedWidgetSearchResultsProps } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport type { AudienceFilterParams, BaseObject, Classification, Company, Folder, GetClassificationAppLinkOptions, Playlist, Presentation, Series, VideoTypes } from 'libs/shared/interfaces';\nimport { GetVideoAppLinkOptions } from 'libs/shared/interfaces/VideoAppLinkOptions';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { ContentPartnerAppLinkHelper } from 'shared/utils/ContentPartnerAppLinkHelper';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { getFolderAppLink } from 'apps/libraries/views/library-folder/LibraryFolderViewUtils';\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nimport { SearchResultsFilterHelper } from './SearchResultsFilterHelper';\n\ninterface GetSeeMoreAppLinkOptions {\n widget: WidgetSearchItem;\n appLinks: MixedWidgetSearchResultsProps['widgetAppLinks'];\n queryParams: HashObject;\n isLastWidget: boolean;\n}\n\nfunction hasMoreContent(widget: WidgetSearchItem): boolean {\n return !!widget.content.cursor;\n}\n\nexport const SearchResultsAppLinkHelper = {\n getSearchWidgetAppLinks(\n queryParams: HashObject,\n audienceParams: AudienceFilterParams,\n availablePresentations: Presentation[],\n presentationSlug: string\n ): MixedWidgetSearchResultsProps['widgetAppLinks'] {\n return {\n partner: ContentPartnerAppLinkHelper.getPartnerDashboardAppLink,\n classification: (classification?: Classification) => {\n const options: GetClassificationAppLinkOptions = {\n ...audienceParams,\n moviesAndTv: TopicsHelper.isMtv(classification)\n };\n\n return ClassificationAppLinkHelper.getAppLink(classification, options, availablePresentations);\n },\n\n videoType: (video: VideoTypes, opts: GetVideoAppLinkOptions) => (\n VideoAppLinkHelper.getAppLink(video, {\n ...opts,\n includeContext: false\n }, presentationSlug)\n ),\n \n series: (series: Series) => SeriesAppLinkHelper.getSeriesAppLink(series, {}, presentationSlug),\n \n playlist: (playlist: Playlist) => ({\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.PLAYLIST,\n args: [ null, playlist.id, TextHelper.slugify(playlist.name) ]\n }),\n \n company: (company: Company) => ({\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.COMPANY_DASHBOARD,\n args: [\n null,\n company.id,\n TextHelper.slugify(company.name)\n ]\n }),\n \n folder: (folder: Folder, opts?: { libraryId?: string }) => {\n if (!opts?.libraryId) {\n return {\n application: AppChannels.MY_VIDEOS,\n action: Actions.MyVideos.MY_VIDEOS_FOLDER,\n args: [ folder.id, TextHelper.slugify(folder.name) ]\n };\n }\n \n return getFolderAppLink(opts?.libraryId, folder, null);\n },\n \n searchSettings: () => ({\n application: AppChannels.SETTINGS,\n action: Actions.Settings.PLATFORM_SETTINGS\n }),\n \n searchHome: (filterParams?: HashObject, options?: { replace: boolean }) => {\n let params: HashObject = { ...filterParams };\n \n if (!options?.replace) {\n params = {\n ...queryParams,\n ...params\n };\n }\n \n return ({\n application: AppChannels.SEARCH,\n action: Actions.Search.HOME,\n // This empty args array needs to be here otherwise FixedWidget will try to\n // populate it with some junk that'll break the query params.\n // This is tech debt that needs to be cleaned up.\n args: [],\n params\n });\n },\n\n tag: (tag: BaseObject) => {\n let tagOrClassification: string[] =\n SearchResultsFilterHelper.getSelectedTagOrClassification(queryParams).map(x => x.name);\n \n if (tagOrClassification.includes(tag.name)) {\n tagOrClassification = tagOrClassification.filter(x => x !== tag.name);\n } else {\n tagOrClassification.push(tag.name);\n }\n\n return ({\n action: Actions.Search.HOME,\n application: AppChannels.SEARCH,\n params: {\n ...queryParams,\n tagOrClassification\n }\n });\n },\n\n getPreviewQuestionsAppLink: interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)\n };\n },\n\n getSeeMoreAppLink(options: GetSeeMoreAppLinkOptions): Core.AppLink {\n if (!hasMoreContent(options.widget))\n return;\n \n const getAppLinkFunc = WidgetTypeIdConfig[options.widget.widgetId]?.getCollectionAppLink;\n \n if (!getAppLinkFunc || SearchResultsFilterHelper.isOnlyActiveWidget(options.widget.widgetId, options.queryParams))\n return;\n \n /**\n * If its the only widget search result item rendered we infinitely\n * load the widget (if we can) therefore we need to hide 'See all' applink\n * - Nish\n */\n if (options.isLastWidget)\n return;\n \n return getAppLinkFunc(options.appLinks);\n }\n};\n\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { MixedWidgetSearchResults } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { SharedSearchRequests } from 'libs/shared/apps/search/flight-requests/SharedSearchRequests';\nimport { SearchDashboard } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SEARCH_CURRICULUM_CODE_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { VideoHighlight } from 'libs/shared/components/video-highlight/VideoHighlight';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ContentRegion } from 'libs/shared/enums/ContentRegion';\nimport { LiteSupportArticle } from 'libs/shared/enums/SupportArticle';\nimport { TutorialVideoType } from 'libs/shared/enums/TutorialVideoType';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useTutorialVideoHighlight } from 'libs/shared/hooks/useTutorialVideoHighlight';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useVideoMixinFunc } from 'shared/hooks/useVideoMixin';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\nimport { SearchResultsFilter } from 'apps/search/views/search-results-v2/components/search-results-filter/SearchResultsFilter';\n\nimport { SearchResultsEmptyState } from './components/search-results-empty-state/SearchResultsEmptyState';\nimport { SearchResultsRequestVideo } from './components/search-results-request-video/SearchResultsRequestVideo';\nimport { getOnLoadWidgetTriggers } from './transformations/on-load/OnLoadWidgets';\nimport { getSearchResultsTransformers } from './transformations/results/SearchResultsTransformations';\nimport { getSearchWidgetItemTransformers } from './transformations/widget-item/WidgetItemTransformations';\nimport { SearchResultsAppLinkHelper } from './utils/SearchResultsAppLinkHelper';\nimport { SearchResultsFilterHelper } from './utils/SearchResultsFilterHelper';\n\nexport const namespace = 'search.searchResultsV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchResultsViewV2Props {\n queryParams: HashObject;\n}\n\ntype EmptyWidgetsState = {[key in WidgetTypeId]?: boolean };\n\nexport function SearchResultsViewV2(props: SearchResultsViewV2Props): JSX.Element {\n const { queryParams = {} } = props;\n\n const [ isEmpty, setIsEmpty ] = React.useState<EmptyWidgetsState>({});\n\n const { appLink } = useTutorialVideos();\n\n const { shouldShowVideo, tutorialVideo, hasDismissedVideoHighlight, dismissVideoHighlight } =\n useTutorialVideoHighlight(TutorialVideoType.SearchAndDiscover);\n \n const videoMixin = useVideoMixinFunc();\n\n function onSetIsEmpty(id: WidgetTypeId, isEmpty: boolean) {\n setIsEmpty(prevState => ({\n ...prevState,\n [id]: isEmpty\n }));\n }\n \n useSetPageMetadata(PageMetadataHelper.getDefaultMetadata({\n title: queryParams.query ?? '',\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n allowIndexing: false\n }));\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem, presentationSlug: null });\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.VideoThumbnail,\n mtv: queryParams.moviesAndTv\n });\n\n /**\n * Data required for search view to render\n */\n const searchData = useFetchSearchDataV2(queryParams);\n\n /**\n * Filters to be applied globally or on indices\n */\n const searchFilters = SearchHelper.getBackendFiltersV2(searchData);\n\n /**\n * Fetch the search dashboard data so we know what widgets to show / fetch\n * for a given query and filters\n */\n const searchDashboard = Flight.useBasicFetch<SearchDashboard>(searchData.hasDataLoaded\n && SharedSearchRequests.searchDashboard(\n queryParams.query,\n searchFilters.backendFilters,\n SearchResultsFilterHelper.getActiveWidgetFilters(\n queryParams,\n { settingsHash: searchData.settings }\n )\n ));\n\n const searchDashboardData = searchDashboard.data?.filter(item => !isEmpty[item.widgetId]);\n \n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasLivePresentationOnly } = useAvailablePresentations();\n \n /**\n * State of the current filters\n */\n const filters = SearchHelper.getFilters({\n data: searchData,\n inaccessibleIndices: searchFilters?.inaccessibleIndices,\n _hasNewSearch: true,\n _hasPartnerProfiles: searchData.settings.hasPartnerProfiles,\n hasCVFilters: !hasLivePresentationOnly\n });\n \n /**\n * Do we have the data we need for the entire view to render\n */\n const hasLoaded = (\n searchData.hasDataLoaded && filters\n );\n\n /**\n * Do we have the data we need to render our results\n */\n const hasSearchCompleted = (\n searchDashboard.hasCompleted &&\n !!filters\n );\n\n /**\n * Do we actually have results\n */\n const hasResults = (\n hasSearchCompleted && (!!searchDashboardData && searchDashboardData.length)\n );\n\n const showEmptyState = !hasResults && !searchDashboard.isFetching;\n\n const hideDivider = (\n (!searchDashboard.hasCompleted && searchDashboard.isFetching) ||\n (hasResults && !!searchDashboardData.find(item => item.widgetId === WidgetTypeId.SearchTags))\n );\n\n const widgetAppLinks = SearchResultsAppLinkHelper.getSearchWidgetAppLinks(\n queryParams,\n AudienceHelper.getAudienceParams(activeAudiences),\n availablePresentations,\n activePresentation?.vanitySlug\n );\n\n function getContentRequest(widgetTypeId: WidgetTypeId, cursor?: string): Flight.Request {\n if (!searchData.hasDataLoaded)\n return;\n\n return SharedSearchRequests.searchDashboardWidget(\n widgetTypeId,\n queryParams.query,\n searchFilters.backendFilters,\n SearchResultsFilterHelper.getWidgetFilters({\n queryParams,\n widgetTypeId,\n cursor,\n options: { settingsHash: searchData.settings }\n })\n );\n }\n\n /**\n * Transform the search results for a widget before rendering\n * - Merges multiple widgets data into single widget for any template Id\n */\n const searchResultsTransformers = getSearchResultsTransformers();\n /**\n * Transform the search widget items before rendering\n * - Transform search tags to normalize the widget data\n * - Transform search relevant topics to sort by exact match and then presentation level\n */\n const widgetItemTransformers = getSearchWidgetItemTransformers({\n query: queryParams.query,\n availablePresentations: searchData.availablePresentations\n });\n /**\n * Do something with search widget response data when it is first loaded\n * - Detect curriculum code search and updates URL\n * - Exclude video ids from related results widget\n * - Fetches video assocs for valid objects\n */\n const widgetsOnLoadTriggers = getOnLoadWidgetTriggers({\n fetchObjects: videoMixin.fetchObjects,\n isCurriculumCodeSearch: !!queryParams[SEARCH_CURRICULUM_CODE_PARAM]\n });\n\n /**\n * Side Effects below\n */\n React.useEffect(() => {\n // Reset this anytime search dasboard data changes\n setIsEmpty({});\n }, [searchDashboard.data]);\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <div className='px-4'>\n <SearchResultsFilter\n searchData={searchData}\n queryParams={queryParams}\n filters={filters}\n hideDivider={hideDivider}\n />\n\n {(() => {\n if (showEmptyState) {\n return (\n <SearchResultsEmptyState\n query={queryParams.query}\n scotland={searchData.currentUser.data?.contentRegion === ContentRegion.SCOT}\n hideRequestVideo={searchData.isLearner}\n />\n );\n }\n\n return (\n <section>\n <VideoActionsContext.Provider value={videoActions}>\n <MixedWidgetSearchResults\n data={searchDashboardData}\n\n widgetAppLinks={widgetAppLinks}\n isTertiary={searchData.isTertiary}\n commonVideoProps={commonVideoProps}\n audiences={searchData.audiences.data}\n currentUser={searchData.currentUser.data}\n availablePresentations={searchData.availablePresentations}\n settingsHash={searchData.settings}\n \n setIsEmpty={onSetIsEmpty}\n getRequest={getContentRequest}\n hasPermissions={searchData.hasPermissions}\n hasLocalPermissions={searchData.hasLocalPermissions}\n getSeeMoreAppLink={(widget, isLastWidget) => SearchResultsAppLinkHelper.getSeeMoreAppLink({\n widget,\n queryParams,\n isLastWidget,\n appLinks: widgetAppLinks\n })}\n getAnalyticsData={(widget, yIndex, xIndex) => ({\n widgetId: widget.widgetId,\n widgetName: widget.name,\n templateId: widget.templateId,\n widgetIndex: yIndex,\n itemIndex: xIndex,\n search: {\n query: queryParams.query || ''\n }\n })}\n getSelectedItems={widget =>\n SearchResultsFilterHelper.getSearchWidgetSelectedItems(queryParams, widget)\n }\n\n onLoadWidgetsTriggers={widgetsOnLoadTriggers}\n widgetItemTransformers={widgetItemTransformers}\n searchResultsTransformers={searchResultsTransformers}\n >\n {\n shouldShowVideo && tutorialVideo?.data && !hasDismissedVideoHighlight &&\n <div className='mb-3'>\n <VideoHighlight\n video={tutorialVideo?.data}\n subtitle={getPhrase('videoHighlightSubtitle')}\n description={getPhrase('videoHighlightDescription')}\n bgColorClassName='bg-light-green'\n appLink={VideoAppLinkHelper.getAppLink(tutorialVideo?.data, {}, null)}\n locationContext={LocationContext.SearchBar}\n commonVideoProps={commonVideoProps}\n sharedPlaylistAppLink={appLink}\n supportArticle={ArticleHelper.getLiteArticle(LiteSupportArticle.SearchAndDiscover)}\n onDismiss={dismissVideoHighlight}\n />\n </div>\n }\n </MixedWidgetSearchResults>\n \n {(!searchData.isLearner && !searchDashboard.isFetching) &&\n <SearchResultsRequestVideo />\n }\n \n </VideoActionsContext.Provider>\n </section>\n );\n })()}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BYJa-jEI2.chunk.js","names":[],"sources":["../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/components/search-widget-tooltip/SearchWidgetTooltip.tsx","../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/mixed-widget-search-results.module.scss","../../../../libs/shared/src/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults.tsx","../../../../libs/shared/src/apps/search/constants/SearchOGQL.ts","../../../../libs/shared/src/apps/search/flight-requests/SharedSearchRequests.ts","../../src/apps/search/hooks/useFetchSchoolLevels.ts","../../src/apps/search/hooks/useFetchSearchData.tsx","../../../../libs/shared/src/images/svg/objects/FilterSvg.tsx","../../../../libs/shared/src/hooks/useDialogKeyboardNavigation.ts","../../../../libs/shared/src/components/action-sheet/action-sheet.module.scss","../../../../libs/shared/src/components/action-sheet/ActionSheet.tsx","../../src/apps/search/components/sm-screen-search-filter/SmScreenSearchFilterItem.tsx","../../src/apps/search/components/sm-screen-search-filter/SmScreenSearchFilter.tsx","../../src/apps/search/views/search-results-v2/components/search-results-filter/search-results-filter.module.scss","../../src/apps/search/views/search-results-v2/components/search-results-filter/SearchResultsFilter.tsx","../../src/apps/search/views/search-results-v2/components/search-results-request-video/SearchResultsRequestVideo.tsx","../../src/apps/search/views/search-results-v2/components/search-results-empty-state/SearchResultsEmptyState.tsx","../../src/apps/search/views/search-results-v2/transformations/on-load/detectCurriculumCodeSearch.ts","../../src/apps/search/views/search-results-v2/transformations/on-load/fetchVideoAssocsObjects.ts","../../src/apps/search/views/search-results-v2/transformations/on-load/OnLoadWidgets.ts","../../src/apps/search/views/search-results-v2/transformations/results/mergeSearchResults.ts","../../src/apps/search/views/search-results-v2/transformations/results/SearchResultsTransformations.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchRelevantTopics.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchTags.ts","../../src/apps/search/views/search-results-v2/transformations/widget-item/WidgetItemTransformations.ts","../../src/apps/search/views/search-results-v2/utils/SearchResultsFilterHelper.ts","../../src/apps/search/views/search-results-v2/utils/SearchResultsAppLinkHelper.ts","../../src/apps/search/views/search-results-v2/SearchResultsViewV2.tsx"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { InfoSvg } from 'libs/shared/images/svg/status/InfoSvg';\n\nconst namespace = 'search.searchWidgetTooltip';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchWidgetTooltipProps {\n widgetId: WidgetTypeId;\n isTertiary: boolean;\n}\n\nfunction getWidgetPhrase(widgetId: WidgetTypeId, isTertiary: boolean) {\n const widgetTooltipPhraseMap: {[key in WidgetTypeId]?: string } = {\n [WidgetTypeId.SearchRelevantTopics]: 'relevantTopicsTooltip',\n [WidgetTypeId.SearchCompanies]: 'studiosAndChannelsTooltip',\n [WidgetTypeId.SearchTopResults]: 'topResultsTooltip',\n [WidgetTypeId.SearchSeries]: 'seriesTooltip',\n [WidgetTypeId.SearchPlaylists]: 'playlistsTooltip',\n [WidgetTypeId.SearchMyVideosFolder]: 'myVideosFoldersTooltip',\n [WidgetTypeId.SearchMySchoolLibraryFolder]: isTertiary ? 'mySchoolFoldersTooltipTertiary' : 'mySchoolFoldersTooltip',\n [WidgetTypeId.SearchMyVideos]: 'myVideosTooltip',\n [WidgetTypeId.SearchMySchoolLibraryVideos]: isTertiary ? 'mySchoolVideosTooltipTertiary' : 'mySchoolVideosTooltip',\n [WidgetTypeId.SearchExchangeArchive]: 'exchangeArchiveTooltip',\n [WidgetTypeId.SearchClickViewLive]: 'clickViewLiveTooltip',\n [WidgetTypeId.SearchRelatedResults]: 'relatedResultsTooltip',\n [WidgetTypeId.SearchContentPartners]: 'channelsTooltip'\n };\n\n return widgetTooltipPhraseMap[widgetId];\n}\n\nexport function SearchWidgetTooltip(props: SearchWidgetTooltipProps): JSX.Element {\n const phrase = getWidgetPhrase(props.widgetId, props.isTertiary);\n\n if (!phrase)\n return <></>;\n\n return (\n <SvgContainer\n className='svg-container text-secondary'\n svg={InfoSvg}\n title={getPhrase(phrase)}\n tooltipPlacement='top'\n tooltipSpanHack\n tooltipSpanHackClassName='ms-2'\n />\n );\n}\n",":local {\n $seriesWidget: 'search-series-widget';\n $posterTemplate: 'poster-fixed-list-large-widget-template';\n $thumbnailTemplate: 'thumbnail-fixed-list-media-small-widget-template';\n $tagSlidingListTemplate: 'tag-sliding-list-widget-template';\n\n .searchResultsWidgetsContainer {\n :global {\n .#{$seriesWidget}.#{$thumbnailTemplate} {\n\n // If a series poster widget with heading is a immediate sibling of series thumbnail widget\n +.#{$seriesWidget}.#{$posterTemplate}.curated-widget.has-heading .curated-widget-header {\n display: none;\n }\n }\n\n .#{$seriesWidget}.#{$posterTemplate} {\n\n // If a series thumbnail widget with heading is a immediate sibling of series poster widget\n +.#{$seriesWidget}.#{$thumbnailTemplate}.curated-widget.has-heading .curated-widget-header {\n display: none;\n }\n }\n\n .#{$tagSlidingListTemplate}.curated-widget {\n padding-bottom: map-get($spacers, 3); // 1rem (16px)\n margin-bottom: map-get($spacers, 4); // 1.5rem (24px)\n border-bottom: 1px solid $gray-300;\n }\n }\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport type { SearchDashboard, SearchDashboardItem, WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { AllSearchWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, type CurrentUser, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { SearchWidgetTooltip } from './components/search-widget-tooltip/SearchWidgetTooltip';\n\nimport styles from './mixed-widget-search-results.module.scss';\n\nconst namespace = 'search.mixedWidgetSearchResults';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getName(widget: WidgetSearchItem, isTertiary: boolean): string {\n if (widget.widgetId === WidgetTypeId.SearchMySchoolLibraryFolder)\n return isTertiary ? getPhrase('tertiaryFolderHeading') : widget.name;\n\n if (widget.widgetId === WidgetTypeId.SearchMySchoolLibraryVideos)\n return isTertiary ? getPhrase('tertiaryLibraryVideoHeading') : widget.name;\n\n return widget.name;\n}\n\nfunction getWidgetMetadata(widget: WidgetSearchItem): Partial<WidgetMetadata> {\n if (widget.widgetId === WidgetTypeId.SearchCurriculumCode) {\n return {\n curriculumLeafName: widget.content?.name,\n curriculumLeafDescription: widget.content?.description\n };\n }\n\n return {};\n}\n\nfunction getWidgetClassName(widget: WidgetSearchItem): string {\n /**\n * This is to uniquely idenfity the widget in search results when\n * search playlist widget comes after search series widget which\n * causes the search playlist widget header to be hidden.\n */\n if (widget.widgetId === WidgetTypeId.SearchSeries) {\n return 'search-series-widget';\n }\n return;\n}\n\n/**\n * Partial loading components can have different behavior depending on\n * if the predicate returns true or false.\n */\nfunction getPartialLoadingPredicate(item: SearchDashboardItem): boolean {\n return [WidgetTypeId.SearchTags].includes(item.widgetId);\n}\n\nexport interface MixedWidgetSearchResultsProps {\n data: SearchDashboard;\n widgetAppLinks: AllSearchWidgetTemplates['appLinks'];\n widgetAppLinkOptions?: AllSearchWidgetTemplates['appLinkOptions'];\n audiences: PresentationAudience[];\n availablePresentations: Presentation[];\n currentUser: CurrentUser;\n commonVideoProps: CommonVideoProps;\n isTertiary: boolean;\n settingsHash: SettingsHash;\n\n getAnalyticsData?: (widget: SearchDashboardItem, yIndex: number, xIndex: number) => HashObject;\n \n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n\n getRequest: (widgetTypeId: WidgetTypeId, cursor?: string) => Flight.Request;\n setIsEmpty?: (widget: WidgetTypeId, isEmpty: boolean) => void;\n\n getSeeMoreAppLink: (widget: WidgetSearchItem, isLastItem: boolean) => Core.AppLink;\n /**\n * Array of transformers to be applied to search results before rendering\n */\n searchResultsTransformers?: Array<UseTransformerFunc<WidgetSearchItem[]>>;\n /**\n * Array of transformers to be applied to each search widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<WidgetSearchItem>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: WidgetSearchItem[]) => void>;\n}\n\nexport function MixedWidgetSearchResults(props: React.PropsWithChildren<MixedWidgetSearchResultsProps>): JSX.Element {\n if (!props.data || !props.data.length)\n return <></>;\n\n return (\n <div className={styles.searchResultsWidgetsContainer}>\n {props.data.map((item, idx) => {\n const isLastWidget = props.data.length - 1 === idx;\n return (\n <React.Fragment key={item.widgetId}>\n <InfiniteWidgetContainerView<SearchDashboardItem, WidgetSearchItem, AllSearchWidgetTemplates>\n index={idx}\n item={item}\n dashboardTarget={DashboardTargetType.Search}\n \n getName={widget => getName(widget, props.isTertiary)}\n getWidgetMetadata={widget => getWidgetMetadata(widget)}\n \n infiniteFetch={isLastWidget}\n getCursor={widget => widget.content?.cursor}\n getRequest={cursor => props.getRequest(item.widgetId, cursor)}\n getPartialLoadingPredicate={() => getPartialLoadingPredicate(item)}\n \n getBadgeComponent={widget => (\n <SearchWidgetTooltip\n widgetId={widget.widgetId}\n isTertiary={props.isTertiary}\n />\n )}\n \n audiences={props.audiences}\n currentUser={props.currentUser}\n appLinks={props.widgetAppLinks}\n appLinkOptions={props.widgetAppLinkOptions}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n settingsHash={props.settingsHash}\n\n hasPermissions={props.hasPermissions}\n getWidgetClassName={getWidgetClassName}\n getAnalyticsData={props.getAnalyticsData}\n getSelectedItems={props.getSelectedItems}\n hasLocalPermissions={props.hasLocalPermissions}\n getSeeMoreAppLink={widget => props.getSeeMoreAppLink(widget, isLastWidget)}\n setIsEmpty={isEmpty => props.setIsEmpty(item.widgetId, isEmpty)}\n\n resultsTransformers={props.searchResultsTransformers}\n widgetItemTransformers={props.widgetItemTransformers}\n onLoadWidgetsTriggers={props.onLoadWidgetsTriggers}\n />\n {item.name === 'Tags' && props.children}\n </React.Fragment>\n );\n })}\n </div>\n );\n}\n","import { SharedWithStatements } from 'libs/shared/constants/WithStatements';\nimport { TagType } from 'libs/shared/enums/TagType';\n\n/**\n * OGQL used for search V5 endpoint\n */\nexport const SearchOGQL = {\n video: SharedWithStatements.VIDEO_COLLECTION,\n series: 'rating,tallPoster',\n playlist:\n 'videos[count(),thumbnail]{limit:1},interactives[count(),_thumbnail]{limit:1},' +\n 'clips[count(),_thumbnail]{limit:1}',\n classification: `_theme[banner,cover,tallposter,thumbnail,icon],cover,thumbnail,tags{tagtype:${TagType.Curation}}`,\n clip: SharedWithStatements.CLIP_COLLECTION,\n interactive: SharedWithStatements.INTERACTIVE_COLLECTION,\n company: 'logo',\n category: 'libraries[_logo],thumbnail',\n partner_profile: SharedWithStatements.PARTNER_PROFILE\n};\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { SearchOGQL } from 'libs/shared/apps/search/constants/SearchOGQL';\nimport { SearchIndices, SearchResultObjectTypes, SearchResults, SearchResultsObject } from 'libs/shared/apps/search/interfaces';\nimport type { WidgetFilter } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SharedSearchHelper } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport type { Playlist, Series } from 'libs/shared/interfaces';\nimport { ThemeAssetHelper } from 'libs/shared/utils/ThemeAssetHelper';\n\nfunction formatSearchResponse(response: SearchResults<SearchResultObjectTypes>) {\n /**\n * Until playlists and series are regionalised, search will always return every series/playlist that exists\n * even if the current user doesn't have access to the content inside (which will happen for example when playlists/series)\n * contain all UK library content but is being searched for by an AU user.\n *\n * For some search queries, this may result in search showing a bunch of \"empty\" playlists/series, which sucks.\n * This will filter all empty collections out and decrement the `totalResults` to avoid this and make search a better\n * experience.\n *\n * Ideally this will be removed one day when this regionalisation is no longer an issue.\n */\n let totalResults = response.totalResults;\n\n const results = response?.results?.filter(result => {\n if (result._index !== 'series' && result._index !== 'playlist')\n return true;\n\n if (result._index === 'playlist') {\n const playlist = result as SearchResultsObject<Playlist>;\n\n if (playlist.clips?.data?.length ||\n playlist.interactives?.data?.length ||\n playlist.videos?.data?.length)\n return true;\n\n totalResults--;\n return false;\n }\n\n if ((result as SearchResultsObject<Series>).videos?.data?.length === 0) {\n totalResults--;\n return false;\n }\n\n return true;\n }) ?? [];\n\n response.results = results;\n response.totalResults = totalResults;\n\n // The first search result will always have the highest score value.\n // We store it so that we can access it for subsequent results pages\n const resultMaxScore = results[0]?._score;\n\n return {\n ...response,\n results: SharedSearchHelper.mapMaxScoreToSearchResults(results, resultMaxScore)\n };\n}\n\nfunction stringifyObject(obj: HashObject): string {\n return Object.entries(obj).reduce((prev, [ , value ]) => {\n let stringifiedValue = value;\n\n if (typeof value === 'object') {\n stringifiedValue = stringifyObject(value);\n } else if ([ 'number', 'boolean', 'string' ].includes(typeof value)) {\n stringifiedValue = value.toString();\n }\n\n if (!prev.length)\n return stringifiedValue;\n\n return `${prev},${stringifiedValue}`;\n }, '');\n}\n\n/**\n * We want to map the filters to the global filters object but we need to remove the filter prefix\n * and exclude the presentation filter\n */\nfunction getGlobalFilters(filters: HashObject, widgetTypeId: WidgetTypeId | null): Record<string, any> {\n return Object.entries(filters)\n .reduce((prev, [ key, value ]) => {\n const actualKey = key.replace(FilterConstants.FILTER_PARAM_PREFIX, '');\n if (actualKey === 'presentation' &&\n widgetTypeId !== WidgetTypeId.SearchTopResults &&\n widgetTypeId !== WidgetTypeId.SearchRelatedResults &&\n widgetTypeId !== WidgetTypeId.SearchSeries\n ) {\n return prev;\n }\n\n return { ...prev, [actualKey]: value };\n }, {});\n}\n\nexport const SharedSearchRequests = {\n searchDashboard(\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:dashboard:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: getGlobalFilters(genericFilters, null),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner\n };\n\n return {\n url: '{gateway}/v5/search/widgets',\n publicUrl: '/api/search/v5/widgets',\n type: HttpVerbs.POST,\n data,\n key\n };\n },\n\n searchDashboardWidget(\n widgetTypeId: WidgetTypeId,\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:dashboard:${widgetTypeId}:widget:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n excludeVideoIds,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: getGlobalFilters(genericFilters, widgetTypeId),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner,\n ogql: SearchOGQL,\n excludeVideoIds\n };\n\n return {\n url: `{gateway}/v5/search/widgets/${widgetTypeId}`,\n publicUrl: `/api/search/v5/widgets/${widgetTypeId}`,\n type: HttpVerbs.POST,\n data,\n key,\n formatData: (data: HashObject) => {\n if (!data)\n return data;\n\n return {\n ...data,\n content: data.content?.data ?\n { ...data.content, data: data.content.data.map(ThemeAssetHelper.applyThemeToClassification) } :\n data.content\n };\n }\n };\n },\n\n searchV5(\n query: string,\n filters: HashObject,\n widgets: WidgetFilter[] = []\n ): Flight.PublicRequest {\n const widgetData = widgets.sort((a, b) => a.id.localeCompare(b.id)).map(w => [ w.id, w?.cursor ]);\n const filterData = stringifyObject(filters);\n \n const key = `search:v5:${query}:${widgetData}:${filterData}`;\n \n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}indicesFilters`]: indicesFilter,\n isLearner,\n ...genericFilters\n } = filters;\n\n const data = {\n widgets,\n indices: indicesFilter,\n filters: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\n query,\n includeAllIndices: false,\n isLearner: !!isLearner,\n ogql: SearchOGQL\n };\n\n return {\n url: '{gateway}/v5/search',\n publicUrl: '/api/search/v5',\n type: HttpVerbs.POST,\n data,\n key\n };\n },\n \n searchV4(options: {\n query: string,\n indices: SearchIndices[],\n filters: HashObject,\n sorts?: HashObject,\n allowSubstitute: boolean,\n cursor?: string,\n limit?: number\n }): Flight.PublicRequest {\n const { query, indices, filters = {}, sorts = {}, allowSubstitute = true, cursor, limit } = options;\n\n let key = `search:v4:${query}:${allowSubstitute}:${indices}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n const {\n [`${FilterConstants.FILTER_PARAM_PREFIX}excludeLibraryExclusive`]: excludeLibraryExclusive,\n isLearner,\n ...genericFilters\n } = filters;\n\n const indexObjects = indices.map(index => {\n if (index !== 'video' || !excludeLibraryExclusive)\n return { index };\n\n return { index, filters: { excludeLibraryExclusive } };\n });\n\n const data = {\n searchType: 'content',\n indices: indexObjects,\n filters: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\n sorts,\n query,\n allowSubstitute,\n cursor: cursor ?? undefined,\n isLearner: !!isLearner,\n limit\n };\n\n return {\n url: '{gateway}/v4/search',\n publicUrl: '/api/search/v4',\n type: HttpVerbs.POST,\n data,\n key,\n formatData: formatSearchResponse\n };\n },\n\n search(options: {\n query: string,\n indices: SearchIndices[],\n filters?: HashObject,\n allowSubstitute?: boolean,\n cursor?: string,\n limit?: number,\n success?: (results: SearchResults) => void,\n error?: (xhr: Xhr) => void\n }): Flight.PublicRequest {\n const { query, indices, filters, allowSubstitute, cursor, limit, success, error } = options;\n\n let key = `search:${query}:${allowSubstitute}:${indices}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n const params = Object.assign({}, {\n index: indices,\n cursor: cursor ?? undefined,\n query,\n allowSubstitute,\n limit,\n ...filters\n });\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v3/search', params),\n publicUrl: UrlHelper.urlBuilder('/api/search', params),\n key,\n formatData: formatSearchResponse,\n success,\n error\n };\n },\n\n tagsAndClassifications(\n query: string,\n indices: SearchIndices[],\n filters: HashObject = {},\n cursor?: string,\n success?: (results: string[]) => void,\n error?: () => void\n ): Flight.PublicRequest {\n const params = {\n index: indices,\n cursor,\n query,\n ...filters\n };\n\n let key = `filter:options:${query}:${indices.join(':')}:${cursor}`;\n\n key += Object.keys(filters).map(filterName => {\n const filter = filters[filterName];\n return Array.isArray(filter) ? filter.join(';') : filter;\n }).join(';');\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v3/search/tags-and-classifications', params),\n publicUrl: UrlHelper.urlBuilder('/api/search/tags-and-classifications', params),\n key,\n success,\n error,\n normalize: false\n };\n }\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Presentation, SchoolLevels } from 'libs/shared/interfaces';\n\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\n\nimport { SearchRequests } from 'apps/search/flight-requests/SearchRequests';\n\nexport function useFetchSchoolLevels(presentation: Presentation) {\n const { hasPermissions } = usePermissions();\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n function getPresentationIds() {\n if (isLearner)\n return presentation ? [presentation?.id] : null;\n\n return availablePresentations?.map(o => o.id);\n }\n\n const presentationIds = getPresentationIds();\n\n return Flight.useBasicFetch<SchoolLevels>(\n hasPresentationsLoaded &&\n presentationIds &&\n SearchRequests.schoolLevels(presentationIds)\n );\n}\n","import { Flight } from 'libs/common/flight';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { TopicResults } from 'libs/shared/apps/search/interfaces';\nimport { MasterObjectTypes } from 'libs/shared/enums/MasterObjectTypes';\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DomainMasterCollectionType, LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser, DashboardTargetType, Library, Rating, User, YearGroup } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { RatingRequests } from 'shared/flight-requests/RatingRequests';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\n\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { useFetchSchoolLevels } from 'apps/search/hooks/useFetchSchoolLevels';\nimport { useSearchCompanies } from 'apps/search/hooks/useSearchCompanies';\nimport { useSearchTopics } from 'apps/search/hooks/useSearchTopics';\n\n/**\n * We need to fetch libraries in order to support the sources filter. \n * However we need to exclude the streamable library, and additionally we need to exclude\n * the exchange library if the user has decided they don't want to see exchange results.\n * \n * We then need to return both of these ids so that the FilterHelper.getBackendFilters()\n * can add them as excludeLibraryExclusive filters\n * \n * - Sha\n */\nfunction useGetLibraries() {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const products = useProducts();\n const settings = useSettings(null);\n const { upsellPresentationType } = useUpsellContext();\n\n const streamableLibrary = Flight.useBasicFetch<HashObject>(LibraryRequests.streamableLearning());\n const streamableLibraryId = streamableLibrary.data?.objectId;\n const showStreamableSearchResults = settings.clickViewLive\n && upsellPresentationType !== PresentationType.StreamableLearning;\n\n const showExchangeSearchResults = products.hasProduct(ProductId.Exchange) && settings.showExchangeSearchResults;\n\n const libraryTypes: DomainMasterCollectionType[] = [ 'sharedLibrary', 'customLibrary', 'workspace', 'hostedLibrary', 'exchange' ];\n const librariesRequest = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated && LibraryRequests.domainLibraries(libraryTypes)\n );\n\n let libraries = librariesRequest.data ?? [];\n const exchangeLibraryIndex = libraries?.findIndex(l => l.type === MasterObjectTypes.Exchange);\n const exchangeLibraryId = libraries[exchangeLibraryIndex]?.id;\n\n if (!showExchangeSearchResults)\n libraries = [ ...libraries.slice(0, exchangeLibraryIndex), ...libraries.slice(exchangeLibraryIndex + 1) ];\n\n if (streamableLibraryId && !showStreamableSearchResults) {\n const streamableIndex = libraries?.findIndex(l => l.id.toString() === streamableLibraryId.toString());\n libraries = [ ...libraries.slice(0, streamableIndex), ...libraries.slice(streamableIndex + 1) ];\n }\n\n const hasLibrariesCompleted = (\n streamableLibrary.hasCompleted &&\n (!currentUser.data?.isAuthenticated || librariesRequest.hasCompleted)\n );\n\n return {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n };\n}\n\nfunction useGetRatings() {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const ratings = Flight.useBasicFetch<Rating[]>(RatingRequests.ratings(currentUser.data?.countryCode));\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n if (!hasPresentationsLoaded)\n return ratings;\n\n if (availablePresentations?.length > 1 || !activePresentation)\n return ratings;\n\n const learningLevel = TopicsHelper.getMappedPresentationLevel(activePresentation.learningLevel);\n if (learningLevel !== PresentationLearningLevel.Level_1)\n return ratings;\n\n return {\n ...ratings,\n data: ratings.data?.filter(rating => {\n // Primary schools shouldn't see ratings higher than PG\n return rating.code && rating.value < 64;\n })\n };\n}\n\n/**\n * This hook contains all the simple data fetching that normally sits in the view.\n * I've done this to help promote readability of of the SearchResultsView - Sha\n */\nexport function useFetchSearchData(\n queryParams: HashObject\n) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const userDetails = Flight.useBasicFetch<User>(currentUser.data?.id && UserRequests.user(currentUser.data.id));\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n const products = useProducts();\n const settings = useSettings(null);\n\n const {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n } = useGetLibraries();\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n const currentPresentationId = activePresentation?.id;\n\n const curriculums = useCurriculums();\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(activePresentation);\n const schoolLevelIds = schoolLevels.data?.schoolLevels?.map(o => o.id);\n const availableTopics = Flight.useBasicFetch<TopicResults>(schoolLevels?.data &&\n ClassificationRequests.topicsFromAllAvailablePresentations(schoolLevelIds));\n\n const ratings = useGetRatings();\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n const canUseSeriesActions = hasLocalPermissions(LocalPermissionName.UseSeriesActions);\n const hasCustomLibraries = hasPermissions(PermissionName.ViewLibraries);\n const hasMoviesAndTv = hasPermissions(PermissionName.ViewMoviesTv);\n\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n const topics = useSearchTopics(\n queryParams,\n ratings.data,\n currentPresentationId,\n availablePresentations,\n isLearner\n );\n\n const companies = useSearchCompanies(\n queryParams,\n ratings.data,\n availablePresentations,\n hasMoviesAndTv\n );\n\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams\n });\n\n const hasDataLoaded = (\n audiences.hasCompleted &&\n hasPresentationsLoaded &&\n currentUser.hasCompleted &&\n (!currentUser.data?.isAuthenticated || userDetails.hasCompleted) &&\n ratings.hasCompleted &&\n config.hasCompleted &&\n availablePresentations &&\n (!currentUser.data?.isAuthenticated || !products.isLoadingProducts) &&\n !settings.isLoadingSettings &&\n hasLibrariesCompleted\n );\n\n return {\n queryParams,\n currentUser,\n userDetails,\n config,\n yearGroups,\n products,\n settings,\n curriculums,\n audiences,\n schoolLevels,\n currentPresentation: activePresentation,\n availablePresentations,\n availableTopics,\n ratings,\n topics,\n companies,\n moviesAndTvDashboard,\n currentPresentationId,\n isLearner,\n isGuest,\n canUseSeriesActions,\n libraries,\n hasDataLoaded,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n hasPermissions,\n hasLocalPermissions,\n hasCustomLibraries,\n hasMoviesAndTv,\n showStreamableSearchResults\n };\n}\n\nexport function useFetchSearchDataV2(\n queryParams: HashObject\n) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const userDetails = Flight.useBasicFetch<User>(currentUser.data?.id && UserRequests.user(currentUser.data.id));\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n const products = useProducts();\n const settings = useSettings(null);\n const isTertiary = useIsTertiary();\n\n const {\n hasLibrariesCompleted,\n libraries,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n showStreamableSearchResults\n } = useGetLibraries();\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n\n const currentPresentationId = activePresentation?.id;\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(activePresentation);\n const schoolLevelIds = schoolLevels.data?.schoolLevels?.map(o => o.id);\n const availableTopics = Flight.useBasicFetch<TopicResults>(schoolLevels?.data &&\n ClassificationRequests.topicsFromAllAvailablePresentations(schoolLevelIds));\n\n const ratings = useGetRatings();\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n const isLearner = hasPermissions(PermissionName.StudentExperience);\n const hasCustomLibraries = hasPermissions(PermissionName.ViewLibraries);\n const hasMoviesAndTv = hasPermissions(PermissionName.ViewMoviesTv);\n \n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams\n });\n\n const hasDataLoaded = (\n audiences.hasCompleted &&\n hasPresentationsLoaded &&\n currentUser.hasCompleted &&\n (!currentUser.data?.isAuthenticated || userDetails.hasCompleted) &&\n ratings.hasCompleted &&\n config.hasCompleted &&\n availablePresentations &&\n (!currentUser.data?.isAuthenticated || !products.isLoadingProducts) &&\n !settings.isLoadingSettings &&\n hasLibrariesCompleted\n );\n\n return {\n queryParams,\n currentUser,\n userDetails,\n yearGroups,\n products,\n settings,\n audiences,\n schoolLevels,\n currentPresentation: activePresentation,\n availablePresentations,\n availableTopics,\n ratings,\n moviesAndTvDashboard,\n currentPresentationId,\n isLearner,\n isGuest,\n libraries,\n hasDataLoaded,\n exchangeLibraryId,\n streamableLibraryId,\n showExchangeSearchResults,\n hasPermissions,\n hasLocalPermissions,\n hasCustomLibraries,\n showStreamableSearchResults,\n hasMoviesAndTv,\n isTertiary\n };\n}\n","import React from 'react';\n\nexport function FilterSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M17.437 8.5a2 2 0 0 0-3.874 0H4.5a.5.5 0 0 0 0 1h9.063a2 2 0 0 0 3.874 0H19.5a.5.5 0 0 0 0-1zM16.5 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-12 5.5a.5.5 0 0 0 0 1h3.063a2 2 0 0 0 3.874 0H19.5a.5.5 0 0 0 0-1h-8.063a2 2 0 0 0-3.874 0zm5-.5a1 1 0 1 1 0 2 1 1 0 0 1 0-2'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])'\n].join(',');\n\nexport function useDialogKeyboardNavigation(onClose: () => void) {\n const focusRef = React.useRef<HTMLDivElement>(null);\n const [ hasFocused, setHasFocused ] = React.useState(false);\n\n function shouldFocusCheck(): boolean {\n return !!focusRef.current;\n }\n \n function focus(): void {\n if (!focusRef.current)\n return;\n \n focusRef.current.focus();\n setHasFocused(true);\n }\n \n function onKeyDown(event: React.KeyboardEvent<HTMLDivElement>): void {\n if (event.key === 'Escape') {\n onClose();\n return;\n }\n \n if (event.key !== 'Tab' || !focusRef.current)\n return;\n \n const focusable = Array.from(\n focusRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n \n if (focusable.length === 0) {\n event.preventDefault();\n focusRef.current.focus();\n return;\n }\n \n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n \n if (event.shiftKey && active === first) { // navigating backwards\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n }\n \n React.useEffect(() => {\n if (!shouldFocusCheck() || hasFocused) return;\n focus();\n }, [ focusRef.current, hasFocused ]);\n\n return {\n focusRef,\n onKeyDown\n };\n}\n",":local {\n .openInAppPrompt {\n z-index: 5000;\n max-height: 75vh;\n animation: slideUp 0.20s ease-out;\n }\n\n .mask {\n z-index: 4999;\n }\n\n @keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n}\n","import React from 'react';\n\nimport { useDialogKeyboardNavigation } from 'libs/shared/hooks/useDialogKeyboardNavigation';\n\nimport styles from './action-sheet.module.scss';\n\ninterface ActionSheetProps {\n onClose: () => void;\n}\n\nexport function ActionSheet(props: React.PropsWithChildren<ActionSheetProps>) {\n const { focusRef, onKeyDown } = useDialogKeyboardNavigation(props.onClose);\n\n return (\n <div>\n <div className={`modal-backdrop show ${styles.mask}`} onClick={props.onClose}/>\n <div\n className={`position-fixed w-100 bg-white pb-3 px-3 bottom-0 start-0 rounded-top-3 overflow-auto ${styles.openInAppPrompt}`}\n ref={focusRef}\n role='dialog'\n aria-label='Action sheet'\n aria-modal='true'\n tabIndex={-1}\n onKeyDown={onKeyDown}\n >\n {props.children}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { FilterIds, FilterState, FilterStateHash, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\ninterface SmScreenSearchFilterItemProps {\n filter: SearchFilter;\n filterState: FilterStateHash;\n hideCaret?: boolean;\n className?: string;\n isMoreFilter?: boolean;\n setParentDraftState?: (id: FilterIds, val: FilterState) => void;\n}\n\nexport function SmScreenSearchFilterItem(props: SmScreenSearchFilterItemProps) {\n const { filterState } = props;\n\n const currentFilterState = props.isMoreFilter ?\n filterState.moreFilters[props.filter.id] :\n filterState[props.filter.id];\n const [ draftState, setDraftState ] = React.useState<FilterState>(currentFilterState);\n \n function onSelectItem(state: FilterState): void {\n setDraftState(state);\n props.setParentDraftState(props.filter.id, state);\n }\n\n const FilterComponent = React.useMemo(() => {\n return props.filter.customComponent ?\n props.filter.customComponent :\n FilterHelper.mapTypeToComponent(props.filter.type);\n }, [props.filter.type]);\n\n return (\n <div className={props.className || ''}>\n <hr className='hr' />\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n filterState={filterState}\n isExpandable={true}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { ResetButton } from 'libs/shared/apps/search/components/reset-button/ResetButton';\nimport { DraftState, FilterIds, FilterState, FilterStateHash, MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { ActionSheet } from 'libs/shared/components/action-sheet/ActionSheet';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { LanguageNamespaceContext } from 'libs/shared/components/text/Text';\n\nimport { SmScreenSearchFilterItem } from 'apps/search/components/sm-screen-search-filter/SmScreenSearchFilterItem';\n\ntype SearchFiltersProps = {\n queryParams: HashObject,\n mainFilters: SearchFilter[],\n appLink: Core.AppLink,\n moreFilters?: MoreFilters,\n isFetchingOptions?: boolean,\n constantIndices?: SearchIndices[],\n analyticsOptions?: AnalyticsOptions,\n\n alignResetButtonLeft?: boolean,\n closeFilter: () => void,\n\n /**\n * Incremental changes flag for partner profiles\n */\n _hasPartnerProfiles?: boolean\n};\n\nconst namespace = 'search.smallScreenSearchFilters';\n\nexport function SmScreenSearchFilter(props: SearchFiltersProps) {\n const { queryParams, appLink, isFetchingOptions, constantIndices = []} = props;\n \n const currentState = React.useMemo(() => {\n return FilterHelper.deriveInitialStateFromQuery(queryParams, props.mainFilters, props.moreFilters, appLink);\n }, [ queryParams, isFetchingOptions, props.mainFilters, props.moreFilters, appLink ]);\n\n // use ref here to create a draft state intermediary holding state within the parent component\n const draftStateRef = React.useRef<FilterStateHash>(ObjectHelper.deepClone(currentState));\n const setDraftState = (id: FilterIds, val: FilterState) => draftStateRef.current[id] = val;\n const setMoreFilterDraftState = (id: FilterIds, val: FilterState) => draftStateRef.current['moreFilters'][id] = val;\n\n const indices = ArrayHelper.uniq([\n ...FilterHelper.getAppliedIndices(queryParams, true, props._hasPartnerProfiles),\n ...constantIndices\n ]);\n \n const { mainFilters, moreFilters } = FilterHelper.mixinDisabledFields(\n currentState,\n indices,\n props.mainFilters,\n props.moreFilters\n );\n \n // Separate the tag filter as it's rendered differently\n const mainFiltersWithoutTags = mainFilters.filter(f => f.type !== 'tag');\n\n function applyFilters() {\n const mainFilterState: DraftState = ObjectHelper.omit(draftStateRef.current, [ 'appLink', 'moreFilters' ]);\n const moreFilterState: Omit<FilterStateHash, 'moreFilters' | 'appLink'> = ObjectHelper.omit(draftStateRef.current?.moreFilters, ['appLink']);\n\n FilterHelper.applyFilter(\n [ ...mainFiltersWithoutTags, ...(moreFilters?.filters ?? []) ],\n currentState,\n { ...mainFilterState, ...moreFilterState },\n appLink\n );\n\n if (props.analyticsOptions) {\n FilterHelper.logFilterEvent(\n props.mainFilters,\n props.moreFilters,\n currentState,\n queryParams.query,\n props.analyticsOptions\n );\n }\n\n props.closeFilter();\n }\n\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => { document.body.style.overflow = ''; };\n }, []);\n\n return (\n <ActionSheet onClose={props.closeFilter}>\n <LanguageNamespaceContext.Provider value={namespace}>\n <div className='pt-3 mb-0 h4'>\n <Text phrase='heading'/>\n </div>\n {mainFiltersWithoutTags.map(filter => (\n <SmScreenSearchFilterItem\n key={filter.id}\n className='mb-4'\n filter={filter}\n filterState={currentState}\n setParentDraftState={setDraftState}\n />\n ))}\n {moreFilters && moreFilters.filters?.map(filter => (\n <SmScreenSearchFilterItem\n key={filter.id}\n className='mb-4'\n filter={filter}\n filterState={currentState}\n setParentDraftState={setMoreFilterDraftState}\n isMoreFilter={true}\n />\n ))}\n <div\n className='position-fixed bottom-0 start-0 p-3 d-flex justify-content-between flex-row-reverse bg-white w-100'\n >\n <button className='btn btn-dark justify-item-end' onClick={applyFilters}>\n {LanguageService.getPhrase(namespace, 'apply')}\n </button>\n {FilterHelper.hasActiveFilters(queryParams) && (\n <ResetButton\n mainFilters={props.mainFilters}\n moreFilters={props.moreFilters}\n currentQueryParam={queryParams.query}\n analyticsOptions={props.analyticsOptions}\n alignLeft={props.alignResetButtonLeft}\n filterState={currentState}\n onClick={props.closeFilter}\n />\n )}\n </div>\n </LanguageNamespaceContext.Provider>\n </ActionSheet>\n );\n}\n",":local {\n .filterButtonContainer {\n top: 5rem;\n z-index: 1020;\n margin-left: -1.5rem;\n margin-right: -1.5rem;\n padding: 0.75rem 1.5rem 0;\n\n &::before {\n content: '';\n position: absolute;\n bottom: 100%;\n left: 0;\n right: 0;\n height: 5rem;\n background-color: inherit;\n }\n }\n\n .filterButton {\n line-height: 1.5rem;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { EntityType, LocationContext } from 'libs/analytics/interfaces';\n\nimport { SearchFilters } from 'libs/shared/apps/search/components/search-filters/SearchFilters';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { FilterSvg } from 'libs/shared/images/svg/objects/FilterSvg';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { SmScreenSearchFilter } from 'apps/search/components/sm-screen-search-filter/SmScreenSearchFilter';\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\n\nimport styles from './search-results-filter.module.scss';\n\nconst namespace = 'search.searchResultsFilter';\n\ninterface SearchResultsFilterProps {\n searchData: ReturnType<typeof useFetchSearchDataV2>;\n queryParams: HashObject;\n filters: ReturnType<typeof SearchHelper.getFilters>;\n hideDivider: boolean;\n}\n\nexport function SearchResultsFilter(props: SearchResultsFilterProps) {\n const { searchData, queryParams, filters, hideDivider } = props;\n\n const breakpoint = useBreakpoints();\n const [ isSmScreenFilterOpen, setIsSmScreenFilterOpen ] = React.useState(false);\n\n const hasSearchData = !!searchData.audiences.data && !!searchData.ratings.data && !!searchData.availableTopics.data;\n\n return (\n <>\n {hasSearchData && (\n !breakpoint.xs ?\n <SearchFilters\n queryParams={queryParams}\n mainFilters={filters?.mainFilters}\n moreFilters={filters?.moreFilters}\n analyticsOptions={{\n entity: EntityType.SearchResults,\n location: LocationContext.SearchFilters\n }}\n appLink={{ application: AppChannels.SEARCH, action: Actions.Search.HOME }}\n hideDivider={hideDivider}\n _hasPartnerProfiles={searchData.settings.hasPartnerProfiles}\n /> :\n <div className={`position-sticky bg-white ${styles.filterButtonContainer}`}>\n <button className={`btn btn-dark w-100 mb-3 ${styles.filterButton}`} onClick={() => setIsSmScreenFilterOpen(true)}>\n <SvgContainer svg={FilterSvg}/>\n <span className='ms-1'>{LanguageService.getPhrase(namespace, 'filterText')}</span>\n </button>\n </div>\n )}\n {breakpoint.xs && isSmScreenFilterOpen &&\n <SmScreenSearchFilter\n queryParams={queryParams}\n mainFilters={filters?.mainFilters}\n moreFilters={filters?.moreFilters}\n analyticsOptions={{\n entity: EntityType.SearchResults,\n location: LocationContext.SearchFilters\n }}\n appLink={{ application: AppChannels.SEARCH, action: Actions.Search.HOME }}\n closeFilter={() => setIsSmScreenFilterOpen(false)}\n _hasPartnerProfiles={searchData.settings?.hasPartnerProfiles}\n />\n }\n </>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { FeedbackOption } from 'libs/shared/views/feedback/enums/FeedbackOption';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'search.searchResultsRequestVideo';\n\ninterface SearchResultsRequestVideo {\n skipBeforeRequestingVideoStep?: boolean;\n description?: string;\n}\n\nexport function SearchResultsRequestVideo(props: SearchResultsRequestVideo): JSX.Element {\n const { skipBeforeRequestingVideoStep = true } = props;\n \n return (\n <div className='d-flex flex-column align-items-center justify-content-center gap-3 mb-3'>\n {props.description ?\n <span>{props.description}</span> :\n <Text phrase='description' namespace={namespace} />\n }\n <AppLink\n appLink={{\n application: AppChannels.DEFAULT,\n action: Actions.Default.GIVE_FEEDBACK,\n params: {\n selectedOption: FeedbackOption.REQUEST_VIDEO,\n skipBeforeRequestingVideoStep: !!skipBeforeRequestingVideoStep\n }\n }}\n className='btn btn-outline-dark'\n >\n <Text phrase='requestVideo' namespace={namespace} />\n </AppLink>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { SearchResultsRequestVideo } from '../search-results-request-video/SearchResultsRequestVideo';\n\nconst namespace = 'search.searchResultsEmptyStateV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchResultsEmptyStateProps {\n query?: string;\n scotland?: boolean;\n hideRequestVideo?: boolean;\n}\n\nexport function SearchResultsEmptyState(props: SearchResultsEmptyStateProps): JSX.Element {\n const imageUrl = (props.scotland && props.query?.trim()?.toLowerCase() === 'nessie') ?\n ImageUrls.EmptyStates.Search.RESULTS_SCOTLAND :\n ImageUrls.EmptyStates.Search.RESULTS;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={imageUrl} />\n\n <EmptyState.Heading>\n {props.query ?\n <Text phrase='headingWithQuery' options={{ query: props.query }} /> :\n <Text phrase='headingWithoutQuery' />\n }\n </EmptyState.Heading>\n\n <EmptyState.Info className='w-50 m-0'>\n <Text phrase='info' />\n <AppLink\n className='info-link'\n appLink={{\n application: AppChannels.SUBJECT,\n action: Actions.Subjects.PRESENTATION_TOPICS,\n args: [null]\n }}\n >\n <Text phrase='topicsAppLink' />\n </AppLink>\n </EmptyState.Info>\n </EmptyState>\n \n {!props.hideRequestVideo &&\n <SearchResultsRequestVideo description={getPhrase('requestVideoInfo')} />\n }\n </LanguageNamespaceContext.Provider>\n );\n}\n","import { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SEARCH_CURRICULUM_CODE_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nexport interface DetectCurriculumCodeSearchOptions {\n isCurriculumCodeSearch: boolean;\n data: WidgetSearchItem[];\n}\n\n/**\n * Detect if we are dealing with a curriculum code search widget\n * Update the search bar UI when we detect that a curriculum code has been searched for\n * and trigger applink to update url params\n */\nexport function detectCurriculumCodeSearch(\n options: DetectCurriculumCodeSearchOptions\n): void {\n const widgets = options.data;\n\n if (!widgets || !widgets.length)\n return;\n \n widgets.forEach(widget => {\n if (widget.widgetId !== WidgetTypeId.SearchCurriculumCode)\n return;\n \n const hasSearchedCode = !!widget?.content?.name && !!widget?.content?.description;\n \n if (options.isCurriculumCodeSearch && !hasSearchedCode) {\n Core.AppLinkHelper.trigger({\n ...Core.AppLinkHelper.getCurrentAppLink(),\n params: {\n ...((Core.AppLinkHelper.getCurrentAppLink().params || {}) as HashObject),\n [SEARCH_CURRICULUM_CODE_PARAM]: undefined\n }\n }, { replace: true });\n return;\n }\n if (!options.isCurriculumCodeSearch && hasSearchedCode) {\n Core.AppLinkHelper.trigger({\n ...Core.AppLinkHelper.getCurrentAppLink(),\n params: {\n ...((Core.AppLinkHelper.getCurrentAppLink().params || {}) as HashObject),\n [SEARCH_CURRICULUM_CODE_PARAM]: true\n }\n }, { replace: true });\n return;\n }\n });\n}\n","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { BaseObject } from 'libs/shared/interfaces';\n\nexport interface FetchVideoAssocsObjectsOptions {\n fetchObjects: (objects: BaseObject[]) => void;\n data: WidgetSearchItem[];\n}\n\nexport function fetchVideoAssocsObjects(options: FetchVideoAssocsObjectsOptions): void {\n const widgets = options.data;\n\n if (!widgets || !widgets.length)\n return;\n \n const objects = widgets.reduce((outer, widget) => {\n return widget.content.data.reduce((inner, video) => ([ ...inner, video ]), outer);\n }, []);\n \n if (!objects.length)\n return;\n \n options.fetchObjects(objects);\n}\n","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { detectCurriculumCodeSearch, DetectCurriculumCodeSearchOptions } from './detectCurriculumCodeSearch';\nimport { fetchVideoAssocsObjects, FetchVideoAssocsObjectsOptions } from './fetchVideoAssocsObjects';\n\ntype AllOnLoadWidgetTriggerOptions =\n & DetectCurriculumCodeSearchOptions &\n FetchVideoAssocsObjectsOptions;\ntype GetOnLoadWidgetTriggersOptions = Omit<AllOnLoadWidgetTriggerOptions, 'data'>;\n\nexport function getOnLoadWidgetTriggers(\n options: GetOnLoadWidgetTriggersOptions\n): Array<(data: WidgetSearchItem[]) => void> {\n return [\n data => detectCurriculumCodeSearch({ data, ...options }),\n data => fetchVideoAssocsObjects({ data, ...options })\n ];\n}\n","import { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\nexport function mergeSearchResults(options: SearchResultsTransformOptions): SearchResultsTransformOptions {\n const { data } = options;\n\n if (!data) return options;\n \n const mergedWidgets = WidgetHelper.mergeWidgets(data, (target, source) => {\n target.content.data = [\n ...(target.content.data || []),\n ...source.content.data\n ];\n });\n\n return {\n ...options,\n data: mergedWidgets\n };\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\nimport { mergeSearchResults } from './mergeSearchResults';\n\nfunction getData(options: SearchResultsTransformOptions): WidgetSearchItem[] {\n if (!options.data) {\n throw new DevError('Data is not defined in the options');\n }\n\n return options.data;\n}\n\nexport function getSearchResultsTransformers(): Array<UseTransformerFunc<WidgetSearchItem[]>> {\n return [\n data => getData(mergeSearchResults({ data }))\n ];\n}\n","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport type { Classification } from 'libs/shared/interfaces';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\n/**\n * Sort first six Relevant topics widget by Exact matches and then by presentation level \n */\nexport function transformSearchRelevantTopics(\n options: WidgetSearchItemTransformOptions\n): WidgetSearchItemTransformOptions {\n if (options.data.widgetId !== WidgetTypeId.SearchRelevantTopics)\n return options;\n\n function sortByLearningLevel(a: Classification, b: Classification) {\n return TopicsHelper.sortByLearningLevel(a, b, options.availablePresentations);\n }\n\n /**\n * We only want to sort the first 6 items.\n * Anything after that are items added\n * through pagination.\n */\n const relevantTopicsData = options.data.content.data.slice(0, 6);\n const remainingTopicsData = options.data.content.data.slice(6);\n \n const exactMatchSortedTopics: Classification[] = [];\n const remainingSortedTopics: Classification[] = [];\n \n relevantTopicsData.forEach(topic => {\n if (!MasterTypeHelper.isClassification(topic))\n return;\n \n if (topic?.name?.toLowerCase() === options.query?.toLowerCase()) {\n exactMatchSortedTopics.push(topic);\n return;\n }\n \n remainingSortedTopics.push(topic);\n });\n \n exactMatchSortedTopics.sort(sortByLearningLevel);\n remainingSortedTopics.sort(sortByLearningLevel);\n \n const sortedItem = {\n ...options.data,\n content: {\n ...options.data.content,\n data: [\n ...exactMatchSortedTopics,\n ...remainingSortedTopics,\n ...remainingTopicsData\n ]\n }\n };\n \n options = {\n ...options,\n data: sortedItem\n };\n\n return options;\n}\n","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\n/**\n * Transform search tag data so that its id is its name\n */\nexport function transformSearchTags(options: WidgetSearchItemTransformOptions): WidgetSearchItemTransformOptions {\n if (options.data.widgetId !== WidgetTypeId.SearchTags)\n return options;\n\n const normalizedItemData = options.data.content.data.map(x => ({\n id: x.name,\n ...x\n }));\n\n options.data = {\n ...options.data,\n content: {\n ...options.data.content,\n data: normalizedItemData\n }\n };\n\n return options;\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\nimport { transformSearchRelevantTopics } from './transformSearchRelevantTopics';\nimport { transformSearchTags } from './transformSearchTags';\n\nfunction getData(options: WidgetSearchItemTransformOptions): WidgetSearchItem {\n if (!options.data) {\n throw new DevError('Data is not defined in the options');\n }\n\n return options.data;\n}\n\ntype GetSearchWidgetItemTransformersOptions = Omit<WidgetSearchItemTransformOptions, 'data'>;\n\nexport function getSearchWidgetItemTransformers(\n options: GetSearchWidgetItemTransformersOptions\n): Array<UseTransformerFunc<WidgetSearchItem>> {\n return [\n data => getData(transformSearchTags({ data, ...options })),\n data => getData(transformSearchRelevantTopics({ data, ...options }))\n ];\n}\n","import { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { SourceFilterOptions, TypeFilterOptions } from 'libs/shared/apps/search/interfaces';\nimport { WidgetFilter } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { BaseObject, DashboardTargetType } from 'libs/shared/interfaces';\n\ninterface HasQueryParamOptions {\n queryParams: HashObject;\n key: string;\n value: string;\n}\n\ninterface GetWidgetIdsFromQueryParamsOptions {\n settingsHash: SettingsHash;\n}\n\ninterface GetWidgetFiltersOptions {\n queryParams: HashObject;\n widgetTypeId: WidgetTypeId;\n cursor?: string;\n options?: GetWidgetIdsFromQueryParamsOptions;\n}\n\nconst SupportedSearchWidgetTypeIds: WidgetTypeId[] = [\n WidgetTypeId.SearchRelevantTopics,\n WidgetTypeId.SearchCompanies,\n WidgetTypeId.SearchPlaylists,\n WidgetTypeId.SearchSeries,\n WidgetTypeId.SearchTopResults,\n WidgetTypeId.SearchMyVideos,\n WidgetTypeId.SearchMyVideosFolder,\n WidgetTypeId.SearchMySchoolLibraryVideos,\n WidgetTypeId.SearchMySchoolLibraryFolder,\n WidgetTypeId.SearchExchangeArchive,\n WidgetTypeId.SearchClickViewLive,\n WidgetTypeId.SearchRelatedResults,\n WidgetTypeId.SearchCurriculumCode,\n WidgetTypeId.SearchContentPartners\n];\n\nfunction hasQueryParam(options: HasQueryParamOptions) {\n const targetParam = options.queryParams?.[options.key];\n \n if (typeof targetParam === 'string') {\n return targetParam === options.value;\n }\n\n if (!Array.isArray(targetParam)) {\n return false;\n }\n\n return targetParam.includes(options.value);\n}\n\nfunction getValidFocusedWidget(queryParams: HashObject, options: GetWidgetIdsFromQueryParamsOptions): WidgetTypeId {\n if (!queryParams?.focus)\n return;\n\n let widgetTypeId: WidgetTypeId;\n\n if (typeof queryParams.focus === 'string') {\n widgetTypeId = SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus);\n }\n\n if (Array.isArray(queryParams.focus) && queryParams.focus.length === 1) {\n widgetTypeId = SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus[0]);\n }\n\n if (!widgetTypeId)\n return;\n\n const widgetTypeIdConfig = WidgetTypeIdConfig[widgetTypeId];\n\n if (!widgetTypeIdConfig?.predicate?.({ targetType: DashboardTargetType.Search, settingsHash: options.settingsHash }))\n return;\n\n return widgetTypeId;\n}\n\nfunction getWidgetIdsFromQueryParams(\n queryParams: HashObject,\n options?: GetWidgetIdsFromQueryParamsOptions\n): WidgetTypeId[] {\n const widgets: WidgetTypeId[] = [];\n\n const focusedWidget = getValidFocusedWidget(queryParams, options);\n\n if (focusedWidget) {\n return [ focusedWidget, WidgetTypeId.SearchTags ];\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Classification, queryParams })) {\n widgets.push(WidgetTypeId.SearchRelevantTopics);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Company, queryParams })) {\n widgets.push(WidgetTypeId.SearchCompanies);\n }\n\n if (options.settingsHash?.hasPartnerProfiles && hasQueryParam({ key: 'type', value: TypeFilterOptions.PartnerProfile, queryParams })) {\n widgets.push(WidgetTypeId.SearchContentPartners);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Series, queryParams })) {\n widgets.push(WidgetTypeId.SearchSeries);\n }\n \n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Playlist, queryParams })) {\n widgets.push(WidgetTypeId.SearchPlaylists);\n }\n\n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Category, queryParams })) {\n widgets.push(WidgetTypeId.SearchMySchoolLibraryFolder, WidgetTypeId.SearchMyVideosFolder);\n }\n \n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.ExchangeArchive, queryParams })) {\n widgets.push(WidgetTypeId.SearchExchangeArchive);\n }\n\n if (options?.settingsHash?.clickViewLive && hasQueryParam({ key: 'source', value: SourceFilterOptions.LiveStreams, queryParams })) {\n widgets.push(WidgetTypeId.SearchClickViewLive);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.MyVideos, queryParams })) {\n widgets.push(WidgetTypeId.SearchMyVideos, WidgetTypeId.SearchMyVideosFolder);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.ClickView, queryParams })) {\n widgets.push(WidgetTypeId.SearchTopResults, WidgetTypeId.SearchRelatedResults);\n }\n\n if (hasQueryParam({ key: 'source', value: SourceFilterOptions.School, queryParams })) {\n widgets.push(WidgetTypeId.SearchMySchoolLibraryVideos, WidgetTypeId.SearchMySchoolLibraryFolder);\n }\n\n if (hasQueryParam({ key: 'type', value: TypeFilterOptions.Video, queryParams }) ||\n hasQueryParam({ key: 'type', value: TypeFilterOptions.Clip, queryParams }) ||\n hasQueryParam({ key: 'type', value: TypeFilterOptions.Interactive, queryParams })) {\n widgets.push(\n WidgetTypeId.SearchTopResults,\n WidgetTypeId.SearchRelatedResults,\n WidgetTypeId.SearchMySchoolLibraryVideos,\n WidgetTypeId.SearchMyVideos,\n WidgetTypeId.SearchExchangeArchive,\n WidgetTypeId.SearchClickViewLive,\n WidgetTypeId.SearchCurriculumCode\n );\n }\n\n if (widgets.length) {\n widgets.push(WidgetTypeId.SearchTopResults);\n widgets.push(WidgetTypeId.SearchTags);\n }\n\n return ArrayHelper.uniq(widgets);\n}\n\nexport const SearchResultsFilterHelper = {\n isOnlyActiveWidget(widgetId: WidgetTypeId, queryParams: HashObject): boolean {\n const targetParam = queryParams?.['focus'];\n \n if (typeof targetParam === 'string')\n return targetParam.toLowerCase() === widgetId.toLowerCase();\n \n if (!Array.isArray(targetParam))\n return false;\n \n if (targetParam.length !== 1)\n return false;\n \n return !!targetParam.find(p => p.toLowerCase() === widgetId.toLowerCase());\n },\n\n getActiveWidgetFilters(\n queryParams: HashObject,\n options?: GetWidgetIdsFromQueryParamsOptions\n ): WidgetFilter[] {\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams, options);\n \n return widgets.map(w => ({ id: w }));\n },\n\n getWidgetFilters(params: GetWidgetFiltersOptions): WidgetFilter[] {\n const { queryParams, widgetTypeId, cursor, options } = params;\n \n if (cursor) {\n return [{\n id: widgetTypeId,\n cursor\n }];\n }\n\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams, options);\n return widgets.map(w => ({ id: w }));\n },\n\n getSelectedTagOrClassification(queryParams: HashObject): BaseObject[] {\n if (typeof queryParams?.tagOrClassification === 'string')\n return [{ id: queryParams.tagOrClassification, name: queryParams.tagOrClassification }];\n\n if (Array.isArray(queryParams?.tagOrClassification))\n return queryParams.tagOrClassification.map((tag: string) => ({\n id: tag,\n name: tag\n }));\n\n return [];\n },\n\n getSearchWidgetSelectedItems(queryParams: HashObject, widgetTypeId: WidgetTypeId): BaseObject[] {\n if (widgetTypeId !== WidgetTypeId.SearchTags)\n return [];\n\n return SearchResultsFilterHelper.getSelectedTagOrClassification(queryParams);\n }\n};\n","import { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { MixedWidgetSearchResultsProps } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport type { AudienceFilterParams, BaseObject, Classification, Company, Folder, GetClassificationAppLinkOptions, Playlist, Presentation, Series, VideoTypes } from 'libs/shared/interfaces';\nimport { GetVideoAppLinkOptions } from 'libs/shared/interfaces/VideoAppLinkOptions';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { ContentPartnerAppLinkHelper } from 'shared/utils/ContentPartnerAppLinkHelper';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { getFolderAppLink } from 'apps/libraries/views/library-folder/LibraryFolderViewUtils';\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nimport { SearchResultsFilterHelper } from './SearchResultsFilterHelper';\n\ninterface GetSeeMoreAppLinkOptions {\n widget: WidgetSearchItem;\n appLinks: MixedWidgetSearchResultsProps['widgetAppLinks'];\n queryParams: HashObject;\n isLastWidget: boolean;\n}\n\nfunction hasMoreContent(widget: WidgetSearchItem): boolean {\n return !!widget.content.cursor;\n}\n\nexport const SearchResultsAppLinkHelper = {\n getSearchWidgetAppLinks(\n queryParams: HashObject,\n audienceParams: AudienceFilterParams,\n availablePresentations: Presentation[],\n presentationSlug: string\n ): MixedWidgetSearchResultsProps['widgetAppLinks'] {\n return {\n partner: ContentPartnerAppLinkHelper.getPartnerDashboardAppLink,\n classification: (classification?: Classification) => {\n const options: GetClassificationAppLinkOptions = {\n ...audienceParams,\n moviesAndTv: TopicsHelper.isMtv(classification)\n };\n\n return ClassificationAppLinkHelper.getAppLink(classification, options, availablePresentations);\n },\n\n videoType: (video: VideoTypes, opts: GetVideoAppLinkOptions) => (\n VideoAppLinkHelper.getAppLink(video, {\n ...opts,\n includeContext: false\n }, presentationSlug)\n ),\n \n series: (series: Series) => SeriesAppLinkHelper.getSeriesAppLink(series, {}, presentationSlug),\n \n playlist: (playlist: Playlist) => ({\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.PLAYLIST,\n args: [ null, playlist.id, TextHelper.slugify(playlist.name) ]\n }),\n \n company: (company: Company) => ({\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.COMPANY_DASHBOARD,\n args: [\n null,\n company.id,\n TextHelper.slugify(company.name)\n ]\n }),\n \n folder: (folder: Folder, opts?: { libraryId?: string }) => {\n if (!opts?.libraryId) {\n return {\n application: AppChannels.MY_VIDEOS,\n action: Actions.MyVideos.MY_VIDEOS_FOLDER,\n args: [ folder.id, TextHelper.slugify(folder.name) ]\n };\n }\n \n return getFolderAppLink(opts?.libraryId, folder, null);\n },\n \n searchSettings: () => ({\n application: AppChannels.SETTINGS,\n action: Actions.Settings.PLATFORM_SETTINGS\n }),\n \n searchHome: (filterParams?: HashObject, options?: { replace: boolean }) => {\n let params: HashObject = { ...filterParams };\n \n if (!options?.replace) {\n params = {\n ...queryParams,\n ...params\n };\n }\n \n return ({\n application: AppChannels.SEARCH,\n action: Actions.Search.HOME,\n // This empty args array needs to be here otherwise FixedWidget will try to\n // populate it with some junk that'll break the query params.\n // This is tech debt that needs to be cleaned up.\n args: [],\n params\n });\n },\n\n tag: (tag: BaseObject) => {\n let tagOrClassification: string[] =\n SearchResultsFilterHelper.getSelectedTagOrClassification(queryParams).map(x => x.name);\n \n if (tagOrClassification.includes(tag.name)) {\n tagOrClassification = tagOrClassification.filter(x => x !== tag.name);\n } else {\n tagOrClassification.push(tag.name);\n }\n\n return ({\n action: Actions.Search.HOME,\n application: AppChannels.SEARCH,\n params: {\n ...queryParams,\n tagOrClassification\n }\n });\n },\n\n getPreviewQuestionsAppLink: interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)\n };\n },\n\n getSeeMoreAppLink(options: GetSeeMoreAppLinkOptions): Core.AppLink {\n if (!hasMoreContent(options.widget))\n return;\n \n const getAppLinkFunc = WidgetTypeIdConfig[options.widget.widgetId]?.getCollectionAppLink;\n \n if (!getAppLinkFunc || SearchResultsFilterHelper.isOnlyActiveWidget(options.widget.widgetId, options.queryParams))\n return;\n \n /**\n * If its the only widget search result item rendered we infinitely\n * load the widget (if we can) therefore we need to hide 'See all' applink\n * - Nish\n */\n if (options.isLastWidget)\n return;\n \n return getAppLinkFunc(options.appLinks);\n }\n};\n\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { MixedWidgetSearchResults } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { SharedSearchRequests } from 'libs/shared/apps/search/flight-requests/SharedSearchRequests';\nimport { SearchDashboard } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\nimport { SEARCH_CURRICULUM_CODE_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { VideoHighlight } from 'libs/shared/components/video-highlight/VideoHighlight';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ContentRegion } from 'libs/shared/enums/ContentRegion';\nimport { LiteSupportArticle } from 'libs/shared/enums/SupportArticle';\nimport { TutorialVideoType } from 'libs/shared/enums/TutorialVideoType';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useTutorialVideoHighlight } from 'libs/shared/hooks/useTutorialVideoHighlight';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useVideoMixinFunc } from 'shared/hooks/useVideoMixin';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\nimport { SearchResultsFilter } from 'apps/search/views/search-results-v2/components/search-results-filter/SearchResultsFilter';\n\nimport { SearchResultsEmptyState } from './components/search-results-empty-state/SearchResultsEmptyState';\nimport { SearchResultsRequestVideo } from './components/search-results-request-video/SearchResultsRequestVideo';\nimport { getOnLoadWidgetTriggers } from './transformations/on-load/OnLoadWidgets';\nimport { getSearchResultsTransformers } from './transformations/results/SearchResultsTransformations';\nimport { getSearchWidgetItemTransformers } from './transformations/widget-item/WidgetItemTransformations';\nimport { SearchResultsAppLinkHelper } from './utils/SearchResultsAppLinkHelper';\nimport { SearchResultsFilterHelper } from './utils/SearchResultsFilterHelper';\n\nexport const namespace = 'search.searchResultsV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchResultsViewV2Props {\n queryParams: HashObject;\n}\n\ntype EmptyWidgetsState = {[key in WidgetTypeId]?: boolean };\n\nexport function SearchResultsViewV2(props: SearchResultsViewV2Props): JSX.Element {\n const { queryParams = {} } = props;\n\n const [ isEmpty, setIsEmpty ] = React.useState<EmptyWidgetsState>({});\n\n const { appLink } = useTutorialVideos();\n\n const { shouldShowVideo, tutorialVideo, hasDismissedVideoHighlight, dismissVideoHighlight } =\n useTutorialVideoHighlight(TutorialVideoType.SearchAndDiscover);\n \n const videoMixin = useVideoMixinFunc();\n\n function onSetIsEmpty(id: WidgetTypeId, isEmpty: boolean) {\n setIsEmpty(prevState => ({\n ...prevState,\n [id]: isEmpty\n }));\n }\n \n useSetPageMetadata(PageMetadataHelper.getDefaultMetadata({\n title: queryParams.query ?? '',\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n allowIndexing: false\n }));\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem, presentationSlug: null });\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.VideoThumbnail,\n mtv: queryParams.moviesAndTv\n });\n\n /**\n * Data required for search view to render\n */\n const searchData = useFetchSearchDataV2(queryParams);\n\n /**\n * Filters to be applied globally or on indices\n */\n const searchFilters = SearchHelper.getBackendFiltersV2(searchData);\n\n /**\n * Fetch the search dashboard data so we know what widgets to show / fetch\n * for a given query and filters\n */\n const searchDashboard = Flight.useBasicFetch<SearchDashboard>(searchData.hasDataLoaded\n && SharedSearchRequests.searchDashboard(\n queryParams.query,\n searchFilters.backendFilters,\n SearchResultsFilterHelper.getActiveWidgetFilters(\n queryParams,\n { settingsHash: searchData.settings }\n )\n ));\n\n const searchDashboardData = searchDashboard.data?.filter(item => !isEmpty[item.widgetId]);\n \n const { activePresentation } = useActivePresentation();\n const { availablePresentations, hasLivePresentationOnly } = useAvailablePresentations();\n \n /**\n * State of the current filters\n */\n const filters = SearchHelper.getFilters({\n data: searchData,\n inaccessibleIndices: searchFilters?.inaccessibleIndices,\n _hasNewSearch: true,\n _hasPartnerProfiles: searchData.settings.hasPartnerProfiles,\n hasCVFilters: !hasLivePresentationOnly\n });\n \n /**\n * Do we have the data we need for the entire view to render\n */\n const hasLoaded = (\n searchData.hasDataLoaded && filters\n );\n\n /**\n * Do we have the data we need to render our results\n */\n const hasSearchCompleted = (\n searchDashboard.hasCompleted &&\n !!filters\n );\n\n /**\n * Do we actually have results\n */\n const hasResults = (\n hasSearchCompleted && (!!searchDashboardData && searchDashboardData.length)\n );\n\n const showEmptyState = !hasResults && !searchDashboard.isFetching;\n\n const hideDivider = (\n (!searchDashboard.hasCompleted && searchDashboard.isFetching) ||\n (hasResults && !!searchDashboardData.find(item => item.widgetId === WidgetTypeId.SearchTags))\n );\n\n const widgetAppLinks = SearchResultsAppLinkHelper.getSearchWidgetAppLinks(\n queryParams,\n AudienceHelper.getAudienceParams(activeAudiences),\n availablePresentations,\n activePresentation?.vanitySlug\n );\n\n function getContentRequest(widgetTypeId: WidgetTypeId, cursor?: string): Flight.Request {\n if (!searchData.hasDataLoaded)\n return;\n\n return SharedSearchRequests.searchDashboardWidget(\n widgetTypeId,\n queryParams.query,\n searchFilters.backendFilters,\n SearchResultsFilterHelper.getWidgetFilters({\n queryParams,\n widgetTypeId,\n cursor,\n options: { settingsHash: searchData.settings }\n })\n );\n }\n\n /**\n * Transform the search results for a widget before rendering\n * - Merges multiple widgets data into single widget for any template Id\n */\n const searchResultsTransformers = getSearchResultsTransformers();\n /**\n * Transform the search widget items before rendering\n * - Transform search tags to normalize the widget data\n * - Transform search relevant topics to sort by exact match and then presentation level\n */\n const widgetItemTransformers = getSearchWidgetItemTransformers({\n query: queryParams.query,\n availablePresentations: searchData.availablePresentations\n });\n /**\n * Do something with search widget response data when it is first loaded\n * - Detect curriculum code search and updates URL\n * - Exclude video ids from related results widget\n * - Fetches video assocs for valid objects\n */\n const widgetsOnLoadTriggers = getOnLoadWidgetTriggers({\n fetchObjects: videoMixin.fetchObjects,\n isCurriculumCodeSearch: !!queryParams[SEARCH_CURRICULUM_CODE_PARAM]\n });\n\n /**\n * Side Effects below\n */\n React.useEffect(() => {\n // Reset this anytime search dasboard data changes\n setIsEmpty({});\n }, [searchDashboard.data]);\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <div className='px-4'>\n <SearchResultsFilter\n searchData={searchData}\n queryParams={queryParams}\n filters={filters}\n hideDivider={hideDivider}\n />\n\n {(() => {\n if (showEmptyState) {\n return (\n <SearchResultsEmptyState\n query={queryParams.query}\n scotland={searchData.currentUser.data?.contentRegion === ContentRegion.SCOT}\n hideRequestVideo={searchData.isLearner}\n />\n );\n }\n\n return (\n <section>\n <VideoActionsContext.Provider value={videoActions}>\n <MixedWidgetSearchResults\n data={searchDashboardData}\n\n widgetAppLinks={widgetAppLinks}\n isTertiary={searchData.isTertiary}\n commonVideoProps={commonVideoProps}\n audiences={searchData.audiences.data}\n currentUser={searchData.currentUser.data}\n availablePresentations={searchData.availablePresentations}\n settingsHash={searchData.settings}\n \n setIsEmpty={onSetIsEmpty}\n getRequest={getContentRequest}\n hasPermissions={searchData.hasPermissions}\n hasLocalPermissions={searchData.hasLocalPermissions}\n getSeeMoreAppLink={(widget, isLastWidget) => SearchResultsAppLinkHelper.getSeeMoreAppLink({\n widget,\n queryParams,\n isLastWidget,\n appLinks: widgetAppLinks\n })}\n getAnalyticsData={(widget, yIndex, xIndex) => ({\n widgetId: widget.widgetId,\n widgetName: widget.name,\n templateId: widget.templateId,\n widgetIndex: yIndex,\n itemIndex: xIndex,\n search: {\n query: queryParams.query || ''\n }\n })}\n getSelectedItems={widget =>\n SearchResultsFilterHelper.getSearchWidgetSelectedItems(queryParams, widget)\n }\n\n onLoadWidgetsTriggers={widgetsOnLoadTriggers}\n widgetItemTransformers={widgetItemTransformers}\n searchResultsTransformers={searchResultsTransformers}\n >\n {\n shouldShowVideo && tutorialVideo?.data && !hasDismissedVideoHighlight &&\n <div className='mb-3'>\n <VideoHighlight\n video={tutorialVideo?.data}\n subtitle={getPhrase('videoHighlightSubtitle')}\n description={getPhrase('videoHighlightDescription')}\n bgColorClassName='bg-light-green'\n appLink={VideoAppLinkHelper.getAppLink(tutorialVideo?.data, {}, null)}\n locationContext={LocationContext.SearchBar}\n commonVideoProps={commonVideoProps}\n sharedPlaylistAppLink={appLink}\n supportArticle={ArticleHelper.getLiteArticle(LiteSupportArticle.SearchAndDiscover)}\n onDismiss={dismissVideoHighlight}\n />\n </div>\n }\n </MixedWidgetSearchResults>\n \n {(!searchData.isLearner && !searchDashboard.isFetching) &&\n <SearchResultsRequestVideo />\n }\n \n </VideoActionsContext.Provider>\n </section>\n );\n })()}\n </div>\n );\n}\n"],"mappings":"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"}