@clickview/lite 0.82.0-rc.2 → 0.82.0

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 (28) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/css/{2258-lite-16c2b3509c.chunk.css → 275-lite-65ac7606d9.chunk.css} +1 -0
  3. package/dist/languages/en.json +1 -1
  4. package/dist/scripts/2126-1ef42f1367-lite.chunk.js +2 -0
  5. package/dist/scripts/{2126-94c739ca6b-lite.chunk.js.map → 2126-1ef42f1367-lite.chunk.js.map} +1 -1
  6. package/dist/scripts/275-3b6b9cfc9c-lite.chunk.js +3 -0
  7. package/dist/scripts/275-3b6b9cfc9c-lite.chunk.js.map +1 -0
  8. package/dist/scripts/4504-c7d0c4e1e7-lite.chunk.js +2 -0
  9. package/dist/scripts/{4504-5a8c62527f-lite.chunk.js.map → 4504-c7d0c4e1e7-lite.chunk.js.map} +1 -1
  10. package/dist/scripts/6741-1e64f67951-lite.chunk.js +3 -0
  11. package/dist/scripts/{6741-ae590891ba-lite.chunk.js.map → 6741-1e64f67951-lite.chunk.js.map} +1 -1
  12. package/dist/scripts/6948-b1b7f560c9-lite.chunk.js +3 -0
  13. package/dist/scripts/{6948-49f33f09c8-lite.chunk.js.map → 6948-b1b7f560c9-lite.chunk.js.map} +1 -1
  14. package/dist/scripts/{8-40155bcddb-lite.chunk.js → 8-a610fce3d1-lite.chunk.js} +2 -2
  15. package/dist/scripts/{8-40155bcddb-lite.chunk.js.map → 8-a610fce3d1-lite.chunk.js.map} +1 -1
  16. package/dist/scripts/{bundle-aff25c8310.min.js → bundle-1fa665690e.min.js} +3 -3
  17. package/dist/scripts/{bundle-aff25c8310.min.js.map → bundle-1fa665690e.min.js.map} +1 -1
  18. package/package.json +1 -1
  19. package/dist/scripts/2126-94c739ca6b-lite.chunk.js +0 -2
  20. package/dist/scripts/2258-3721ba5687-lite.chunk.js +0 -3
  21. package/dist/scripts/2258-3721ba5687-lite.chunk.js.map +0 -1
  22. package/dist/scripts/4504-5a8c62527f-lite.chunk.js +0 -2
  23. package/dist/scripts/6741-ae590891ba-lite.chunk.js +0 -3
  24. package/dist/scripts/6948-49f33f09c8-lite.chunk.js +0 -3
  25. /package/dist/scripts/{2258-3721ba5687-lite.chunk.js.LICENSE.txt → 275-3b6b9cfc9c-lite.chunk.js.LICENSE.txt} +0 -0
  26. /package/dist/scripts/{6741-ae590891ba-lite.chunk.js.LICENSE.txt → 6741-1e64f67951-lite.chunk.js.LICENSE.txt} +0 -0
  27. /package/dist/scripts/{6948-49f33f09c8-lite.chunk.js.LICENSE.txt → 6948-b1b7f560c9-lite.chunk.js.LICENSE.txt} +0 -0
  28. /package/dist/scripts/{bundle-aff25c8310.min.js.LICENSE.txt → bundle-1fa665690e.min.js.LICENSE.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"scripts/4504-5a8c62527f-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/hooks/UseBatchFetch.ts","file:///app/packages/libs/shared/src/hooks/UseInfiniteScroll.ts","file:///app/packages/libs/shared/src/hooks/UseInfiniteList.ts","file:///app/packages/libs/shared/src/views/feedback/enums/FeedbackOption.ts","file:///app/packages/projects/lite/src/apps/libraries/views/library-folder/LibraryFolderViewUtils.ts","file:///app/packages/libs/shared/src/hooks/useTransformer.tsx","file:///app/packages/libs/shared/src/components/widgets/curated-widgets/hooks/useInfiniteWidgetFetch.ts","file:///app/packages/libs/shared/src/components/widgets/curated-widgets/InfiniteWidgetContainerView.tsx","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/components/search-widget-tooltip/SearchWidgetTooltip.tsx","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/mixed-widget-search-results.scss","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults.tsx","file:///app/packages/libs/shared/src/apps/search/constants/SearchOGQL.ts","file:///app/packages/libs/shared/src/apps/search/flight-requests/SharedSearchRequests.ts","file:///app/packages/projects/lite/src/apps/search/hooks/useFetchSearchData.tsx","file:///app/packages/projects/lite/src/apps/search/hooks/useFetchSchoolLevels.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/components/search-results-request-video/SearchResultsRequestVideo.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/components/search-results-empty-state/SearchResultsEmptyState.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/OnLoadWidgets.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/detectCurriculumCodeSearch.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/fetchVideoAssocsObjects.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/WidgetItemTransformations.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/utils/SearchResultsFilterHelper.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/utils/SearchResultsAppLinkHelper.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/SearchResultsViewV2.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/results/SearchResultsTransformations.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/results/mergeSearchResults.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchTags.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchRelevantTopics.ts","file:///app/packages/projects/lite/src/shared/flight-requests/RatingRequests.ts","file:///app/packages/projects/lite/src/shared/hooks/usePresentationAudiences.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoMixin.ts"],"sourcesContent":["import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nconst CHUNK_SIZE = 50;\n\nexport interface UseBatchFetchResult<T extends BaseObject> {\n itemsArr: T[];\n items: { [key: string]: T} | null;\n isFetching: boolean;\n hasCompleted: boolean;\n}\n\n/**\n * Used to fetch multiple items by id with Flight. Will fetch 25 items at a time firing off multiple\n * requests if there are more than 25 items.\n * This will return items as null until we have all our items. Items will be returned as an object with\n * their ids as they key for easy mapping\n * \n * @param itemIds \n * @param getRequest \n */\nexport function useBatchFetch<T extends BaseObject>(\n itemIds: string[],\n getRequest: (ids: string[]) => Flight.Request\n): UseBatchFetchResult<T> {\n const chunks = ArrayHelper.chunk<string>(itemIds, CHUNK_SIZE);\n\n const requests = chunks.map(chunk => getRequest(ArrayHelper.uniq(chunk)));\n\n const responses = Flight.useBasicFetchAll<T[]>(requests);\n\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length\n ? itemsArr.reduce((acc, item) => ({ ...acc, [item.id]: item }), {})\n : null;\n\n return {\n itemsArr,\n items,\n isFetching: responses.isFetching,\n hasCompleted: responses.hasCompleted\n };\n}\n\n/**\n * When you need the useBatchFetch() behavior, but your list of objects to hydrate\n * will grow, such as on a scrolling page. useGrowingBatchFetch() will use local state\n * to determine what we've already built a request for and what items are new\n * as to not re-fetch items - Sha\n */\nexport function useGrowingBatchFetch<TResponse, TObjects = string>(\n objs: TObjects[],\n getRequest: (items: TObjects[]) => Flight.Request,\n _getKey?: (obj: TObjects) => string\n) {\n const getKey = _getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const { fetchItems, ...data } = useGrowingBatchFetchFunc<TResponse, TObjects>({ getRequest, _getKey });\n\n React.useEffect(() => {\n if (!objs?.length)\n return;\n\n fetchItems(objs);\n }, [objs?.map(getKey).join(',')]);\n\n return data;\n}\n\ninterface UseGrowingBatchFetchFuncOptions<TObjects> {\n getRequest: (items: TObjects[]) => Flight.Request;\n _getKey?: (obj: TObjects) => string;\n}\n\n/**\n * When you need the useGrowingBatchFetch() behaviour, but need to trigger the\n * fetch manually and update the objects - Nish \n */\nexport function useGrowingBatchFetchFunc<TResponse, TObjects = string>(\n options: UseGrowingBatchFetchFuncOptions<TObjects>\n) {\n const getKey = options._getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const fetchedItems = React.useRef<Set<string>>(new Set<string>());\n const [ requests, setRequests ] = React.useState<Flight.Request[]>([]);\n\n function fetchItems(objs: TObjects[]) {\n if (!objs?.length)\n return;\n\n const unfetchedItems: TObjects[] = [];\n \n objs.forEach(obj => {\n const key = getKey(obj);\n\n if (fetchedItems.current.has(key))\n return;\n\n unfetchedItems.push(obj);\n fetchedItems.current.add(key);\n });\n \n if (!unfetchedItems.length)\n return;\n \n setRequests(r => ([ ...r, ...ArrayHelper.chunk<TObjects>(unfetchedItems, CHUNK_SIZE).map(options.getRequest) ]));\n }\n\n const responses = Flight.useBasicFetchAll<TResponse[]>(requests);\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length\n ? itemsArr.reduce<Record<string, TResponse>>((acc, item) => ({ ...acc, [getKey(item)]: item }), {})\n : null;\n\n return {\n hasFirstRequestCompleted: !!responses.responses?.[0]?.hasCompleted,\n itemsArr,\n items,\n isFetching: responses.isFetching,\n fetchItems\n };\n}\n","import { useEffect } from 'react';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst SCROLL_TOLERANCE = 400; // value in px\n\ninterface UseInfiniteScrollOptions {\n fetchNextPage: () => void;\n hasMore: boolean;\n isFetching: boolean;\n scrollContainer?: HTMLElement;\n}\n\nexport function useInfiniteScroll(options: UseInfiniteScrollOptions): void {\n const handleScroll = (): void => {\n if (options.isFetching)\n return;\n\n if (!options.scrollContainer) {\n const currentScrollHeight = window.innerHeight + document.documentElement.scrollTop;\n \n const totalHeight = document.documentElement.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n } else {\n const { scrollContainer } = options;\n const currentScrollHeight = scrollContainer.getBoundingClientRect().height + scrollContainer.scrollTop;\n \n const totalHeight = scrollContainer.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n }\n\n options.fetchNextPage();\n };\n\n useEffect(() => {\n const onScroll = FunctionHelper.throttle(handleScroll, 200);\n\n const scrollContainer = options.scrollContainer || window;\n\n if (options.hasMore)\n scrollContainer.addEventListener('scroll', onScroll);\n\n return () => scrollContainer.removeEventListener('scroll', onScroll);\n }, [ options.hasMore, options.fetchNextPage, options.scrollContainer ]);\n}","import { useEffect, useState } from 'react';\n\nimport { HttpStatus, HttpStatusClass } from 'libs/common/backbone/enums/HttpStatus';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { BaseObject, BasePaginatedCollection } from 'libs/shared/interfaces';\n\nimport { useInfiniteScroll } from './UseInfiniteScroll';\nimport { useSelectAllPages } from './UseSelectAllPages';\n\nexport interface UseInfiniteListResult<T extends BaseObject> {\n items: T[];\n hasMore: boolean;\n isFetching: boolean;\n nextCursor: string;\n totalItems?: number;\n hasFirstPageCompleted: boolean;\n}\n\n/**\n * Hook to extract an infinite list from the application state,\n * save it locally in state and only update when new data\n * is fetched.\n * \n * @param getRequest - callback function to get the request for each page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n * \n * @param fetchNext - callback function to fetch a page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n */\nexport function useInfiniteList<TObject = BaseObject, TResponse = BasePaginatedCollection<TObject>>(\n getRequest: ((cursor?: string) => Flight.Request) | false,\n fetchNext: ((cursor?: string) => void) | false,\n onError?: (pageNumber: number, statusCode: HttpStatus) => void,\n getItems?: (responseData: TResponse) => TObject[],\n getCursor?: (responseData: TResponse) => string,\n scrollContainer?: HTMLElement\n): UseInfiniteListResult<TObject> {\n const [ pagesFetched, setPagesFetched ] = useState(0);\n\n const fetchNextFn = fetchNext as (cursor?: string) => void;\n\n function getKey(cursor?: string): string {\n if (!getRequest)\n return null;\n\n const request = getRequest(cursor);\n\n if (!request)\n return null;\n\n return request.key;\n }\n\n const response = useSelectAllPages<TObject, TResponse>(\n getKey,\n getItems,\n getCursor\n );\n\n function fetchNextPage(): void {\n if (!fetchNext || !getRequest || !response)\n return;\n\n setPagesFetched(currentVal => currentVal + 1);\n return fetchNextFn(response.nextCursor);\n }\n\n useInfiniteScroll({\n fetchNextPage,\n hasMore: !!response?.nextCursor,\n isFetching: response?.isFetching,\n scrollContainer\n });\n\n useEffect(() => {\n if (!response)\n return;\n\n if (response.shouldInitialFetch && fetchNext) {\n fetchNextFn();\n setPagesFetched(currentVal => currentVal + 1);\n }\n }, [ response?.shouldInitialFetch, fetchNext ]);\n\n useEffect(() => {\n if (!response?.statusCode || !FunctionHelper.isFunction(onError))\n return;\n\n const httpStatusClass: HttpStatusClass = +(response.statusCode?.toString()?.substr(0, 1));\n\n if (httpStatusClass !== HttpStatusClass.ClientError && httpStatusClass !== HttpStatusClass.ServerError)\n return;\n\n onError(pagesFetched, response.statusCode);\n }, [response?.statusCode]);\n\n return {\n items: response?.items,\n hasMore: !!response?.nextCursor,\n nextCursor: response?.nextCursor,\n isFetching: response?.isFetching,\n totalItems: response?.totalItems,\n hasFirstPageCompleted: response?.hasFirstPageCompleted\n };\n}","export enum FeedbackOption {\n SUGGEST_IMPROVEMENT = 'suggestImprovement',\n REPORT_BUG = 'reportBug',\n REQUEST_VIDEO = 'requestVideo',\n REQUEST_LIVESTREAM = 'requestLivestream',\n GIVE_PRAISE = 'givePraise',\n RAISE_ISSUE = 'raiseIssue',\n OTHER = 'other'\n}","import { Core } from 'libs/common/core';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { Folder, Library } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getFolderAppLink(libraryId: string, folder: Folder, sort: string): Core.AppLink {\n if (!libraryId || !folder)\n return null;\n\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.FOLDER,\n args: [ libraryId, folder.id, TextHelper.slugify(folder.name) ],\n params: {\n sort\n }\n };\n}\n\nexport function getFolderBgColourClass(folder: Folder | Library): string {\n let charCode = 0;\n\n for (let i = 0; i < folder.name?.length ?? 0; i++) {\n charCode += folder.name.charCodeAt(i);\n }\n\n return BG_COLOUR_CLASS_NAMES[charCode % BG_COLOUR_CLASS_NAMES.length];\n}","import React from 'react';\n\nimport { Middleware, type MiddlewareFunctionSync } from 'libs/common/backbone/core';\n\nexport type UseTransformerFunc<T> = (options: T) => T;\n\nexport function useTransformer<T>(transformations?: MiddlewareFunctionSync<T>[]) {\n const middleware = React.useMemo(() => new Middleware<T>(), []);\n\n React.useEffect(() => {\n if (!transformations || !transformations.length)\n return;\n\n transformations.forEach(fn => middleware.useSync(fn));\n }, []);\n\n function push(fn: MiddlewareFunctionSync<T>): void {\n if (!middleware)\n return;\n\n middleware.useSync(fn);\n }\n\n function execute(options: T): T {\n if (!middleware)\n return;\n \n return middleware.goSync(options);\n }\n \n return {\n push,\n execute\n };\n}","import React from 'react';\n\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { handleHttpError } from 'libs/shared/errors/handlers/HttpErrorHandlers';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useInfiniteList } from 'libs/shared/hooks/UseInfiniteList';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useTransformer, UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { BaseWidget } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.useInfiniteWidgetFetch';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UseInfiniteWidgetFetchOptions<TItem, TWidget> {\n item: TItem;\n infiniteFetch: boolean;\n getRequest: (cursor?: string) => Flight.Request;\n getCursor: (widget: TWidget) => string;\n setIsEmpty?: (isEmpty: boolean) => void;\n \n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\nexport function useInfiniteWidgetFetch<\n TItem extends BaseWidget,\n TWidget extends BaseWidget\n>(options: UseInfiniteWidgetFetchOptions<TItem, TWidget>) {\n const fetch = Flight.useGetFetch();\n const alerts = useAlerts();\n const { ref: partialLoadingRef, inView } = useLazyLoad();\n const resultsTransformers = useTransformer<TWidget[]>(options.resultsTransformers ?? []);\n const widgetItemTransformers = useTransformer<TWidget>(options.widgetItemTransformers ?? []);\n \n function fetchNext(cursor?: string) {\n return fetch(options.getRequest(cursor));\n }\n\n function onError(pageNumber: number, httpStatus: HttpStatus): void {\n if (pageNumber === 1)\n return handleHttpError(httpStatus);\n\n alerts.error(getPhrase('error'));\n }\n \n function getItems(response: TWidget) {\n return [response];\n }\n \n const fetchResults = useInfiniteList<TWidget, TWidget>(\n inView && options.getRequest,\n inView && fetchNext,\n onError,\n getItems,\n options.infiniteFetch && options.getCursor\n );\n\n function transformResults(data: TWidget[]): TWidget[] {\n if (!data || !data.length)\n return;\n\n const results = resultsTransformers.execute(data);\n\n if (!options.widgetItemTransformers?.length)\n return results;\n\n const transformedResults = results.map(item => widgetItemTransformers.execute(item));\n\n return transformedResults;\n }\n\n /**\n * This is an array of widgets because technically we can have same widget type id\n * but different template id. This is the case the search series widget.\n */\n const items = transformResults(fetchResults.items);\n\n /**\n * Side effects below\n */\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted || !items)\n return;\n\n if (!options.onLoadWidgetsTriggers?.length || !items.length)\n return;\n\n options.onLoadWidgetsTriggers.forEach(onLoad => onLoad(items));\n }, [ fetchResults.hasFirstPageCompleted, items ]);\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted)\n return;\n\n if (!items) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (Array.isArray(items) && !items.length) {\n options.setIsEmpty?.(true);\n return;\n }\n }, [fetchResults.hasFirstPageCompleted]);\n\n\n const isEmpty = !items?.length;\n const showLoading = !fetchResults.hasFirstPageCompleted;\n const showInfiniteScrollFooter = options.infiniteFetch && (fetchResults.hasMore || fetchResults.isFetching);\n\n return {\n widgets: items,\n isEmpty,\n showLoading,\n showInfiniteScrollFooter,\n isFetching: fetchResults.isFetching,\n nextCursor: fetchResults.nextCursor,\n fetchNext,\n partialLoadingRef\n };\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllSearchWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, BaseWidget, type CurrentUser, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { useInfiniteWidgetFetch } from './hooks/useInfiniteWidgetFetch';\ninterface InfiniteWidgetContainerViewProps<TItem, TWidget> {\n index: number;\n item: TItem;\n /**\n * If set to false will only fetch the first page\n */\n infiniteFetch: boolean;\n\n currentUser: CurrentUser;\n audiences: PresentationAudience[];\n commonVideoProps: CommonVideoProps;\n dashboardTarget?: DashboardTargetType;\n availablePresentations: Presentation[];\n appLinks: AllSearchWidgetTemplates['appLinks'];\n appLinkOptions: AllSearchWidgetTemplates['appLinkOptions'];\n\n hasPermissions: HasPermissionsFunc;\n getName: (widget: TWidget) => string;\n getPartialLoadingPredicate?: () => boolean;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getWidgetClassName?: (widget: TWidget) => string;\n getBadgeComponent: (widget: TWidget) => JSX.Element;\n getSeeMoreAppLink: (widget: TWidget) => Core.AppLink;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n getWidgetMetadata: (widget: TWidget) => Partial<WidgetMetadata>;\n getAnalyticsData?: (widget: TWidget, yIndex: number, xIndex: number) => HashObject;\n\n getCursor: (widget: TWidget) => string;\n getRequest: (cursor?: string) => Flight.Request;\n setIsEmpty?: (isEmpty: boolean) => void;\n \n /**\n * Array of transformers to be applied to results before rendering\n */\n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n /**\n * Array of transformers to be applied to each widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function InfiniteWidgetContainerView<\nTItem extends BaseWidget = BaseWidget,\nTWidget extends BaseWidget = BaseWidget\n>(props: InfiniteWidgetContainerViewProps<TItem, TWidget>): JSX.Element {\n const {\n isEmpty,\n widgets,\n partialLoadingRef,\n showLoading,\n fetchNext,\n isFetching,\n nextCursor,\n showInfiniteScrollFooter\n } = useInfiniteWidgetFetch({\n getRequest: props.getRequest,\n getCursor: props.getCursor,\n setIsEmpty: props.setIsEmpty,\n item: props.item,\n infiniteFetch: props.infiniteFetch,\n resultsTransformers: props.resultsTransformers,\n onLoadWidgetsTriggers: props.onLoadWidgetsTriggers,\n widgetItemTransformers: props.widgetItemTransformers\n });\n \n const template = WidgetTemplateConfig[props.item.templateId];\n const PartialTemplate = template.partialLoading;\n \n if (!template || !showLoading && isEmpty)\n return <></>;\n \n if (showLoading) {\n return (\n <div ref={partialLoadingRef} className='py-2'>\n <PartialTemplate\n name={props.item.name}\n description={props.item?.description}\n predicate={props?.getPartialLoadingPredicate}\n />\n </div>\n );\n }\n\n return (\n <>\n {widgets.map((widget, index) => {\n const isLastItem = index === widgets.length - 1;\n return (\n <React.Fragment key={`${widget.widgetId}-${widget.templateId}-${index}`}>\n <WidgetContainerView\n id={widget.index.toString()}\n widgetIndex={props.item.index}\n dashboardTarget={props.dashboardTarget}\n\n appLinks={props.appLinks}\n appLinkOptions={props.appLinkOptions}\n audiences={props.audiences}\n content={widget.content.data}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n currentUser={props.currentUser}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n \n name={props.getName(widget)}\n hasPermissions={props.hasPermissions}\n getSelectedItems={props.getSelectedItems}\n metadata={props.getWidgetMetadata(widget)}\n seeMoreLink={props.getSeeMoreAppLink(widget)}\n badgeComponent={props.getBadgeComponent(widget)}\n getAnalyticsData={xIndex => props.getAnalyticsData(widget, props.index, xIndex)}\n className={props.getWidgetClassName(widget)}\n\n settings={null}\n description={null}\n isPreviewing={false}\n onClickRemoveItem={null}\n />\n {showInfiniteScrollFooter && isLastItem && (\n <InfiniteScrollFooter\n isFetching={isFetching}\n fetchNext={fetchNext}\n fetchOnScroll\n nextCursor={nextCursor}\n />\n )}\n </React.Fragment>\n );\n })}\n </>\n );\n}","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 { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\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.SearchRelatedResults]: 'relatedResultsTooltip'\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 svgName={cvSvgLibrary.Info}\n title={getPhrase(phrase)}\n tooltipPlacement='top'\n tooltipSpanHack\n tooltipSpanHackClassName='ms-2'\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"searchResultsWidgetsContainer\":\"Z5jXs\"};","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 { 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.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\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: 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 <InfiniteWidgetContainerView<SearchDashboardItem, WidgetSearchItem>\n index={idx}\n item={item}\n key={item.widgetId}\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\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 );\n })}\n </div>\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: `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};","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';\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\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: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\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: 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 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 };\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};","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 { 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 { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\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\n const streamableLibrary = Flight.useBasicFetch<HashObject>(LibraryRequests.streamableLearning());\n const streamableLibraryId = streamableLibrary.data?.objectId;\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) {\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 };\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 {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n\n if (!hasPresentationsLoaded)\n return ratings;\n\n if (availablePresentations?.length > 1 || !currentPresentation)\n return ratings;\n\n const learningLevel = TopicsHelper.getMappedPresentationLevel(currentPresentation.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 } = useGetLibraries();\n\n const {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n const currentPresentationId = currentPresentation?.id;\n\n const curriculums = useCurriculums();\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(currentPresentation);\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,\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 };\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 } = useGetLibraries();\n\n const {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n const currentPresentationId = currentPresentation?.id;\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(currentPresentation);\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,\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 hasMoviesAndTv,\n isTertiary\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 { usePresentation } from 'shared/hooks/usePresentation';\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 {\n availablePresentations,\n hasPresentationsLoaded\n } = usePresentation();\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}","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}","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={{ application: AppChannels.SUBJECT, action: Actions.Subjects.PRESENTATION_TOPICS }}\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}","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { detectCurriculumCodeSearch, DetectCurriculumCodeSearchOptions } from './detectCurriculumCodeSearch';\nimport { fetchVideoAssocsObjects, FetchVideoAssocsObjectsOptions } from './fetchVideoAssocsObjects';\n\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}","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\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}","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}","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 { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { BaseObject } from 'libs/shared/interfaces';\n\ninterface HasQueryParamOptions {\n queryParams: HashObject;\n key: string;\n value: string;\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.SearchRelatedResults,\n WidgetTypeId.SearchCurriculumCode\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): WidgetTypeId {\n if (!queryParams?.focus)\n return;\n\n if (typeof queryParams.focus === 'string') {\n return SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus);\n }\n\n if (Array.isArray(queryParams.focus) && queryParams.focus.length === 1) {\n return SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus[0]);\n }\n\n return;\n}\n\nfunction getWidgetIdsFromQueryParams(queryParams: HashObject): WidgetTypeId[] {\n const widgets: WidgetTypeId[] = [];\n\n const focusedWidget = getValidFocusedWidget(queryParams);\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 (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 (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.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 ): WidgetFilter[] {\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams);\n \n return widgets.map(w => ({ id: w }));\n },\n\n getWidgetFilters(\n queryParams: HashObject,\n widgetTypeId: WidgetTypeId,\n cursor?: string\n ): WidgetFilter[] {\n if (cursor) {\n return [{\n id: widgetTypeId,\n cursor\n }];\n }\n\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams);\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};","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, 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 { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { LitePresentationHelper } from 'shared/utils/LitePresentationHelper';\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 getSearchWidgetAppLinkOptions(\n presentation: Presentation,\n availablePresentations: Presentation[]\n ): MixedWidgetSearchResultsProps['widgetAppLinkOptions'] {\n return {\n company: (company: Company): Core.AppLinkOptions => ({\n middlewareOptions: {\n presentationSlug: LitePresentationHelper.getPresentationSlugByCompany(\n company,\n presentation,\n availablePresentations\n )\n }\n })\n };\n },\n \n getSearchWidgetAppLinks(\n queryParams: HashObject,\n audienceParams: AudienceFilterParams = {}\n ): MixedWidgetSearchResultsProps['widgetAppLinks'] {\n return {\n classification: (classification?: Classification) => {\n const options: GetClassificationAppLinkOptions = {\n ...audienceParams,\n moviesAndTv: TopicsHelper.isMtv(classification)\n };\n\n return ClassificationAppLinkHelper.getAppLink(classification, options);\n },\n \n videoType: (video: VideoTypes, opts: GetVideoAppLinkOptions) => (\n VideoAppLinkHelper.getAppLink(video, {\n ...opts,\n includeContext: false\n })\n ),\n \n series: SeriesAppLinkHelper.getSeriesAppLink,\n \n playlist: (playlist: Playlist) => ({\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.PLAYLIST,\n args: [ playlist.id, TextHelper.slugify(playlist.name) ]\n }),\n \n \n company: (company: Company) => ({\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.COMPANY_DASHBOARD,\n args: [ company.id, TextHelper.slugify(company.name) ]\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.SEARCH_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 { EntityType, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { MixedWidgetSearchResults } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { SearchFilters } from 'libs/shared/apps/search/components/search-filters/SearchFilters';\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 { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ContentRegion } from 'libs/shared/enums/ContentRegion';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useVideoMixinFunc } from 'shared/hooks/useVideoMixin';\n\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\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 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 });\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(queryParams)\n ));\n\n const searchDashboardData = searchDashboard.data?.filter(item => !isEmpty[item.widgetId]);\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 });\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 );\n\n const widgetAppLinkOptions = SearchResultsAppLinkHelper.getSearchWidgetAppLinkOptions(\n searchData.currentPresentation,\n searchData.availablePresentations\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(queryParams, widgetTypeId, cursor)\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 /**\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 {(!!searchData.audiences.data && !!searchData.ratings.data && !!searchData.availableTopics.data) && (\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 _hasNewSearch\n />\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 widgetAppLinkOptions={widgetAppLinkOptions}\n isTertiary={searchData.isTertiary}\n commonVideoProps={commonVideoProps}\n audiences={searchData.audiences.data}\n currentUser={searchData.currentUser.data}\n availablePresentations={searchData.availablePresentations}\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 {(!searchData.isLearner && !searchDashboard.isFetching) &&\n <SearchResultsRequestVideo />\n }\n \n </VideoActionsContext.Provider>\n </section>\n );\n })()}\n </div>\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}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\n/**\n * Paginated data returns more widgets so if we dont merge the widget content by widget type id,\n * it would add another widget to the page rather than appending content to the relevant\n * search result index\n * \n * For example:\n * Say we receive these widgets for a query:\n * - topics widget\n * - related results widget\n * \n * If a user scrolls down to the end of page we fetch more items from the last widget\n * which in this case is 'related results widget'. \n * Now our overall response looks like this\n * - topics widget\n * - related results widget\n * - related results widget\n * \n * Since this is a new widget item entry it will be rendered as a new widget with seprate headings etc.\n * In this case we want to combine these two widgets data into one so its looks like this again:\n * - topics widget\n * - related results widget (data is combined)\n * \n * But what if widget we get recieve has a different widget template id. This currently happens for\n * the 'series widget' - series widget can have the tall poster template or the thumbnail like template.\n * \n * so to visualize this it can be like:\n * - topics widget\n * - top results widget\n * - series widget (template: tall poster)\n * - series widget (template: thumbnail)\n * \n * Since they technically will look different based on the template id we will not merge the data in this case.\n * It will merge the data to the same widget as long as the combination of widget Id + template Id is the same.\n * \n * Since they are separate widgets they will render duplicate headings - we handle this in css instead which\n * checks for adjacent siblings and if its the same widget - it hides the widget heading so it will look\n * like its a single widget rather than separate widgets.\n * \n * - Nish\n */\nexport function mergeSearchResults(options: SearchResultsTransformOptions): SearchResultsTransformOptions {\n const { data } = options;\n \n if (!data) return options;\n \n const items = [...data];\n\n const groupedWidgets = ArrayHelper.groupBy(items, 'widgetId');\n\n const mergedWidgets: WidgetSearchItem[] = [];\n\n for (const widgetGroup of Object.values(groupedWidgets)) {\n let currentMergedWidget: WidgetSearchItem = null;\n const widgets: WidgetSearchItem[] = [];\n\n for (const widget of widgetGroup) {\n if (!currentMergedWidget) {\n currentMergedWidget = widget;\n continue;\n }\n\n /**\n * Widgets of the same type may have different templates. When this occurs,\n * we want to make sure each widgetType + template combo is pushed\n * as a separate widget.\n */\n if (widget.templateId !== currentMergedWidget.templateId) {\n widgets.push(currentMergedWidget);\n currentMergedWidget = widget;\n continue;\n }\n\n currentMergedWidget.content.data = [\n ...(currentMergedWidget.content.data || []),\n ...widget.content.data\n ];\n }\n\n widgets.push(currentMergedWidget);\n mergedWidgets.push(...widgets);\n }\n\n return {\n ...options,\n data: mergedWidgets\n };\n}","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\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}","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/**\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}","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { Rating } from 'libs/shared/interfaces';\n\nexport const RatingRequests = {\n ratings(countryCode?: string, includeE?: boolean): Flight.PublicRequest {\n return {\n url: '/api/domain/v2/me/ratings',\n publicUrl: UrlHelper.urlBuilder('/api/domain/v2/me/ratings', { countryCode }),\n key: `ratings:${includeE}`,\n // v2/me/ratings doesn't support `query={orderby:value}`. Adding this due to time constraints\n formatData: (ratings: Rating[]) => {\n const resp = ratings.sort((a, b) => a.value - b.value);\n \n if (includeE)\n return resp;\n\n return resp.filter(r => r.code !== 'E');\n }\n };\n }\n};","import { Flight } from 'libs/common/react/index';\n\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport { usePresentation } from 'shared/hooks/usePresentation';\n\nexport const usePresentationAudiences = () => {\n const { activePresentation, getFallbackPresentation } = usePresentation({ redirectOnError: true });\n\n const presentation = activePresentation || getFallbackPresentation();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n !!presentation &&\n AudienceRequests.presentationAudiences(presentation.id)\n );\n\n return audiences;\n};","import { Flight } from 'libs/common/react/index';\n\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useGrowingBatchFetch, useGrowingBatchFetchFunc } from 'libs/shared/hooks/UseBatchFetch';\nimport { Clip, ClipCollection, Video, VideoCollection } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\ntype Types = Video[] | VideoCollection | Clip[] | ClipCollection;\n\nfunction getValidObjects(objects: Types): (Video | Clip)[] {\n if (!objects)\n return [];\n\n if (Array.isArray(objects))\n return objects.filter(o => !!o && (VideoHelper.isVideo(o) || VideoHelper.isClip(o)));\n\n if ('data' in objects)\n return objects.data.filter(o => !!o && (VideoHelper.isVideo(o) || VideoHelper.isClip(o)));\n\n return [];\n}\n\ninterface VideoMixinOptions {\n /**\n * If the videos that are having new data mixed into are sitting on an explicit Flight namespace,\n * providing that namespace here is required\n */\n flightNamespace?: string;\n}\n\nexport function useVideoMixin(objects: Types, options: VideoMixinOptions = {}) {\n const videoIds = getValidObjects(objects).map(v => v.id);\n\n useGrowingBatchFetch(\n videoIds,\n ids => VideoRequests.videoMixinAssocs(ids, options.flightNamespace),\n null\n );\n}\n\nexport function useVideoMixinFunc(options: VideoMixinOptions = {}) {\n function getRequest(ids: string[]): Flight.Request {\n return VideoRequests.videoMixinAssocs(ids, options.flightNamespace);\n }\n \n function fetchObjects(items: Types) {\n return fetchItems(getValidObjects(items).map(v => v.id));\n }\n\n const { fetchItems } = useGrowingBatchFetchFunc({ getRequest });\n\n return { fetchObjects };\n}"],"names":["CHUNK_SIZE","useBatchFetch","itemIds","getRequest","requests","map","chunk","responses","itemsArr","data","items","length","reduce","acc","item","id","isFetching","hasCompleted","useGrowingBatchFetch","objs","_getKey","getKey","obj","useGrowingBatchFetchFunc","fetchItems","join","options","fetchedItems","Set","setRequests","hasFirstRequestCompleted","unfetchedItems","forEach","key","current","has","push","add","r","SCROLL_TOLERANCE","useInfiniteList","fetchNext","onError","getItems","getCursor","scrollContainer","handleScroll","useState","pagesFetched","setPagesFetched","fetchNextFn","response","cursor","request","fetchNextPage","currentVal","nextCursor","hasMore","getBoundingClientRect","height","scrollTop","scrollHeight","window","innerHeight","document","documentElement","useEffect","onScroll","FunctionHelper","addEventListener","removeEventListener","shouldInitialFetch","statusCode","httpStatusClass","toString","substr","HttpStatus","totalItems","hasFirstPageCompleted","FeedbackOption","getFolderAppLink","libraryId","folder","sort","application","action","args","name","params","getFolderBgColourClass","charCode","i","charCodeAt","useTransformer","transformations","middleware","fn","useSync","execute","goSync","getPhrase","LanguageService","InfiniteWidgetContainerView","props","fetch","alerts","partialLoadingRef","ref","inView","resultsTransformers","widgetItemTransformers","fetchResults","pageNumber","httpStatus","error","infiniteFetch","results","transformResults","onLoadWidgetsTriggers","onLoad","Array","isArray","setIsEmpty","isEmpty","showLoading","showInfiniteScrollFooter","widgets","useInfiniteWidgetFetch","template","WidgetTemplateConfig","templateId","PartialTemplate","partialLoading","className","description","predicate","getPartialLoadingPredicate","widget","index","isLastItem","widgetId","WidgetContainerView","widgetIndex","dashboardTarget","appLinks","appLinkOptions","audiences","content","widgetTypeId","currentUser","commonVideoProps","availablePresentations","getName","hasPermissions","getSelectedItems","metadata","getWidgetMetadata","seeMoreLink","getSeeMoreAppLink","badgeComponent","getBadgeComponent","getAnalyticsData","xIndex","getWidgetClassName","settings","isPreviewing","onClickRemoveItem","InfiniteScrollFooter","fetchOnScroll","SearchWidgetTooltip","isTertiary","phrase","WidgetTypeId","SvgContainer","svgName","title","tooltipPlacement","tooltipSpanHack","tooltipSpanHackClassName","MixedWidgetSearchResults","idx","isLastWidget","curriculumLeafName","curriculumLeafDescription","includes","widgetAppLinks","widgetAppLinkOptions","hasLocalPermissions","searchResultsTransformers","SearchOGQL","video","series","playlist","classification","TagType","clip","interactive","company","category","formatSearchResponse","totalResults","filter","result","_index","clips","interactives","videos","resultMaxScore","_score","SharedSearchHelper","stringifyObject","Object","entries","prev","value","stringifiedValue","searchDashboard","query","filters","widgetData","a","b","localeCompare","w","filterData","FilterConstants","indicesFilter","isLearner","genericFilters","indices","replace","includeAllIndices","url","publicUrl","type","HttpVerbs","searchDashboardWidget","excludeVideoIds","ogql","searchV5","searchV4","sorts","allowSubstitute","limit","keys","filterName","excludeLibraryExclusive","searchType","undefined","formatData","search","success","assign","UrlHelper","tagsAndClassifications","normalize","useFetchSearchDataV2","queryParams","userDetails","config","yearGroups","isAuthenticated","customerId","products","useIsTertiary","streamableLibrary","LibraryRequests","streamableLibraryId","objectId","showExchangeSearchResults","hasProduct","ProductId","librariesRequest","libraries","exchangeLibraryIndex","findIndex","l","MasterObjectTypes","exchangeLibraryId","slice","streamableIndex","hasLibrariesCompleted","useGetLibraries","activePresentation","getFallbackPresentation","hasPresentationsLoaded","currentPresentation","currentPresentationId","schoolLevels","presentation","presentationIds","o","SearchRequests","schoolLevelIds","availableTopics","ratings","RatingRequests","countryCode","TopicsHelper","learningLevel","PresentationLearningLevel","rating","code","useGetRatings","hasCustomLibraries","hasMoviesAndTv","isGuest","moviesAndTvDashboard","targetType","dashboard","hasDataLoaded","isLoadingProducts","isLoadingSettings","SearchResultsRequestVideo","skipBeforeRequestingVideoStep","Text","namespace","AppLink","appLink","selectedOption","SearchResultsEmptyState","imageUrl","scotland","trim","toLowerCase","ImageUrls","EmptyState","src","hideRequestVideo","getOnLoadWidgetTriggers","hasSearchedCode","isCurriculumCodeSearch","detectCurriculumCodeSearch","objects","outer","inner","fetchObjects","fetchVideoAssocsObjects","DevError","SupportedSearchWidgetTypeIds","hasQueryParam","targetParam","getWidgetIdsFromQueryParams","focusedWidget","focus","find","getValidFocusedWidget","ArrayHelper","SearchResultsFilterHelper","isOnlyActiveWidget","p","getActiveWidgetFilters","getWidgetFilters","getSelectedTagOrClassification","tagOrClassification","tag","getSearchWidgetSelectedItems","SearchResultsAppLinkHelper","getSearchWidgetAppLinkOptions","middlewareOptions","presentationSlug","LitePresentationHelper","getSearchWidgetAppLinks","audienceParams","moviesAndTv","ClassificationAppLinkHelper","videoType","opts","VideoAppLinkHelper","includeContext","SeriesAppLinkHelper","TextHelper","searchSettings","searchHome","filterParams","x","getPreviewQuestionsAppLink","InteractiveHelper","getAppLinkFunc","WidgetTypeIdConfig","getCollectionAppLink","SearchResultsViewV2","videoMixin","useVideoMixin","onSetIsEmpty","prevState","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","allowIndexing","activeAudiences","SharedViewModelKeys","storage","videoActions","useVideoActions","location","useCommonVideoProps","locationContext","mtv","searchData","searchFilters","backendFilters","searchDashboardData","inaccessibleIndices","_hasNewSearch","hasLoaded","hasResults","showEmptyState","hideDivider","AudienceHelper","getContentRequest","getData","groupedWidgets","mergedWidgets","values","currentMergedWidget","mergeSearchResults","normalizedItemData","transformSearchTags","sortByLearningLevel","relevantTopicsData","remainingTopicsData","exactMatchSortedTopics","remainingSortedTopics","topic","MasterTypeHelper","sortedItem","transformSearchRelevantTopics","widgetsOnLoadTriggers","SearchFilters","mainFilters","moreFilters","analyticsOptions","entity","contentRegion","ContentRegion","VideoActionsContext","yIndex","widgetName","itemIndex","includeE","resp","usePresentationAudiences","redirectOnError","getValidObjects","videoIds","v","ids","flightNamespace","useVideoMixinFunc"],"sourceRoot":""}
