@clickview/lite 0.59.0-rc.7 → 0.59.0-rc.8
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.
- package/dist/bundles.json +1 -1
- package/dist/scripts/1041-e67122b7dc-lite.chunk.js +2 -0
- package/dist/scripts/1041-e67122b7dc-lite.chunk.js.map +1 -0
- package/dist/scripts/{1080-aebdd2fd94-lite.chunk.js → 1080-db39a50a32-lite.chunk.js} +2 -2
- package/dist/scripts/1080-db39a50a32-lite.chunk.js.map +1 -0
- package/dist/scripts/{1169-b84be13a05-lite.chunk.js → 1169-394baed329-lite.chunk.js} +2 -2
- package/dist/scripts/1169-394baed329-lite.chunk.js.map +1 -0
- package/dist/scripts/{143-e8df681adb-lite.chunk.js → 143-851fefbbc8-lite.chunk.js} +2 -2
- package/dist/scripts/143-851fefbbc8-lite.chunk.js.map +1 -0
- package/dist/scripts/{170-edaa4055be-lite.chunk.js → 170-6dda8ec96e-lite.chunk.js} +3 -3
- package/dist/scripts/170-6dda8ec96e-lite.chunk.js.map +1 -0
- package/dist/scripts/2015-0cb7aead83-lite.chunk.js +2 -0
- package/dist/scripts/2015-0cb7aead83-lite.chunk.js.map +1 -0
- package/dist/scripts/204-67566b75e7-lite.chunk.js +2 -0
- package/dist/scripts/204-67566b75e7-lite.chunk.js.map +1 -0
- package/dist/scripts/2215-c47eb22183-lite.chunk.js +2 -0
- package/dist/scripts/2215-c47eb22183-lite.chunk.js.map +1 -0
- package/dist/scripts/{2340-16e28533f3-lite.chunk.js → 2340-6179f12db3-lite.chunk.js} +2 -2
- package/dist/scripts/2340-6179f12db3-lite.chunk.js.map +1 -0
- package/dist/scripts/2571-70477f279b-lite.chunk.js +2 -0
- package/dist/scripts/2571-70477f279b-lite.chunk.js.map +1 -0
- package/dist/scripts/{2581-bf3d282cb9-lite.chunk.js → 2581-f21f1ac71e-lite.chunk.js} +3 -3
- package/dist/scripts/2581-f21f1ac71e-lite.chunk.js.map +1 -0
- package/dist/scripts/3731-eeabea3393-lite.chunk.js +3 -0
- package/dist/scripts/3731-eeabea3393-lite.chunk.js.map +1 -0
- package/dist/scripts/{4013-3070636adb-lite.chunk.js → 4013-9e41670948-lite.chunk.js} +3 -3
- package/dist/scripts/4013-9e41670948-lite.chunk.js.map +1 -0
- package/dist/scripts/{4205-cf817cce7b-lite.chunk.js → 4205-2d3c5f264f-lite.chunk.js} +2 -2
- package/dist/scripts/4205-2d3c5f264f-lite.chunk.js.map +1 -0
- package/dist/scripts/{490-9b7a10c66a-lite.chunk.js → 490-f8e5bbb09c-lite.chunk.js} +2 -2
- package/dist/scripts/490-f8e5bbb09c-lite.chunk.js.map +1 -0
- package/dist/scripts/4944-c5ba3ff091-lite.chunk.js +2 -0
- package/dist/scripts/4944-c5ba3ff091-lite.chunk.js.map +1 -0
- package/dist/scripts/{5220-85356e2ed6-lite.chunk.js → 5220-0cca67a7e7-lite.chunk.js} +3 -3
- package/dist/scripts/5220-0cca67a7e7-lite.chunk.js.map +1 -0
- package/dist/scripts/{5224-6e7208837b-lite.chunk.js → 5224-ebdead7925-lite.chunk.js} +2 -2
- package/dist/scripts/5224-ebdead7925-lite.chunk.js.map +1 -0
- package/dist/scripts/{5836-27add12a78-lite.chunk.js → 5836-921d683eb5-lite.chunk.js} +2 -2
- package/dist/scripts/5836-921d683eb5-lite.chunk.js.map +1 -0
- package/dist/scripts/{5936-e61ae32ed3-lite.chunk.js → 5936-d1117ce842-lite.chunk.js} +2 -2
- package/dist/scripts/5936-d1117ce842-lite.chunk.js.map +1 -0
- package/dist/scripts/{6118-857c2f6b97-lite.chunk.js → 6118-3dbd569840-lite.chunk.js} +2 -2
- package/dist/scripts/6118-3dbd569840-lite.chunk.js.map +1 -0
- package/dist/scripts/{6263-dcc4cb4933-lite.chunk.js → 6263-d084bdb444-lite.chunk.js} +2 -2
- package/dist/scripts/6263-d084bdb444-lite.chunk.js.map +1 -0
- package/dist/scripts/{6368-d33570d16d-lite.chunk.js → 6368-c296821dd9-lite.chunk.js} +2 -2
- package/dist/scripts/6368-c296821dd9-lite.chunk.js.map +1 -0
- package/dist/scripts/{6741-5bf7ea5363-lite.chunk.js → 6741-9799a705b8-lite.chunk.js} +3 -3
- package/dist/scripts/6741-9799a705b8-lite.chunk.js.map +1 -0
- package/dist/scripts/{6934-11a3f3e147-lite.chunk.js → 6934-5647e18a41-lite.chunk.js} +2 -2
- package/dist/scripts/6934-5647e18a41-lite.chunk.js.map +1 -0
- package/dist/scripts/7234-fecb9339e5-lite.chunk.js +2 -0
- package/dist/scripts/7234-fecb9339e5-lite.chunk.js.map +1 -0
- package/dist/scripts/{7709-fb358991a1-lite.chunk.js → 7709-18e41d81b8-lite.chunk.js} +2 -2
- package/dist/scripts/7709-18e41d81b8-lite.chunk.js.map +1 -0
- package/dist/scripts/{9139-63b528ce93-lite.chunk.js → 9139-251b1d5a38-lite.chunk.js} +2 -2
- package/dist/scripts/9139-251b1d5a38-lite.chunk.js.map +1 -0
- package/dist/scripts/{9173-c164578a27-lite.chunk.js → 9173-1cb2d7c045-lite.chunk.js} +2 -2
- package/dist/scripts/9173-1cb2d7c045-lite.chunk.js.map +1 -0
- package/dist/scripts/9284-ca348ab523-lite.chunk.js +2 -0
- package/dist/scripts/9284-ca348ab523-lite.chunk.js.map +1 -0
- package/dist/scripts/{9395-7aa400f517-lite.chunk.js → 9395-10f1a8adfe-lite.chunk.js} +3 -3
- package/dist/scripts/{9395-7aa400f517-lite.chunk.js.map → 9395-10f1a8adfe-lite.chunk.js.map} +1 -1
- package/dist/scripts/{953-4e10bd618b-lite.chunk.js → 953-279b3b79cd-lite.chunk.js} +3 -3
- package/dist/scripts/{953-4e10bd618b-lite.chunk.js.map → 953-279b3b79cd-lite.chunk.js.map} +1 -1
- package/dist/scripts/bundle-55d31077c4.min.js +3 -0
- package/dist/scripts/bundle-55d31077c4.min.js.map +1 -0
- package/package.json +1 -1
- package/dist/scripts/1080-aebdd2fd94-lite.chunk.js.map +0 -1
- package/dist/scripts/1169-b84be13a05-lite.chunk.js.map +0 -1
- package/dist/scripts/143-e8df681adb-lite.chunk.js.map +0 -1
- package/dist/scripts/170-edaa4055be-lite.chunk.js.map +0 -1
- package/dist/scripts/204-abf7907929-lite.chunk.js +0 -2
- package/dist/scripts/204-abf7907929-lite.chunk.js.map +0 -1
- package/dist/scripts/2215-69d4d628e5-lite.chunk.js +0 -2
- package/dist/scripts/2215-69d4d628e5-lite.chunk.js.map +0 -1
- package/dist/scripts/2340-16e28533f3-lite.chunk.js.map +0 -1
- package/dist/scripts/2581-bf3d282cb9-lite.chunk.js.map +0 -1
- package/dist/scripts/3525-36cfbbfcf2-lite.chunk.js +0 -2
- package/dist/scripts/3525-36cfbbfcf2-lite.chunk.js.map +0 -1
- package/dist/scripts/4013-3070636adb-lite.chunk.js.map +0 -1
- package/dist/scripts/4205-cf817cce7b-lite.chunk.js.map +0 -1
- package/dist/scripts/490-9b7a10c66a-lite.chunk.js.map +0 -1
- package/dist/scripts/4944-44f59087ce-lite.chunk.js +0 -2
- package/dist/scripts/4944-44f59087ce-lite.chunk.js.map +0 -1
- package/dist/scripts/5220-85356e2ed6-lite.chunk.js.map +0 -1
- package/dist/scripts/5224-6e7208837b-lite.chunk.js.map +0 -1
- package/dist/scripts/5836-27add12a78-lite.chunk.js.map +0 -1
- package/dist/scripts/5886-13395190b8-lite.chunk.js +0 -3
- package/dist/scripts/5886-13395190b8-lite.chunk.js.map +0 -1
- package/dist/scripts/5936-e61ae32ed3-lite.chunk.js.map +0 -1
- package/dist/scripts/6118-857c2f6b97-lite.chunk.js.map +0 -1
- package/dist/scripts/6263-dcc4cb4933-lite.chunk.js.map +0 -1
- package/dist/scripts/6368-d33570d16d-lite.chunk.js.map +0 -1
- package/dist/scripts/6741-5bf7ea5363-lite.chunk.js.map +0 -1
- package/dist/scripts/6934-11a3f3e147-lite.chunk.js.map +0 -1
- package/dist/scripts/7234-ef069e6013-lite.chunk.js +0 -2
- package/dist/scripts/7234-ef069e6013-lite.chunk.js.map +0 -1
- package/dist/scripts/7709-fb358991a1-lite.chunk.js.map +0 -1
- package/dist/scripts/8813-887868f687-lite.chunk.js +0 -2
- package/dist/scripts/8813-887868f687-lite.chunk.js.map +0 -1
- package/dist/scripts/9139-63b528ce93-lite.chunk.js.map +0 -1
- package/dist/scripts/9173-c164578a27-lite.chunk.js.map +0 -1
- package/dist/scripts/9284-7f6bbe012f-lite.chunk.js +0 -2
- package/dist/scripts/9284-7f6bbe012f-lite.chunk.js.map +0 -1
- package/dist/scripts/bundle-403f576ace.min.js +0 -3
- package/dist/scripts/bundle-403f576ace.min.js.map +0 -1
- /package/dist/css/{3525-lite-52288b11e5.chunk.css → 1041-lite-52288b11e5.chunk.css} +0 -0
- /package/dist/css/{8813-lite-52288b11e5.chunk.css → 2015-lite-52288b11e5.chunk.css} +0 -0
- /package/dist/css/{5886-lite-3633cd9770.chunk.css → 3731-lite-3633cd9770.chunk.css} +0 -0
- /package/dist/scripts/{170-edaa4055be-lite.chunk.js.LICENSE.txt → 170-6dda8ec96e-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{2581-bf3d282cb9-lite.chunk.js.LICENSE.txt → 2581-f21f1ac71e-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{4013-3070636adb-lite.chunk.js.LICENSE.txt → 3731-eeabea3393-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{5220-85356e2ed6-lite.chunk.js.LICENSE.txt → 4013-9e41670948-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{5886-13395190b8-lite.chunk.js.LICENSE.txt → 5220-0cca67a7e7-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{6741-5bf7ea5363-lite.chunk.js.LICENSE.txt → 6741-9799a705b8-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{9395-7aa400f517-lite.chunk.js.LICENSE.txt → 9395-10f1a8adfe-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{953-4e10bd618b-lite.chunk.js.LICENSE.txt → 953-279b3b79cd-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-403f576ace.min.js.LICENSE.txt → bundle-55d31077c4.min.js.LICENSE.txt} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/6118-857c2f6b97-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/components/widgets/items/popout-video-widget-item/PopoutVideoWidgetItem.tsx","file:///app/packages/libs/shared/src/components/widgets/items/popout-video-widget-item/popout-video-widget-item.scss","file:///app/packages/libs/shared/src/hooks/UseBatchFetch.ts","file:///app/packages/libs/shared/src/hooks/UseMergeAudiences.ts","file:///app/packages/libs/shared/src/utils/audience-helper/AudienceStringBuilders.ts","file:///app/packages/libs/shared/src/utils/audience-helper/AudienceHelper.ts","file:///app/packages/projects/lite/src/apps/default/views/popup-plugin/components/nav-tiles.scss","file:///app/packages/projects/lite/src/apps/default/views/popup-plugin/components/Navtiles.tsx","file:///app/packages/projects/lite/src/apps/default/views/popup-plugin/PopupPluginView.tsx","file:///app/packages/projects/lite/src/apps/default/views/popup-plugin/hooks/useGetVideoHistoryVideos.ts","file:///app/packages/projects/lite/src/apps/watch-history/flight-requests/VideoHistoryRequests.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoMixin.ts"],"sourcesContent":["import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { VideoSubTextType } from 'libs/shared/components/video-sub-text/VideoSubText';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { useMergeAudiences } from 'libs/shared/hooks/UseMergeAudiences';\nimport { CanFavouriteFunc, FavouriteFunc, PresentationAudience, Video, VideoTypes, WidgetType, YearGroup } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport styles from './popout-video-widget-item.scss';\n\nexport interface PopoutVideoWidgetItemProps extends FixedWidgetItemProps<VideoTypes> {\n canFavourite: CanFavouriteFunc;\n setFavourite: FavouriteFunc;\n presentationAudiences: PresentationAudience[];\n imageCdnUrl: string;\n yearGroups: YearGroup[];\n showVideoGuidance: boolean;\n hideTitle?: boolean;\n hideSeries?: boolean;\n companyLogoFallbackUrl?: string;\n subTextType?: VideoSubTextType;\n getSubTextAppLink?: (video: Video) => Core.AppLink;\n getInteractiveGuidanceAppLink: (id: string, type: MasterType) => Core.AppLink;\n getResourceGuidanceAppLink: (id: string, type: MasterType) => Core.AppLink;\n getClassroomGuideAppLink: (id: string, type: MasterType) => Core.AppLink;\n preventPopout?: boolean;\n isPlugin: boolean;\n showNewVideoIndicator?: boolean;\n}\n\nexport const PopoutVideoWidgetItem = React.memo(function(props: PopoutVideoWidgetItemProps): JSX.Element {\n const { data: video, getSubTextAppLink, context, thumbnailSize, preloadImage, presentationAudiences } = props;\n \n const videoAudiences = video?.subjectPresentationAudiences?.data;\n const mergedAudience = useMergeAudiences(videoAudiences, presentationAudiences);\n\n const breakpoints = useBreakpoints();\n\n let width = styles.rowWidth;\n\n if (context.type === WidgetType.LargeRow)\n width = styles.largeRowWidth;\n\n return (\n <div className={`px-1 flex-shrink-0 position-relative ${width}`}>\n <VideoThumbnail\n type={props.preventPopout || breakpoints.xs ? 'static' : 'popout'}\n textPosition={ThumbnailTextPosition.Below}\n video={video}\n appLink={props.getAppLink(video)}\n subTextAppLink={VideoHelper.isVideo(video) && getSubTextAppLink?.(video)}\n imageOptions={{ size: thumbnailSize }}\n preload={preloadImage}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n canFavourite={props.canFavourite}\n setFavourite={props.setFavourite}\n imageCdnUrl={props.imageCdnUrl}\n audience={mergedAudience}\n hideRating={!!mergedAudience}\n hideDuration={false}\n yearGroups={props.yearGroups}\n hideTitle={props.hideTitle}\n showVideoGuidance={props.showVideoGuidance}\n companyLogoFallbackUrl={props.companyLogoFallbackUrl}\n subTextType={props.subTextType}\n isPlugin={props.isPlugin}\n getInteractiveGuidanceAppLink={props.getInteractiveGuidanceAppLink}\n getResourceGuidanceAppLink={props.getResourceGuidanceAppLink}\n getClassroomGuideAppLink={props.getClassroomGuideAppLink}\n showNewVideoIndicator={props.showNewVideoIndicator}\n />\n </div>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"rowWidth\":\"JSM4l\",\"largeRowWidth\":\"YYpNz\"};","import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { Flight } from 'libs/common/flight';\nimport { ApplicationState, HashObject } from 'libs/common/react/interfaces';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nexport interface UseBatchFetchResult<T extends BaseObject> {\n items: { [key: string]: T} | null;\n isFetching: 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 [ idBatches, setIdBatches ] = React.useState<string[][]>([]);\n\n React.useEffect(() => {\n if (!itemIds?.length)\n return;\n\n const newBatches = [...idBatches];\n newBatches.push([]);\n\n itemIds.forEach(id => {\n if (newBatches.find(batch => batch.find(_id => _id === id)))\n return;\n\n newBatches[newBatches.length - 1].push(id);\n });\n\n setIdBatches(newBatches.filter(batch => batch.length));\n }, [itemIds ? itemIds.join(',') : null]);\n\n const dispatch = useDispatch();\n\n const state = useSelector((state: ApplicationState) => state);\n\n React.useEffect(() => {\n idBatches.forEach(idBatch => {\n const request = getRequest(idBatch);\n const response = Flight.getResponse<T[]>(state, request.key);\n\n if (response.shouldFetch)\n Flight.fetch(dispatch, request);\n });\n }, [idBatches?.length]);\n\n if (!idBatches?.length)\n return { items: null, isFetching: false };\n \n const items: { [key: string]: T} = {};\n\n /* Used locally to only return our items if we've fetched all of them */\n const responses: HashObject<Flight.Response<T[]>> = {};\n \n idBatches.forEach((idBatch, i) => {\n const request = getRequest(idBatch);\n const response = Flight.getResponse<T[]>(state, request.key);\n responses[i] = response;\n\n if (response.data)\n response.data.forEach(v => items[v.id] = v);\n });\n\n return {\n items: Object.keys(responses).some(k => !!responses[k].data) ? items : null,\n isFetching: !!Object.keys(responses).some(k => responses[k].isFetching)\n };\n}","import React from 'react';\n\nimport { Audience, PresentationAudience } from '../interfaces';\nimport { AudienceHelper } from '../utils/audience-helper/AudienceHelper';\n\nexport function useMergeAudiences(\n audiences: Audience[],\n presentationAudiences: PresentationAudience[]\n): PresentationAudience {\n // Memoize the audience functions as they are somewhat expensive and the result shouldn't change\n const sortedAudiences = React.useMemo(() => {\n if (!audiences?.length || !presentationAudiences || !AudienceHelper.shouldShowAudiences(presentationAudiences))\n return null;\n\n return AudienceHelper.getSortedPresentationAudiences(audiences, presentationAudiences);\n }, [audiences]);\n\n const mergedAudience = React.useMemo(() => {\n if (!sortedAudiences?.length)\n return null;\n\n return AudienceHelper.getMergedPresentationAudienceString(sortedAudiences);\n }, [sortedAudiences]);\n\n return mergedAudience;\n}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nconst HAS_NUMBER_REGEX = /\\d/;\nconst COUNT_OFFSET = 1;\n\nexport const AudienceStringBuilders = {\n /**\n * Handles audience sets like:\n * - Year 7, Year 8, etc\n * - Kindergarten, Grade 1, Grade 2, etc\n */\n yearsAndGradesBuilder(audiences: PresentationAudience[]): string {\n /**\n * Create a string with all of the audiences\n */\n const combinedNames = audiences.map(a => a.name).join(' ');\n\n /**\n * Extract all the numbers and matches from the string\n */\n const numberList = combinedNames.split(' ').filter(name => !isNaN(+name)).map(num => +num) || [];\n const wordList = combinedNames.split(' ').filter(name => isNaN(+name)) || [];\n\n // Find an audience that doesn't have a number, like \"Kindergarten\" or \"Foundation\".\n const audienceWithoutNum = audiences.find(p => {\n return !HAS_NUMBER_REGEX.test(p.name);\n });\n\n // Get audience label prefix\n let prefix = wordList.find(name => name !== audienceWithoutNum?.name);\n\n // Pluralise the prefix is there are multiple audiences\n if (audiences.length > 1)\n prefix += 's';\n\n if (audienceWithoutNum && numberList.length)\n return `${prefix} ${audienceWithoutNum.name.charAt(0)} - ${numberList.pop()}`;\n\n /**\n * Build set of logical audience ranges\n */\n const audienceRange = processAudienceRanges(numberList);\n\n return `${prefix} ${audienceRange.join(', ')}`;\n },\n\n internationalSecondaryBuilder(audiences: PresentationAudience[]): string {\n return AudienceStringBuilders.englandSecondaryBuilder(audiences);\n },\n\n scotlandPrimaryBuilder(audiences: PresentationAudience[]): string {\n const firstAudience = ArrayHelper.first(audiences);\n const lastAudience = ArrayHelper.last(audiences);\n\n let [firstAudienceLevel] = firstAudience.name.split(' ');\n let [lastAudienceLevel] = lastAudience.name.split(' ');\n\n if (firstAudienceLevel === 'First')\n firstAudienceLevel = '1st';\n\n if (lastAudienceLevel === 'First')\n lastAudienceLevel = '1st';\n\n if (firstAudienceLevel === 'Second')\n firstAudienceLevel = '2nd';\n\n if (lastAudienceLevel === 'Second')\n lastAudienceLevel = '2nd';\n\n if (firstAudienceLevel === lastAudienceLevel)\n return `${firstAudienceLevel} Level`;\n\n return `${firstAudienceLevel} - ${lastAudienceLevel} Level`;\n },\n\n internationalPrimaryBuilder(audiences: PresentationAudience[]): string {\n const firstAudience = ArrayHelper.first(audiences);\n const lastAudience = ArrayHelper.last(audiences);\n\n if (firstAudience.name === lastAudience.name)\n return firstAudience.name;\n\n let [firstAudienceLevel] = firstAudience.name.split(' ');\n let [lastAudienceLevel] = lastAudience.name.split(' ');\n\n if (firstAudienceLevel === 'Lower')\n firstAudienceLevel = 'Low';\n\n if (lastAudienceLevel === 'Lower')\n lastAudienceLevel = 'Low';\n\n if (firstAudienceLevel === 'Middle')\n firstAudienceLevel = 'Mid';\n\n if (lastAudienceLevel === 'Middle')\n lastAudienceLevel = 'Mid';\n\n return `${firstAudienceLevel} - ${lastAudienceLevel} Pri`;\n },\n\n /**\n * Handles the english secondary audiences, which can be: Lower Secondary, Upper Secondary, and Advanced\n */\n englandSecondaryBuilder(audiences: PresentationAudience[]): string {\n const firstAudience = ArrayHelper.first(audiences);\n const lastAudience = ArrayHelper.last(audiences);\n\n if (firstAudience.name === lastAudience.name)\n return firstAudience.name;\n\n if (lastAudience.name === 'Advanced') {\n const [level] = firstAudience.name.split(' ');\n\n if (level.toLowerCase() === 'lower')\n return 'Lower Sec - Adv';\n\n return 'Upper Sec - Adv';\n }\n\n return 'Lower - Upper Sec';\n },\n\n scotlandSecondaryBuilder(audiences: PresentationAudience[]): string {\n const firstAudience = ArrayHelper.first(audiences);\n const lastAudience = ArrayHelper.last(audiences);\n\n if (firstAudience.name === lastAudience.name)\n return firstAudience.name;\n\n if (lastAudience.name === 'Senior Phase')\n return `${firstAudience.name} - Senior`;\n\n return 'Third - Fourth Level';\n },\n\n /**\n * Handles the audience set: Reception, Key Stage 1, Lower Key Stage 2, and Upper Key Stage 2\n */\n englandPrimaryBuilder(audiences: PresentationAudience[]): string {\n // The first and last audience will build out the range\n const firstAudience = ArrayHelper.first(audiences);\n const lastAudience = ArrayHelper.last(audiences);\n\n // The first word in the strings will either be \"Upper\", \"Lower\", \"Key\", or \"Reception\"\n const firstAudienceFirstWord = ArrayHelper.first(firstAudience.name.split(' '));\n const lastAudienceFirstWord = ArrayHelper.first(lastAudience.name.split(' '));\n\n // Each audience in this set except for \"Reception\" has a number. Get the numbers for the first and last audiences\n const firstAudienceNumber = firstAudience.name.split(' ').find(word => !isNaN(+word));\n const lastAudienceNumber = lastAudience.name.split(' ').find(word => !isNaN(+word));\n\n // If there's only one audience on the video:\n if (firstAudience === lastAudience) {\n // For these 2 audiences, return the full name as it's short enough already\n if (firstAudienceFirstWord === 'Key' || firstAudienceFirstWord === 'Reception')\n return firstAudience.name;\n\n // For the Upper/Lower key stage audiences, abbreviate the \"key stage\" part to KS1/KS2\n return `${firstAudienceFirstWord} KS${firstAudienceNumber}`;\n }\n\n /**\n * Handle when the object has >1 audience\n */\n\n let firstAudienceString = '';\n let lastAudienceString = '';\n\n // Reception is always shortened to \"R\" when in a range\n if (firstAudienceFirstWord === 'Reception') {\n firstAudienceString = 'R';\n } else {\n // All other audiences will be abbreviated to \"KS1/KS2\"\n firstAudienceString = `KS${firstAudienceNumber}`;\n }\n\n // The last audience will always be a key stage, so abbreviate this too\n lastAudienceString = `KS${lastAudienceNumber}`;\n\n // If the audience range contains both the \"Lower\" and \"Upper\" audiences, abbreviate those and return\n if (firstAudienceFirstWord === 'Lower' && lastAudienceFirstWord === 'Upper') {\n return `L ${firstAudienceString} - U ${lastAudienceString}`;\n }\n\n // Add \"Lower\" and \"Upper\" to the strings if it's needed\n if (firstAudienceFirstWord === 'Lower') {\n firstAudienceString = `Lower ${firstAudienceString}`;\n }\n\n if (lastAudienceFirstWord === 'Upper') {\n lastAudienceString = `Upper ${lastAudienceString}`;\n }\n\n // This handles a case where the range is Reception - Key Stage 1. In which case we don't abbreviate the key stage part to KS1.\n if (lastAudienceFirstWord === 'Key') {\n lastAudienceString = lastAudience.name;\n }\n\n return `${firstAudienceString} - ${lastAudienceString}`;\n }\n};\n\nfunction processAudienceRanges(audienceValues: number[]): string[] {\n /**\n * Lookahead by increments of offset\n */\n const offset = COUNT_OFFSET;\n\n let initialVal; let nextVal;\n let isContinguous: boolean = false;\n\n const ranges: string[] = [];\n\n // Audience values need to be in ascending order\n audienceValues = audienceValues.sort((a, b) => a - b);\n\n let i; let j;\n\n for (i = 0; i < audienceValues.length; i++) {\n j = i + 1;\n\n // Set our lower boundary to compare against\n if (!isContinguous)\n initialVal = audienceValues[i];\n\n nextVal = audienceValues[j];\n\n /**\n * Where the next number is also the next incremental value\n * we're going to continue iterating until the next value\n * is no longer contiguos.\n */\n if (audienceValues[i] + offset === nextVal) {\n isContinguous = true;\n } else if (isContinguous) {\n /**\n * Where we were tracking a contiguous set, format appropriately \n * and store the vals\n */\n\n ranges.push(`${initialVal} - ${audienceValues[i]}`);\n isContinguous = false;\n } else {\n /**\n * Where the values arent contiguous, just store the current value\n */\n\n ranges.push(`${audienceValues[i]}`);\n isContinguous = false;\n }\n }\n\n return ranges;\n}","import { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { Audience, BaseObject, PresentationAudience } from 'libs/shared/interfaces';\n\nimport { AudienceStringBuilders } from './AudienceStringBuilders';\n\nconst DIGIT_REGEX = /([0-9]+)/ig;\nconst SPACE_REGEX = /\\s|\\+/ig;\n\n/**\n * Where there is 1 or less audiences on a presentation, it provides little value to\n * the user's experience, so we'll hide audiences altogether.\n */\nconst MIN_AUDIENCE_THRESHOLD = 1;\n\nexport const AudienceHelper = {\n /**\n * This is needed to sort an object's audiences, as they are not sorted by the backend.\n * To do this, we take the presentation audiences (sorted) and filter them by the object's\n * audiences, leaving behind a sorted array of object audiences.\n */\n getSortedPresentationAudiences(\n objectAudiences: Audience[],\n presentationAudiences: PresentationAudience[]\n ): PresentationAudience[] {\n /**\n * Atm there is a bug in flight's optimize, around multiple parts of the page \n * fetching the same object with a different response. We are filtering out\n * falsey values in our object audience ids until that's fixed. - Sha\n */\n const objectAudienceIds = objectAudiences\n .filter(v => !!v)\n .map(audience => audience.id.toString());\n\n /**\n * Remove audiences that aren't relevant for the user's current presentation\n */\n const filteredAudiences = presentationAudiences.filter(presAudience => {\n return objectAudienceIds.includes(presAudience.masterId.toString());\n });\n\n return filteredAudiences;\n },\n\n /**\n * This function accepts a set of presentation audiences, and returns a single\n * audience where the name is a merged string of the names of all of the audiences passed in.\n *\n * As we add more presentations that have different audience sets, we'll need to extend the `switch`\n * statement below to either include new string builder functions, or to include new presentation IDs\n * for existing string builder functions.\n */\n getMergedPresentationAudienceString(presentationAudiences: PresentationAudience[]): PresentationAudience {\n const { presentationId } = ArrayHelper.first(presentationAudiences);\n\n let mergedAudienceString = '';\n\n switch (+presentationId) {\n // Generic `Name Number`. Sometimes has just name. Examples: Year 12, Grade 4, Kindergarten\n case HardCoded.PresentationIds.DEFAULT:\n case HardCoded.PresentationIds.AU_SECONDARY:\n case HardCoded.PresentationIds.US_ELEMENTARY:\n case HardCoded.PresentationIds.AU_PRIMARY:\n case HardCoded.PresentationIds.STREAMABLE_LEARNING:\n if (presentationAudiences.length === 1)\n return presentationAudiences[0];\n\n mergedAudienceString = AudienceStringBuilders.yearsAndGradesBuilder(presentationAudiences);\n break;\n\n case HardCoded.PresentationIds.INTERNATIONAL_SECONDARY:\n if (presentationAudiences.length === 1)\n return presentationAudiences[0];\n\n // TODO: Implement this properly\n mergedAudienceString = AudienceStringBuilders.internationalSecondaryBuilder(presentationAudiences);\n break;\n\n case HardCoded.PresentationIds.INTERNATIONAL_PRIMARY:\n mergedAudienceString = AudienceStringBuilders.internationalPrimaryBuilder(presentationAudiences);\n break;\n\n case HardCoded.PresentationIds.SCOTLAND_PRIMARY:\n mergedAudienceString = AudienceStringBuilders.scotlandPrimaryBuilder(presentationAudiences);\n break;\n\n case HardCoded.PresentationIds.ENGLISH_SECONDARY:\n mergedAudienceString = AudienceStringBuilders.englandSecondaryBuilder(presentationAudiences);\n break;\n\n \n case HardCoded.PresentationIds.SCOTLAND_SECONDARY:\n mergedAudienceString = AudienceStringBuilders.scotlandSecondaryBuilder(presentationAudiences);\n break;\n\n // Key Stage 1, Lower Key Stage 2, etc.\n case HardCoded.PresentationIds.ENGLAND_PRIMARY:\n mergedAudienceString = AudienceStringBuilders.englandPrimaryBuilder(presentationAudiences);\n break;\n\n // These presentations only have 1 audience mapped. These are never shown as badges in the product.\n case HardCoded.PresentationIds.US_MIDDLE:\n case HardCoded.PresentationIds.US_HIGH:\n case HardCoded.PresentationIds.AU_TERTIARY:\n case HardCoded.PresentationIds.UK_TERTIARY:\n default:\n break;\n }\n\n if (!mergedAudienceString)\n return null;\n\n return { name: mergedAudienceString } as PresentationAudience;\n },\n\n /**\n * This function assumes the members array passed in is ordered by `name`.\n */\n sortMembersWithDuplicateNamesByAudience(members: BaseObject[]): BaseObject[] {\n // Returns the lowest level audience out of an array of audience objects by looking at the name\n const getLowestAudience = (audiences: Audience[]) => {\n if (!audiences.length)\n return null;\n\n let lowestAudience: Audience;\n let lowestAudienceDigit: number;\n\n audiences.forEach(audience => {\n const digit = +ArrayHelper.first(audience.name.match(DIGIT_REGEX));\n\n if (!lowestAudience) {\n lowestAudience = audience;\n lowestAudienceDigit = digit;\n return;\n }\n\n if (digit < lowestAudienceDigit)\n lowestAudience = audience;\n });\n\n return lowestAudience;\n };\n\n // This is used to track how many times a member's name appears in the collection\n const nameCountMap: HashObject<number> = {};\n\n let sorted: BaseObject[] = [];\n\n members.forEach(member => {\n if (!nameCountMap[member.name]) {\n nameCountMap[member.name] = 1;\n sorted.push(member);\n return;\n }\n\n sorted.push(member);\n nameCountMap[member.name]++;\n\n // Take the slice of duplicates that we want to sort by audience\n const slice = sorted.splice(sorted.length - nameCountMap[member.name]);\n\n // Sort the slice by lowest audience\n const sortedSlice = slice.sort((a: any, b: any) => {\n const firstObjLowestAudience = getLowestAudience(a.subjectPresentationAudiences.data);\n const secondObjLowestAudience = getLowestAudience(b.subjectPresentationAudiences.data);\n\n if (!firstObjLowestAudience && secondObjLowestAudience)\n return 1;\n\n if (!secondObjLowestAudience)\n return -1;\n\n const comparison = firstObjLowestAudience.name.localeCompare(secondObjLowestAudience.name);\n\n if (comparison === 0) return comparison;\n\n return comparison > 0 ? -1 : 1;\n });\n\n sorted = sorted.concat(sortedSlice);\n });\n\n return sorted;\n },\n\n getActiveAudiencesFromParams(audiences: PresentationAudience[], params: HashObject = {}): PresentationAudience[] {\n if (!ObjectHelper.isObject(params) || ObjectHelper.isEmpty(params))\n return;\n\n if (!audiences || !audiences.length)\n return;\n\n if (!AudienceHelper.shouldShowAudiences(audiences))\n return;\n\n // 'a' is shorthand for audience\n let { a } = params;\n\n if (!a)\n return;\n\n // Only a single query param was passed, we'll wrap it in an array\n if (typeof a === 'string')\n a = [a];\n\n const normalizeAudienceName = (audienceName: string) => {\n return audienceName.replace(SPACE_REGEX, '').toLowerCase();\n };\n\n // Build an audience lookup\n const audienceLookup = a.reduce((state: HashObject, audienceStr: string) => {\n state[normalizeAudienceName(audienceStr)] = audienceStr;\n return state;\n }, {});\n\n // Filter out our active audience based on whether their name matches the lookup object\n return audiences.filter((audience: PresentationAudience) => {\n return audienceLookup[normalizeAudienceName(audience.name)];\n });\n },\n\n getAudienceParams(audiences: PresentationAudience[]): HashObject {\n if (!audiences?.length)\n return null;\n\n return { a: audiences.map(a => a.name) };\n },\n\n shouldShowAudiences(audiences: PresentationAudience[] = []): boolean {\n if (!audiences)\n return false;\n\n return audiences.length > MIN_AUDIENCE_THRESHOLD;\n }\n};\n","// extracted by mini-css-extract-plugin\nexport default {\"leftNavIcon\":\"ssG3i\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { IconCircle } from 'libs/shared/components/icon-circle/IconCircle';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { CuratedDashboard, Library } from 'libs/shared/interfaces';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavConfig } from 'shared/views/left-nav/LeftNavConfig';\n\nimport { LibraryHelper } from 'apps/libraries/utils/LibraryHelper';\n\nimport styles from './nav-tiles.scss';\n\nconst namespace = 'default.popupPlugin';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface NavItemTileProps {\n id: LeftNavId;\n name: string;\n imageUrl?: string;\n iconClassName: string;\n svgName: string;\n appLink: Core.AppLink;\n}\n\nfunction NavItemTile(props: NavItemTileProps): JSX.Element {\n return (\n <li className={`columns-of-five-md col-6 mb-3`}>\n <AppLink\n appLink={props.appLink}\n className={`border rounded-3 d-flex align-items-center\n justify-content-center flex-column text-decoration-none h-100 py-3 px-1 text-center`}\n >\n <div className={`${styles.leftNavIcon} ${props.iconClassName} mx-auto mb-3`}>\n <IconCircle\n imageUrl={ImageHelper.createUrl(props.imageUrl, { size: ImageSize.Small })}\n svgName={props.svgName}\n svgSize={SvgContainerSize.Large}\n />\n </div>\n <div className='h6'>\n {props.name}\n </div>\n </AppLink>\n </li>\n );\n}\n\ninterface NavTilesProps {\n hasPermissions: HasPermissionsFunc;\n moviesAndTvDashboard: CuratedDashboard;\n libraries: Library[];\n}\n\nexport function NavTiles(props: NavTilesProps): JSX.Element {\n const { hasPermissions, moviesAndTvDashboard, libraries } = props;\n\n function shouldShowLibraries(): boolean {\n if (!libraries?.length)\n return false;\n \n if (!hasPermissions(PermissionName.StudentExperience))\n return true;\n\n return hasPermissions(PermissionName.ViewLibraries);\n }\n\n function showNavItem(leftNavId: LeftNavId) {\n switch (leftNavId) {\n case LeftNavId.StudentFeed: return hasPermissions(PermissionName.StudentExperience);\n case LeftNavId.Discover: return hasPermissions(PermissionName.ViewDiscover);\n case LeftNavId.MoviesAndTv: return hasPermissions(PermissionName.ViewMoviesTv);\n case LeftNavId.Libraries: return shouldShowLibraries();\n case LeftNavId.Classrooms: return hasPermissions(PermissionName.ViewClassrooms);\n default: return true;\n }\n }\n\n return (\n <ul className='list-unstyled row'>\n {showNavItem(LeftNavId.StudentFeed) && (\n <NavItemTile\n id={LeftNavId.StudentFeed}\n appLink={LeftNavConfig[LeftNavId.StudentFeed].appLink}\n name={getPhrase('home')}\n iconClassName='bg-purple'\n svgName={cvSvgLibrary.House}\n />\n )}\n {showNavItem(LeftNavId.Discover) && (\n <NavItemTile\n id={LeftNavId.Discover}\n appLink={LeftNavConfig[LeftNavId.Discover].appLink}\n name={getPhrase('discover')}\n iconClassName='bg-blue'\n svgName={cvSvgLibrary.Compass}\n />\n )}\n {showNavItem(LeftNavId.MoviesAndTv) && !!moviesAndTvDashboard && (\n <NavItemTile\n id={LeftNavId.MoviesAndTv}\n appLink={LeftNavConfig[LeftNavId.MoviesAndTv].appLink}\n name={getPhrase('moviesAndTv')}\n iconClassName='bg-indigo'\n svgName={cvSvgLibrary.Popcorn}\n />\n )}\n <NavItemTile\n id={LeftNavId.Playlists}\n appLink={LeftNavConfig[LeftNavId.Playlists].appLink}\n name={getPhrase('playlists')}\n iconClassName='bg-green'\n svgName={cvSvgLibrary.Playlist}\n />\n <NavItemTile\n id={LeftNavId.MyVideos}\n appLink={LeftNavConfig[LeftNavId.MyVideos].appLink}\n name={getPhrase('myVideos')}\n iconClassName='bg-orange'\n svgName={cvSvgLibrary.Video}\n />\n {showNavItem(LeftNavId.Libraries) && (\n LibraryHelper.sort(libraries).map((library, index) => (\n <NavItemTile\n key={index}\n id={LeftNavId.Library}\n name={library.name}\n appLink={{\n ...LeftNavConfig[LeftNavId.Library].appLink,\n args: [ library.id, TextHelper.slugify(library.name) ]\n }}\n iconClassName='bg-teal'\n imageUrl={library.owner?.logo?.url}\n svgName={!(library.owner?.logo?.url) && cvSvgLibrary.Library}\n />\n ))\n )}\n </ul>\n );\n}","import React from 'react';\nimport { Radio } from 'backbone';\n\nimport { CommonChannels } from 'libs/common/backbone/constants/CommonChannels';\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { useFocusSearchBar } from 'libs/shared/components/search-bar/SearchUtils';\nimport { FixedWidget, PartialFixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { PopoutVideoWidgetItem, PopoutVideoWidgetItemProps } from 'libs/shared/components/widgets/items/popout-video-widget-item/PopoutVideoWidgetItem';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { FavouriteRequests } from 'libs/shared/flight-requests/FavouriteRequests';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Config, CurrentUser, DashboardTargetType, Library, PresentationAudience, VideoTypesCollection, YearGroup } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { LayoutHelper } from 'shared/utils/LayoutHelper';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { NavTiles } from 'apps/default/views/popup-plugin/components/Navtiles';\nimport { useGetVideoHistory } from 'apps/default/views/popup-plugin/hooks/useGetVideoHistoryVideos';\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nconst namespace = 'default.popupPlugin';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n\nexport function PopupPluginView(): JSX.Element {\n const { isPlugin } = usePluginHelper();\n const { focusSearchBar } = useFocusSearchBar();\n\n useSetPageMetadata({ title: getPhrase('title') });\n\n /**\n * Required for video widgets\n */\n const { activePresentation } = usePresentation();\n const { hasPermissions, isLoaded } = usePermissions();\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.VideoThumbnail);\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n activePresentation &&\n AudienceRequests.audiencesByPresentationId(activePresentation.id)\n );\n\n /**\n * Watch history videos\n */\n const videoHistory = useGetVideoHistory();\n\n /**\n * Favourite videos\n */\n const favouriteVideos = Flight.useBasicFetch<VideoTypesCollection>(\n currentUser.data && FavouriteRequests.getFavourites(currentUser.data.id)\n );\n\n /**\n * Required for displaying our Nav item tiles.\n */\n const libraries = Flight.useBasicFetch<Library[]>(\n hasPermissions(PermissionName.ViewLibraries) &&\n LibraryRequests.domainLibraries([ 'customLibrary', 'sharedLibrary' ])\n );\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams: {}\n });\n Flight.useBasicFetch(!!libraries.data?.length &&\n LibraryRequests.librariesWithOwnerLogos(libraries.data.map(s => s.id)));\n\n useListenOn(CommonChannels.SHELL, Core.EventNames.ROUTE, appLink => {\n /**\n * Ignore applinks with no href. Like the embed popup - Sha\n */\n if (!Core.AppLinkHelper.getHref(appLink))\n return;\n\n /**\n * Enable the nav as we leave our popup view - Sha\n */\n LayoutHelper.enableNav();\n\n /**\n * Re-focus the search bar when the routing has ended.\n * We need to do this because the user may be mid typing, but the layout\n * re-render causes the search bar to lose focus - Sha\n */\n Radio.channel(CommonChannels.SHELL).once('routing:end', focusSearchBar);\n });\n\n const hasLoaded = (\n moviesAndTvDashboard.hasCompleted &&\n isLoaded &&\n (!hasPermissions(PermissionName.ViewLibraries) || libraries.hasCompleted) &&\n config.hasCompleted\n );\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <div className='px-4'>\n <NavTiles\n hasPermissions={hasPermissions}\n moviesAndTvDashboard={moviesAndTvDashboard.data}\n libraries={libraries.data}\n />\n\n {videoHistory.hasCompleted ?\n <div className='mb-3'>\n <FixedWidget<PopoutVideoWidgetItemProps>\n name={getPhrase('recentlyWatched')}\n collection={videoHistory.data || []}\n contents={WidgetContents.Videos}\n childComponent={PopoutVideoWidgetItem}\n extraChildComponentProps={{\n setFavourite,\n canFavourite,\n presentationAudiences: audiences.data,\n getSubTextAppLink: SeriesAppLinkHelper.getSeriesAppLink,\n imageCdnUrl: config.data.imageCdnUrl,\n yearGroups: yearGroups.data,\n showVideoGuidance: VideoHelper.showVideoGuidance(hasPermissions),\n isPlugin,\n getClassroomGuideAppLink: VideoAppLinkHelper.getClassroomGuideAppLink,\n getResourceGuidanceAppLink: VideoAppLinkHelper.getResourceGuidanceAppLink,\n getInteractiveGuidanceAppLink: VideoAppLinkHelper.getInteractiveGuidanceAppLink\n }}\n getChildAppLink={VideoAppLinkHelper.getAppLink}\n appLink={{\n application: AppChannels.WATCH_HISTORY,\n action: Actions.WatchHistory.HOME\n }}\n prefetched\n />\n </div> :\n <div className='mb-3'><PartialFixedWidget /></div>\n }\n\n {favouriteVideos.hasCompleted ?\n <FixedWidget<PopoutVideoWidgetItemProps>\n name={getPhrase('favourites')}\n collection={favouriteVideos.data.data || []}\n contents={WidgetContents.Videos}\n childComponent={PopoutVideoWidgetItem}\n extraChildComponentProps={{\n setFavourite,\n canFavourite,\n presentationAudiences: audiences.data,\n getSubTextAppLink: SeriesAppLinkHelper.getSeriesAppLink,\n imageCdnUrl: config.data.imageCdnUrl,\n yearGroups: yearGroups.data,\n showVideoGuidance: VideoHelper.showVideoGuidance(hasPermissions),\n isPlugin,\n getClassroomGuideAppLink: VideoAppLinkHelper.getClassroomGuideAppLink,\n getResourceGuidanceAppLink: VideoAppLinkHelper.getResourceGuidanceAppLink,\n getInteractiveGuidanceAppLink: VideoAppLinkHelper.getInteractiveGuidanceAppLink\n }}\n getChildAppLink={VideoAppLinkHelper.getAppLink}\n appLink={{\n application: AppChannels.DEFAULT,\n action: Actions.MyFavourites.MY_FAVOURITES\n }}\n prefetched\n /> :\n <PartialFixedWidget />\n }\n </div>\n );\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\n\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useBatchFetch } from 'libs/shared/hooks/UseBatchFetch';\nimport { VideoHistoryCollection, VideoTypes } from 'libs/shared/interfaces';\n\nimport { useVideoMixin } from 'shared/hooks/useVideoMixin';\n\nimport { VideoHistoryRequests } from 'apps/watch-history/flight-requests/VideoHistoryRequests';\n\nexport function useGetVideoHistory() {\n const videoHistory = Flight.useBasicFetch<VideoHistoryCollection>(VideoHistoryRequests.userVideoHistory());\n\n const videosFetchResult = useBatchFetch<VideoTypes>(\n videoHistory.data?.data?.map(v => v.videoId) ?? [],\n VideoRequests.watchHistoryVideos\n );\n\n /**\n * We must do this to get the videos back into the correct order - Sha\n */\n const videoHistoryVideos = React.useMemo(() => {\n const videosMap = new Map<string, VideoTypes>();\n\n videoHistory.data?.data?.forEach(history => {\n if (videosMap.has(history.videoId))\n return;\n\n const video = videosFetchResult.items?.[history.videoId];\n\n if (video)\n videosMap.set(history.videoId, video);\n });\n\n return [...videosMap.values()];\n }, [ videosFetchResult.items, videoHistory.data ]);\n \n useVideoMixin(videoHistoryVideos);\n\n return {\n data: videoHistoryVideos,\n hasCompleted: !videosFetchResult.isFetching\n };\n}","\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { VideoHistoryCollection } from 'libs/shared/interfaces';\n\nexport const VideoHistoryRequests = {\n userVideoHistory(\n cursor?: string,\n success?: (data: HashObject) => void,\n error?: (Xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n let key = 'video:history';\n let url = `{gateway}/v1/users/me/watch-history`;\n\n if (cursor) {\n key += `:${cursor}`;\n url += `?cursor=${cursor}`;\n }\n\n return {\n key,\n url,\n formatData: (historyCollection: VideoHistoryCollection) => {\n return {\n data: historyCollection.data.map(historyData => {\n // Convert last watched times from UTC to local time\n const lastTimeWatchedLocal = DateHelper.format(historyData.lastTimeWatched);\n const lastDateWatchedLocal = DateHelper.format(lastTimeWatchedLocal, 'YYYY-MM-DD');\n\n return {\n ...historyData,\n lastTimeWatched: lastTimeWatchedLocal,\n lastDateWatched: lastDateWatchedLocal\n };\n }),\n pagination: historyCollection.pagination\n };\n },\n success,\n error,\n always\n };\n },\n\n videoHistory(\n ids: string[],\n namespace?: string,\n success?: (data: HashObject) => void,\n error?: (Xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n const params = ids.sort().map(i => `videoId=${i}`);\n\n return {\n key: `video:history:videos:${params.join('&')}`,\n url: `{gateway}/v1/videos/history?${params.join('&')}`,\n normalizeOptions: {\n namespace\n },\n formatData: (historyCollection: HashObject[]) => {\n if (!historyCollection?.length)\n return historyCollection;\n\n /**\n * Data is formatted to enable it to be merged with the existing video object in the store\n * Where we need to merge more history properties with the video object, map them below.\n */\n return historyCollection.map((watchHistory: HashObject) => ({\n id: watchHistory.videoId,\n lastProgressPoint: watchHistory.lastProgressPoint\n }));\n },\n success,\n error,\n always\n };\n }\n};","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { Clip, ClipCollection, CurrentUser, Video, VideoCollection } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nconst CHUNK_SIZE = 50;\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 = {}): void {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const hydratedVideos = React.useRef<Set<string>>(new Set<string>());\n\n const videos = getValidObjects(objects);\n\n const videoIds = videos.map(v => v.id);\n\n const [ request, setRequest ] = React.useState<Flight.Request[]>([]);\n\n React.useEffect(() => {\n if (!videoIds?.length || !currentUser.hasCompleted)\n return;\n\n const unhydratedVideos: string[] = [];\n\n videoIds.forEach(id => {\n if (!hydratedVideos.current.has(id)) {\n unhydratedVideos.push(id);\n hydratedVideos.current.add(id);\n }\n });\n \n if (!unhydratedVideos.length)\n return;\n\n setRequest(r => {\n const newRequests = [...r] ;\n\n ArrayHelper.chunk<string>(unhydratedVideos, CHUNK_SIZE).forEach(chunk => {\n newRequests.push(VideoRequests.videoMixinAssocs(chunk, options.flightNamespace));\n\n if (currentUser.data?.isAuthenticated)\n newRequests.push(ClassificationRequests.hasCurriculumLinks(chunk, null, options.flightNamespace));\n });\n\n return newRequests;\n });\n }, [ videoIds?.length, currentUser.hasCompleted ]);\n\n Flight.useBasicFetchAll(request);\n}"],"names":["PopoutVideoWidgetItem","props","video","data","getSubTextAppLink","context","thumbnailSize","preloadImage","presentationAudiences","videoAudiences","subjectPresentationAudiences","mergedAudience","breakpoints","useBreakpoints","width","type","className","VideoThumbnail","preventPopout","xs","textPosition","ThumbnailTextPosition","appLink","getAppLink","subTextAppLink","VideoHelper","imageOptions","size","preload","analyticsData","analyticsOptions","canFavourite","setFavourite","imageCdnUrl","audience","hideRating","hideDuration","yearGroups","hideTitle","showVideoGuidance","companyLogoFallbackUrl","subTextType","isPlugin","getInteractiveGuidanceAppLink","getResourceGuidanceAppLink","getClassroomGuideAppLink","showNewVideoIndicator","useBatchFetch","itemIds","getRequest","idBatches","setIdBatches","length","newBatches","push","forEach","id","find","batch","_id","filter","join","dispatch","state","idBatch","request","key","shouldFetch","items","isFetching","responses","i","response","v","Object","keys","some","k","useMergeAudiences","audiences","sortedAudiences","HAS_NUMBER_REGEX","AudienceStringBuilders","yearsAndGradesBuilder","combinedNames","map","a","name","numberList","split","isNaN","num","wordList","audienceWithoutNum","p","test","prefix","charAt","pop","audienceRange","audienceValues","initialVal","nextVal","j","isContinguous","ranges","sort","b","processAudienceRanges","internationalSecondaryBuilder","englandSecondaryBuilder","scotlandPrimaryBuilder","firstAudience","ArrayHelper","lastAudience","firstAudienceLevel","lastAudienceLevel","internationalPrimaryBuilder","toLowerCase","scotlandSecondaryBuilder","englandPrimaryBuilder","firstAudienceFirstWord","lastAudienceFirstWord","firstAudienceNumber","word","lastAudienceNumber","firstAudienceString","lastAudienceString","DIGIT_REGEX","SPACE_REGEX","AudienceHelper","getSortedPresentationAudiences","objectAudiences","objectAudienceIds","toString","presAudience","includes","masterId","getMergedPresentationAudienceString","mergedAudienceString","presentationId","HardCoded","sortMembersWithDuplicateNamesByAudience","members","getLowestAudience","digit","match","lowestAudience","lowestAudienceDigit","nameCountMap","sorted","member","sortedSlice","splice","firstObjLowestAudience","secondObjLowestAudience","comparison","localeCompare","concat","getActiveAudiencesFromParams","params","ObjectHelper","shouldShowAudiences","normalizeAudienceName","audienceName","replace","audienceLookup","reduce","audienceStr","getAudienceParams","getPhrase","LanguageService","NavItemTile","AppLink","iconClassName","IconCircle","imageUrl","ImageHelper","svgName","svgSize","SvgContainer","S","NavTiles","hasPermissions","moviesAndTvDashboard","libraries","showNavItem","leftNavId","LeftNavId","PermissionName","LeftNavConfig","LibraryHelper","library","index","args","TextHelper","owner","logo","url","PopupPluginView","usePluginHelper","focusSearchBar","useSetPageMetadata","title","activePresentation","usePresentation","usePermissions","isLoaded","useLiteFavourites","u","config","ConfigRequests","currentUser","UserRequests","isAuthenticated","CustomerRequests","customerId","AudienceRequests","videoHistory","VideoHistoryRequests","videosFetchResult","videoId","VideoRequests","videoHistoryVideos","videosMap","Map","history","has","set","values","useVideoMixin","hasCompleted","useGetVideoHistory","favouriteVideos","FavouriteRequests","LibraryRequests","targetType","queryParams","dashboard","s","CommonChannels","LayoutHelper","Radio","once","collection","contents","WidgetContents","childComponent","extraChildComponentProps","SeriesAppLinkHelper","VideoAppLinkHelper","getChildAppLink","application","action","prefetched","userVideoHistory","cursor","success","error","always","formatData","historyCollection","historyData","lastTimeWatchedLocal","lastTimeWatched","lastDateWatchedLocal","lastDateWatched","pagination","ids","namespace","normalizeOptions","watchHistory","lastProgressPoint","CHUNK_SIZE","objects","options","hydratedVideos","Set","videos","Array","isArray","o","getValidObjects","videoIds","setRequest","unhydratedVideos","current","add","r","newRequests","chunk","flightNamespace"],"sourceRoot":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/6263-dcc4cb4933-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/common/src/react/utils/PortalHelper.ts","file:///app/packages/libs/shared/src/apps/calendar/components/coming-soon-tag/coming-soon-tag.scss","file:///app/packages/libs/shared/src/apps/calendar/components/coming-soon-tag/ComingSoonTag.tsx","file:///app/packages/libs/shared/src/apps/calendar/components/generic-calendar-date/generic-calendar-date.scss","file:///app/packages/libs/shared/src/apps/calendar/components/generic-calendar-date/GenericCalendarDate.tsx","file:///app/packages/libs/shared/src/components/back-button/BackButton.tsx","file:///app/packages/libs/shared/src/components/banner-header/banner-header.scss","file:///app/packages/libs/shared/src/components/banner-header/BannerHeader.tsx","file:///app/packages/libs/shared/src/components/breadcrumbs/Breadcrumbs.tsx","file:///app/packages/libs/shared/src/components/infinite-scroll-footer/infinite-scroll-footer.scss","file:///app/packages/libs/shared/src/components/infinite-scroll-footer/InfiniteScrollFooter.tsx","file:///app/packages/libs/shared/src/components/video-list/partial-loading/partial-video-list.scss","file:///app/packages/libs/shared/src/components/video-list/partial-loading/PartialVideoList.tsx","file:///app/packages/libs/shared/src/errors/handlers/HttpErrorHandlers.ts","file:///app/packages/libs/shared/src/hooks/UseHandleObjectError.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/hooks/useBreadcrumbs.ts","file:///app/packages/libs/shared/src/utils/PartialLoadingHelper.ts","file:///app/packages/libs/shared/src/apps/playlists/utils/PlaylistHelper.ts","file:///app/packages/libs/shared/src/apps/playlists/components/playlist-header-details/PlaylistHeaderDetails.tsx","file:///app/packages/projects/lite/src/apps/playlists/components/playlist-header/partial-loading/partial-playlist-header.scss","file:///app/packages/projects/lite/src/apps/playlists/components/playlist-header/partial-loading/PartialPlaylistHeader.tsx","file:///app/packages/projects/lite/src/apps/playlists/components/playlist-header/PlaylistHeaderUtils.ts","file:///app/packages/projects/lite/src/apps/playlists/components/playlist-header/playlist-header.scss","file:///app/packages/projects/lite/src/apps/playlists/components/playlist-header/PlaylistHeader.tsx","file:///app/packages/projects/lite/src/apps/playlists/components/video-list/SortableVideoListContainer.tsx","file:///app/packages/projects/lite/src/apps/playlists/views/playlist/empty-state/PlaylistEmptyState.tsx","file:///app/packages/projects/lite/src/apps/playlists/views/playlist/PlaylistViewUtils.ts","file:///app/packages/projects/lite/src/apps/playlists/views/playlist/PlaylistView.tsx","file:///app/packages/libs/shared/src/hooks/UseReorderedItems.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoMixin.ts","file:///app/node_modules/react-bootstrap/esm/Row.js"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PortalHelper = {\n renderInPortalIfExists(component: React.ReactElement, portalContainer: Element | null): React.ReactElement {\n if (portalContainer)\n return createPortal(component, portalContainer);\n\n return component;\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"tag\":\"XRj8d\",\"tooltip\":\"X6mLk\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './coming-soon-tag.scss';\n\nconst namespace = 'specialEventCalendar.comingSoonTag';\n\ninterface ComingSoonProps {\n className?: string;\n onlyIcon?: boolean;\n}\n\nexport function ComingSoonTag(props: ComingSoonProps): JSX.Element {\n return (\n <Tooltip title={LanguageService.getPhrase(namespace, 'tooltip')} spanHackClassName={`d-block ${styles.tooltip}`} spanHack>\n <div className={`d-flex text-dark align-items-center ${styles.tag} ${props.className}`}>\n <SvgContainer svgName={cvSvgLibrary.Timer} />\n {!props.onlyIcon && LanguageService.getPhrase(namespace, 'comingSoon')}\n </div>\n </Tooltip>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"dateItem\":\"I3SBm\",\"label\":\"PRORs\",\"body\":\"RfiM_\",\"bodyDay\":\"ZOVny\",\"bodyRange\":\"vYhXN\",\"bodyMonth\":\"mYslO\",\"month\":\"EPkkQ\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsOptions } from 'libs/analytics/interfaces';\n\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\n\nimport styles from './generic-calendar-date.scss';\n\nexport interface GenericCalendarDateProps {\n label?: string;\n body: {\n type: 'month' | 'range' | 'day';\n text: string;\n };\n month?: string;\n getAppLink?: () => Core.AppLink;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n className?: string;\n theme?: CalendarTheme;\n}\n\nexport function GenericCalendarDate(props: GenericCalendarDateProps): JSX.Element {\n function getBodyClass(): string {\n switch (props.body.type) {\n case 'range':\n return styles.bodyRange;\n case 'day':\n return styles.bodyDay;\n case 'month':\n return styles.bodyMonth;\n }\n }\n\n return (\n <AppLink\n appLink={props.getAppLink?.()}\n className={`text-decoration-none text-center bg-white text-dark border border-3 ${props.theme?.border} rounded-3 d-block fw-semibold ${props.className}`}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n >\n <div className={`position-relative ${styles.dateItem}`}>\n <div className={`${props.theme?.background} py-1 ${styles.label} d-flex align-items-center justify-content-center`}>\n {props.label ? props.label : <> </>}\n </div>\n <div className={`${getBodyClass()} ${styles.body} my-2`}>\n {props.body.text}\n </div>\n <div className={`mb-0 ${styles.month}`}>\n {props.month}\n </div>\n </div>\n </AppLink>\n );\n}","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.backButton';\n\ninterface BackButtonProps {\n appLink: Core.AppLink;\n backToName?: string;\n color?: 'black' | 'white';\n extraClasses?: string;\n /**\n * Whether or not the button text has a text shadow. Defaults to true\n */\n textShadow?: boolean;\n}\n\nBackButton.defaultProps = {\n color: 'black',\n extraClasses: ''\n};\n\nexport function BackButton(props: BackButtonProps): React.ReactElement {\n const { backToName, appLink, color, extraClasses, textShadow } = {\n textShadow: true,\n ...props\n };\n\n const backPhrase = backToName\n ? LanguageService.getPhrase(namespace, 'backTo', { backToName })\n : LanguageService.getPhrase(namespace, 'back');\n\n const colorClass = color === 'black' ? '' : 'text-white';\n const textShadowClass = textShadow ? 'text-shadow' : '';\n\n return (\n <AppLink\n appLink={appLink}\n className={`d-inline-flex align-items-center h5 mb-0 ${extraClasses} ${colorClass} ${textShadowClass}`}\n >\n <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Medium} />\n <span className='ms-1'>{backPhrase}</span>\n </AppLink>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"bannerContent\":\"sSCTB\",\"actionsContainer\":\"Z5WI2\",\"bannerContentWithLogo\":\"rgs7Q\",\"container\":\"M51HJ\",\"logoContainer\":\"vkeJk\",\"logoContainerLeft\":\"M3U9B\",\"logoHeading\":\"EtRwC\",\"specialEventContainer\":\"rOxDc\",\"headingLarge\":\"_8pnV\",\"heading\":\"JXVBH\"};","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ComingSoonTag } from 'libs/shared/apps/calendar/components/coming-soon-tag/ComingSoonTag';\nimport { GenericCalendarDate } from 'libs/shared/apps/calendar/components/generic-calendar-date/GenericCalendarDate';\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { BackButton } from 'libs/shared/components/back-button/BackButton';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ImageMinDimensions } from 'libs/shared/constants/ImageSizes';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Banner, CalendarEvent, Logo } from 'libs/shared/interfaces';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport styles from './banner-header.scss';\n\nconst RATIO = `${ImageMinDimensions[ImageType.Banners].width}:${ImageMinDimensions[ImageType.Banners].height}`;\nconst DEFAULT_WIDTH = 1200; // This is ImageSize.Large for a Banner.\nconst LARGE_SCREEN_WIDTH = 1920;\n\nfunction useGetImageWidth(): number {\n const breakpoints = useBreakpoints();\n\n if (breakpoints.xxl)\n return LARGE_SCREEN_WIDTH;\n\n return DEFAULT_WIDTH;\n}\n\nfunction getSizeClass(heading: string): string {\n if (heading.length < 160)\n return 'h1';\n\n return styles.headingLarge;\n}\n\ninterface BannerHeaderProps {\n heading: string;\n banner?: Banner;\n bannerClassName?: string;\n imageCdnUrl?: string;\n logo?: Logo;\n actions?: ActionOptions[];\n specialEvent?: CalendarEvent;\n backButtonAppLink?: Core.AppLink;\n backButtonText?: string;\n backButtonClasses?: string;\n sortComponent?: JSX.Element;\n blockColourClass?: string;\n actionsDropdownClassName?: string;\n detailsComponent?: () => React.ReactElement;\n imageOptions?: ImageOptions;\n showComingSoon?: boolean;\n alignLogoLeft?: boolean;\n calendarTheme?: CalendarTheme;\n}\n\nconst namespace = 'shared.bannerHeader';\n\nexport const BannerHeader = React.memo(function(props: React.PropsWithChildren<BannerHeaderProps>): React.ReactElement {\n const { heading, banner, imageCdnUrl, actions, sortComponent, blockColourClass, specialEvent } = props;\n\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n const imageWidth = useGetImageWidth();\n\n const specialEventIsToday = React.useMemo(() => {\n if (!specialEvent || props.showComingSoon)\n return false;\n\n const today = DateHelper.format(new Date(), 'YYYY-MM-DD');\n\n if (!specialEvent.endDate)\n return specialEvent.startDate === today;\n\n return specialEvent.startDate <= today && specialEvent.endDate >= today;\n }, [specialEvent]);\n\n function getSpecialEventMonthText(specialEvent: CalendarEvent): string {\n if (!specialEvent.endDate)\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n if (DateHelper.isSame(specialEvent.startDate, specialEvent.endDate, 'month'))\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n return `${DateHelper.format(specialEvent.startDate, 'MMM')} - ${DateHelper.format(specialEvent.endDate, 'MMM')}`;\n }\n\n const imageOptions = props.imageOptions || {\n width: imageWidth,\n ratio: RATIO,\n resizeType: ResizeType.Cover\n };\n\n const url = !!banner && !!imageCdnUrl && ImageHelper.createBannerUrl(banner, {\n fallbackBaseUrl: imageCdnUrl,\n fallbackCategoryName: heading,\n type: ImageType.Banners\n }, imageOptions);\n\n const containerProps: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> = {\n className: `banner banner-header ${props.bannerClassName}`,\n style: url ? { backgroundImage: `url('${url}')` } : {}\n };\n\n if (!banner && blockColourClass) {\n delete containerProps.style;\n containerProps.className += ` ${blockColourClass}`;\n }\n\n const DetailsComponent = props.detailsComponent;\n\n return PortalHelper.renderInPortalIfExists(\n // \"banner\" is used in playlists in Online. banner-header is used by all other projects\n <header {...containerProps}>\n <div className={`container ${styles.container} position-relative inner-banner`}>\n {props.backButtonAppLink && (\n <div className='pt-3'>\n <BackButton\n appLink={props.backButtonAppLink}\n backToName={props.backButtonText}\n extraClasses={props.backButtonClasses}\n color='white'\n />\n </div>\n )}\n \n <div className={`${props.alignLogoLeft ? 'position-absolute top-50 start-0 translate-middle-y w-100 ps-4' : `${styles.bannerContent} px-2 ${props.logo?.url ? styles.bannerContentWithLogo : ''}`}`}>\n {!!specialEvent && (\n <div className={`position-relative ${styles.specialEventContainer}`}>\n <GenericCalendarDate\n body={{\n type: specialEvent.endDate ? 'range' : 'day',\n text: specialEvent.endDate\n ? `${DateHelper.format(specialEvent.startDate, 'DD')}-${DateHelper.format(specialEvent.endDate, 'DD')}`\n : DateHelper.format(specialEvent.startDate, 'DD')\n }}\n month={getSpecialEventMonthText(specialEvent)}\n theme={props.calendarTheme}\n />\n </div>\n )}\n <div>\n {specialEventIsToday && (\n <div className='rounded-pill py-1 px-2 my-1 me-1 fw-semibold bg-light-blue lh-1 d-inline-block'>\n <Text namespace={namespace} phrase='onToday' />\n </div>\n )}\n {props.showComingSoon && (\n <ComingSoonTag className='pe-2 fw-semibold mb-1 rounded-pill justify-content-start text-nowrap' />\n )}\n <div className='d-flex align-items-center'>\n {props.alignLogoLeft &&\n <div className={`${styles.logoContainerLeft} d-none d-md-block partial-loading-background rounded-circle overflow-hidden me-3`}>\n {props.logo?.url &&\n <LazyImage src={ImageHelper.createUrl(props.logo?.url, { size: ImageSize.Medium })} />}\n </div>\n }\n <h1 className={`text-white text-shadow pe-3 position-static ${styles.heading} ${getSizeClass(heading)} ${props.alignLogoLeft ? 'w-50' : ''}`}>\n {heading}\n {DetailsComponent && <DetailsComponent />}\n </h1>\n </div>\n </div>\n {!!actions && (\n <div className={styles.actionsContainer}>\n <Actions\n actions={actions}\n sortComponent={sortComponent}\n actionsDropdownClassName={props.actionsDropdownClassName}\n />\n </div>\n )}\n </div>\n {!props.alignLogoLeft && !!props.logo?.url &&\n <div className={styles.logoContainer}>\n <img\n src={ImageHelper.createUrl(props.logo.url, { size: ImageSize.Small })}\n className='rounded-circle'\n />\n </div>\n }\n </div>\n </header>,\n portalContainerContext?.container\n );\n}, (prevProps, nextProps): boolean => (\n prevProps.actions === nextProps.actions\n && prevProps.heading === nextProps.heading\n && prevProps.logo?.url === nextProps.logo?.url\n));\n\nexport function PartialBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className={`partial-banner partial-loading-background ${styles.banner}`} />,\n portalContainerContext?.container\n );\n}","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { SvgContainer, SvgContainerSize } from '../svg-container/SvgContainer';\n\nconst namespace = 'shared.breadcrumbComponent';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst COLLAPSE_CHARACTER_COUNT = 64;\nconst MAX_SEGMENT_LENGTH = 48;\n\nexport interface Breadcrumb {\n name: string;\n appLink?: Core.AppLink;\n active?: boolean;\n}\n\ninterface BreadcrumbItemProps {\n breadcrumb: Breadcrumb;\n withBackIcon?: boolean;\n}\n\nexport const BreadcrumbItem = React.forwardRef((\n props: BreadcrumbItemProps,\n ref: React.ForwardedRef<HTMLElement>\n) => {\n const { breadcrumb: { name, appLink, active }, withBackIcon } = props;\n\n let trimmedName = name;\n let title: string = null;\n\n if (trimmedName.length > MAX_SEGMENT_LENGTH) {\n trimmedName = name.slice(0, MAX_SEGMENT_LENGTH) + '...';\n\n // Only setting the title when we trim, because otherwise it's really not needed - Sha\n title = name;\n }\n\n return (\n <li\n className={`breadcrumb-item${active ? ' active' : ''}`}\n title={title}\n >\n {active\n ? <strong>{trimmedName}</strong>\n : <AppLink appLink={appLink} ref={ref}>\n {withBackIcon && <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Small} />}\n <span className={withBackIcon ? 'ms-2' : ''}>{trimmedName}</span>\n </AppLink>\n }\n </li>\n );\n});\n\ninterface BreadcrumbsProps {\n breadcrumbs: Breadcrumb[];\n}\n\nexport const Breadcrumbs = ({ breadcrumbs }: BreadcrumbsProps) => {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n const length = breadcrumbs?.length || 0;\n \n const [ collapse, setCollapse ] = React.useState(false);\n const [ shouldFocus, setShouldFocus ] = React.useState(false);\n const expandRef = React.useRef<HTMLElement>();\n\n React.useEffect(() => {\n const characterLength = breadcrumbs?.reduce((prev, next) => prev + next.name.length, 0) ?? 0;\n\n if (length > 4 && characterLength > COLLAPSE_CHARACTER_COUNT)\n setCollapse(true);\n }, [breadcrumbs?.length]);\n\n /**\n * Focus our first expanded item the first time it appears.\n */\n React.useLayoutEffect(() => {\n if (shouldFocus)\n expandRef.current?.focus();\n }, [ expandRef.current, shouldFocus ]);\n\n function onClickExpand() {\n setCollapse(false);\n setShouldFocus(true);\n }\n\n if (!length || (isMobile && length < 2))\n return <></>;\n\n if (isMobile)\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n <BreadcrumbItem breadcrumb={breadcrumbs[length - 2]} withBackIcon />\n </ol>\n </nav>\n );\n\n const first = <BreadcrumbItem breadcrumb={breadcrumbs[0]} />;\n const second = length > 2 ? <BreadcrumbItem breadcrumb={breadcrumbs[1]} /> : <></>;\n const secondLast = length > 3 ? <BreadcrumbItem breadcrumb={breadcrumbs[length - 2]} /> : <></>;\n const last = length > 1 ? <BreadcrumbItem breadcrumb={breadcrumbs[length - 1]} /> : <></>;\n const rest = breadcrumbs.slice(2, length - 2);\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {first}\n {second}\n {collapse ?\n <li className='breadcrumb-item'>\n <button\n className='btn-link'\n onClick={onClickExpand}\n aria-label={getPhrase('expand')}\n >\n ...\n </button>\n </li> :\n rest.map((breadcrumb, idx) => (\n <BreadcrumbItem\n key={idx}\n breadcrumb={breadcrumb}\n ref={idx === 0 ? expandRef : null}\n />\n ))\n }\n {secondLast}\n {last}\n </ol>\n </nav>\n );\n};\n\nexport const PartialBreadcrumbs = React.memo(function({ numItems = 3 }: { numItems?: number; }) {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n if (isMobile) {\n return (\n <div className='partial-loading-background' style={{ height: '1.3125rem', width: '6rem' }} />\n );\n }\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {PartialLoadingHelper.getPartialLoadingItems({ numItems }).map(({ width }, idx) => (\n <li key={idx} className='breadcrumb-item'>\n <span className='d-inline-block partial-loading-background' style={{ width }} dangerouslySetInnerHTML={{ __html: ' ' }} />\n </li>\n ))}\n </ol>\n </nav>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"VwD1b\",\"spinner\":\"eJ85e\"};","import * as React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { useInView } from 'react-intersection-observer';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './infinite-scroll-footer.scss';\n\ninterface InfiniteScrollFooterProps {\n isFetching: boolean;\n fetchNext?: (nextCursor: string) => void;\n nextCursor?: string;\n fetchOnScroll?: boolean;\n}\n\nInfiniteScrollFooter.defaultProps = {\n fetchOnScroll: false\n};\n\nexport function InfiniteScrollFooter(props: InfiniteScrollFooterProps): React.ReactElement {\n const [ ref, inView ] = useInView();\n\n React.useEffect(() => {\n if (!props.fetchOnScroll)\n return;\n\n if (!inView || props.isFetching)\n return;\n\n props.fetchNext?.(props.nextCursor);\n }, [ inView, props.isFetching ]);\n\n return (\n <div className={`p-3 text-center ${styles.container}`} ref={ref}>\n {props.isFetching\n ? <Spinner as='span' animation='border' role='status' className={styles.spinner} />\n : (\n <SvgContainer\n svgName={cvSvgLibrary.ChevronDown}\n className='svg-container cursor-pointer'\n size={SvgContainerSize.Large}\n onClick={() => props.fetchNext?.(props.nextCursor)}\n />\n )\n }\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialOptions\":\"Gufgq\",\"partialName\":\"SicQQ\",\"partialDescription\":\"dPGMq\",\"partialThumbnail\":\"vZrnb\",\"partialDragHandle\":\"iq73R\"};","import React from 'react';\nimport { Col, Row } from 'react-bootstrap';\n\nimport { VideoListHelper } from 'libs/shared/components/video-list/VideoListHelper';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\n\nimport styles from './partial-video-list.scss';\n\ninterface PartialVideoListProps {\n withReordering?: boolean;\n numVideos?: number;\n allowBulkActions?: boolean;\n}\n\nPartialVideoList.defaultProps = {\n numVideos: 15\n};\n\nexport function PartialVideoList(props: PartialVideoListProps): JSX.Element {\n return (\n <div className='mx-2'>\n {Array(props.numVideos).fill(null).map((_, i) => (\n <div className='d-flex' key={i}>\n {props.allowBulkActions && <div className='form-check pe-3 pe-sm-2 mx-0 mx-md-2' />}\n <PartialVideoItem {...props} />\n </div>\n ))}\n </div>\n );\n}\n\nexport function PartialVideoItem(props: PartialVideoListProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const size = VideoListHelper.getSize(breakpoints, 'md');\n const isSmall = size === 'sm';\n\n const withDragHandle = props.withReordering && !breakpoints.xs;\n\n return (\n <Row className={`${isSmall ? '' : 'py-2'} flex-grow-1`}>\n <Col {...VideoListHelper.getThumbnailColumns()} className={`flex-column align-items-flex-start ${isSmall ? `pb-2 pe-1` : 'mb-1 pe-3 pe-md-2'}`}>\n <Row>\n {!!withDragHandle && (\n <div className='d-flex align-items-center justify-content-center col-2'>\n <div className={`partial-loading-background ${styles.partialDragHandle}`} />\n </div>\n )}\n <Col xs={VideoListHelper.getThumbnailColSize(withDragHandle)}>\n <div className={`partial-loading-background ${isSmall ? 'rounded' : 'rounded-3'} ${styles.partialThumbnail}`} />\n </Col>\n </Row>\n </Col>\n <Col {...VideoListHelper.getDetailsColumns()} className={isSmall ? 'pb-2' : 'px-2'}>\n <div className={`partial-loading-background mb-1 ${styles.partialName}`} />\n <div className={`partial-loading-background ${styles.partialDescription}`} />\n </Col>\n </Row>\n );\n}\n\n","import { BaseError } from 'libs/common/backbone/core/BaseError';\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Core } from 'libs/common/core';\n\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { PrivateResourceError } from 'libs/shared/errors/general/private-resource/PrivateResourceError';\nimport { RegionLockedResourceError } from 'libs/shared/errors/general/region-locked-resource/RegionLockedResourceError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\nexport interface HttpErrorMap {\n notFound?: new () => BaseError;\n forbidden?: {\n rating?: new (description: string) => BaseError;\n yearLevel?: new (description: string) => BaseError;\n region?: new () => BaseError;\n privacy?: new (video?: VideoTypes) => BaseError;\n };\n badRequest?: new () => BaseError;\n}\n\nexport type IgnoreHttpErrorMap = {\n [key in keyof HttpErrorMap]: boolean;\n};\n\nconst defaultErrors: HttpErrorMap = {\n notFound: NotFoundError,\n forbidden: {\n rating: PrivateResourceError,\n yearLevel: PrivateResourceError,\n region: RegionLockedResourceError,\n privacy: PrivateResourceError\n },\n badRequest: UnspecifiedError\n};\n\nexport function handleHttpError(\n info: HttpStatus | Xhr,\n customErrorMap: HttpErrorMap = {},\n /**\n * Prevent certain errors in the errorMap from being thrown\n * so that you may implement your own handler\n */\n ignoreMap: IgnoreHttpErrorMap = {}\n): void {\n if (!info)\n return;\n\n let statusCode: HttpStatus;\n\n if (typeof(info) === 'number') {\n statusCode = info;\n } else {\n statusCode = info.status;\n }\n\n const errorMap = {\n ...defaultErrors,\n ...customErrorMap\n };\n\n if (!statusCode)\n return;\n\n if (!Core.ErrorHelper.isStatusCodeError(statusCode))\n return;\n\n if (statusCode === HttpStatus.NotFound) {\n if (!ignoreMap.notFound)\n Core.ErrorHelper.throw(new errorMap.notFound());\n return;\n }\n\n if (statusCode === HttpStatus.Forbidden) {\n /**\n * TODO: Work out how to go about handling all forbidden errors, such as region locking, year levels,\n * ratings, and privacy.\n */\n if (!ignoreMap.forbidden)\n Core.ErrorHelper.throw(new errorMap.forbidden.privacy());\n return;\n }\n\n if (!ignoreMap.badRequest)\n Core.ErrorHelper.throw(new errorMap.badRequest());\n}\n\nexport function handleXhrError(xhr: Xhr, customErrorMap?: HttpErrorMap): void {\n handleHttpError(xhr.status, customErrorMap);\n}","import { useEffect } from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { handleHttpError, HttpErrorMap, IgnoreHttpErrorMap } from 'libs/shared/errors/handlers/HttpErrorHandlers';\n\nfunction generateCacheKey(flightObjs: Array<Flight.Response<any>>): string {\n return flightObjs.map(obj => obj.statusCode).join(':');\n}\n\n// TODO: Change this to just `useHandleHttpError` and only accept a status code.\nexport function useHandleObjectError(\n _flightObjs: Flight.Response<any> | Array<Flight.Response<any>>,\n customErrors?: HttpErrorMap,\n ignoreErrors?: IgnoreHttpErrorMap\n): void {\n const flightObjs = Array.isArray(_flightObjs) ? _flightObjs : [_flightObjs];\n\n useEffect(() => {\n flightObjs.forEach(obj => {\n handleHttpError(obj.statusCode, customErrors, ignoreErrors);\n });\n }, [ generateCacheKey(flightObjs), customErrors, ignoreErrors ]);\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}","import React from 'react';\n\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BreadcrumbService } from 'libs/shared/services/BreadcrumbService';\n\nexport function useBreadcrumbs(current: Breadcrumb): Breadcrumb[] {\n const [ match, useBuilder ] = React.useMemo(() => BreadcrumbService.getBuilder(), []);\n\n const breadcrumbs = useBuilder(match);\n\n if (!breadcrumbs || !current)\n return breadcrumbs;\n\n return [ ...breadcrumbs, { ...current, active: true }];\n}\n\n","const DEFAULT_PARTIAL_LOADING_OPTIONS: PartialLoadingOptions = {\n numItems: 5,\n minWidth: 50, // px\n maxWidth: 100 // px\n};\n\nexport interface PartialLoadingOptions {\n numItems?: number;\n minWidth?: number;\n maxWidth?: number;\n}\n\ninterface PartialLoadingItem {\n width: string;\n}\n\nexport const PartialLoadingHelper = {\n getPartialLoadingItems(options: PartialLoadingOptions = {}): PartialLoadingItem[] {\n const opts = {\n ...DEFAULT_PARTIAL_LOADING_OPTIONS,\n ...options\n };\n\n const getRandomFilterWidth = () => Math.max(Math.floor(Math.random() * opts.maxWidth), opts.minWidth);\n\n return [...Array(opts.numItems)].map(() => ({ width: `${getRandomFilterWidth()}px` }));\n }\n};","import { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { BaseObject, CurrentUser, Playlist } from 'libs/shared/interfaces';\n\nexport const PlaylistHelper = {\n isPlaylist(obj: BaseObject): obj is Playlist {\n return obj?.typeId === MasterType.Playlist;\n },\n\n isOwner(playlist: Playlist, currentUser: CurrentUser): boolean {\n if (!currentUser || !playlist || ObjectHelper.isEmpty(playlist._liteOwner))\n return false;\n\n return playlist._liteOwner.id.toString() === currentUser.id?.toString();\n },\n\n getVideoCount(playlist: Playlist): number {\n if (!playlist)\n return;\n\n let count = 0;\n\n if (playlist.videos?.count)\n count += playlist.videos.count;\n\n if (playlist.clips?.count)\n count += playlist.clips.count;\n\n if (playlist.interactives?.count)\n count += playlist.interactives.count;\n\n return count;\n }\n};","import React from 'react';\n\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { PlaylistHelper } from 'libs/shared/apps/playlists/utils/PlaylistHelper';\nimport { ClickViewAvatar } from 'libs/shared/components/clickview-avatar/ClickViewAvatar';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { CurrentUser, Playlist } from 'libs/shared/interfaces';\n\nconst namespace = 'playlists.playlistHeaderDetails';\n\nconst Separator = ({ className }: { className: string }) =>\n <span className={className}>•</span>;\n\nfunction getPlaylistOwnerName(playlist: Playlist): string {\n const { _liteOwner } = playlist;\n\n if (!_liteOwner)\n return;\n\n if (_liteOwner.name && _liteOwner.surname)\n return TextHelper.toTitleCase(_liteOwner.name + ' ' + _liteOwner.surname.substring(0, 1));\n\n if (_liteOwner.name)\n return _liteOwner.name.split(' ')[0];\n}\n\nfunction getLastUpdated(playlist: Playlist): string {\n if (!playlist.contentModifiedDate)\n return '';\n\n const now = new Date();\n const lastUpdated = DateHelper.convertUTCToLocal(playlist.contentModifiedDate);\n\n // Don't show if last updated over a month ago\n if (DateHelper.isBefore(lastUpdated, DateHelper.subtract(now, 1, 'month')))\n return '';\n\n return DateHelper.fromNow(lastUpdated);\n}\n\ninterface PlaylistHeaderDetailsProps {\n playlist: Playlist;\n currentUser: CurrentUser;\n totalVideos: number;\n \n hideOwnerName?: boolean;\n\n // Custom classes for everything as online and lite use different styles\n detailsClassName: string;\n clickViewAvatarClassName: string;\n separatorClassName: string;\n}\n\nexport function PlaylistHeaderDetails(props: PlaylistHeaderDetailsProps): React.ReactElement {\n const currentUserIsOwner = PlaylistHelper.isOwner(props.playlist, props.currentUser);\n\n const followerCount = props.playlist.followers?.count;\n\n const lastUpdated = getLastUpdated(props.playlist);\n\n return (\n <div className={props.detailsClassName}>\n {/* Owner name */}\n {(!props.hideOwnerName && !currentUserIsOwner) && (\n <>\n {props.playlist._isClickViewCurated?.value ? (\n <>\n <div className={props.clickViewAvatarClassName}>\n <ClickViewAvatar />\n </div>\n <span>ClickView</span>\n </>\n ) : (\n <Text namespace={namespace} phrase='createdBy' options={{ user: getPlaylistOwnerName(props.playlist) }} />\n )}\n\n <Separator className={props.separatorClassName} />\n </>\n )}\n\n {/* Video count */}\n {typeof props.totalVideos === 'number' && (\n <Text namespace={namespace} phrase='videos' options={{ smartCount: props.totalVideos }} />\n )}\n\n {/* Follower count */}\n {followerCount > 0 && (\n <>\n <Separator className={props.separatorClassName} />\n <Text namespace={namespace} phrase='followers' options={{ smartCount: followerCount }} />\n </>\n )}\n\n {/* Last updated */}\n {!!lastUpdated && (\n <>\n <Separator className={props.separatorClassName} />\n <Text namespace={namespace} phrase='lastUpdated' options={{ timeAgo: lastUpdated }} />\n </>\n )}\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialDescription\":\"vDX0m\"};","import React from 'react';\n\nimport { PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\n\nimport styles from './partial-playlist-header.scss';\n\nexport function PartialPlaylistHeader(): JSX.Element {\n return (\n <>\n <PartialBannerHeader />\n <div className='mb-2'>\n <div className={`partial-loading-background my-2 border-bottom ${styles.partialDescription}`} />\n </div>\n </>\n );\n}","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, EventVersion, LocationContext, ToggleDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { PlaylistHelper } from 'libs/shared/apps/playlists/utils/PlaylistHelper';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { getOpenInCurationStudioLabel } from 'libs/shared/hooks/useCurationStudio';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { PlaylistHeaderProps } from './PlaylistHeader';\n\nconst namespace = 'playlists.playlistHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface GetPlaylistActionsArgs {\n isAuthenticated: boolean;\n isPlugin: boolean;\n isMobile: boolean;\n setIsFollowing: (val: boolean) => void;\n isFollowing: boolean;\n setShowFollowSpinner: (val: boolean) => void;\n showFollowSpinner: boolean;\n isUserCurator: boolean;\n openInCuratorLink: string;\n}\n\nexport const PlaylistHeaderUtils = {\n getPlaylistActions(headerProps: PlaylistHeaderProps, args: GetPlaylistActionsArgs): ActionOptions[] {\n const {\n isAuthenticated,\n isPlugin,\n isMobile,\n setIsFollowing,\n isFollowing,\n setShowFollowSpinner,\n showFollowSpinner,\n isUserCurator,\n openInCuratorLink\n } = args;\n\n const analyticsData = {\n id: headerProps.playlist.id,\n name: headerProps.playlist.name,\n followerCount: headerProps.playlist.followers?.count,\n videoCount: headerProps.playlist.videos?.count,\n interactiveCount: headerProps.playlist.interactives?.count,\n clipCount: headerProps.playlist.clips?.count,\n isClickViewPlaylist: headerProps.playlist._isClickViewCurated?.value\n };\n\n const analyticsOptions: AnalyticsOptions = {\n location: LocationContext.Banner,\n entity: EntityType.Playlist,\n workflowPhase: WorkflowPhase.Start\n };\n\n const actions: ActionOptions[] = [];\n\n if (!isAuthenticated)\n return actions;\n\n const isOwner = PlaylistHelper.isOwner(headerProps.playlist, headerProps.currentUser);\n\n if (!isPlugin) {\n if (headerProps.playAllAppLink) {\n actions.push({\n label: getPhrase('playAll'),\n appLink: headerProps.playAllAppLink,\n svgName: cvSvgLibrary.Play,\n className: !isMobile ? 'btn btn-outline-dark me-2' : '',\n button: !isMobile,\n analyticsData,\n analyticsOptions: {\n ...analyticsOptions,\n actionType: UserAction.Play\n }\n });\n }\n\n if (isUserCurator)\n actions.push({\n label: getOpenInCurationStudioLabel(),\n href: openInCuratorLink,\n openInNewTab: true\n });\n\n actions.push({\n label: getPhrase('share'),\n appLink: {\n application: AppChannels.DEFAULT,\n action: Actions.Default.SHARE,\n args: [headerProps.playlist.id],\n params: { entityType: 'playlist' }\n },\n svgName: cvSvgLibrary.Share2,\n className: !isMobile ? 'btn btn-outline-dark me-2' : '',\n button: !isMobile,\n analyticsData,\n analyticsOptions: {\n ...analyticsOptions,\n actionType: UserAction.Share,\n eventVersion: EventVersion.V3\n }\n });\n }\n\n if (!isOwner) {\n actions.push({\n label: getPhrase(isFollowing ? 'following' : 'follow'),\n onClick: () => {\n setIsFollowing(!isFollowing);\n setShowFollowSpinner(true);\n headerProps.follow(\n !isFollowing,\n () => {\n setShowFollowSpinner(false);\n AnalyticsHelper.logUserAction(analyticsData, {\n ...analyticsOptions,\n actionType: UserAction.Follow,\n descriptor: isFollowing ? ToggleDescriptor.Off : ToggleDescriptor.On,\n workflowPhase: WorkflowPhase.Complete\n });\n },\n () => {\n setShowFollowSpinner(false);\n setIsFollowing(isFollowing);\n }\n );\n },\n svgName: isFollowing ? cvSvgLibrary.BellFilled : cvSvgLibrary.Bell,\n className: !isMobile\n ? `btn follow-btn btn-${isFollowing ? 'outline-dark' : 'dark'} me-2`\n : '',\n button: !isMobile,\n showSpinner: showFollowSpinner\n });\n }\n\n if (isOwner) {\n actions.push({\n label: getPhrase('edit'),\n appLink: {\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.EDIT_PLAYLIST,\n args: [headerProps.playlist.id]\n },\n svgName: cvSvgLibrary.Edit,\n button: false,\n analyticsData,\n analyticsOptions: {\n ...analyticsOptions,\n actionType: UserAction.Edit\n }\n });\n\n actions.push({\n label: getPhrase('delete'),\n appLink: {\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.DELETE_PLAYLIST,\n args: [headerProps.playlist.id]\n },\n svgName: cvSvgLibrary.Delete,\n className: 'text-danger',\n button: false,\n analyticsData,\n analyticsOptions: {\n ...analyticsOptions,\n actionType: UserAction.Delete\n }\n });\n }\n\n if (headerProps.playlist._isClickViewCurated?.value) {\n actions.push({\n label: getPhrase('copy'),\n appLink: {\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.COPY_PLAYLIST,\n args: [headerProps.playlist.id]\n },\n button: false,\n analyticsData,\n analyticsOptions: {\n ...analyticsOptions,\n actionType: UserAction.Copy\n }\n });\n }\n\n return actions;\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"clickViewAvatar\":\"PHe9c\"};","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { PlaylistHeaderDetails } from 'libs/shared/apps/playlists/components/playlist-header-details/PlaylistHeaderDetails';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs, PartialBreadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { Classification, CurrentUser, Playlist } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\n\nimport { PartialPlaylistHeader } from './partial-loading/PartialPlaylistHeader';\nimport { PlaylistHeaderUtils } from './PlaylistHeaderUtils';\n\nimport styles from './playlist-header.scss';\n\nexport interface PlaylistHeaderProps {\n playlist: Playlist;\n currentUser: CurrentUser;\n isFollowing: boolean;\n follow: (shouldFollow: boolean, onSuccess: () => void, onError: () => void) => void;\n imageCdnUrl: string;\n showPartialLoading: boolean;\n playAllAppLink: Core.AppLink;\n isUserCurator: boolean;\n openInCuratorLink: string;\n\n // For breadcrumbs\n getBreadcrumbs: () => Breadcrumb[];\n topicPath: Classification[];\n moviesAndTv: boolean;\n classificationId: string;\n totalVideos: number;\n}\n\nexport function PlaylistHeader(props: PlaylistHeaderProps): JSX.Element {\n const { isPlugin } = usePluginHelper();\n\n // Store isFollowing in local state so that it updates immediately.\n const [ isFollowing, setIsFollowing ] = React.useState(props.isFollowing);\n const [ showFollowSpinner, setShowFollowSpinner ] = React.useState(false);\n\n React.useEffect(() => setIsFollowing(props.isFollowing), [props.isFollowing]);\n\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n if (props.showPartialLoading)\n return <PartialPlaylistHeader />;\n\n const description = props.playlist.description;\n\n const actions: ActionOptions[] = PlaylistHeaderUtils.getPlaylistActions(props, {\n isAuthenticated: props.currentUser.isAuthenticated,\n isPlugin,\n isMobile,\n setIsFollowing,\n isFollowing,\n setShowFollowSpinner,\n showFollowSpinner,\n isUserCurator: props.isUserCurator,\n openInCuratorLink: props.openInCuratorLink\n });\n\n const breadcrumbs = props.getBreadcrumbs();\n\n return (\n <>\n <BannerHeader\n heading={props.playlist.name}\n banner={props.playlist.banner}\n imageCdnUrl={props.imageCdnUrl}\n actions={actions.length && actions}\n actionsDropdownClassName='btn btn-outline-dark'\n blockColourClass={getBgColorClass(props.playlist.name, BG_COLOUR_CLASS_NAMES)}\n detailsComponent={() => (\n <PlaylistHeaderDetails\n playlist={props.playlist}\n currentUser={props.currentUser}\n detailsClassName='mb-n1 font-size-normal fw-normal mt-1'\n clickViewAvatarClassName={styles.clickViewAvatar}\n separatorClassName='mx-1'\n totalVideos={props.totalVideos}\n />\n )}\n />\n {(!!description || !!breadcrumbs?.length) && (\n <div className='border-bottom py-3'>\n {(() => {\n if (!props.playlist || (props.classificationId && !props.topicPath))\n return <PartialBreadcrumbs />;\n\n return (\n <div className='pb-2'>\n <Breadcrumbs breadcrumbs={breadcrumbs} />\n </div>\n );\n })()}\n {!!description && <p className='mb-0'>{description}</p>}\n </div>\n )}\n </>\n );\n}\n","import * as React from 'react';\nimport { DragEndEvent, DragStartEvent } from '@dnd-kit/core';\n\nimport { DevError } from 'libs/common/backbone/errors/DevError';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Core } from 'libs/common/core';\n\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { PartialVideoList } from 'libs/shared/components/video-list/partial-loading/PartialVideoList';\nimport { SortableVideoList, VideoList, VideoListProps } from 'libs/shared/components/video-list/VideoList';\nimport { YearGroup } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface SortableVideoListContainerProps extends VideoListProps {\n playlistId: string;\n yearGroups: YearGroup[];\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n onSortStart?: (index: number) => void;\n canEdit?: boolean;\n showPartialLoading?: boolean;\n fetchRestrictions?: () => void;\n showSignIn?: boolean;\n}\n\nexport function SortableVideoListContainer(props: SortableVideoListContainerProps): React.ReactElement {\n const { onSortComplete, onSortStart, showPartialLoading, ...videoListProps } = props;\n\n const [ currentSortingIndex, setCurrentSortingIndex ] = React.useState<number>();\n\n const onSortStartHandler = (event: DragStartEvent) => {\n const index = props.videos.findIndex(v => v.id.toString() === event.active.id.toString());\n\n setCurrentSortingIndex(index);\n\n if (FunctionHelper.isFunction(onSortStart))\n onSortStart(index);\n };\n\n const onSortEnd = (event: DragEndEvent) => {\n setCurrentSortingIndex(null);\n\n const { active, over } = event;\n \n const oldIndex = props.videos.findIndex(v => v.id.toString() === active.id.toString());\n const newIndex = props.videos.findIndex(v => v.id.toString() === over.id.toString());\n\n if (!FunctionHelper.isFunction(onSortComplete)) {\n Core.ErrorHelper.throw(new DevError('An onSortComplete callback function must be passed to SortableVideoListComponent'));\n return;\n }\n \n onSortComplete(oldIndex, newIndex);\n };\n\n if (showPartialLoading)\n return <PartialVideoList withReordering={props.canEdit || props.showIndexes} />;\n\n if (!props.canEdit)\n return <VideoList {...videoListProps} />;\n\n return (\n <SortableVideoList\n {...videoListProps}\n currentSortingIndex={currentSortingIndex}\n onSortStart={onSortStartHandler}\n onSortEnd={onSortEnd}\n dragHandleIcon={cvSvgLibrary.Hamburger}\n dragHandleIconSize={SvgContainerSize.XXL}\n presentationAudiences={props.presentationAudiences}\n />\n );\n}","import React from 'react';\n\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';\n\nconst namespace = 'playlists.playlistEmptyState';\n\nexport function PlaylistEmptyState(): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={ImageUrls.EmptyStates.Playlists.PLAYLIST_VIDEOS} />\n\n <EmptyState.Heading><Text phrase='heading' /></EmptyState.Heading>\n\n <EmptyState.Info><Text phrase='info' /></EmptyState.Info>\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AssocDescriptor, EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { PlaylistHelper } from 'libs/shared/apps/playlists/utils/PlaylistHelper';\nimport { VideoActionsOptions } from 'libs/shared/context/VideoActionsContext';\nimport { CurrentUser, Playlist, Video, VideoTypes } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { PlaylistNotFoundError } from 'shared/errors/playlists/playlist-not-found/LitePlaylistNotFoundError';\nimport { PlaylistPrivateError } from 'shared/errors/playlists/playlist-private/PlaylistPrivateError';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\n\nconst getPhrase = LanguageService.encloseNamespace('playlists.playlist');\n\n/**\n * NOTE:\n * This will be wrong if we increase the playlist limit from 100, or\n * stop fetching all 100 videos at once.\n */\nexport function getLastUpdatedDate(videos: Video[]): string {\n const videoLastUpdatedDates: string[] = videos && videos.length && videos.map(v => v.dateAssociated);\n\n return (videoLastUpdatedDates && videoLastUpdatedDates.length)\n ? ArrayHelper.max<string, number>(videoLastUpdatedDates, (date: string) => new Date(date).getTime())\n : null;\n}\n\nexport function usePlaylistViewVideoActions(\n playlist: Playlist,\n currentUser: CurrentUser,\n shareId: string\n) {\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem, shareId });\n\n if (!PlaylistHelper.isOwner(playlist, currentUser))\n return videoActions;\n\n const getVideoActions = (video: VideoTypes, options?: VideoActionsOptions) => {\n const { canConsume } = VideoHelper.getCanBeConsumed(video);\n\n const removeFromPlaylistAction = {\n label: getPhrase('removeFromPlaylist'),\n button: false,\n svgName: cvSvgLibrary.Delete,\n appLink: {\n application: AppChannels.PLAYLISTS,\n action: Actions.Playlists.REMOVE_VIDEO_FROM_PLAYLIST,\n args: [ video.id, playlist.id ],\n params: { typeId: video.typeId }\n },\n className: 'text-danger',\n analyticsOptions: {\n entity: EntityType.Video,\n actionType: UserAction.Dissociate,\n location: LocationContext.VideoListItem,\n workflowPhase: WorkflowPhase.Start,\n descriptor: AssocDescriptor.Playlist\n },\n analyticsData: {\n id: video.id,\n playlistId: playlist.id\n },\n group: 'delete'\n };\n\n if (!canConsume)\n return [removeFromPlaylistAction];\n\n return [ ...videoActions.getVideoActions(video, options), removeFromPlaylistAction ];\n };\n\n return {\n ...videoActions,\n getVideoActions\n };\n}\n\nexport function logSortAction(playlistId: string, videoId: string, workflowPhase: WorkflowPhase): void {\n AnalyticsHelper.logUserAction({ id: videoId, playlistId }, {\n location: LocationContext.VideoList,\n entity: EntityType.Video,\n actionType: UserAction.Move,\n workflowPhase\n });\n}\n\nexport const playlistErrors = {\n notFound: PlaylistNotFoundError,\n forbidden: {\n privacy: PlaylistPrivateError\n }\n};","import * as React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\n\nimport { LocationContext, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { PlaylistHelper } from 'libs/shared/apps/playlists/utils/PlaylistHelper';\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\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 { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useBreadcrumbs } from 'libs/shared/hooks/useBreadcrumbs';\nimport { useCurationStudio } from 'libs/shared/hooks/useCurationStudio';\nimport { useHandleObjectError } from 'libs/shared/hooks/UseHandleObjectError';\nimport { useInfiniteList } from 'libs/shared/hooks/UseInfiniteList';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useReorderedItems } from 'libs/shared/hooks/UseReorderedItems';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Classification, Config, Following, OnlineCurrentUser, Playlist, Presentation, PresentationAudience, Series, VideoTypes, YearGroup } from 'libs/shared/interfaces';\nimport { GetVideoAppLinkOptions } from 'libs/shared/interfaces/VideoAppLinkOptions';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\nimport { ReorderHelper } from 'libs/shared/utils/ReorderHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { useVideoMixin } from 'shared/hooks/useVideoMixin';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { PlaylistHeader } from 'apps/playlists/components/playlist-header/PlaylistHeader';\nimport { SortableVideoListContainer } from 'apps/playlists/components/video-list/SortableVideoListContainer';\n\nimport { PlaylistEmptyState } from './empty-state/PlaylistEmptyState';\nimport { logSortAction, playlistErrors, usePlaylistViewVideoActions } from './PlaylistViewUtils';\n\nconst namespace = 'playlists.playlist';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PlaylistViewProps {\n playlistId: string;\n shareId?: string;\n classificationId?: string;\n getSeriesAppLink: (series: Series) => Core.AppLink;\n moviesAndTv?: boolean;\n hideBreadCrumbs?: boolean;\n}\n\nexport function PlaylistView(props: PlaylistViewProps): React.ReactElement {\n const dispatch = useDispatch();\n const alerts = useAlerts();\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<OnlineCurrentUser>(UserRequests.currentUser());\n const { isUserCurator, getOpenInCurationStudioLink } = useCurationStudio();\n const { hasPermissions } = usePermissions();\n const { isPlugin } = usePluginHelper();\n\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n const topicPath = Flight.useBasicFetch<Classification[]>(\n props.classificationId &&\n ClassificationRequests.path(props.classificationId)\n );\n\n const classification = Flight.useBasicFetch<Classification>(\n props.classificationId &&\n ClassificationRequests.classification(props.classificationId, currentUser.data?.id)\n );\n\n const classificationPresentation = Flight.useBasicFetch<Presentation>(\n classification.hasCompleted &&\n ClassificationRequests.presentationById(classification.data?.presentationId)\n );\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n (!props.classificationId || classificationPresentation.hasCompleted) &&\n AudienceRequests.presentationAudiences(classificationPresentation.data?.id)\n );\n\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.VideoThumbnail);\n\n const playlistRequest = props.shareId\n ? PlaylistRequests.getSharedPlaylist(props.playlistId, props.shareId)\n : PlaylistRequests.getPlaylist(props.playlistId);\n\n const playlistItemCountRequest = props.shareId\n ? PlaylistRequests.getSharedPlaylistVideosCount(props.playlistId, props.shareId)\n : PlaylistRequests.getPlaylistVideosCount(props.playlistId);\n\n const playlist = Flight.useBasicFetch<Playlist>(playlistRequest);\n const playlistWithCounts = Flight.useBasicFetch<Playlist>(playlistItemCountRequest);\n\n const getVideoItemActions = usePlaylistViewVideoActions(playlist.data, currentUser.data, props.shareId);\n\n useHandleObjectError(playlist, playlistErrors);\n\n const getVideosRequest = (cursor?: string) => {\n return props.shareId\n ? PlaylistRequests.getSharedPlaylistVideos(props.playlistId, props.shareId, cursor)\n : PlaylistRequests.getPlaylistVideos(props.playlistId, cursor);\n };\n\n const following = Flight.useBasicFetch<Following>(\n currentUser.data?.id &&\n PlaylistRequests.getIsFollowingPlaylist(props.playlistId, currentUser.data?.id)\n );\n\n const fetchNext = (cursor?: string) => {\n Flight.getFetch(dispatch)(getVideosRequest(cursor));\n };\n\n const { items: videos, hasMore, isFetching } = useInfiniteList<VideoTypes>(getVideosRequest, fetchNext);\n\n useVideoMixin(videos);\n\n // Locally stored array of videos used to immediately reflect changes in order.\n const [ reorderedVideos, setReorderedVideos ] = useReorderedItems(videos);\n\n useDeepLinks({ id: props.playlistId, app: 'playlists', shareId: props.shareId });\n useSetPageMetadata(PageMetadataHelper.getPlaylistMetadata({\n content: playlist.data,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n canonicalLink: SeoHelper.getCanonicalLink({ stripPresentationSlug: true }),\n allowIndexing: false\n }));\n\n const onSortStart = (index: number) => {\n const video = videos[index];\n\n if (video)\n logSortAction(props.playlistId, video.id, WorkflowPhase.Start);\n };\n\n const onSortComplete = (oldIdx: number, newIdx: number) => {\n if (oldIdx === newIdx)\n return;\n\n const video = videos[oldIdx];\n\n if (!video)\n return;\n\n const { reorderedItems, reorderRequest } = ReorderHelper.reorder(videos, oldIdx, newIdx);\n setReorderedVideos(reorderedItems);\n\n logSortAction(props.playlistId, video.id, WorkflowPhase.Complete);\n\n const onError = () => {\n setReorderedVideos(null);\n };\n\n Flight.fetch(dispatch, PlaylistRequests.reorderVideos(props.playlistId, reorderRequest, null, onError));\n };\n\n const follow = (shouldFollow: boolean, onSuccess: () => void, onError: () => void) => {\n const req = shouldFollow\n ? PlaylistRequests.followPlaylist\n : PlaylistRequests.unfollowPlaylist;\n\n const error = () => {\n onError();\n alerts.error(getPhrase(shouldFollow ? 'followError' : 'unfollowError'));\n };\n\n Flight.fetch(dispatch, req(props.playlistId, currentUser.data?.id, onSuccess, error));\n };\n\n const playlistIsEmpty = !!videos && videos.length === 0;\n\n const getVideoAppLink = (video: VideoTypes, playNext: boolean, options: GetVideoAppLinkOptions = {}) => {\n return VideoAppLinkHelper.getAppLink(video, {\n ...options,\n contextId: props.playlistId,\n context: RelatedVideosContext.Playlist,\n shareId: props.shareId,\n moviesAndTv: props.moviesAndTv,\n playNext\n });\n };\n\n const isFollowingComplete = !currentUser.data?.isAuthenticated || !!following.hasCompleted;\n\n // The play all applink should start from the first consumable video\n const firstPlayAllVideo = videos?.find(v => VideoHelper.getCanBeConsumed(v)?.canConsume);\n const canEdit = PlaylistHelper.isOwner(playlist.data, currentUser.data);\n\n const videoDataLoaded = (\n videos && currentUser.data && config.data\n );\n\n const getSignInAppLink = (appLink: Core.AppLink): Core.AppLink => {\n const redirectUrl = Core.AppLinkHelper.getHref(appLink);\n const params = redirectUrl !== '/' ? { redirectUrl } : {};\n \n return {\n application: AppChannels.DEFAULT,\n action: Actions.Default.CHALLENGE,\n params\n };\n };\n\n const breadcrumbs = useBreadcrumbs({ name: playlist.data?.name });\n\n return (\n <VideoActionsContext.Provider value={currentUser.data?.isAuthenticated && getVideoItemActions}>\n <div className='bg-white px-3'>\n <PlaylistHeader\n playlist={playlist.data}\n currentUser={currentUser.data}\n isFollowing={following.data?.isFollowing}\n follow={follow}\n playAllAppLink={firstPlayAllVideo && getVideoAppLink(firstPlayAllVideo, true)}\n showPartialLoading={!playlist.data || !videoDataLoaded || !isFollowingComplete}\n imageCdnUrl={!!config.data && config.data.imageCdnUrl}\n getBreadcrumbs={() => props.hideBreadCrumbs ? null : breadcrumbs}\n topicPath={topicPath.data}\n moviesAndTv={props.moviesAndTv}\n classificationId={props.classificationId}\n isUserCurator={isUserCurator}\n openInCuratorLink={getOpenInCurationStudioLink(playlist.data?.typeId, playlist.data?.id)}\n totalVideos={PlaylistHelper.getVideoCount(playlistWithCounts.data)}\n />\n <div className='mt-2'>\n {!playlistIsEmpty\n ? (\n <SortableVideoListContainer\n videos={reorderedVideos || videos}\n yearGroups={yearGroups.data}\n playlistId={!!playlist.data && playlist.data.id}\n onSortStart={onSortStart}\n onSortComplete={onSortComplete}\n canEdit={canEdit}\n showPartialLoading={!videoDataLoaded}\n getVideoAppLink={(v, opts) => getVideoAppLink(v, false, opts)}\n getSubTextAppLink={video => props.getSeriesAppLink(video.series)}\n setFavourite={setFavourite}\n canFavourite={canFavourite}\n showSignIn={!currentUser.data?.isAuthenticated}\n getSignInAppLink={getSignInAppLink}\n canRemovePrivateVideos={canEdit}\n presentationAudiences={props.moviesAndTv ? null : audiences.data}\n showIndexes={true}\n hasPermissions={hasPermissions}\n getPreviewQuestionsAppLink={interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)}\n imageCdnUrl={config.data?.imageCdnUrl}\n isPlugin={isPlugin}\n getClassroomGuideAppLink={VideoAppLinkHelper.getClassroomGuideAppLink}\n getInteractiveGuidanceAppLink={VideoAppLinkHelper.getInteractiveGuidanceAppLink}\n getResourceGuidanceAppLink={VideoAppLinkHelper.getResourceGuidanceAppLink}\n />\n ) : <PlaylistEmptyState />\n }\n </div>\n {(hasMore || isFetching) && <InfiniteScrollFooter isFetching={isFetching} fetchNext={fetchNext} />}\n </div>\n </VideoActionsContext.Provider>\n );\n}\n","import { useEffect, useState } from 'react';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nfunction isOrderEqual(arr1: BaseObject[], arr2: BaseObject[]): boolean {\n let isEqual = true;\n\n if (arr1.length !== arr2.length)\n return false;\n\n for (let i = 0; i < arr1.length; i++) {\n if (arr1[i].id !== arr2[i].id) {\n isEqual = false;\n break;\n }\n }\n\n return isEqual;\n}\n\n/**\n * This function can be used to temporarily store an array of reordered objects\n * until the array obtained from the application store updates to the new order.\n * \n * @param items array of objects from application store.\n */\nexport function useReorderedItems<T extends BaseObject>(\n items: T[]\n): [ T[], React.Dispatch<React.SetStateAction<T[]>> ] {\n const [ reorderedItems, setReorderedItems ] = useState<T[]>();\n\n useEffect(() => {\n if (!reorderedItems)\n return;\n\n if (items.length !== reorderedItems.length || isOrderEqual(items, reorderedItems))\n setReorderedItems(null);\n }, [items]);\n\n return [ reorderedItems, setReorderedItems ];\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { Clip, ClipCollection, CurrentUser, Video, VideoCollection } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nconst CHUNK_SIZE = 50;\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 = {}): void {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const hydratedVideos = React.useRef<Set<string>>(new Set<string>());\n\n const videos = getValidObjects(objects);\n\n const videoIds = videos.map(v => v.id);\n\n const [ request, setRequest ] = React.useState<Flight.Request[]>([]);\n\n React.useEffect(() => {\n if (!videoIds?.length || !currentUser.hasCompleted)\n return;\n\n const unhydratedVideos: string[] = [];\n\n videoIds.forEach(id => {\n if (!hydratedVideos.current.has(id)) {\n unhydratedVideos.push(id);\n hydratedVideos.current.add(id);\n }\n });\n \n if (!unhydratedVideos.length)\n return;\n\n setRequest(r => {\n const newRequests = [...r] ;\n\n ArrayHelper.chunk<string>(unhydratedVideos, CHUNK_SIZE).forEach(chunk => {\n newRequests.push(VideoRequests.videoMixinAssocs(chunk, options.flightNamespace));\n\n if (currentUser.data?.isAuthenticated)\n newRequests.push(ClassificationRequests.hasCurriculumLinks(chunk, null, options.flightNamespace));\n });\n\n return newRequests;\n });\n }, [ videoIds?.length, currentUser.hasCompleted ]);\n\n Flight.useBasicFetchAll(request);\n}","\"use client\";\n\nimport classNames from 'classnames';\nimport * as React from 'react';\nimport { useBootstrapPrefix, useBootstrapBreakpoints, useBootstrapMinBreakpoint } from './ThemeProvider';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst Row = /*#__PURE__*/React.forwardRef(({\n bsPrefix,\n className,\n // Need to define the default \"as\" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595\n as: Component = 'div',\n ...props\n}, ref) => {\n const decoratedBsPrefix = useBootstrapPrefix(bsPrefix, 'row');\n const breakpoints = useBootstrapBreakpoints();\n const minBreakpoint = useBootstrapMinBreakpoint();\n const sizePrefix = `${decoratedBsPrefix}-cols`;\n const classes = [];\n breakpoints.forEach(brkPoint => {\n const propValue = props[brkPoint];\n delete props[brkPoint];\n let cols;\n if (propValue != null && typeof propValue === 'object') {\n ({\n cols\n } = propValue);\n } else {\n cols = propValue;\n }\n const infix = brkPoint !== minBreakpoint ? `-${brkPoint}` : '';\n if (cols != null) classes.push(`${sizePrefix}${infix}-${cols}`);\n });\n return /*#__PURE__*/_jsx(Component, {\n ref: ref,\n ...props,\n className: classNames(className, decoratedBsPrefix, ...classes)\n });\n});\nRow.displayName = 'Row';\nexport default Row;"],"names":["PortalHelper","renderInPortalIfExists","component","portalContainer","createPortal","namespace","ComingSoonTag","props","Tooltip","title","LanguageService","spanHackClassName","spanHack","className","SvgContainer","svgName","onlyIcon","GenericCalendarDate","AppLink","appLink","getAppLink","theme","border","analyticsData","analyticsOptions","background","label","body","type","getBodyClass","text","month","BackButton","textShadow","backToName","color","extraClasses","backPhrase","colorClass","textShadowClass","size","S","defaultProps","RATIO","width","height","getSizeClass","heading","length","BannerHeader","banner","imageCdnUrl","actions","sortComponent","blockColourClass","specialEvent","portalContainerContext","BannerPortalContext","imageWidth","useBreakpoints","xxl","specialEventIsToday","showComingSoon","today","DateHelper","Date","endDate","startDate","imageOptions","ratio","resizeType","url","ImageHelper","fallbackBaseUrl","fallbackCategoryName","containerProps","bannerClassName","style","backgroundImage","DetailsComponent","detailsComponent","backButtonAppLink","backButtonText","backButtonClasses","alignLogoLeft","logo","getSpecialEventMonthText","calendarTheme","Text","phrase","LazyImage","src","Actions","actionsDropdownClassName","container","prevProps","nextProps","PartialBannerHeader","getPhrase","BreadcrumbItem","ref","breadcrumb","name","active","withBackIcon","trimmedName","slice","Breadcrumbs","breadcrumbs","isMobile","collapse","setCollapse","shouldFocus","setShouldFocus","expandRef","characterLength","reduce","prev","next","current","focus","first","second","secondLast","last","rest","onClick","map","idx","key","PartialBreadcrumbs","numItems","dangerouslySetInnerHTML","__html","InfiniteScrollFooter","inView","fetchOnScroll","isFetching","fetchNext","nextCursor","Spinner","as","animation","role","PartialVideoList","Array","numVideos","fill","_","i","allowBulkActions","PartialVideoItem","breakpoints","isSmall","VideoListHelper","withDragHandle","withReordering","xs","Row","Col","defaultErrors","notFound","forbidden","rating","yearLevel","region","privacy","badRequest","handleHttpError","info","customErrorMap","ignoreMap","statusCode","status","errorMap","generateCacheKey","flightObjs","obj","join","useHandleObjectError","_flightObjs","customErrors","ignoreErrors","isArray","useEffect","forEach","SCROLL_TOLERANCE","useInfiniteList","getRequest","onError","getItems","getCursor","scrollContainer","options","handleScroll","useState","pagesFetched","setPagesFetched","fetchNextFn","response","cursor","request","fetchNextPage","currentVal","hasMore","getBoundingClientRect","scrollTop","scrollHeight","window","innerHeight","document","documentElement","onScroll","FunctionHelper","addEventListener","removeEventListener","shouldInitialFetch","httpStatusClass","toString","substr","HttpStatus","items","totalItems","hasFirstPageCompleted","useBreadcrumbs","match","useBuilder","DEFAULT_PARTIAL_LOADING_OPTIONS","minWidth","maxWidth","PartialLoadingHelper","getPartialLoadingItems","opts","Math","max","floor","random","PlaylistHelper","isPlaylist","typeId","MasterType","isOwner","playlist","currentUser","ObjectHelper","_liteOwner","id","getVideoCount","count","videos","clips","interactives","Separator","getPlaylistOwnerName","surname","TextHelper","substring","split","PlaylistHeaderDetails","currentUserIsOwner","followerCount","followers","lastUpdated","contentModifiedDate","now","getLastUpdated","detailsClassName","hideOwnerName","_isClickViewCurated","value","clickViewAvatarClassName","ClickViewAvatar","user","separatorClassName","totalVideos","smartCount","timeAgo","PartialPlaylistHeader","PlaylistHeaderUtils","getPlaylistActions","headerProps","args","isAuthenticated","isPlugin","setIsFollowing","isFollowing","setShowFollowSpinner","showFollowSpinner","isUserCurator","openInCuratorLink","videoCount","interactiveCount","clipCount","isClickViewPlaylist","location","entity","workflowPhase","playAllAppLink","push","button","actionType","href","openInNewTab","application","action","params","entityType","eventVersion","follow","AnalyticsHelper","descriptor","showSpinner","PlaylistHeader","usePluginHelper","showPartialLoading","description","getBreadcrumbs","getBgColorClass","classificationId","topicPath","SortableVideoListContainer","onSortComplete","onSortStart","videoListProps","currentSortingIndex","setCurrentSortingIndex","canEdit","showIndexes","event","index","findIndex","v","onSortEnd","over","oldIndex","newIndex","DevError","dragHandleIcon","dragHandleIconSize","presentationAudiences","VideoList","PlaylistEmptyState","EmptyState","ImageUrls","logSortAction","playlistId","videoId","playlistErrors","PlaylistPrivateError","PlaylistView","dispatch","alerts","config","ConfigRequests","UserRequests","useCurationStudio","getOpenInCurationStudioLink","hasPermissions","usePermissions","yearGroups","data","CustomerRequests","customerId","ClassificationRequests","classification","classificationPresentation","hasCompleted","presentationId","audiences","AudienceRequests","useLiteFavourites","u","setFavourite","canFavourite","playlistRequest","shareId","PlaylistRequests","playlistItemCountRequest","playlistWithCounts","getVideoItemActions","videoActions","useVideoActions","getVideoActions","video","canConsume","VideoHelper","removeFromPlaylistAction","group","usePlaylistViewVideoActions","getVideosRequest","following","useVideoMixin","reorderedItems","setReorderedItems","arr1","arr2","isEqual","isOrderEqual","reorderedVideos","setReorderedVideos","useDeepLinks","app","useSetPageMetadata","PageMetadataHelper","content","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","canonicalLink","SeoHelper","stripPresentationSlug","allowIndexing","playlistIsEmpty","playNext","VideoAppLinkHelper","contextId","context","RelatedVideosContext","moviesAndTv","isFollowingComplete","firstPlayAllVideo","find","videoDataLoaded","VideoActionsContext","shouldFollow","onSuccess","req","error","hideBreadCrumbs","oldIdx","newIdx","ReorderHelper","reorderRequest","getVideoAppLink","getSubTextAppLink","getSeriesAppLink","series","showSignIn","getSignInAppLink","redirectUrl","canRemovePrivateVideos","getPreviewQuestionsAppLink","interactive","InteractiveHelper","getClassroomGuideAppLink","getInteractiveGuidanceAppLink","getResourceGuidanceAppLink","CHUNK_SIZE","objects","hydratedVideos","Set","filter","o","getValidObjects","videoIds","setRequest","unhydratedVideos","has","add","r","newRequests","chunk","flightNamespace","bsPrefix","Component","decoratedBsPrefix","minBreakpoint","sizePrefix","classes","brkPoint","propValue","cols","infix","displayName"],"sourceRoot":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/6368-d33570d16d-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/user-manager/errors/cannot-year-group-rollover/CannotYearGroupRolloverError.ts","file:///app/packages/libs/shared/src/apps/user-manager/interfaces/viewmodels/BulkUserActionsViewModel.ts","file:///app/packages/libs/shared/src/apps/user-manager/utils/BulkUserActionsAnalyticsHelper.ts","file:///app/packages/libs/shared/src/enums/BatchJobStatus.ts","file:///app/packages/projects/lite/src/apps/settings/hooks/useCanManageLti.ts","file:///app/packages/projects/lite/src/apps/settings/hooks/useGetSettingsGroups.ts","file:///app/packages/projects/lite/src/shared/flight-requests/JobRequests.ts"],"sourcesContent":["import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { DialogError } from 'libs/shared/errors/primitives/DialogError';\nimport { DialogOptions } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nconst lang = 'userManager.cannotYearGroupRolloverError';\n\nexport class CannotYearGroupRolloverError extends DialogError {\n private previousRolloverDate: string;\n\n constructor(previousRolloverDate: string) {\n super('CannotYearGroupRolloverError');\n\n const localDate = DateHelper.convertUTCToLocal(previousRolloverDate);\n this.previousRolloverDate = DateHelper.format(localDate, 'MMMM Do YYYY');\n }\n\n // @ts-ignore\n public get name(): string {\n return 'CannotYearGroupRolloverError';\n }\n\n // @ts-ignore\n public get dialogOptions(): DialogOptions {\n return {\n title: LanguageService.getPhrase(lang, 'heading'),\n text: LanguageService.getPhrase(lang, 'text', {\n previousRolloverDate: this.previousRolloverDate,\n supportUrl: ArticleHelper.getSupportRequestUrl(),\n linkClass: 'info-link'\n }),\n buttons: [{\n text: LanguageService.getPhrase(lang, 'okay'),\n className: 'btn btn-dark',\n success: true\n }]\n };\n }\n}","import { Classroom, YearGroup } from 'libs/shared/interfaces';\n\nimport { BulkUserActionOptions, BulkUserSubAction } from '../../components/bulk-actions-wizard/layout/BulkUserActionsWizardLayout';\nimport { UserManagerQueryParams } from '../query-params/UserManagerQueryParams';\n\n// Please keep this array up to date with the interface below, so that the data we log to analytics remains accurate\nexport const BaseBulkUserActionsViewModelKeys: Array<keyof BulkUserActionsViewModel> = [\n 'userIdMap', 'params', 'action', 'subAction', 'allUsersSelected', 'allUsersCount', 'scrollContainer'\n];\n\nexport interface BulkUserActionsViewModel {\n userIdMap?: Map<string, boolean>;\n params?: UserManagerQueryParams;\n\n action?: BulkUserActionOptions; // TODO: Rename this to \"actionCategory\"\n subAction?: BulkUserSubAction; // TODO: Rename this to \"action\"\n\n // Used to determine if we can show year level rollover\n allUsersSelected?: boolean;\n allUsersCount?: number;\n scrollContainer?: HTMLElement;\n}\n\nexport interface BulkUserActionsYearGroupRolloverViewModel extends BulkUserActionsViewModel {\n yearGroup: YearGroup;\n}\n\nexport interface BulkUserActionsAddToClassroomViewModel extends BulkUserActionsViewModel {\n classroom: Classroom;\n}\n\nexport interface BulkUserActionsResetPasswordViewModel extends BulkUserActionsViewModel {\n password: string;\n changeOnNextLogin: boolean;\n}","import { HashObject } from 'libs/common/react/interfaces';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { BatchJobStatus } from 'libs/shared/enums/BatchJobStatus';\n\nimport { BulkUserActionStepId } from '../components/bulk-actions-wizard/layout/BulkUserActionsWizardLayout';\nimport { BaseBulkUserActionsViewModelKeys, BulkUserActionsViewModel } from '../interfaces/viewmodels/BulkUserActionsViewModel';\n\nexport const BulkUserActionsAnalyticsHelper = {\n getAnalyticsActionName(viewModel: BulkUserActionsViewModel): string | null {\n if (!viewModel?.action)\n return null;\n\n switch (viewModel.action) {\n case 'activation': {\n if (!viewModel?.subAction)\n return 'Deactivate / reactivate';\n\n if (viewModel.subAction === 'deactivate')\n return 'Deactivate';\n\n return 'Reactivate';\n }\n case 'addToClassroom':\n return 'Add to classroom';\n case 'changeYearGroup':\n return 'Change year level';\n case 'delete':\n return 'Delete user';\n case 'resetEmail':\n return 'Send password reset email';\n case 'activationEmail':\n return 'Send account activation email';\n case 'resetPassword':\n return 'Reset password';\n case 'yearGroupRollover':\n return 'Annual year level rollover';\n case 'removeFromSchool':\n return 'Remove user';\n default:\n return null;\n }\n },\n\n onClickNext(viewModel: BulkUserActionsViewModel, currentStep: BulkUserActionStepId): void {\n if (!viewModel)\n return;\n\n const analyticsData: HashObject = {\n userCount: viewModel.userIdMap.size,\n step: currentStep\n };\n\n const actionName = BulkUserActionsAnalyticsHelper.getAnalyticsActionName(viewModel);\n\n if (actionName)\n analyticsData.action = actionName;\n\n const actionData = ObjectHelper.omit(viewModel, BaseBulkUserActionsViewModelKeys);\n\n // Adds extra items like the `yearGroup` on year level actions or `password` on the reset pw action\n if (Object.keys(actionData).length)\n analyticsData.actionData = actionData;\n\n AnalyticsHelper.logUserAction(analyticsData, {\n location: LocationContext.BulkUserActionsWizard,\n workflowPhase: WorkflowPhase.Next,\n actionType: UserAction.BulkAction,\n entity: EntityType.User\n });\n },\n\n logYearGroupRolloverEntry(location: LocationContext): void {\n AnalyticsHelper.logUserAction({\n action: BulkUserActionsAnalyticsHelper.getAnalyticsActionName({ action: 'yearGroupRollover' })\n }, {\n entity: EntityType.User,\n actionType: UserAction.BulkAction,\n workflowPhase: WorkflowPhase.Start,\n location\n });\n },\n\n getJobStatus(status: BatchJobStatus): string | null {\n switch (status) {\n case BatchJobStatus.Completed:\n return 'Success';\n case BatchJobStatus.CompletedWithError:\n return 'Completed with some errors';\n case BatchJobStatus.Failed:\n return 'Failed';\n default:\n return null;\n }\n }\n};","export enum BatchJobStatus {\n Submitted = 0,\n Queued = 1,\n Pending = 2,\n InProgress = 3,\n Completed = 4,\n CompletedWithError = 5,\n Failed = 6\n}","import React from 'react';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\n/**\n * Checks if the user can access LTI based on if they have the LTI domain option enabled\n * on their customer.\n */\nexport const useCanManageLti = () => {\n const [ canAccess, setCanAccess ] = React.useState<boolean>(undefined);\n\n const { hasLti } = useSettings(LocationContext.Settings);\n\n React.useEffect(() => {\n if (hasLti && canAccess !== true) {\n setCanAccess(true);\n return;\n }\n\n if (!hasLti && canAccess !== false)\n setCanAccess(false);\n }, [hasLti]);\n\n return { canAccess };\n};","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { CannotYearGroupRolloverError } from 'libs/shared/apps/user-manager/errors/cannot-year-group-rollover/CannotYearGroupRolloverError';\nimport { BulkUserActionsViewModel } from 'libs/shared/apps/user-manager/interfaces/viewmodels/BulkUserActionsViewModel';\nimport { YearGroupRolloverStatus } from 'libs/shared/apps/user-manager/interfaces/YearGroupRolloverStatus';\nimport { BulkUserActionsAnalyticsHelper } from 'libs/shared/apps/user-manager/utils/BulkUserActionsAnalyticsHelper';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\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 { CurrentUser, YearGroup } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { JobRequests } from 'shared/flight-requests/JobRequests';\n\nimport { SettingsGroup } from 'apps/settings/interfaces/SettingsGroup';\nimport { UserManagerRequests } from 'apps/user-manager/flight-requests/UserManagerRequests';\n\nimport { useCanManageLti } from './useCanManageLti';\n\nconst namespace = 'settings.hooks';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function useGetSettingsGroups(): SettingsGroup[] {\n const { hasPermissions } = usePermissions();\n\n const { canAccess: canManageLti } = useCanManageLti();\n\n const { hasProduct } = useProducts();\n\n const [ , setBulkActionsViewModel ] = useViewModel<BulkUserActionsViewModel>(\n SharedViewModelKeys.BULK_USER_ACTIONS\n );\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const yearGroupRolloverStatus = Flight.useBasicFetch<YearGroupRolloverStatus>(!!currentUser.data &&\n JobRequests.getYearGroupRolloverStatus(currentUser.data.customerId));\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data && UserManagerRequests.yearGroups(currentUser.data.customerId)\n );\n\n const {\n domainSettings,\n hasAccessToRostering,\n hasManageGroupPermissions,\n hasClassrooms\n } = useSettings(LocationContext.Settings);\n\n const groups: SettingsGroup[] = [\n {\n // Account Management\n id: 'my-account',\n imageUrl: ImageUrls.Settings.MY_ACCOUNT,\n name: getPhrase('myAccount'),\n modules: [\n {\n id: 'profile-details',\n name: getPhrase('profileDetails'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.PROFILE_DETAILS\n },\n permissions: [PermissionName.EditProfileDetails]\n },\n {\n id: 'email-settings',\n name: getPhrase('emailPassword'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.ACCOUNT\n }\n },\n {\n id: 'topic-preferences',\n name: getPhrase('preferences'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.TOPIC_PREFERENCES\n },\n permissions: [PermissionName.ManageSubjectPreferences]\n },\n {\n id: 'audience-preferences',\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.AUDIENCE_PREFERENCES\n },\n permissions: [PermissionName.ManageSubjectPreferences],\n hide: true\n },\n {\n id: 'curriculum-preferences',\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.CURRICULUM\n },\n permissions: [PermissionName.ManageSubjectPreferences],\n hide: true\n },\n {\n id: 'school-level-preferences',\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.SCHOOL_LEVEL\n },\n permissions: [PermissionName.ManageSubjectPreferences],\n hide: true\n },\n {\n id: 'search-settings',\n name: getPhrase('searchSettings'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.SEARCH_SETTINGS\n },\n permissions: [PermissionName.Exchange],\n hide: !hasProduct(ProductId.Exchange)\n },\n {\n id: 'notification-settings',\n name: getPhrase('notificationSettings'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.NOTIFICATION_SETTINGS\n }\n }\n ]\n },\n {\n // User Management\n id: 'user-management',\n imageUrl: ImageUrls.Settings.USER_MANAGEMENT,\n name: getPhrase('userManagement'),\n modules: [\n {\n id: 'student-manager',\n name: getPhrase('studentManager'),\n appLink: {\n application: AppChannels.USER_MANAGER,\n action: Actions.UserManager.STUDENTS\n },\n permissions: [PermissionName.ManageUsers]\n },\n {\n id: 'staff-manager',\n name: getPhrase('staffManager'),\n appLink: {\n application: AppChannels.USER_MANAGER,\n action: Actions.UserManager.STAFF\n },\n permissions: [PermissionName.ManageUsers]\n },\n {\n id: 'year-group-rollover',\n name: getPhrase('yearGroupRollover'),\n permissions: [PermissionName.ManageUsers],\n onClick: () => {\n if (yearGroupRolloverStatus.data.canRollover) {\n setBulkActionsViewModel({\n action: 'yearGroupRollover',\n subAction: 'yearGroupRollover'\n });\n\n BulkUserActionsAnalyticsHelper.logYearGroupRolloverEntry(LocationContext.Settings);\n \n Core.AppLinkHelper.trigger({\n application: AppChannels.USER_MANAGER,\n action: Actions.UserManager.WIZARD_YEAR_GROUP_ROLLOVER_ACTION_DETAILS,\n params: { userType: UserGroup.Learner }\n });\n return;\n }\n\n Core.ErrorHelper.throw(new CannotYearGroupRolloverError(\n yearGroupRolloverStatus.data.previousRolloverDate\n ));\n },\n hide: !yearGroups.data || yearGroups.data.length < 2\n },\n {\n id: 'security',\n name: getPhrase('security'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.SECURITY\n },\n permissions: [PermissionName.ManageUsers]\n },\n {\n id: 'sso-year-group-mappings',\n name: getPhrase('ssoYearGroupMappings'),\n permissions: [PermissionName.ManageUsers],\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.SSO_YEAR_GROUP_MAPPINGS\n }\n },\n {\n id: 'join-requests',\n name: getPhrase('domainSettings'),\n permissions: [PermissionName.ManageUsers],\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.REQUESTING_ACCESS\n },\n hide: !domainSettings\n }\n ]\n },\n {\n // Integrations\n id: 'integrations',\n imageUrl: ImageUrls.Settings.INTEGRATIONS,\n name: getPhrase('integrations'),\n modules: [\n {\n id: 'integrations',\n name: getPhrase('integrations'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.INTEGRATIONS\n },\n permissions: [PermissionName.ManageIntegrations]\n },\n {\n id: 'lti',\n name: getPhrase('ltiPlatforms'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.LTI_PLATFORMS\n },\n permissions: [PermissionName.ManageIntegrations]\n },\n {\n id: 'export-libraries',\n name: getPhrase('exportLibraries'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.EXPORT_LIBRARIES\n },\n permissions: [PermissionName.ManageIntegrations]\n },\n {\n id: 'rostering',\n name: getPhrase('rostering'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.ROSTERING\n },\n permissions: [PermissionName.Rostering],\n hide: !hasAccessToRostering\n },\n {\n id: 'rss-feed',\n name: getPhrase('rssFeed'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.RSS_FEED\n },\n permissions: [PermissionName.ManageIntegrations]\n }\n ]\n },\n {\n // School Management\n id: 'school-management',\n imageUrl: ImageUrls.Settings.SCHOOL_MANAGEMENT,\n name: getPhrase('schoolManagement'),\n modules: [\n {\n id: 'video-playback',\n name: getPhrase('videoPlayback'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.VIDEO_PLAYBACK\n },\n permissions: [PermissionName.ManageCustomerSettings]\n },\n {\n id: 'archived-classrooms',\n name: getPhrase('archivedClassrooms'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.ARCHIVED_CLASSROOMS\n },\n permissions: [PermissionName.ManageCustomerSettings],\n hide: !hasClassrooms\n },\n {\n id: 'local-cache',\n name: getPhrase('localCache'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.LOCAL_CACHES\n },\n permissions: [PermissionName.ManageLocalCache]\n },\n {\n id: 'manage-group-permissions',\n name: getPhrase('manageGroupPermissions'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.MANAGE_GROUP_PERMISSIONS\n },\n permissions: [PermissionName.ManageCustomerSettings],\n hide: !hasManageGroupPermissions\n }\n ]\n },\n {\n // Video security\n id: 'video-security',\n imageUrl: ImageUrls.Settings.VIDEO_SECURITY,\n name: getPhrase('videoSecurity'),\n modules: [\n {\n id: 'content-permissions',\n name: getPhrase('contentPermissions'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.CONTENT_PERMISSIONS\n },\n permissions: [PermissionName.ManageCustomerSettings]\n },\n {\n id: 'video-restrictions',\n name: getPhrase('videoRestrictions'),\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.VIDEO_RESTRICTIONS\n },\n permissions: [PermissionName.ManageVideoAccess],\n hide: !hasPermissions(PermissionName.ManageVideoAccess)\n }\n ]\n }\n ];\n\n return groups.map(group => {\n return {\n ...group,\n modules: group.modules.filter(m => {\n if (m.permissions?.length && !hasPermissions(m.permissions))\n return false;\n\n if (m.id === 'lti' && canManageLti !== true)\n return false;\n \n return true;\n })\n };\n }).filter(group => !!group.modules.length);\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 { UserAuditLogQueryParams } from 'libs/shared/apps/user-manager/components/audit-log/components/audit-log-filters/UserAuditLogFilters';\nimport { SUPPORTED_BATCH_JOB_TYPES } from 'libs/shared/apps/user-manager/utils/BulkUserActionsHelper';\nimport { BatchJobResultStatus } from 'libs/shared/enums/BatchJobResultStatus';\nimport { BatchJobType } from 'libs/shared/enums/BatchJobType';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { BaseObject, BatchJob, BatchJobProgress, BatchJobResultsResponse, CreateBatchJobRequest } from 'libs/shared/interfaces';\n\nexport const JobRequests = {\n createJob(\n data: CreateBatchJobRequest,\n success?: (job: BatchJob) => void,\n error?: () => void\n ): Flight.Request {\n return {\n url: '{gateway}/v1/batch/jobs',\n key: 'create:job',\n type: HttpVerbs.POST,\n data,\n success,\n error\n };\n },\n\n getJobs(queryParams: UserAuditLogQueryParams): Flight.Request {\n const params: HashObject = {};\n\n let bulkActionTypes: BatchJobType[] = [];\n let userTypes: UserGroup[] = [];\n\n if (queryParams.cursor)\n params.cursor = queryParams.cursor;\n\n if (queryParams.sort) {\n if (queryParams.sort === 'oldest')\n params.order = 'ASC';\n else\n params.order = 'DESC';\n }\n\n if (queryParams.bulkActionType) {\n bulkActionTypes = Array.isArray(queryParams.bulkActionType)\n ? queryParams.bulkActionType\n : [queryParams.bulkActionType];\n\n params.type = bulkActionTypes;\n } else {\n // only show supported type in the table by default\n params.type = SUPPORTED_BATCH_JOB_TYPES;\n }\n\n if (queryParams.userType) {\n userTypes = Array.isArray(queryParams.userType)\n ? queryParams.userType\n : [queryParams.userType];\n\n params.dataType = userTypes;\n }\n \n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/batch/jobs', params),\n key: `batch:jobs:${queryParams.cursor}:${queryParams.sort}:${bulkActionTypes.sort().join(':')}:${userTypes.sort().join(':')}`\n };\n },\n\n getJob(id: string): Flight.Request {\n return {\n url: `{gateway}/v1/batch/jobs/${id}`,\n key: `job:${id}`\n };\n },\n\n getJobProgress(\n id: string,\n success?: (progress: BatchJobProgress) => void,\n error?: (xhr?: Xhr) => void\n ): Flight.Request {\n return {\n url: `{gateway}/v1/batch/jobs/${id}/progress`,\n key: `job:${id}:progress`,\n invalidationKeys: `job:${id}:progress`,\n success,\n error\n };\n },\n\n getJobResults<TObject extends BaseObject>(\n id: string,\n status: BatchJobResultStatus,\n cursor?: string,\n success?: (results: BatchJobResultsResponse<TObject>) => void,\n error?: (xhr?: Xhr) => void\n ): Flight.Request {\n const params: HashObject = {\n status\n };\n\n if (cursor)\n params.cursor = cursor;\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/batch/jobs/${id}/results`, params),\n key: `job:${id}:results:${status}:${cursor}`,\n success,\n error\n };\n },\n\n getYearGroupRolloverStatus(customerId: string): Flight.Request {\n return {\n url: `{gateway}/v1/batch/validations/customers/${customerId}/year-group-roll-over`,\n key: 'year:group:rollover:status'\n };\n },\n\n sendJobReports(ids: string[]): Flight.Request {\n return {\n url: '{gateway}/v1/batch/results/export',\n key: `send:job:reports:${ids.sort().join(':')}`,\n type: HttpVerbs.POST,\n data: {\n jobIds: ids\n }\n };\n },\n\n getJobSummary(id: string): Flight.Request {\n return {\n url: `{gateway}/v1/batch/jobs/${id}/summary`,\n key: `job:summary:${id}`\n };\n }\n};"],"names":["lang","CannotYearGroupRolloverError","previousRolloverDate","localDate","title","text","this","supportUrl","linkClass","buttons","className","success","BaseBulkUserActionsViewModelKeys","BulkUserActionsAnalyticsHelper","getAnalyticsActionName","viewModel","action","subAction","onClickNext","currentStep","analyticsData","userCount","userIdMap","size","step","actionName","actionData","ObjectHelper","Object","keys","length","AnalyticsHelper","location","workflowPhase","actionType","entity","logYearGroupRolloverEntry","getJobStatus","status","BatchJobStatus","useCanManageLti","undefined","canAccess","setCanAccess","hasLti","getPhrase","useGetSettingsGroups","hasPermissions","canManageLti","hasProduct","setBulkActionsViewModel","currentUser","yearGroupRolloverStatus","data","customerId","yearGroups","domainSettings","hasAccessToRostering","hasManageGroupPermissions","hasClassrooms","id","imageUrl","name","modules","appLink","application","permissions","hide","onClick","canRollover","params","userType","map","group","filter","m","JobRequests","createJob","error","url","key","type","getJobs","queryParams","bulkActionTypes","userTypes","cursor","sort","order","bulkActionType","Array","isArray","dataType","join","getJob","getJobProgress","invalidationKeys","getJobResults","getYearGroupRolloverStatus","sendJobReports","ids","jobIds","getJobSummary"],"sourceRoot":""}
|