1
+ {"version":3,"file":"scripts/4504-c7d0c4e1e7-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/hooks/UseBatchFetch.ts","file:///app/packages/libs/shared/src/hooks/UseInfiniteScroll.ts","file:///app/packages/libs/shared/src/hooks/UseInfiniteList.ts","file:///app/packages/libs/shared/src/views/feedback/enums/FeedbackOption.ts","file:///app/packages/projects/lite/src/apps/libraries/views/library-folder/LibraryFolderViewUtils.ts","file:///app/packages/libs/shared/src/hooks/useTransformer.tsx","file:///app/packages/libs/shared/src/components/widgets/curated-widgets/hooks/useInfiniteWidgetFetch.ts","file:///app/packages/libs/shared/src/components/widgets/curated-widgets/InfiniteWidgetContainerView.tsx","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/components/search-widget-tooltip/SearchWidgetTooltip.tsx","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/mixed-widget-search-results.scss","file:///app/packages/libs/shared/src/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults.tsx","file:///app/packages/libs/shared/src/apps/search/constants/SearchOGQL.ts","file:///app/packages/libs/shared/src/apps/search/flight-requests/SharedSearchRequests.ts","file:///app/packages/projects/lite/src/apps/search/hooks/useFetchSearchData.tsx","file:///app/packages/projects/lite/src/apps/search/hooks/useFetchSchoolLevels.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/components/search-results-request-video/SearchResultsRequestVideo.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/components/search-results-empty-state/SearchResultsEmptyState.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/OnLoadWidgets.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/detectCurriculumCodeSearch.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/on-load/fetchVideoAssocsObjects.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/WidgetItemTransformations.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/utils/SearchResultsFilterHelper.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/utils/SearchResultsAppLinkHelper.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/SearchResultsViewV2.tsx","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/results/SearchResultsTransformations.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/results/mergeSearchResults.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchTags.ts","file:///app/packages/projects/lite/src/apps/search/views/search-results-v2/transformations/widget-item/transformSearchRelevantTopics.ts","file:///app/packages/projects/lite/src/shared/flight-requests/RatingRequests.ts","file:///app/packages/projects/lite/src/shared/hooks/usePresentationAudiences.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoMixin.ts"],"sourcesContent":["import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nconst CHUNK_SIZE = 50;\n\nexport interface UseBatchFetchResult<T extends BaseObject> {\n itemsArr: T[];\n items: { [key: string]: T} | null;\n isFetching: boolean;\n hasCompleted: boolean;\n}\n\n/**\n * Used to fetch multiple items by id with Flight. Will fetch 25 items at a time firing off multiple\n * requests if there are more than 25 items.\n * This will return items as null until we have all our items. Items will be returned as an object with\n * their ids as they key for easy mapping\n * \n * @param itemIds \n * @param getRequest \n */\nexport function useBatchFetch<T extends BaseObject>(\n itemIds: string[],\n getRequest: (ids: string[]) => Flight.Request\n): UseBatchFetchResult<T> {\n const chunks = ArrayHelper.chunk<string>(itemIds, CHUNK_SIZE);\n\n const requests = chunks.map(chunk => getRequest(ArrayHelper.uniq(chunk)));\n\n const responses = Flight.useBasicFetchAll<T[]>(requests);\n\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length\n ? itemsArr.reduce((acc, item) => ({ ...acc, [item.id]: item }), {})\n : null;\n\n return {\n itemsArr,\n items,\n isFetching: responses.isFetching,\n hasCompleted: responses.hasCompleted\n };\n}\n\n/**\n * When you need the useBatchFetch() behavior, but your list of objects to hydrate\n * will grow, such as on a scrolling page. useGrowingBatchFetch() will use local state\n * to determine what we've already built a request for and what items are new\n * as to not re-fetch items - Sha\n */\nexport function useGrowingBatchFetch<TResponse, TObjects = string>(\n objs: TObjects[],\n getRequest: (items: TObjects[]) => Flight.Request,\n _getKey?: (obj: TObjects) => string\n) {\n const getKey = _getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const { fetchItems, ...data } = useGrowingBatchFetchFunc<TResponse, TObjects>({ getRequest, _getKey });\n\n React.useEffect(() => {\n if (!objs?.length)\n return;\n\n fetchItems(objs);\n }, [objs?.map(getKey).join(',')]);\n\n return data;\n}\n\ninterface UseGrowingBatchFetchFuncOptions<TObjects> {\n getRequest: (items: TObjects[]) => Flight.Request;\n _getKey?: (obj: TObjects) => string;\n}\n\n/**\n * When you need the useGrowingBatchFetch() behaviour, but need to trigger the\n * fetch manually and update the objects - Nish \n */\nexport function useGrowingBatchFetchFunc<TResponse, TObjects = string>(\n options: UseGrowingBatchFetchFuncOptions<TObjects>\n) {\n const getKey = options._getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const fetchedItems = React.useRef<Set<string>>(new Set<string>());\n const [ requests, setRequests ] = React.useState<Flight.Request[]>([]);\n\n function fetchItems(objs: TObjects[]) {\n if (!objs?.length)\n return;\n\n const unfetchedItems: TObjects[] = [];\n \n objs.forEach(obj => {\n const key = getKey(obj);\n\n if (fetchedItems.current.has(key))\n return;\n\n unfetchedItems.push(obj);\n fetchedItems.current.add(key);\n });\n \n if (!unfetchedItems.length)\n return;\n \n setRequests(r => ([ ...r, ...ArrayHelper.chunk<TObjects>(unfetchedItems, CHUNK_SIZE).map(options.getRequest) ]));\n }\n\n const responses = Flight.useBasicFetchAll<TResponse[]>(requests);\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length\n ? itemsArr.reduce<Record<string, TResponse>>((acc, item) => ({ ...acc, [getKey(item)]: item }), {})\n : null;\n\n return {\n hasFirstRequestCompleted: !!responses.responses?.[0]?.hasCompleted,\n itemsArr,\n items,\n isFetching: responses.isFetching,\n fetchItems\n };\n}\n","import { useEffect } from 'react';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst SCROLL_TOLERANCE = 400; // value in px\n\ninterface UseInfiniteScrollOptions {\n fetchNextPage: () => void;\n hasMore: boolean;\n isFetching: boolean;\n scrollContainer?: HTMLElement;\n}\n\nexport function useInfiniteScroll(options: UseInfiniteScrollOptions): void {\n const handleScroll = (): void => {\n if (options.isFetching)\n return;\n\n if (!options.scrollContainer) {\n const currentScrollHeight = window.innerHeight + document.documentElement.scrollTop;\n \n const totalHeight = document.documentElement.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n } else {\n const { scrollContainer } = options;\n const currentScrollHeight = scrollContainer.getBoundingClientRect().height + scrollContainer.scrollTop;\n \n const totalHeight = scrollContainer.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n }\n\n options.fetchNextPage();\n };\n\n useEffect(() => {\n const onScroll = FunctionHelper.throttle(handleScroll, 200);\n\n const scrollContainer = options.scrollContainer || window;\n\n if (options.hasMore)\n scrollContainer.addEventListener('scroll', onScroll);\n\n return () => scrollContainer.removeEventListener('scroll', onScroll);\n }, [ options.hasMore, options.fetchNextPage, options.scrollContainer ]);\n}","import { useEffect, useState } from 'react';\n\nimport { HttpStatus, HttpStatusClass } from 'libs/common/backbone/enums/HttpStatus';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { BaseObject, BasePaginatedCollection } from 'libs/shared/interfaces';\n\nimport { useInfiniteScroll } from './UseInfiniteScroll';\nimport { useSelectAllPages } from './UseSelectAllPages';\n\nexport interface UseInfiniteListResult<T extends BaseObject> {\n items: T[];\n hasMore: boolean;\n isFetching: boolean;\n nextCursor: string;\n totalItems?: number;\n hasFirstPageCompleted: boolean;\n}\n\n/**\n * Hook to extract an infinite list from the application state,\n * save it locally in state and only update when new data\n * is fetched.\n * \n * @param getRequest - callback function to get the request for each page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n * \n * @param fetchNext - callback function to fetch a page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n */\nexport function useInfiniteList<TObject = BaseObject, TResponse = BasePaginatedCollection<TObject>>(\n getRequest: ((cursor?: string) => Flight.Request) | false,\n fetchNext: ((cursor?: string) => void) | false,\n onError?: (pageNumber: number, statusCode: HttpStatus) => void,\n getItems?: (responseData: TResponse) => TObject[],\n getCursor?: (responseData: TResponse) => string,\n scrollContainer?: HTMLElement\n): UseInfiniteListResult<TObject> {\n const [ pagesFetched, setPagesFetched ] = useState(0);\n\n const fetchNextFn = fetchNext as (cursor?: string) => void;\n\n function getKey(cursor?: string): string {\n if (!getRequest)\n return null;\n\n const request = getRequest(cursor);\n\n if (!request)\n return null;\n\n return request.key;\n }\n\n const response = useSelectAllPages<TObject, TResponse>(\n getKey,\n getItems,\n getCursor\n );\n\n function fetchNextPage(): void {\n if (!fetchNext || !getRequest || !response)\n return;\n\n setPagesFetched(currentVal => currentVal + 1);\n return fetchNextFn(response.nextCursor);\n }\n\n useInfiniteScroll({\n fetchNextPage,\n hasMore: !!response?.nextCursor,\n isFetching: response?.isFetching,\n scrollContainer\n });\n\n useEffect(() => {\n if (!response)\n return;\n\n if (response.shouldInitialFetch && fetchNext) {\n fetchNextFn();\n setPagesFetched(currentVal => currentVal + 1);\n }\n }, [ response?.shouldInitialFetch, fetchNext ]);\n\n useEffect(() => {\n if (!response?.statusCode || !FunctionHelper.isFunction(onError))\n return;\n\n const httpStatusClass: HttpStatusClass = +(response.statusCode?.toString()?.substr(0, 1));\n\n if (httpStatusClass !== HttpStatusClass.ClientError && httpStatusClass !== HttpStatusClass.ServerError)\n return;\n\n onError(pagesFetched, response.statusCode);\n }, [response?.statusCode]);\n\n return {\n items: response?.items,\n hasMore: !!response?.nextCursor,\n nextCursor: response?.nextCursor,\n isFetching: response?.isFetching,\n totalItems: response?.totalItems,\n hasFirstPageCompleted: response?.hasFirstPageCompleted\n };\n}","export enum FeedbackOption {\n SUGGEST_IMPROVEMENT = 'suggestImprovement',\n REPORT_BUG = 'reportBug',\n REQUEST_VIDEO = 'requestVideo',\n REQUEST_LIVESTREAM = 'requestLivestream',\n GIVE_PRAISE = 'givePraise',\n RAISE_ISSUE = 'raiseIssue',\n OTHER = 'other'\n}","import { Core } from 'libs/common/core';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { Folder, Library } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getFolderAppLink(libraryId: string, folder: Folder, sort: string): Core.AppLink {\n if (!libraryId || !folder)\n return null;\n\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.FOLDER,\n args: [ libraryId, folder.id, TextHelper.slugify(folder.name) ],\n params: {\n sort\n }\n };\n}\n\nexport function getFolderBgColourClass(folder: Folder | Library): string {\n let charCode = 0;\n\n for (let i = 0; i < folder.name?.length ?? 0; i++) {\n charCode += folder.name.charCodeAt(i);\n }\n\n return BG_COLOUR_CLASS_NAMES[charCode % BG_COLOUR_CLASS_NAMES.length];\n}","import React from 'react';\n\nimport { Middleware, type MiddlewareFunctionSync } from 'libs/common/backbone/core';\n\nexport type UseTransformerFunc<T> = (options: T) => T;\n\nexport function useTransformer<T>(transformations?: MiddlewareFunctionSync<T>[]) {\n const middleware = React.useMemo(() => new Middleware<T>(), []);\n\n React.useEffect(() => {\n if (!transformations || !transformations.length)\n return;\n\n transformations.forEach(fn => middleware.useSync(fn));\n }, []);\n\n function push(fn: MiddlewareFunctionSync<T>): void {\n if (!middleware)\n return;\n\n middleware.useSync(fn);\n }\n\n function execute(options: T): T {\n if (!middleware)\n return;\n \n return middleware.goSync(options);\n }\n \n return {\n push,\n execute\n };\n}","import React from 'react';\n\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { handleHttpError } from 'libs/shared/errors/handlers/HttpErrorHandlers';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useInfiniteList } from 'libs/shared/hooks/UseInfiniteList';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useTransformer, UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { BaseWidget } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.useInfiniteWidgetFetch';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UseInfiniteWidgetFetchOptions<TItem, TWidget> {\n item: TItem;\n infiniteFetch: boolean;\n getRequest: (cursor?: string) => Flight.Request;\n getCursor: (widget: TWidget) => string;\n setIsEmpty?: (isEmpty: boolean) => void;\n \n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\nexport function useInfiniteWidgetFetch<\n TItem extends BaseWidget,\n TWidget extends BaseWidget\n>(options: UseInfiniteWidgetFetchOptions<TItem, TWidget>) {\n const fetch = Flight.useGetFetch();\n const alerts = useAlerts();\n const { ref: partialLoadingRef, inView } = useLazyLoad();\n const resultsTransformers = useTransformer<TWidget[]>(options.resultsTransformers ?? []);\n const widgetItemTransformers = useTransformer<TWidget>(options.widgetItemTransformers ?? []);\n \n function fetchNext(cursor?: string) {\n return fetch(options.getRequest(cursor));\n }\n\n function onError(pageNumber: number, httpStatus: HttpStatus): void {\n if (pageNumber === 1)\n return handleHttpError(httpStatus);\n\n alerts.error(getPhrase('error'));\n }\n \n function getItems(response: TWidget) {\n return [response];\n }\n \n const fetchResults = useInfiniteList<TWidget, TWidget>(\n inView && options.getRequest,\n inView && fetchNext,\n onError,\n getItems,\n options.infiniteFetch && options.getCursor\n );\n\n function transformResults(data: TWidget[]): TWidget[] {\n if (!data || !data.length)\n return;\n\n const results = resultsTransformers.execute(data);\n\n if (!options.widgetItemTransformers?.length)\n return results;\n\n const transformedResults = results.map(item => widgetItemTransformers.execute(item));\n\n return transformedResults;\n }\n\n /**\n * This is an array of widgets because technically we can have same widget type id\n * but different template id. This is the case the search series widget.\n */\n const items = transformResults(fetchResults.items);\n\n /**\n * Side effects below\n */\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted || !items)\n return;\n\n if (!options.onLoadWidgetsTriggers?.length || !items.length)\n return;\n\n options.onLoadWidgetsTriggers.forEach(onLoad => onLoad(items));\n }, [ fetchResults.hasFirstPageCompleted, items ]);\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted)\n return;\n\n if (!items) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (Array.isArray(items) && !items.length) {\n options.setIsEmpty?.(true);\n return;\n }\n }, [fetchResults.hasFirstPageCompleted]);\n\n\n const isEmpty = !items?.length;\n const showLoading = !fetchResults.hasFirstPageCompleted;\n const showInfiniteScrollFooter = options.infiniteFetch && (fetchResults.hasMore || fetchResults.isFetching);\n\n return {\n widgets: items,\n isEmpty,\n showLoading,\n showInfiniteScrollFooter,\n isFetching: fetchResults.isFetching,\n nextCursor: fetchResults.nextCursor,\n fetchNext,\n partialLoadingRef\n };\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllSearchWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, BaseWidget, type CurrentUser, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { useInfiniteWidgetFetch } from './hooks/useInfiniteWidgetFetch';\ninterface InfiniteWidgetContainerViewProps<TItem, TWidget> {\n index: number;\n item: TItem;\n /**\n * If set to false will only fetch the first page\n */\n infiniteFetch: boolean;\n\n currentUser: CurrentUser;\n audiences: PresentationAudience[];\n commonVideoProps: CommonVideoProps;\n dashboardTarget?: DashboardTargetType;\n availablePresentations: Presentation[];\n appLinks: AllSearchWidgetTemplates['appLinks'];\n appLinkOptions: AllSearchWidgetTemplates['appLinkOptions'];\n\n hasPermissions: HasPermissionsFunc;\n getName: (widget: TWidget) => string;\n getPartialLoadingPredicate?: () => boolean;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getWidgetClassName?: (widget: TWidget) => string;\n getBadgeComponent: (widget: TWidget) => JSX.Element;\n getSeeMoreAppLink: (widget: TWidget) => Core.AppLink;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n getWidgetMetadata: (widget: TWidget) => Partial<WidgetMetadata>;\n getAnalyticsData?: (widget: TWidget, yIndex: number, xIndex: number) => HashObject;\n\n getCursor: (widget: TWidget) => string;\n getRequest: (cursor?: string) => Flight.Request;\n setIsEmpty?: (isEmpty: boolean) => void;\n \n /**\n * Array of transformers to be applied to results before rendering\n */\n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n /**\n * Array of transformers to be applied to each widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function InfiniteWidgetContainerView<\nTItem extends BaseWidget = BaseWidget,\nTWidget extends BaseWidget = BaseWidget\n>(props: InfiniteWidgetContainerViewProps<TItem, TWidget>): JSX.Element {\n const {\n isEmpty,\n widgets,\n partialLoadingRef,\n showLoading,\n fetchNext,\n isFetching,\n nextCursor,\n showInfiniteScrollFooter\n } = useInfiniteWidgetFetch({\n getRequest: props.getRequest,\n getCursor: props.getCursor,\n setIsEmpty: props.setIsEmpty,\n item: props.item,\n infiniteFetch: props.infiniteFetch,\n resultsTransformers: props.resultsTransformers,\n onLoadWidgetsTriggers: props.onLoadWidgetsTriggers,\n widgetItemTransformers: props.widgetItemTransformers\n });\n \n const template = WidgetTemplateConfig[props.item.templateId];\n const PartialTemplate = template.partialLoading;\n \n if (!template || !showLoading && isEmpty)\n return <></>;\n \n if (showLoading) {\n return (\n <div ref={partialLoadingRef} className='py-2'>\n <PartialTemplate\n name={props.item.name}\n description={props.item?.description}\n predicate={props?.getPartialLoadingPredicate}\n />\n </div>\n );\n }\n\n return (\n <>\n {widgets.map((widget, index) => {\n const isLastItem = index === widgets.length - 1;\n return (\n <React.Fragment key={`${widget.widgetId}-${widget.templateId}-${index}`}>\n <WidgetContainerView\n id={widget.index.toString()}\n widgetIndex={props.item.index}\n dashboardTarget={props.dashboardTarget}\n\n appLinks={props.appLinks}\n appLinkOptions={props.appLinkOptions}\n audiences={props.audiences}\n content={widget.content.data}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n currentUser={props.currentUser}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n \n name={props.getName(widget)}\n hasPermissions={props.hasPermissions}\n getSelectedItems={props.getSelectedItems}\n metadata={props.getWidgetMetadata(widget)}\n seeMoreLink={props.getSeeMoreAppLink(widget)}\n badgeComponent={props.getBadgeComponent(widget)}\n getAnalyticsData={xIndex => props.getAnalyticsData(widget, props.index, xIndex)}\n className={props.getWidgetClassName(widget)}\n\n settings={null}\n description={null}\n isPreviewing={false}\n onClickRemoveItem={null}\n />\n {showInfiniteScrollFooter && isLastItem && (\n <InfiniteScrollFooter\n isFetching={isFetching}\n fetchNext={fetchNext}\n fetchOnScroll\n nextCursor={nextCursor}\n />\n )}\n </React.Fragment>\n );\n })}\n </>\n );\n}","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 { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\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.SearchRelatedResults]: 'relatedResultsTooltip'\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 svgName={cvSvgLibrary.Info}\n title={getPhrase(phrase)}\n tooltipPlacement='top'\n tooltipSpanHack\n tooltipSpanHackClassName='ms-2'\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"searchResultsWidgetsContainer\":\"Z5jXs\"};","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 { 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.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\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: 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 <InfiniteWidgetContainerView<SearchDashboardItem, WidgetSearchItem>\n index={idx}\n item={item}\n key={item.widgetId}\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\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 );\n })}\n </div>\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: `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};","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';\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\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: Object.entries(genericFilters)\n .reduce((prev, [ key, value ]) =>\n ({ ...prev, [key.replace('filters.', '')]: value }), {}),\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: 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 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 };\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};","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 { 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 { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\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\n const streamableLibrary = Flight.useBasicFetch<HashObject>(LibraryRequests.streamableLearning());\n const streamableLibraryId = streamableLibrary.data?.objectId;\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) {\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 };\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 {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n\n if (!hasPresentationsLoaded)\n return ratings;\n\n if (availablePresentations?.length > 1 || !currentPresentation)\n return ratings;\n\n const learningLevel = TopicsHelper.getMappedPresentationLevel(currentPresentation.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 } = useGetLibraries();\n\n const {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n const currentPresentationId = currentPresentation?.id;\n\n const curriculums = useCurriculums();\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(currentPresentation);\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,\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 };\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 } = useGetLibraries();\n\n const {\n activePresentation, availablePresentations, getFallbackPresentation, hasPresentationsLoaded\n } = usePresentation();\n\n const currentPresentation = activePresentation || getFallbackPresentation();\n const currentPresentationId = currentPresentation?.id;\n\n const audiences = usePresentationAudiences();\n\n const schoolLevels = useFetchSchoolLevels(currentPresentation);\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,\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 hasMoviesAndTv,\n isTertiary\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 { usePresentation } from 'shared/hooks/usePresentation';\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 {\n availablePresentations,\n hasPresentationsLoaded\n } = usePresentation();\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}","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}","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={{ application: AppChannels.SUBJECT, action: Actions.Subjects.PRESENTATION_TOPICS }}\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}","import { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { detectCurriculumCodeSearch, DetectCurriculumCodeSearchOptions } from './detectCurriculumCodeSearch';\nimport { fetchVideoAssocsObjects, FetchVideoAssocsObjectsOptions } from './fetchVideoAssocsObjects';\n\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}","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\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}","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}","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 { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { BaseObject } from 'libs/shared/interfaces';\n\ninterface HasQueryParamOptions {\n queryParams: HashObject;\n key: string;\n value: string;\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.SearchRelatedResults,\n WidgetTypeId.SearchCurriculumCode\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): WidgetTypeId {\n if (!queryParams?.focus)\n return;\n\n if (typeof queryParams.focus === 'string') {\n return SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus);\n }\n\n if (Array.isArray(queryParams.focus) && queryParams.focus.length === 1) {\n return SupportedSearchWidgetTypeIds.find(w => w === queryParams.focus[0]);\n }\n\n return;\n}\n\nfunction getWidgetIdsFromQueryParams(queryParams: HashObject): WidgetTypeId[] {\n const widgets: WidgetTypeId[] = [];\n\n const focusedWidget = getValidFocusedWidget(queryParams);\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 (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 (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.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 ): WidgetFilter[] {\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams);\n \n return widgets.map(w => ({ id: w }));\n },\n\n getWidgetFilters(\n queryParams: HashObject,\n widgetTypeId: WidgetTypeId,\n cursor?: string\n ): WidgetFilter[] {\n if (cursor) {\n return [{\n id: widgetTypeId,\n cursor\n }];\n }\n\n const widgets: WidgetTypeId[] = getWidgetIdsFromQueryParams(queryParams);\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};","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, 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 { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { LitePresentationHelper } from 'shared/utils/LitePresentationHelper';\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 getSearchWidgetAppLinkOptions(\n presentation: Presentation,\n availablePresentations: Presentation[]\n ): MixedWidgetSearchResultsProps['widgetAppLinkOptions'] {\n return {\n company: (company: Company): Core.AppLinkOptions => ({\n middlewareOptions: {\n presentationSlug: LitePresentationHelper.getPresentationSlugByCompany(\n company,\n presentation,\n availablePresentations\n )\n }\n })\n };\n },\n \n getSearchWidgetAppLinks(\n queryParams: HashObject,\n audienceParams: AudienceFilterParams = {}\n ): MixedWidgetSearchResultsProps['widgetAppLinks'] {\n return {\n classification: (classification?: Classification) => {\n const options: GetClassificationAppLinkOptions = {\n ...audienceParams,\n moviesAndTv: TopicsHelper.isMtv(classification)\n };\n\n return ClassificationAppLinkHelper.getAppLink(classification, options);\n },\n \n videoType: (video: VideoTypes, opts: GetVideoAppLinkOptions) => (\n VideoAppLinkHelper.getAppLink(video, {\n ...opts,\n includeContext: false\n })\n ),\n \n series: SeriesAppLinkHelper.getSeriesAppLink,\n \n playlist: (playlist: Playlist) => ({\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.PLAYLIST,\n args: [ playlist.id, TextHelper.slugify(playlist.name) ]\n }),\n \n \n company: (company: Company) => ({\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.COMPANY_DASHBOARD,\n args: [ company.id, TextHelper.slugify(company.name) ]\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.SEARCH_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 { EntityType, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { MixedWidgetSearchResults } from 'libs/shared/apps/search/components/mixed-widget-search-results/MixedWidgetSearchResults';\nimport { SearchFilters } from 'libs/shared/apps/search/components/search-filters/SearchFilters';\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 { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ContentRegion } from 'libs/shared/enums/ContentRegion';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useVideoMixinFunc } from 'shared/hooks/useVideoMixin';\n\nimport { useFetchSearchDataV2 } from 'apps/search/hooks/useFetchSearchData';\nimport { SearchHelper } from 'apps/search/utils';\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 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 });\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(queryParams)\n ));\n\n const searchDashboardData = searchDashboard.data?.filter(item => !isEmpty[item.widgetId]);\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 });\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 );\n\n const widgetAppLinkOptions = SearchResultsAppLinkHelper.getSearchWidgetAppLinkOptions(\n searchData.currentPresentation,\n searchData.availablePresentations\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(queryParams, widgetTypeId, cursor)\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 /**\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 {(!!searchData.audiences.data && !!searchData.ratings.data && !!searchData.availableTopics.data) && (\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 _hasNewSearch\n />\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 widgetAppLinkOptions={widgetAppLinkOptions}\n isTertiary={searchData.isTertiary}\n commonVideoProps={commonVideoProps}\n audiences={searchData.audiences.data}\n currentUser={searchData.currentUser.data}\n availablePresentations={searchData.availablePresentations}\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 {(!searchData.isLearner && !searchDashboard.isFetching) &&\n <SearchResultsRequestVideo />\n }\n \n </VideoActionsContext.Provider>\n </section>\n );\n })()}\n </div>\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}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetSearchItem } from 'libs/shared/apps/search/interfaces/WidgetSearchResults';\n\nimport { SearchResultsTransformOptions } from '../interfaces/SearchResultsTransformOptions';\n\n/**\n * Paginated data returns more widgets so if we dont merge the widget content by widget type id,\n * it would add another widget to the page rather than appending content to the relevant\n * search result index\n * \n * For example:\n * Say we receive these widgets for a query:\n * - topics widget\n * - related results widget\n * \n * If a user scrolls down to the end of page we fetch more items from the last widget\n * which in this case is 'related results widget'. \n * Now our overall response looks like this\n * - topics widget\n * - related results widget\n * - related results widget\n * \n * Since this is a new widget item entry it will be rendered as a new widget with seprate headings etc.\n * In this case we want to combine these two widgets data into one so its looks like this again:\n * - topics widget\n * - related results widget (data is combined)\n * \n * But what if widget we get recieve has a different widget template id. This currently happens for\n * the 'series widget' - series widget can have the tall poster template or the thumbnail like template.\n * \n * so to visualize this it can be like:\n * - topics widget\n * - top results widget\n * - series widget (template: tall poster)\n * - series widget (template: thumbnail)\n * \n * Since they technically will look different based on the template id we will not merge the data in this case.\n * It will merge the data to the same widget as long as the combination of widget Id + template Id is the same.\n * \n * Since they are separate widgets they will render duplicate headings - we handle this in css instead which\n * checks for adjacent siblings and if its the same widget - it hides the widget heading so it will look\n * like its a single widget rather than separate widgets.\n * \n * - Nish\n */\nexport function mergeSearchResults(options: SearchResultsTransformOptions): SearchResultsTransformOptions {\n const { data } = options;\n \n if (!data) return options;\n \n const items = [...data];\n\n const groupedWidgets = ArrayHelper.groupBy(items, 'widgetId');\n\n const mergedWidgets: WidgetSearchItem[] = [];\n\n for (const widgetGroup of Object.values(groupedWidgets)) {\n let currentMergedWidget: WidgetSearchItem = null;\n const widgets: WidgetSearchItem[] = [];\n\n for (const widget of widgetGroup) {\n if (!currentMergedWidget) {\n currentMergedWidget = widget;\n continue;\n }\n\n /**\n * Widgets of the same type may have different templates. When this occurs,\n * we want to make sure each widgetType + template combo is pushed\n * as a separate widget.\n */\n if (widget.templateId !== currentMergedWidget.templateId) {\n widgets.push(currentMergedWidget);\n currentMergedWidget = widget;\n continue;\n }\n\n currentMergedWidget.content.data = [\n ...(currentMergedWidget.content.data || []),\n ...widget.content.data\n ];\n }\n\n widgets.push(currentMergedWidget);\n mergedWidgets.push(...widgets);\n }\n\n return {\n ...options,\n data: mergedWidgets\n };\n}","import { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { WidgetSearchItemTransformOptions } from '../interfaces/WidgetSearchItemTransformOptions';\n\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}","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/**\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}","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { Rating } from 'libs/shared/interfaces';\n\nexport const RatingRequests = {\n ratings(countryCode?: string, includeE?: boolean): Flight.PublicRequest {\n return {\n url: '/api/domain/v2/me/ratings',\n publicUrl: UrlHelper.urlBuilder('/api/domain/v2/me/ratings', { countryCode }),\n key: `ratings:${includeE}`,\n // v2/me/ratings doesn't support `query={orderby:value}`. Adding this due to time constraints\n formatData: (ratings: Rating[]) => {\n const resp = ratings.sort((a, b) => a.value - b.value);\n \n if (includeE)\n return resp;\n\n return resp.filter(r => r.code !== 'E');\n }\n };\n }\n};","import { Flight } from 'libs/common/react/index';\n\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport { usePresentation } from 'shared/hooks/usePresentation';\n\nexport const usePresentationAudiences = () => {\n const { activePresentation, getFallbackPresentation } = usePresentation({ redirectOnError: true });\n\n const presentation = activePresentation || getFallbackPresentation();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n !!presentation &&\n AudienceRequests.presentationAudiences(presentation.id)\n );\n\n return audiences;\n};","import { Flight } from 'libs/common/react/index';\n\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useGrowingBatchFetch, useGrowingBatchFetchFunc } from 'libs/shared/hooks/UseBatchFetch';\nimport { Clip, ClipCollection, Video, VideoCollection } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\ntype Types = Video[] | VideoCollection | Clip[] | ClipCollection;\n\nfunction getValidObjects(objects: Types): (Video | Clip)[] {\n if (!objects)\n return [];\n\n if (Array.isArray(objects))\n return objects.filter(o => !!o && (VideoHelper.isVideo(o) || VideoHelper.isClip(o)));\n\n if ('data' in objects)\n return objects.data.filter(o => !!o && (VideoHelper.isVideo(o) || VideoHelper.isClip(o)));\n\n return [];\n}\n\ninterface VideoMixinOptions {\n /**\n * If the videos that are having new data mixed into are sitting on an explicit Flight namespace,\n * providing that namespace here is required\n */\n flightNamespace?: string;\n}\n\nexport function useVideoMixin(objects: Types, options: VideoMixinOptions = {}) {\n const videoIds = getValidObjects(objects).map(v => v.id);\n\n useGrowingBatchFetch(\n videoIds,\n ids => VideoRequests.videoMixinAssocs(ids, options.flightNamespace),\n null\n );\n}\n\nexport function useVideoMixinFunc(options: VideoMixinOptions = {}) {\n function getRequest(ids: string[]): Flight.Request {\n return VideoRequests.videoMixinAssocs(ids, options.flightNamespace);\n }\n \n function fetchObjects(items: Types) {\n return fetchItems(getValidObjects(items).map(v => v.id));\n }\n\n const { fetchItems } = useGrowingBatchFetchFunc({ getRequest });\n\n return { fetchObjects };\n}"],"names":["CHUNK_SIZE","useBatchFetch","itemIds","getRequest","requests","map","chunk","responses","itemsArr","data","items","length","reduce","acc","item","id","isFetching","hasCompleted","useGrowingBatchFetch","objs","_getKey","getKey","obj","useGrowingBatchFetchFunc","fetchItems","join","options","fetchedItems","Set","setRequests","hasFirstRequestCompleted","unfetchedItems","forEach","key","current","has","push","add","r","SCROLL_TOLERANCE","useInfiniteList","fetchNext","onError","getItems","getCursor","scrollContainer","handleScroll","useState","pagesFetched","setPagesFetched","fetchNextFn","response","cursor","request","fetchNextPage","currentVal","nextCursor","hasMore","getBoundingClientRect","height","scrollTop","scrollHeight","window","innerHeight","document","documentElement","useEffect","onScroll","FunctionHelper","addEventListener","removeEventListener","shouldInitialFetch","statusCode","httpStatusClass","toString","substr","HttpStatus","totalItems","hasFirstPageCompleted","FeedbackOption","getFolderAppLink","libraryId","folder","sort","application","action","args","name","params","getFolderBgColourClass","charCode","i","charCodeAt","useTransformer","transformations","middleware","fn","useSync","execute","goSync","getPhrase","LanguageService","InfiniteWidgetContainerView","props","fetch","alerts","partialLoadingRef","ref","inView","resultsTransformers","widgetItemTransformers","fetchResults","pageNumber","httpStatus","error","infiniteFetch","results","transformResults","onLoadWidgetsTriggers","onLoad","Array","isArray","setIsEmpty","isEmpty","showLoading","showInfiniteScrollFooter","widgets","useInfiniteWidgetFetch","template","WidgetTemplateConfig","templateId","PartialTemplate","partialLoading","className","description","predicate","getPartialLoadingPredicate","widget","index","isLastItem","widgetId","WidgetContainerView","widgetIndex","dashboardTarget","appLinks","appLinkOptions","audiences","content","widgetTypeId","currentUser","commonVideoProps","availablePresentations","getName","hasPermissions","getSelectedItems","metadata","getWidgetMetadata","seeMoreLink","getSeeMoreAppLink","badgeComponent","getBadgeComponent","getAnalyticsData","xIndex","getWidgetClassName","settings","isPreviewing","onClickRemoveItem","InfiniteScrollFooter","fetchOnScroll","SearchWidgetTooltip","isTertiary","phrase","WidgetTypeId","SvgContainer","svgName","title","tooltipPlacement","tooltipSpanHack","tooltipSpanHackClassName","MixedWidgetSearchResults","idx","isLastWidget","curriculumLeafName","curriculumLeafDescription","includes","widgetAppLinks","widgetAppLinkOptions","hasLocalPermissions","searchResultsTransformers","SearchOGQL","video","series","playlist","classification","TagType","clip","interactive","company","category","formatSearchResponse","totalResults","filter","result","_index","clips","interactives","videos","resultMaxScore","_score","SharedSearchHelper","stringifyObject","Object","entries","prev","value","stringifiedValue","searchDashboard","query","filters","widgetData","a","b","localeCompare","w","filterData","FilterConstants","indicesFilter","isLearner","genericFilters","indices","replace","includeAllIndices","url","publicUrl","type","HttpVerbs","searchDashboardWidget","excludeVideoIds","ogql","searchV5","searchV4","sorts","allowSubstitute","limit","keys","filterName","excludeLibraryExclusive","searchType","undefined","formatData","search","success","assign","UrlHelper","tagsAndClassifications","normalize","useFetchSearchDataV2","queryParams","userDetails","config","yearGroups","isAuthenticated","customerId","products","useIsTertiary","streamableLibrary","LibraryRequests","streamableLibraryId","objectId","showExchangeSearchResults","hasProduct","ProductId","librariesRequest","libraries","exchangeLibraryIndex","findIndex","l","MasterObjectTypes","exchangeLibraryId","slice","streamableIndex","hasLibrariesCompleted","useGetLibraries","activePresentation","getFallbackPresentation","hasPresentationsLoaded","currentPresentation","currentPresentationId","schoolLevels","presentation","presentationIds","o","SearchRequests","schoolLevelIds","availableTopics","ratings","RatingRequests","countryCode","TopicsHelper","learningLevel","PresentationLearningLevel","rating","code","useGetRatings","hasCustomLibraries","hasMoviesAndTv","isGuest","moviesAndTvDashboard","targetType","dashboard","hasDataLoaded","isLoadingProducts","isLoadingSettings","SearchResultsRequestVideo","skipBeforeRequestingVideoStep","Text","namespace","AppLink","appLink","selectedOption","SearchResultsEmptyState","imageUrl","scotland","trim","toLowerCase","ImageUrls","EmptyState","src","hideRequestVideo","getOnLoadWidgetTriggers","hasSearchedCode","isCurriculumCodeSearch","detectCurriculumCodeSearch","objects","outer","inner","fetchObjects","fetchVideoAssocsObjects","DevError","SupportedSearchWidgetTypeIds","hasQueryParam","targetParam","getWidgetIdsFromQueryParams","focusedWidget","focus","find","getValidFocusedWidget","ArrayHelper","SearchResultsFilterHelper","isOnlyActiveWidget","p","getActiveWidgetFilters","getWidgetFilters","getSelectedTagOrClassification","tagOrClassification","tag","getSearchWidgetSelectedItems","SearchResultsAppLinkHelper","getSearchWidgetAppLinkOptions","middlewareOptions","presentationSlug","LitePresentationHelper","getSearchWidgetAppLinks","audienceParams","moviesAndTv","ClassificationAppLinkHelper","videoType","opts","VideoAppLinkHelper","includeContext","SeriesAppLinkHelper","TextHelper","searchSettings","searchHome","filterParams","x","getPreviewQuestionsAppLink","InteractiveHelper","getAppLinkFunc","WidgetTypeIdConfig","getCollectionAppLink","SearchResultsViewV2","videoMixin","useVideoMixin","onSetIsEmpty","prevState","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","allowIndexing","activeAudiences","SharedViewModelKeys","storage","videoActions","useVideoActions","location","useCommonVideoProps","locationContext","mtv","searchData","searchFilters","backendFilters","searchDashboardData","inaccessibleIndices","_hasNewSearch","hasLoaded","hasResults","showEmptyState","hideDivider","AudienceHelper","getContentRequest","getData","groupedWidgets","mergedWidgets","values","currentMergedWidget","mergeSearchResults","normalizedItemData","transformSearchTags","sortByLearningLevel","relevantTopicsData","remainingTopicsData","exactMatchSortedTopics","remainingSortedTopics","topic","MasterTypeHelper","sortedItem","transformSearchRelevantTopics","widgetsOnLoadTriggers","SearchFilters","mainFilters","moreFilters","analyticsOptions","entity","contentRegion","ContentRegion","VideoActionsContext","yIndex","widgetName","itemIndex","includeE","resp","usePresentationAudiences","redirectOnError","getValidObjects","videoIds","v","ids","flightNamespace","useVideoMixinFunc"],"sourceRoot":""}