@clickview/streamable-learning 0.48.0-rc.0 → 0.48.0-rc.1
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/.vite/manifest.json +646 -646
- package/dist/bundles.json +1 -1
- package/dist/css/DU3tPCD_.chunk.css +12 -0
- package/dist/en.json +1 -1
- package/dist/scripts/{m9QbGES0.chunk.js → ACTQklJQ.chunk.js} +2 -2
- package/dist/scripts/{m9QbGES0.chunk.js.map → ACTQklJQ.chunk.js.map} +1 -1
- package/dist/scripts/{B7if0Lk52.chunk.js → B-qOny0I2.chunk.js} +2 -2
- package/dist/scripts/{B7if0Lk52.chunk.js.map → B-qOny0I2.chunk.js.map} +1 -1
- package/dist/scripts/{BSjm_rCE.chunk.js → B5jBIPaP.chunk.js} +2 -2
- package/dist/scripts/{BSjm_rCE.chunk.js.map → B5jBIPaP.chunk.js.map} +1 -1
- package/dist/scripts/{CPkKuTSK2.chunk.js → B703cBe72.chunk.js} +2 -2
- package/dist/scripts/{CPkKuTSK2.chunk.js.map → B703cBe72.chunk.js.map} +1 -1
- package/dist/scripts/{DNNNPLMp.chunk.js → B7iwtSij.chunk.js} +2 -2
- package/dist/scripts/{DNNNPLMp.chunk.js.map → B7iwtSij.chunk.js.map} +1 -1
- package/dist/scripts/{CXNve4Wq2.chunk.js → BCBfXCYM2.chunk.js} +2 -2
- package/dist/scripts/{CXNve4Wq2.chunk.js.map → BCBfXCYM2.chunk.js.map} +1 -1
- package/dist/scripts/{CoYNU7We2.chunk.js → BKnxYKDu2.chunk.js} +2 -2
- package/dist/scripts/{CoYNU7We2.chunk.js.map → BKnxYKDu2.chunk.js.map} +1 -1
- package/dist/scripts/{BoxedFO8.chunk.js → BLrjbrp8.chunk.js} +2 -2
- package/dist/scripts/{BoxedFO8.chunk.js.map → BLrjbrp8.chunk.js.map} +1 -1
- package/dist/scripts/{CibcLNJP2.chunk.js → BTYwcYPL2.chunk.js} +2 -2
- package/dist/scripts/{CibcLNJP2.chunk.js.map → BTYwcYPL2.chunk.js.map} +1 -1
- package/dist/scripts/{CwI-7tep2.chunk.js → BXJetawx2.chunk.js} +2 -2
- package/dist/scripts/{CwI-7tep2.chunk.js.map → BXJetawx2.chunk.js.map} +1 -1
- package/dist/scripts/{BV74ZRR22.chunk.js → BZOcEcTA2.chunk.js} +2 -2
- package/dist/scripts/{BV74ZRR22.chunk.js.map → BZOcEcTA2.chunk.js.map} +1 -1
- package/dist/scripts/{DxsW8K0n2.chunk.js → BaMNOAYj2.chunk.js} +2 -2
- package/dist/scripts/{DxsW8K0n2.chunk.js.map → BaMNOAYj2.chunk.js.map} +1 -1
- package/dist/scripts/{DrDQfaFN2.chunk.js → BihZ4r0z2.chunk.js} +3 -3
- package/dist/scripts/{DrDQfaFN2.chunk.js.map → BihZ4r0z2.chunk.js.map} +1 -1
- package/dist/scripts/{CK6c6uHp2.chunk.js → BpgHKWR52.chunk.js} +2 -2
- package/dist/scripts/{CK6c6uHp2.chunk.js.map → BpgHKWR52.chunk.js.map} +1 -1
- package/dist/scripts/{JtFbyaXc.chunk.js → Br0Uc4GG.chunk.js} +2 -2
- package/dist/scripts/{JtFbyaXc.chunk.js.map → Br0Uc4GG.chunk.js.map} +1 -1
- package/dist/scripts/{Dd8r1SE32.chunk.js → BsAo7Lri2.chunk.js} +2 -2
- package/dist/scripts/{Dd8r1SE32.chunk.js.map → BsAo7Lri2.chunk.js.map} +1 -1
- package/dist/scripts/{BMjES83N2.chunk.js → BvJXPFoz2.chunk.js} +2 -2
- package/dist/scripts/{BMjES83N2.chunk.js.map → BvJXPFoz2.chunk.js.map} +1 -1
- package/dist/scripts/{CpFOQcL7.chunk.js → BxypZGPK.chunk.js} +2 -2
- package/dist/scripts/{CpFOQcL7.chunk.js.map → BxypZGPK.chunk.js.map} +1 -1
- package/dist/scripts/C4MLxDS-.chunk.js +1 -0
- package/dist/scripts/{DLp7yHzT2.chunk.js → C5i1HsPp2.chunk.js} +2 -2
- package/dist/scripts/{DLp7yHzT2.chunk.js.map → C5i1HsPp2.chunk.js.map} +1 -1
- package/dist/scripts/{Bkv1Tbyu.chunk.js → CCoZQmgX.chunk.js} +2 -2
- package/dist/scripts/{Bkv1Tbyu.chunk.js.map → CCoZQmgX.chunk.js.map} +1 -1
- package/dist/scripts/{Clh6wBrg.chunk.js → CGxa1Jzq.chunk.js} +2 -2
- package/dist/scripts/{Clh6wBrg.chunk.js.map → CGxa1Jzq.chunk.js.map} +1 -1
- package/dist/scripts/{DAvXFgC62.chunk.js → CKdklY2o2.chunk.js} +2 -2
- package/dist/scripts/{DAvXFgC62.chunk.js.map → CKdklY2o2.chunk.js.map} +1 -1
- package/dist/scripts/{CeWjJPIz.chunk.js → CN8PeBwg.chunk.js} +2 -2
- package/dist/scripts/{CeWjJPIz.chunk.js.map → CN8PeBwg.chunk.js.map} +1 -1
- package/dist/scripts/{B1jitqYS2.chunk.js → CNJrD44-2.chunk.js} +2 -2
- package/dist/scripts/{B1jitqYS2.chunk.js.map → CNJrD44-2.chunk.js.map} +1 -1
- package/dist/scripts/{DIHDe4Sg.chunk.js → CNmmq34f.chunk.js} +2 -2
- package/dist/scripts/{DIHDe4Sg.chunk.js.map → CNmmq34f.chunk.js.map} +1 -1
- package/dist/scripts/{CikSQKH-.chunk.js → CUUUI6pl.chunk.js} +2 -2
- package/dist/scripts/{CikSQKH-.chunk.js.map → CUUUI6pl.chunk.js.map} +1 -1
- package/dist/scripts/{DNO0KpY72.chunk.js → CWFInhB82.chunk.js} +2 -2
- package/dist/scripts/{DNO0KpY72.chunk.js.map → CWFInhB82.chunk.js.map} +1 -1
- package/dist/scripts/{i2-k6ULv2.chunk.js → CbLL7dIz2.chunk.js} +2 -2
- package/dist/scripts/{i2-k6ULv2.chunk.js.map → CbLL7dIz2.chunk.js.map} +1 -1
- package/dist/scripts/{KCdpQ8qv2.chunk.js → Ce1TZZdV2.chunk.js} +2 -2
- package/dist/scripts/{KCdpQ8qv2.chunk.js.map → Ce1TZZdV2.chunk.js.map} +1 -1
- package/dist/scripts/{NV4_mMU8.chunk.js → Ces-KTwe.chunk.js} +2 -2
- package/dist/scripts/{NV4_mMU8.chunk.js.map → Ces-KTwe.chunk.js.map} +1 -1
- package/dist/scripts/{0xQRFMBY.chunk.js → CkYqp83j.chunk.js} +2 -2
- package/dist/scripts/{0xQRFMBY.chunk.js.map → CkYqp83j.chunk.js.map} +1 -1
- package/dist/scripts/{DvL3J2BU.chunk.js → CrCAJmt6.chunk.js} +2 -2
- package/dist/scripts/{DvL3J2BU.chunk.js.map → CrCAJmt6.chunk.js.map} +1 -1
- package/dist/scripts/{CcDgbmw52.chunk.js → CsC3VVvE2.chunk.js} +2 -2
- package/dist/scripts/{CcDgbmw52.chunk.js.map → CsC3VVvE2.chunk.js.map} +1 -1
- package/dist/scripts/{C9UjF0q6.chunk.js → D0SYGnyF.chunk.js} +2 -2
- package/dist/scripts/{C9UjF0q6.chunk.js.map → D0SYGnyF.chunk.js.map} +1 -1
- package/dist/scripts/{BqO6i89w2.chunk.js → D7tastET2.chunk.js} +2 -2
- package/dist/scripts/{BqO6i89w2.chunk.js.map → D7tastET2.chunk.js.map} +1 -1
- package/dist/scripts/{CeI-LCE-.chunk.js → DIavEegC.chunk.js} +2 -2
- package/dist/scripts/{CeI-LCE-.chunk.js.map → DIavEegC.chunk.js.map} +1 -1
- package/dist/scripts/{BKbKu9Rp.chunk.js → DK3xia1t.chunk.js} +2 -2
- package/dist/scripts/{BKbKu9Rp.chunk.js.map → DK3xia1t.chunk.js.map} +1 -1
- package/dist/scripts/{BCdnm1Nn.chunk.js → DKnZ8BaN.chunk.js} +2 -2
- package/dist/scripts/{BCdnm1Nn.chunk.js.map → DKnZ8BaN.chunk.js.map} +1 -1
- package/dist/scripts/{awemA_vU2.chunk.js → DO8_mR5i2.chunk.js} +2 -2
- package/dist/scripts/{awemA_vU2.chunk.js.map → DO8_mR5i2.chunk.js.map} +1 -1
- package/dist/scripts/{DlQrdOls.chunk.js → DR80oZtZ.chunk.js} +2 -2
- package/dist/scripts/{DlQrdOls.chunk.js.map → DR80oZtZ.chunk.js.map} +1 -1
- package/dist/scripts/{DMq5Gp-U2.chunk.js → DU1SE31v2.chunk.js} +2 -2
- package/dist/scripts/{DMq5Gp-U2.chunk.js.map → DU1SE31v2.chunk.js.map} +1 -1
- package/dist/scripts/{XnBhLH-02.chunk.js → Dj4AeYQQ2.chunk.js} +2 -2
- package/dist/scripts/{XnBhLH-02.chunk.js.map → Dj4AeYQQ2.chunk.js.map} +1 -1
- package/dist/scripts/{CmrPRojb.chunk.js → DnSy_Myx.chunk.js} +2 -2
- package/dist/scripts/{CmrPRojb.chunk.js.map → DnSy_Myx.chunk.js.map} +1 -1
- package/dist/scripts/{D0vsmyva.chunk.js → Dr1flAez.chunk.js} +2 -2
- package/dist/scripts/{D0vsmyva.chunk.js.map → Dr1flAez.chunk.js.map} +1 -1
- package/dist/scripts/{BXT8nHry2.chunk.js → DwzBzBlI2.chunk.js} +2 -2
- package/dist/scripts/{BXT8nHry2.chunk.js.map → DwzBzBlI2.chunk.js.map} +1 -1
- package/dist/scripts/{CvqqZmNo2.chunk.js → DyT1OGvP2.chunk.js} +2 -2
- package/dist/scripts/{CvqqZmNo2.chunk.js.map → DyT1OGvP2.chunk.js.map} +1 -1
- package/dist/scripts/{E9tNds1l.chunk.js → Llxar-VU.chunk.js} +2 -2
- package/dist/scripts/{E9tNds1l.chunk.js.map → Llxar-VU.chunk.js.map} +1 -1
- package/dist/scripts/{app-B1XBsz23.js → app-BIigh9wv.js} +4 -4
- package/dist/scripts/{app-B1XBsz23.js.map → app-BIigh9wv.js.map} +1 -1
- package/dist/scripts/{BMl02f_62.chunk.js → bycmewy72.chunk.js} +2 -2
- package/dist/scripts/{BMl02f_62.chunk.js.map → bycmewy72.chunk.js.map} +1 -1
- package/dist/scripts/{DmfbtOlu.chunk.js → jWpq99N3.chunk.js} +2 -2
- package/dist/scripts/{DmfbtOlu.chunk.js.map → jWpq99N3.chunk.js.map} +1 -1
- package/dist/scripts/{BDliRFoa.chunk.js → oTYyWWB-.chunk.js} +2 -2
- package/dist/scripts/{BDliRFoa.chunk.js.map → oTYyWWB-.chunk.js.map} +1 -1
- package/dist/scripts/{lokG7Sha2.chunk.js → qcrBN1zR2.chunk.js} +2 -2
- package/dist/scripts/{lokG7Sha2.chunk.js.map → qcrBN1zR2.chunk.js.map} +1 -1
- package/dist/scripts/{UAcFqQzZ.chunk.js → smdLElLq.chunk.js} +2 -2
- package/dist/scripts/{UAcFqQzZ.chunk.js.map → smdLElLq.chunk.js.map} +1 -1
- package/dist/scripts/{D8_5yfHY2.chunk.js → tYi-sUb22.chunk.js} +2 -2
- package/dist/scripts/{D8_5yfHY2.chunk.js.map → tYi-sUb22.chunk.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/D5Jnyjf8.chunk.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C9UjF0q6.chunk.js","names":[],"sources":["../../../../libs/shared/src/components/video-list/partial-loading/partial-video-list.module.scss","../../../../libs/shared/src/components/video-list/partial-loading/PartialVideoList.tsx","../../../../libs/shared/src/flight-requests/DashboardRequests.ts"],"sourcesContent":[":local {\n .partialOptions {\n width: 5.375rem;\n }\n\n .partialName {\n width: 18.75rem;\n height: 1.3125rem;\n }\n\n .partialDescription {\n width: 12.5rem;\n height: 1.3125rem;\n }\n\n .partialThumbnail {\n padding-bottom: 56.25%;\n }\n\n .partialDragHandle {\n width: 1.25rem;\n height: 1.25rem;\n }\n}","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.module.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 <>\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 </>\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 { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { CuratedDashboard, CuratedDashboardCollection, CuratedWidget, CuratedWidgetContent, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardUserType, Presentation, WidgetPreference } from 'libs/shared/interfaces';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { HardCoded } from '../constants/HardCoded';\nimport { ContentRegion } from '../enums/ContentRegion';\nimport { WidgetTemplate } from '../enums/WidgetTemplate';\nimport { MasterTypeHelper } from '../utils/MasterTypeHelper';\nimport { ThemeAssetHelper } from '../utils/ThemeAssetHelper';\n\ninterface GetDashboardWidgetContentOptions {\n hideTigTag?: boolean;\n hideTwig?: boolean;\n cursor?: string;\n}\n\nconst TWIG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Twig.EnglandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.InternationalSecondary),\n ...Object.values(HardCoded.Classifications.Twig.ScotlandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.NewZealandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.CanadaMiddle),\n ...Object.values(HardCoded.Classifications.Twig.CanadaHigh)\n]);\n\nconst TIG_TAG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Tigtag.EnglandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.InternationalPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.ScotlandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.NewZealandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaElementary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaMiddle)\n]);\n\nfunction getQueryParamsKey(queryParams: CuratedWidgetQueryParams): string {\n return Object.keys(queryParams)\n .map((key: keyof CuratedWidgetQueryParams) => queryParams[key])\n .join(':');\n}\n\nfunction getNamespaceKey(queryParams: CuratedWidgetQueryParams, options: GetDashboardWidgetContentOptions): string {\n if (!options.cursor)\n return getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]));\n\n return `${getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]))}:${options.cursor}`;\n}\n\nfunction shouldNormalizeWidgetRequest(\n template: WidgetTemplate\n): boolean {\n if (template === WidgetTemplate.EditableCoverFixedPillListSmall)\n return false;\n\n return true;\n}\n\nexport const DashboardRequests = {\n classificationDashboard(\n classificationId: string,\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n dashboardId?: string | null\n ): Flight.PublicRequest {\n const queryParamOpts = {\n target: `classification:${classificationId}`,\n status: statuses,\n userType\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key: `classification:dashboard:${classificationId}:${userType}:${dashboardId}:${statuses?.join(':')}`,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n }\n };\n },\n\n dashboardWidgetContent(\n id: string,\n queryParams: CuratedWidgetQueryParams = {},\n template?: WidgetTemplate,\n presentation?: Presentation,\n options: GetDashboardWidgetContentOptions = {}\n ): Flight.PublicRequest {\n const queryParamsWithCursor = { ...queryParams, cursor: options.cursor };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/widgets/${id}`, queryParamsWithCursor),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/widgets/${id}`, queryParamsWithCursor),\n key: `widget:${id}:${getQueryParamsKey(queryParamsWithCursor)}`,\n formatData: (widget: CuratedWidget) => {\n const formatted = WidgetHelper.formatResponseData(widget, presentation);\n\n if (Array.isArray(formatted.content)) {\n formatted.content = formatted.content.map(\n entity => MasterTypeHelper.isClassification(entity) ?\n ThemeAssetHelper.applyThemeToClassification(entity) :\n entity\n ) as CuratedWidgetContent;\n }\n\n if (!options.hideTigTag && !options.hideTwig)\n return formatted;\n\n // Filter out the Twig topics for users who don't have access to the Twig library\n if (Array.isArray(formatted.content)) {\n const newContent = formatted.content.filter(entity => {\n if (MasterTypeHelper.isClassification(entity)) {\n if (TIG_TAG_TOPIC_IDS.has(entity.id))\n return !options.hideTigTag;\n\n if (TWIG_TOPIC_IDS.has(entity.id))\n return !options.hideTwig;\n\n return true;\n }\n \n return true;\n }) as CuratedWidgetContent;\n \n formatted.content = newContent;\n }\n \n return formatted;\n },\n normalizeOptions: {\n namespace: getNamespaceKey(queryParams, options)\n },\n normalize: shouldNormalizeWidgetRequest(template)\n };\n },\n\n getDashboard(\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n target: string,\n curriculumIds?: string[],\n dashboardId?: string,\n contentRegion?: ContentRegion,\n success?: (data: CuratedDashboard) => void\n ): Flight.PublicRequest {\n const queryParamOpts: HashObject = {\n target,\n status: statuses,\n userType\n };\n\n if (curriculumIds?.length)\n queryParamOpts['widgets.curriculum'] = curriculumIds;\n\n if (contentRegion)\n queryParamOpts.contentRegion = contentRegion;\n\n const key = `dashboard:${target}:${userType}:${dashboardId}:${statuses.join(':')}:${contentRegion ?? ''}`;\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n },\n success\n };\n },\n\n updateWidgetPreferences(widgetId: string, preferences: WidgetPreference[], currentUser: CurrentUser): Flight.Request {\n return {\n url: `{gateway}/v1/discover/widgets/${widgetId}/preferences`,\n key: 'update:widget:preferences',\n invalidationKeys: [`widget:${widgetId}`],\n type: HttpVerbs.PUT,\n data: {\n userId: currentUser.id,\n customerId: currentUser.customerId,\n metadata: preferences\n }\n };\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"D0SYGnyF.chunk.js","names":[],"sources":["../../../../libs/shared/src/components/video-list/partial-loading/partial-video-list.module.scss","../../../../libs/shared/src/components/video-list/partial-loading/PartialVideoList.tsx","../../../../libs/shared/src/flight-requests/DashboardRequests.ts"],"sourcesContent":[":local {\n .partialOptions {\n width: 5.375rem;\n }\n\n .partialName {\n width: 18.75rem;\n height: 1.3125rem;\n }\n\n .partialDescription {\n width: 12.5rem;\n height: 1.3125rem;\n }\n\n .partialThumbnail {\n padding-bottom: 56.25%;\n }\n\n .partialDragHandle {\n width: 1.25rem;\n height: 1.25rem;\n }\n}","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.module.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 <>\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 </>\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 { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { CuratedDashboard, CuratedDashboardCollection, CuratedWidget, CuratedWidgetContent, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardUserType, Presentation, WidgetPreference } from 'libs/shared/interfaces';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { HardCoded } from '../constants/HardCoded';\nimport { ContentRegion } from '../enums/ContentRegion';\nimport { WidgetTemplate } from '../enums/WidgetTemplate';\nimport { MasterTypeHelper } from '../utils/MasterTypeHelper';\nimport { ThemeAssetHelper } from '../utils/ThemeAssetHelper';\n\ninterface GetDashboardWidgetContentOptions {\n hideTigTag?: boolean;\n hideTwig?: boolean;\n cursor?: string;\n}\n\nconst TWIG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Twig.EnglandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.InternationalSecondary),\n ...Object.values(HardCoded.Classifications.Twig.ScotlandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.NewZealandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.CanadaMiddle),\n ...Object.values(HardCoded.Classifications.Twig.CanadaHigh)\n]);\n\nconst TIG_TAG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Tigtag.EnglandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.InternationalPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.ScotlandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.NewZealandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaElementary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaMiddle)\n]);\n\nfunction getQueryParamsKey(queryParams: CuratedWidgetQueryParams): string {\n return Object.keys(queryParams)\n .map((key: keyof CuratedWidgetQueryParams) => queryParams[key])\n .join(':');\n}\n\nfunction getNamespaceKey(queryParams: CuratedWidgetQueryParams, options: GetDashboardWidgetContentOptions): string {\n if (!options.cursor)\n return getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]));\n\n return `${getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]))}:${options.cursor}`;\n}\n\nfunction shouldNormalizeWidgetRequest(\n template: WidgetTemplate\n): boolean {\n if (template === WidgetTemplate.EditableCoverFixedPillListSmall)\n return false;\n\n return true;\n}\n\nexport const DashboardRequests = {\n classificationDashboard(\n classificationId: string,\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n dashboardId?: string | null\n ): Flight.PublicRequest {\n const queryParamOpts = {\n target: `classification:${classificationId}`,\n status: statuses,\n userType\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key: `classification:dashboard:${classificationId}:${userType}:${dashboardId}:${statuses?.join(':')}`,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n }\n };\n },\n\n dashboardWidgetContent(\n id: string,\n queryParams: CuratedWidgetQueryParams = {},\n template?: WidgetTemplate,\n presentation?: Presentation,\n options: GetDashboardWidgetContentOptions = {}\n ): Flight.PublicRequest {\n const queryParamsWithCursor = { ...queryParams, cursor: options.cursor };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/widgets/${id}`, queryParamsWithCursor),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/widgets/${id}`, queryParamsWithCursor),\n key: `widget:${id}:${getQueryParamsKey(queryParamsWithCursor)}`,\n formatData: (widget: CuratedWidget) => {\n const formatted = WidgetHelper.formatResponseData(widget, presentation);\n\n if (Array.isArray(formatted.content)) {\n formatted.content = formatted.content.map(\n entity => MasterTypeHelper.isClassification(entity) ?\n ThemeAssetHelper.applyThemeToClassification(entity) :\n entity\n ) as CuratedWidgetContent;\n }\n\n if (!options.hideTigTag && !options.hideTwig)\n return formatted;\n\n // Filter out the Twig topics for users who don't have access to the Twig library\n if (Array.isArray(formatted.content)) {\n const newContent = formatted.content.filter(entity => {\n if (MasterTypeHelper.isClassification(entity)) {\n if (TIG_TAG_TOPIC_IDS.has(entity.id))\n return !options.hideTigTag;\n\n if (TWIG_TOPIC_IDS.has(entity.id))\n return !options.hideTwig;\n\n return true;\n }\n \n return true;\n }) as CuratedWidgetContent;\n \n formatted.content = newContent;\n }\n \n return formatted;\n },\n normalizeOptions: {\n namespace: getNamespaceKey(queryParams, options)\n },\n normalize: shouldNormalizeWidgetRequest(template)\n };\n },\n\n getDashboard(\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n target: string,\n curriculumIds?: string[],\n dashboardId?: string,\n contentRegion?: ContentRegion,\n success?: (data: CuratedDashboard) => void\n ): Flight.PublicRequest {\n const queryParamOpts: HashObject = {\n target,\n status: statuses,\n userType\n };\n\n if (curriculumIds?.length)\n queryParamOpts['widgets.curriculum'] = curriculumIds;\n\n if (contentRegion)\n queryParamOpts.contentRegion = contentRegion;\n\n const key = `dashboard:${target}:${userType}:${dashboardId}:${statuses.join(':')}:${contentRegion ?? ''}`;\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n },\n success\n };\n },\n\n updateWidgetPreferences(widgetId: string, preferences: WidgetPreference[], currentUser: CurrentUser): Flight.Request {\n return {\n url: `{gateway}/v1/discover/widgets/${widgetId}/preferences`,\n key: 'update:widget:preferences',\n invalidationKeys: [`widget:${widgetId}`],\n type: HttpVerbs.PUT,\n data: {\n userId: currentUser.id,\n customerId: currentUser.customerId,\n metadata: preferences\n }\n };\n }\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t}from"./ImQRQGZr.chunk.js";import{C as n,l as r,n as i,ut as a,v as o}from"./Dun43GrB.chunk.js";import{d as s,l as c,y as l}from"./BQ5XMoHG.chunk.js";import{t as u}from"./B7tm2CBz.chunk.js";import{t as d}from"./C9ET3pjZ.chunk.js";import{n as f}from"./CAEQvGr_.chunk.js";import{n as p}from"./LVrVQvKT.chunk.js";import{t as m}from"./ibuOpDkQ.chunk.js";import{t as h}from"./BVWg3YHX.chunk.js";import{i as g}from"./CEsevkum.chunk.js";import{t as _}from"./H6wjCesG.chunk.js";import{n as v,t as y}from"./CL1ST5J62.chunk.js";import{M as b}from"./app-
|
|
2
|
-
//# sourceMappingURL=
|
|
1
|
+
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t}from"./ImQRQGZr.chunk.js";import{C as n,l as r,n as i,ut as a,v as o}from"./Dun43GrB.chunk.js";import{d as s,l as c,y as l}from"./BQ5XMoHG.chunk.js";import{t as u}from"./B7tm2CBz.chunk.js";import{t as d}from"./C9ET3pjZ.chunk.js";import{n as f}from"./CAEQvGr_.chunk.js";import{n as p}from"./LVrVQvKT.chunk.js";import{t as m}from"./ibuOpDkQ.chunk.js";import{t as h}from"./BVWg3YHX.chunk.js";import{i as g}from"./CEsevkum.chunk.js";import{t as _}from"./H6wjCesG.chunk.js";import{n as v,t as y}from"./CL1ST5J62.chunk.js";import{M as b}from"./app-BIigh9wv.js";import{t as x}from"./DlFudnBx.chunk.js";var S=p.CLASSIFICATION_COLLECTION,C={allSubjectPreferences:()=>`{gateway}/v1/users/me/classifications/preferences?query=${S}&type=subject`,mySubjectPreferences:()=>`{gateway}/v1/users/me/classifications/following?query=${S}`,followSubjects:()=>`{gateway}/v1/users/me/classifications/following`,unfollowSubjects:e=>f.urlBuilder(`{gateway}/v1/users/me/classifications/following`,{id:e}),allLevelPreferences:()=>`{gateway}/v1/users/me/audiences?type=subject`,myLevelPreferences:()=>`{gateway}/v1/users/me/audiences/following`,followLevels:()=>`{gateway}/v1/users/me/audiences/following`,unfollowLevels:e=>f.urlBuilder(`{gateway}/v1/users/me/audiences/following`,{id:e}),getCurrentPresentations:e=>`{gateway}/v1/users/me/presentations${e?`?type=${e}`:``}`,getAvailablePresentations:e=>`{gateway}/v1/users/me/presentations/available${e?`?type=${e}`:``}`,setPresentation:e=>`{gateway}/v1/users/me/presentations/${e}`},w={availablePresentations(e){return{url:C.getAvailablePresentations(e),key:`available:presentations:${e}`,normalizeOptions:{namespace:`presentation`}}},setPresentation(e,t,n,r){return{url:C.setPresentation(e.id),key:`set:${t}:presentation`,type:l.POST,data:{},normalizeOptions:{namespace:`presentation`},invalidationKeys:[`current:presentation:${t.toLocaleLowerCase()}`,`subject:preference:options`,`my:subject:preferences`,`level:preference:options`,`my:level:preferences`,`classifications`,`presentation:audiences`,`widgets:v3`,`content:update:videos`,`content:updates`],success:n,error:r}},allSubjectPreferences(){return{url:C.allSubjectPreferences(),key:`subject:preference:options`}},mySubjectPreferences(e){return{url:C.mySubjectPreferences(),key:`my:subject:preferences`,normalize:!1,success:e}},followSubjects(e,t,n,r){return{url:C.followSubjects(),key:`follow:subjects`,data:e,type:l.POST,success:t,error:n,always:r,invalidationKeys:[...e.map(e=>`classification:${e}`),`my:subject:preferences`,`classifications`,`content:updates`]}},unfollowSubjects(e,t,n,r){return{url:C.unfollowSubjects(e),key:`unfollow:subjects`,type:l.DELETE,success:t,error:n,always:r,invalidationKeys:[...e.map(e=>`classification:${e}`),`my:subject:preferences`,`classifications`,`content:updates`]}},allLevelPreferences(){return{url:C.allLevelPreferences(),key:`level:preference:options`,normalize:!1}},myLevelPreferences(e){return{url:C.myLevelPreferences(),key:`my:level:preferences`,normalizeOptions:{idAttribute:`masterId`},success:e}},followLevels(e,t,n,r){return{url:C.followLevels(),key:`follow:levels`,data:e.map(e=>e.masterId),normalize:!1,updateState:{keys:`my:level:preferences`,updateData:t=>{let n=t[`my:level:preferences`]??[];return e.forEach(e=>{n.find(t=>t.masterId===e.masterId)||n.push(e)}),{"my:level:preferences":n}}},type:l.POST,success:t,error:n,always:r}},unfollowLevels(e,t,n,r){return{url:C.unfollowLevels(e.map(e=>e.masterId)),key:`unfollow:levels`,normalize:!1,updateState:{keys:`my:level:preferences`,updateData:t=>{let n=t[`my:level:preferences`]??[];return e.forEach(e=>{if(!n.find(t=>t.masterId===e.masterId))return;let t=n.findIndex(t=>t.masterId===e.masterId);n=[...n.slice(0,t),...n.slice(t+1)]}),{"my:level:preferences":n}}},type:l.DELETE,success:t,error:n,always:r}}},T=e(a()),E=`videos.hooks`,D=new Map,O=e=>{function a(e){return`${e.toLowerCase()}:${y.PRESENTATION_ID}`}let[l,f]=v(a(h.Curriculum),void 0,{storage:g.LocalStorage}),[p,S]=T.useState(null),[C,O]=T.useState(null),[k,A]=T.useState(!1),j=c(m.currentUser()),M=c(x.availablePresentations(h.Curriculum)),N=s(),P=_(),{hasLocalPermissions:F}=b(),I=F(d.ManagePublicPresentation);function L(){return isNaN(+l)?u.first(M.data)?.id:l}function R(){if(j.data?.isAuthenticated)return x.presentation(h.Curriculum);let e=L();return e?x.presentationById(e):null}let z=c(R());T.useEffect(()=>{z.data&&(S(z.data),e&&!C&&N(x.curriculumLinks(e,z.data?.id)).then(e=>{O(e),D.set(z.data?.id?.toString(),e)}))},[z.data?.id]);let B=M.data?.map(e=>e.id)??[],V=c(e&&B.length&&x.getMappedCurriculums(e,B));async function H(n,r){if(p.id.toString()===n.toString())return;let i=M.data.find(e=>e.id.toString()===n.toString());S(i),I&&f(n);try{if(e&&await U(n),I)return;await N(w.setPresentation(i,h.Curriculum)),W(i,r)}catch{P.error(t.getPhrase(E,`curriculumUpdateError`)),S(p)}}async function U(t){if(!e)return;if(D.has(t.toString())){O(D.get(t.toString()));return}if(!V.data.find(e=>e.id.toString()===t.toString())){O([]);return}A(!0);let n=await N(x.curriculumLinks(e,t));O(n),D.set(t.toString(),n),A(!1)}function W(e,t){if(!t.shouldLog)return;let a={id:e.id,name:e.id,description:e.description};t.video&&(a.videoId=t.video.id,a.videoName=t.video.name),i.logUserAction(a,{entity:r.Presentation,actionType:n.Select,descriptor:o.Curriculum,location:t.locationContext})}function G(){return p?e?!!C&&V.hasCompleted:!0:!1}return{preferredCurriculum:p||z.data,curriculumLinks:C||[],availableCurriculums:M.data||[],mappedCurriculums:V.data||[],updateCurriculum:H,hasCompleted:G(),isFetching:k}};export{O as t};
|
|
2
|
+
//# sourceMappingURL=D7tastET2.chunk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BqO6i89w2.chunk.js","names":[],"sources":["../../../../libs/shared/src/flight-requests/PreferenceRequests.ts","../../src/apps/videos/hooks/useCurriculums.ts"],"sourcesContent":["import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { SharedWithStatements } from 'libs/shared/constants/WithStatements';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { Presentation, PresentationAudience } from 'libs/shared/interfaces';\n\nconst classificationQuery = SharedWithStatements.CLASSIFICATION_COLLECTION;\n\nconst endpoints = {\n // Subjects\n allSubjectPreferences: () => `{gateway}/v1/users/me/classifications/preferences?query=${classificationQuery}&type=subject`,\n mySubjectPreferences: () => `{gateway}/v1/users/me/classifications/following?query=${classificationQuery}`,\n followSubjects: () => '{gateway}/v1/users/me/classifications/following',\n unfollowSubjects: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/classifications/following', { id: ids }),\n\n // Levels\n allLevelPreferences: () => `{gateway}/v1/users/me/audiences?type=subject`,\n myLevelPreferences: () => `{gateway}/v1/users/me/audiences/following`,\n followLevels: () => `{gateway}/v1/users/me/audiences/following`,\n unfollowLevels: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/audiences/following', { id: ids }),\n\n getCurrentPresentations: (type?: PresentationType) =>\n `{gateway}/v1/users/me/presentations${type ? `?type=${type}` : ''}`,\n getAvailablePresentations: (type?: PresentationType) =>\n `{gateway}/v1/users/me/presentations/available${type ? `?type=${type}` : ''}`,\n setPresentation: (id: string) => `{gateway}/v1/users/me/presentations/${id}`\n};\n\nexport const PreferenceRequests = {\n /**\n * Presentations\n */\n\n availablePresentations(type?: PresentationType): Flight.Request {\n return {\n url: endpoints.getAvailablePresentations(type),\n key: `available:presentations:${type}`,\n normalizeOptions: {\n namespace: 'presentation'\n }\n };\n },\n\n setPresentation(\n presentation: Presentation,\n type: PresentationType,\n success?: () => void,\n error?: () => void\n ): Flight.Request {\n return {\n url: endpoints.setPresentation(presentation.id),\n key: `set:${type}:presentation`,\n type: HttpVerbs.POST,\n data: {},\n normalizeOptions: {\n namespace: 'presentation'\n },\n invalidationKeys: [\n `current:presentation:${type.toLocaleLowerCase()}`,\n 'subject:preference:options',\n 'my:subject:preferences',\n 'level:preference:options',\n 'my:level:preferences',\n 'classifications',\n 'presentation:audiences',\n 'widgets:v3',\n 'content:update:videos',\n 'content:updates'\n ],\n success,\n error\n };\n },\n\n /**\n * Subjects\n */\n allSubjectPreferences(): Flight.Request {\n return {\n url: endpoints.allSubjectPreferences(),\n key: `subject:preference:options`\n };\n },\n\n mySubjectPreferences(success?: (data: any) => void): Flight.Request {\n return {\n url: endpoints.mySubjectPreferences(),\n key: `my:subject:preferences`,\n normalize: false,\n success\n };\n },\n\n followSubjects(\n subjectIds: string[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.followSubjects(),\n key: `follow:subjects`,\n data: subjectIds,\n type: HttpVerbs.POST,\n success,\n error,\n always,\n invalidationKeys: [ ...subjectIds.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications', 'content:updates' ]\n };\n },\n\n unfollowSubjects(\n subjectIds: string[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.unfollowSubjects(subjectIds),\n key: `unfollow:subjects`,\n type: HttpVerbs.DELETE,\n success,\n error,\n always,\n invalidationKeys: [ ...subjectIds.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications', 'content:updates' ]\n };\n },\n\n /**\n * Levels\n */\n allLevelPreferences(): Flight.Request {\n return {\n url: endpoints.allLevelPreferences(),\n key: `level:preference:options`,\n normalize: false\n };\n },\n\n myLevelPreferences(success?: (data: any) => void): Flight.Request {\n return {\n url: endpoints.myLevelPreferences(),\n key: `my:level:preferences`,\n normalizeOptions: {\n idAttribute: 'masterId'\n },\n success\n };\n },\n\n followLevels(\n levels: PresentationAudience[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.followLevels(),\n key: `follow:levels`,\n data: levels.map(l => l.masterId),\n normalize: false,\n // Update the store to immediately reflect changes\n updateState: {\n keys: 'my:level:preferences',\n updateData: storeData => {\n const preferences = storeData['my:level:preferences'] ?? [] as PresentationAudience[];\n\n levels.forEach(newLevel => {\n if (preferences.find((p: PresentationAudience) => p.masterId === newLevel.masterId))\n return;\n\n preferences.push(newLevel);\n });\n\n return {\n 'my:level:preferences': preferences\n };\n }\n },\n type: HttpVerbs.POST,\n success,\n error,\n always\n };\n },\n\n unfollowLevels(\n levels: PresentationAudience[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.unfollowLevels(levels.map(l => l.masterId)),\n key: `unfollow:levels`,\n normalize: false,\n // Update the store to immediately reflect changes\n updateState: {\n keys: 'my:level:preferences',\n updateData: storeData => {\n let preferences = storeData['my:level:preferences'] ?? [] as PresentationAudience[];\n\n levels.forEach(oldLevel => {\n if (!preferences.find((p: PresentationAudience) => p.masterId === oldLevel.masterId))\n return;\n\n const idxOfValue = preferences.findIndex((p: PresentationAudience) => p.masterId === oldLevel.masterId);\n\n preferences = [ ...preferences.slice(0, idxOfValue), ...preferences.slice(idxOfValue + 1) ];\n });\n\n return {\n 'my:level:preferences': preferences\n };\n }\n },\n type: HttpVerbs.DELETE,\n success,\n error,\n always\n };\n }\n};\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, PresentationDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { PreferenceRequests } from 'libs/shared/flight-requests/PreferenceRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CurrentUser, Curriculum, CurriculumAnalyticsOptions, CurriculumData, Presentation } from 'libs/shared/interfaces';\n\nconst namespace = 'videos.hooks';\n\nconst curriculumLinksCache = new Map<string, Curriculum[][]>();\n\nexport const useCurriculums = (videoId?: string): CurriculumData => {\n function getPublicPresentationLocalStorageKey(type: PresentationType): string {\n return `${type.toLowerCase()}:${SharedViewModelKeys.PRESENTATION_ID}`;\n }\n\n const [ publicPresentationId, setPublicPresentationId ] = useViewModel<string>(\n getPublicPresentationLocalStorageKey(PresentationType.Curriculum),\n undefined,\n { storage: StorageType.LocalStorage }\n );\n\n const [ activeCurriculum, setActiveCurriculum ] = React.useState<Presentation>(null);\n const [ curriculumLinks, setCurriculumLinks ] = React.useState<Curriculum[][]>(null);\n const [ isFetching, setIsFetching ] = React.useState<boolean>(false);\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const availableCurriculums = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Curriculum)\n );\n\n const fetchAsync = Flight.useGetFetchAsync();\n const alerts = useAlerts();\n const { hasLocalPermissions } = usePermissions();\n const canManagePublicPresentation = hasLocalPermissions(LocalPermissionName.ManagePublicPresentation);\n \n function getAnonPresentationId(): string {\n /**\n * Where a public user has already nominated a presentation and \n * it's persisted in LocalStorage retrieve that.\n */\n const hasValidPublicPresentationId = !isNaN(+publicPresentationId);\n if (hasValidPublicPresentationId)\n return publicPresentationId;\n\n /**\n * Where the public user has yet to nominate a presentation, we'll preload with a Level 1 presentation\n * They'll be prompted to select a presentation\n */\n return ArrayHelper.first(availableCurriculums.data)?.id;\n }\n\n function getPreferredCurriculumRequest() {\n if (currentUser.data?.isAuthenticated)\n return ClassificationRequests.presentation(PresentationType.Curriculum);\n\n const anonPresentationId = getAnonPresentationId();\n\n if (!anonPresentationId)\n return null;\n\n return ClassificationRequests.presentationById(anonPresentationId);\n }\n\n const preferredCurriculum = Flight.useBasicFetch<Presentation>(getPreferredCurriculumRequest());\n\n React.useEffect(() => {\n if (!preferredCurriculum.data)\n return;\n\n setActiveCurriculum(preferredCurriculum.data);\n\n if (videoId && !curriculumLinks) {\n fetchAsync<Curriculum[][]>(ClassificationRequests.curriculumLinks(videoId, preferredCurriculum.data?.id))\n .then(links => {\n setCurriculumLinks(links);\n curriculumLinksCache.set(preferredCurriculum.data?.id?.toString(), links);\n });\n }\n }, [preferredCurriculum.data?.id]);\n \n const availableCurriculumIds = availableCurriculums.data?.map(c => c.id) ?? [];\n\n const mappedCurriculums = Flight.useBasicFetch<Presentation[]>(\n videoId &&\n availableCurriculumIds.length &&\n ClassificationRequests.getMappedCurriculums(\n videoId,\n availableCurriculumIds\n )\n );\n\n async function updateCurriculum(\n curriculumId: string,\n analyticsOptions: CurriculumAnalyticsOptions\n ): Promise<void> {\n if (activeCurriculum.id.toString() === curriculumId.toString())\n return;\n\n const curriculum = availableCurriculums.data.find(c => c.id.toString() === curriculumId.toString());\n\n setActiveCurriculum(curriculum);\n\n /**\n * In a public context, we'll persist the selected presentation's id to Local Storage\n */\n if (canManagePublicPresentation)\n setPublicPresentationId(curriculumId);\n\n try {\n if (videoId)\n await updateCurriculumLinks(curriculumId);\n\n if (canManagePublicPresentation)\n return;\n\n await fetchAsync(\n PreferenceRequests.setPresentation(curriculum, PresentationType.Curriculum)\n );\n\n logCurriculumChangeEvent(curriculum, analyticsOptions);\n } catch {\n alerts.error(LanguageService.getPhrase(namespace, 'curriculumUpdateError'));\n\n // If we fail to update, rollback to the previous curriculum\n setActiveCurriculum(activeCurriculum);\n }\n }\n\n async function updateCurriculumLinks(curriculumId: string) {\n if (!videoId)\n return;\n\n // If we've already fetched the links for this curriculum, use the cached data\n if (curriculumLinksCache.has(curriculumId.toString())) {\n setCurriculumLinks(curriculumLinksCache.get(curriculumId.toString()));\n return;\n }\n \n // If we don't have any curriculums mapped to our video, set the links to an empty array\n if (!mappedCurriculums.data.find(c => c.id.toString() === curriculumId.toString())) {\n setCurriculumLinks([]);\n return;\n }\n\n // Fetch the curriculum links for our video\n setIsFetching(true);\n\n const links = await fetchAsync<Curriculum[][]>(\n ClassificationRequests.curriculumLinks(videoId, curriculumId)\n );\n\n setCurriculumLinks(links);\n curriculumLinksCache.set(curriculumId.toString(), links);\n\n setIsFetching(false);\n }\n\n function logCurriculumChangeEvent(curriculum: Presentation, analyticsOptions: CurriculumAnalyticsOptions): void {\n if (!analyticsOptions.shouldLog)\n return;\n\n const analyticsData: HashObject = {\n id: curriculum.id,\n name: curriculum.id,\n description: curriculum.description\n };\n\n if (analyticsOptions.video) {\n analyticsData.videoId = analyticsOptions.video.id;\n analyticsData.videoName = analyticsOptions.video.name;\n }\n\n AnalyticsHelper.logUserAction(analyticsData, {\n entity: EntityType.Presentation,\n actionType: UserAction.Select,\n descriptor: PresentationDescriptor.Curriculum,\n location: analyticsOptions.locationContext\n });\n }\n\n function hasCompleted(): boolean {\n if (!activeCurriculum)\n return false;\n\n if (!videoId)\n return true;\n\n return !!curriculumLinks && mappedCurriculums.hasCompleted;\n }\n\n return {\n preferredCurriculum: activeCurriculum || preferredCurriculum.data,\n curriculumLinks: curriculumLinks || [],\n availableCurriculums: availableCurriculums.data || [],\n mappedCurriculums: mappedCurriculums.data || [],\n updateCurriculum,\n hasCompleted: hasCompleted(),\n isFetching\n };\n};\n"],"mappings":"qoBAQA,IAAM,EAAsB,EAAqB,0BAE3C,EAAY,CAEhB,0BAA6B,2DAA2D,EAAoB,eAC5G,yBAA4B,yDAAyD,IACrF,mBAAsB,kDACtB,iBAAmB,GAAkB,EAAU,WAAW,kDAAmD,CAAE,GAAI,EAAK,CAAC,CAGzH,wBAA2B,+CAC3B,uBAA0B,4CAC1B,iBAAoB,4CACpB,eAAiB,GAAkB,EAAU,WAAW,4CAA6C,CAAE,GAAI,EAAK,CAAC,CAEjH,wBAA0B,GACxB,sCAAsC,EAAO,SAAS,IAAS,KACjE,0BAA4B,GAC1B,gDAAgD,EAAO,SAAS,IAAS,KAC3E,gBAAkB,GAAe,uCAAuC,IACzE,CAEY,EAAqB,CAKhC,uBAAuB,EAAyC,CAC9D,MAAO,CACL,IAAK,EAAU,0BAA0B,EAAK,CAC9C,IAAK,2BAA2B,IAChC,iBAAkB,CAChB,UAAW,eAAA,CAEd,EAGH,gBACE,EACA,EACA,EACA,EACgB,CAChB,MAAO,CACL,IAAK,EAAU,gBAAgB,EAAa,GAAG,CAC/C,IAAK,OAAO,EAAK,eACjB,KAAM,EAAU,KAChB,KAAM,EAAE,CACR,iBAAkB,CAChB,UAAW,eACZ,CACD,iBAAkB,CAChB,wBAAwB,EAAK,mBAAmB,GAChD,6BACA,yBACA,2BACA,uBACA,kBACA,yBACA,aACA,wBACA,kBACD,CACD,UACA,QACD,EAMH,uBAAwC,CACtC,MAAO,CACL,IAAK,EAAU,uBAAuB,CACtC,IAAK,6BACN,EAGH,qBAAqB,EAA+C,CAClE,MAAO,CACL,IAAK,EAAU,sBAAsB,CACrC,IAAK,yBACL,UAAW,GACX,UACD,EAGH,eACE,EACA,EACA,EACA,EACgB,CAChB,MAAO,CACL,IAAK,EAAU,gBAAgB,CAC/B,IAAK,kBACL,KAAM,EACN,KAAM,EAAU,KAChB,UACA,QACA,SACA,iBAAkB,CAAE,GAAG,EAAW,IAAI,GAAM,kBAAkB,IAAK,CAAE,yBAA0B,kBAAmB,mBACnH,EAGH,iBACE,EACA,EACA,EACA,EACgB,CAChB,MAAO,CACL,IAAK,EAAU,iBAAiB,EAAW,CAC3C,IAAK,oBACL,KAAM,EAAU,OAChB,UACA,QACA,SACA,iBAAkB,CAAE,GAAG,EAAW,IAAI,GAAM,kBAAkB,IAAK,CAAE,yBAA0B,kBAAmB,mBACnH,EAMH,qBAAsC,CACpC,MAAO,CACL,IAAK,EAAU,qBAAqB,CACpC,IAAK,2BACL,UAAW,GACZ,EAGH,mBAAmB,EAA+C,CAChE,MAAO,CACL,IAAK,EAAU,oBAAoB,CACnC,IAAK,uBACL,iBAAkB,CAChB,YAAa,WACd,CACD,UACD,EAGH,aACE,EACA,EACA,EACA,EACgB,CAChB,MAAO,CACL,IAAK,EAAU,cAAc,CAC7B,IAAK,gBACL,KAAM,EAAO,IAAI,GAAK,EAAE,SAAS,CACjC,UAAW,GAEX,YAAa,CACX,KAAM,uBACN,WAAY,GAAa,CACvB,IAAM,EAAc,EAAU,yBAA2B,EAAE,CAS3D,OAPA,EAAO,QAAQ,GAAY,CACrB,EAAY,KAAM,GAA4B,EAAE,WAAa,EAAS,SAAS,EAGnF,EAAY,KAAK,EAAS,EAC1B,CAEK,CACL,uBAAwB,EACzB,EAEJ,CACD,KAAM,EAAU,KAChB,UACA,QACA,SACD,EAGH,eACE,EACA,EACA,EACA,EACgB,CAChB,MAAO,CACL,IAAK,EAAU,eAAe,EAAO,IAAI,GAAK,EAAE,SAAS,CAAC,CAC1D,IAAK,kBACL,UAAW,GAEX,YAAa,CACX,KAAM,uBACN,WAAY,GAAa,CACvB,IAAI,EAAc,EAAU,yBAA2B,EAAE,CAWzD,OATA,EAAO,QAAQ,GAAY,CACzB,GAAI,CAAC,EAAY,KAAM,GAA4B,EAAE,WAAa,EAAS,SAAS,CAClF,OAEF,IAAM,EAAa,EAAY,UAAW,GAA4B,EAAE,WAAa,EAAS,SAAS,CAEvG,EAAc,CAAE,GAAG,EAAY,MAAM,EAAG,EAAW,CAAE,GAAG,EAAY,MAAM,EAAa,EAAE,CAAE,EAC3F,CAEK,CACL,uBAAwB,EACzB,EAEJ,CACD,KAAM,EAAU,OAChB,UACA,QACA,SACD,EAEJ,UC3MK,EAAY,eAEZ,EAAuB,IAAI,IAEpB,EAAkB,GAAqC,CAClE,SAAS,EAAqC,EAAgC,CAC5E,MAAO,GAAG,EAAK,aAAa,CAAC,GAAG,EAAoB,kBAGtD,GAAM,CAAE,EAAsB,GAA4B,EACxD,EAAqC,EAAiB,WAAW,CACjE,IAAA,GACA,CAAE,QAAS,EAAY,aAAc,CACtC,CAEK,CAAE,EAAkB,GAAA,EAA8B,SAAuB,KAAK,CAC9E,CAAE,EAAiB,GAAA,EAA6B,SAAyB,KAAK,CAC9E,CAAE,EAAY,GAAA,EAAwB,SAAkB,GAAM,CAE9D,EAAc,EAAkC,EAAa,aAAa,CAAC,CAC3E,EAAuB,EAC3B,EAAuB,uBAAuB,EAAiB,WAAW,CAC3E,CAEK,EAAa,GAAyB,CACtC,EAAS,GAAW,CACpB,CAAE,uBAAwB,GAAgB,CAC1C,EAA8B,EAAoB,EAAoB,yBAAyB,CAErG,SAAS,GAAgC,CAavC,OARsC,MAAM,CAAC,EAAqB,CAQ3D,EAAY,MAAM,EAAqB,KAAK,EAAE,GAN5C,EASX,SAAS,GAAgC,CACvC,GAAI,EAAY,MAAM,gBACpB,OAAO,EAAuB,aAAa,EAAiB,WAAW,CAEzE,IAAM,EAAqB,GAAuB,CAKlD,OAHK,EAGE,EAAuB,iBAAiB,EAAmB,CAFzD,KAKX,IAAM,EAAsB,EAAmC,GAA+B,CAAC,CAE/F,EAAM,cAAgB,CACf,EAAoB,OAGzB,EAAoB,EAAoB,KAAK,CAEzC,GAAW,CAAC,GACd,EAA2B,EAAuB,gBAAgB,EAAS,EAAoB,MAAM,GAAG,CAAC,CACtG,KAAK,GAAS,CACb,EAAmB,EAAM,CACzB,EAAqB,IAAI,EAAoB,MAAM,IAAI,UAAU,CAAE,EAAM,EACzE,GAEL,CAAC,EAAoB,MAAM,GAAG,CAAC,CAElC,IAAM,EAAyB,EAAqB,MAAM,IAAI,GAAK,EAAE,GAAG,EAAI,EAAE,CAExE,EAAoB,EACxB,GACA,EAAuB,QACvB,EAAuB,qBACrB,EACA,EACD,CACF,CAED,eAAe,EACb,EACA,EACe,CACf,GAAI,EAAiB,GAAG,UAAU,GAAK,EAAa,UAAU,CAC5D,OAEF,IAAM,EAAa,EAAqB,KAAK,KAAK,GAAK,EAAE,GAAG,UAAU,GAAK,EAAa,UAAU,CAAC,CAEnG,EAAoB,EAAW,CAK3B,GACF,EAAwB,EAAa,CAEvC,GAAI,CAIF,GAHI,GACF,MAAM,EAAsB,EAAa,CAEvC,EACF,OAEF,MAAM,EACJ,EAAmB,gBAAgB,EAAY,EAAiB,WAAW,CAC5E,CAED,EAAyB,EAAY,EAAiB,MAChD,CACN,EAAO,MAAM,EAAgB,UAAU,EAAW,wBAAwB,CAAC,CAG3E,EAAoB,EAAiB,EAIzC,eAAe,EAAsB,EAAsB,CACzD,GAAI,CAAC,EACH,OAGF,GAAI,EAAqB,IAAI,EAAa,UAAU,CAAC,CAAE,CACrD,EAAmB,EAAqB,IAAI,EAAa,UAAU,CAAC,CAAC,CACrE,OAIF,GAAI,CAAC,EAAkB,KAAK,KAAK,GAAK,EAAE,GAAG,UAAU,GAAK,EAAa,UAAU,CAAC,CAAE,CAClF,EAAmB,EAAE,CAAC,CACtB,OAIF,EAAc,GAAK,CAEnB,IAAM,EAAQ,MAAM,EAClB,EAAuB,gBAAgB,EAAS,EAAa,CAC9D,CAED,EAAmB,EAAM,CACzB,EAAqB,IAAI,EAAa,UAAU,CAAE,EAAM,CAExD,EAAc,GAAM,CAGtB,SAAS,EAAyB,EAA0B,EAAoD,CAC9G,GAAI,CAAC,EAAiB,UACpB,OAEF,IAAM,EAA4B,CAChC,GAAI,EAAW,GACf,KAAM,EAAW,GACjB,YAAa,EAAW,YACzB,CAEG,EAAiB,QACnB,EAAc,QAAU,EAAiB,MAAM,GAC/C,EAAc,UAAY,EAAiB,MAAM,MAGnD,EAAgB,cAAc,EAAe,CAC3C,OAAQ,EAAW,aACnB,WAAY,EAAW,OACvB,WAAY,EAAuB,WACnC,SAAU,EAAiB,gBAC5B,CAAC,CAGJ,SAAS,GAAwB,CAO/B,OANK,EAGA,EAGE,CAAC,CAAC,GAAmB,EAAkB,aAFrC,GAHA,GAQX,MAAO,CACL,oBAAqB,GAAoB,EAAoB,KAC7D,gBAAiB,GAAmB,EAAE,CACtC,qBAAsB,EAAqB,MAAQ,EAAE,CACrD,kBAAmB,EAAkB,MAAQ,EAAE,CAC/C,mBACA,aAAc,GAAc,CAC5B,aACD"}
|
|
1
|
+
{"version":3,"file":"D7tastET2.chunk.js","names":[],"sources":["../../../../libs/shared/src/flight-requests/PreferenceRequests.ts","../../src/apps/videos/hooks/useCurriculums.ts"],"sourcesContent":["import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { SharedWithStatements } from 'libs/shared/constants/WithStatements';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { Presentation, PresentationAudience } from 'libs/shared/interfaces';\n\nconst classificationQuery = SharedWithStatements.CLASSIFICATION_COLLECTION;\n\nconst endpoints = {\n // Subjects\n allSubjectPreferences: () => `{gateway}/v1/users/me/classifications/preferences?query=${classificationQuery}&type=subject`,\n mySubjectPreferences: () => `{gateway}/v1/users/me/classifications/following?query=${classificationQuery}`,\n followSubjects: () => '{gateway}/v1/users/me/classifications/following',\n unfollowSubjects: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/classifications/following', { id: ids }),\n\n // Levels\n allLevelPreferences: () => `{gateway}/v1/users/me/audiences?type=subject`,\n myLevelPreferences: () => `{gateway}/v1/users/me/audiences/following`,\n followLevels: () => `{gateway}/v1/users/me/audiences/following`,\n unfollowLevels: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/audiences/following', { id: ids }),\n\n getCurrentPresentations: (type?: PresentationType) =>\n `{gateway}/v1/users/me/presentations${type ? `?type=${type}` : ''}`,\n getAvailablePresentations: (type?: PresentationType) =>\n `{gateway}/v1/users/me/presentations/available${type ? `?type=${type}` : ''}`,\n setPresentation: (id: string) => `{gateway}/v1/users/me/presentations/${id}`\n};\n\nexport const PreferenceRequests = {\n /**\n * Presentations\n */\n\n availablePresentations(type?: PresentationType): Flight.Request {\n return {\n url: endpoints.getAvailablePresentations(type),\n key: `available:presentations:${type}`,\n normalizeOptions: {\n namespace: 'presentation'\n }\n };\n },\n\n setPresentation(\n presentation: Presentation,\n type: PresentationType,\n success?: () => void,\n error?: () => void\n ): Flight.Request {\n return {\n url: endpoints.setPresentation(presentation.id),\n key: `set:${type}:presentation`,\n type: HttpVerbs.POST,\n data: {},\n normalizeOptions: {\n namespace: 'presentation'\n },\n invalidationKeys: [\n `current:presentation:${type.toLocaleLowerCase()}`,\n 'subject:preference:options',\n 'my:subject:preferences',\n 'level:preference:options',\n 'my:level:preferences',\n 'classifications',\n 'presentation:audiences',\n 'widgets:v3',\n 'content:update:videos',\n 'content:updates'\n ],\n success,\n error\n };\n },\n\n /**\n * Subjects\n */\n allSubjectPreferences(): Flight.Request {\n return {\n url: endpoints.allSubjectPreferences(),\n key: `subject:preference:options`\n };\n },\n\n mySubjectPreferences(success?: (data: any) => void): Flight.Request {\n return {\n url: endpoints.mySubjectPreferences(),\n key: `my:subject:preferences`,\n normalize: false,\n success\n };\n },\n\n followSubjects(\n subjectIds: string[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.followSubjects(),\n key: `follow:subjects`,\n data: subjectIds,\n type: HttpVerbs.POST,\n success,\n error,\n always,\n invalidationKeys: [ ...subjectIds.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications', 'content:updates' ]\n };\n },\n\n unfollowSubjects(\n subjectIds: string[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.unfollowSubjects(subjectIds),\n key: `unfollow:subjects`,\n type: HttpVerbs.DELETE,\n success,\n error,\n always,\n invalidationKeys: [ ...subjectIds.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications', 'content:updates' ]\n };\n },\n\n /**\n * Levels\n */\n allLevelPreferences(): Flight.Request {\n return {\n url: endpoints.allLevelPreferences(),\n key: `level:preference:options`,\n normalize: false\n };\n },\n\n myLevelPreferences(success?: (data: any) => void): Flight.Request {\n return {\n url: endpoints.myLevelPreferences(),\n key: `my:level:preferences`,\n normalizeOptions: {\n idAttribute: 'masterId'\n },\n success\n };\n },\n\n followLevels(\n levels: PresentationAudience[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.followLevels(),\n key: `follow:levels`,\n data: levels.map(l => l.masterId),\n normalize: false,\n // Update the store to immediately reflect changes\n updateState: {\n keys: 'my:level:preferences',\n updateData: storeData => {\n const preferences = storeData['my:level:preferences'] ?? [] as PresentationAudience[];\n\n levels.forEach(newLevel => {\n if (preferences.find((p: PresentationAudience) => p.masterId === newLevel.masterId))\n return;\n\n preferences.push(newLevel);\n });\n\n return {\n 'my:level:preferences': preferences\n };\n }\n },\n type: HttpVerbs.POST,\n success,\n error,\n always\n };\n },\n\n unfollowLevels(\n levels: PresentationAudience[],\n success?: () => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: endpoints.unfollowLevels(levels.map(l => l.masterId)),\n key: `unfollow:levels`,\n normalize: false,\n // Update the store to immediately reflect changes\n updateState: {\n keys: 'my:level:preferences',\n updateData: storeData => {\n let preferences = storeData['my:level:preferences'] ?? [] as PresentationAudience[];\n\n levels.forEach(oldLevel => {\n if (!preferences.find((p: PresentationAudience) => p.masterId === oldLevel.masterId))\n return;\n\n const idxOfValue = preferences.findIndex((p: PresentationAudience) => p.masterId === oldLevel.masterId);\n\n preferences = [ ...preferences.slice(0, idxOfValue), ...preferences.slice(idxOfValue + 1) ];\n });\n\n return {\n 'my:level:preferences': preferences\n };\n }\n },\n type: HttpVerbs.DELETE,\n success,\n error,\n always\n };\n }\n};\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, PresentationDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { PreferenceRequests } from 'libs/shared/flight-requests/PreferenceRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CurrentUser, Curriculum, CurriculumAnalyticsOptions, CurriculumData, Presentation } from 'libs/shared/interfaces';\n\nconst namespace = 'videos.hooks';\n\nconst curriculumLinksCache = new Map<string, Curriculum[][]>();\n\nexport const useCurriculums = (videoId?: string): CurriculumData => {\n function getPublicPresentationLocalStorageKey(type: PresentationType): string {\n return `${type.toLowerCase()}:${SharedViewModelKeys.PRESENTATION_ID}`;\n }\n\n const [ publicPresentationId, setPublicPresentationId ] = useViewModel<string>(\n getPublicPresentationLocalStorageKey(PresentationType.Curriculum),\n undefined,\n { storage: StorageType.LocalStorage }\n );\n\n const [ activeCurriculum, setActiveCurriculum ] = React.useState<Presentation>(null);\n const [ curriculumLinks, setCurriculumLinks ] = React.useState<Curriculum[][]>(null);\n const [ isFetching, setIsFetching ] = React.useState<boolean>(false);\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const availableCurriculums = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Curriculum)\n );\n\n const fetchAsync = Flight.useGetFetchAsync();\n const alerts = useAlerts();\n const { hasLocalPermissions } = usePermissions();\n const canManagePublicPresentation = hasLocalPermissions(LocalPermissionName.ManagePublicPresentation);\n \n function getAnonPresentationId(): string {\n /**\n * Where a public user has already nominated a presentation and \n * it's persisted in LocalStorage retrieve that.\n */\n const hasValidPublicPresentationId = !isNaN(+publicPresentationId);\n if (hasValidPublicPresentationId)\n return publicPresentationId;\n\n /**\n * Where the public user has yet to nominate a presentation, we'll preload with a Level 1 presentation\n * They'll be prompted to select a presentation\n */\n return ArrayHelper.first(availableCurriculums.data)?.id;\n }\n\n function getPreferredCurriculumRequest() {\n if (currentUser.data?.isAuthenticated)\n return ClassificationRequests.presentation(PresentationType.Curriculum);\n\n const anonPresentationId = getAnonPresentationId();\n\n if (!anonPresentationId)\n return null;\n\n return ClassificationRequests.presentationById(anonPresentationId);\n }\n\n const preferredCurriculum = Flight.useBasicFetch<Presentation>(getPreferredCurriculumRequest());\n\n React.useEffect(() => {\n if (!preferredCurriculum.data)\n return;\n\n setActiveCurriculum(preferredCurriculum.data);\n\n if (videoId && !curriculumLinks) {\n fetchAsync<Curriculum[][]>(ClassificationRequests.curriculumLinks(videoId, preferredCurriculum.data?.id))\n .then(links => {\n setCurriculumLinks(links);\n curriculumLinksCache.set(preferredCurriculum.data?.id?.toString(), links);\n });\n }\n }, [preferredCurriculum.data?.id]);\n \n const availableCurriculumIds = availableCurriculums.data?.map(c => c.id) ?? [];\n\n const mappedCurriculums = Flight.useBasicFetch<Presentation[]>(\n videoId &&\n availableCurriculumIds.length &&\n ClassificationRequests.getMappedCurriculums(\n videoId,\n availableCurriculumIds\n )\n );\n\n async function updateCurriculum(\n curriculumId: string,\n analyticsOptions: CurriculumAnalyticsOptions\n ): Promise<void> {\n if (activeCurriculum.id.toString() === curriculumId.toString())\n return;\n\n const curriculum = availableCurriculums.data.find(c => c.id.toString() === curriculumId.toString());\n\n setActiveCurriculum(curriculum);\n\n /**\n * In a public context, we'll persist the selected presentation's id to Local Storage\n */\n if (canManagePublicPresentation)\n setPublicPresentationId(curriculumId);\n\n try {\n if (videoId)\n await updateCurriculumLinks(curriculumId);\n\n if (canManagePublicPresentation)\n return;\n\n await fetchAsync(\n PreferenceRequests.setPresentation(curriculum, PresentationType.Curriculum)\n );\n\n logCurriculumChangeEvent(curriculum, analyticsOptions);\n } catch {\n alerts.error(LanguageService.getPhrase(namespace, 'curriculumUpdateError'));\n\n // If we fail to update, rollback to the previous curriculum\n setActiveCurriculum(activeCurriculum);\n }\n }\n\n async function updateCurriculumLinks(curriculumId: string) {\n if (!videoId)\n return;\n\n // If we've already fetched the links for this curriculum, use the cached data\n if (curriculumLinksCache.has(curriculumId.toString())) {\n setCurriculumLinks(curriculumLinksCache.get(curriculumId.toString()));\n return;\n }\n \n // If we don't have any curriculums mapped to our video, set the links to an empty array\n if (!mappedCurriculums.data.find(c => c.id.toString() === curriculumId.toString())) {\n setCurriculumLinks([]);\n return;\n }\n\n // Fetch the curriculum links for our video\n setIsFetching(true);\n\n const links = await fetchAsync<Curriculum[][]>(\n ClassificationRequests.curriculumLinks(videoId, curriculumId)\n );\n\n setCurriculumLinks(links);\n curriculumLinksCache.set(curriculumId.toString(), links);\n\n setIsFetching(false);\n }\n\n function logCurriculumChangeEvent(curriculum: Presentation, analyticsOptions: CurriculumAnalyticsOptions): void {\n if (!analyticsOptions.shouldLog)\n return;\n\n const analyticsData: HashObject = {\n id: curriculum.id,\n name: curriculum.id,\n description: curriculum.description\n };\n\n if (analyticsOptions.video) {\n analyticsData.videoId = analyticsOptions.video.id;\n analyticsData.videoName = analyticsOptions.video.name;\n }\n\n AnalyticsHelper.logUserAction(analyticsData, {\n entity: EntityType.Presentation,\n actionType: UserAction.Select,\n descriptor: PresentationDescriptor.Curriculum,\n location: analyticsOptions.locationContext\n });\n }\n\n function hasCompleted(): boolean {\n if (!activeCurriculum)\n return false;\n\n if (!videoId)\n return true;\n\n return !!curriculumLinks && mappedCurriculums.hasCompleted;\n }\n\n return {\n preferredCurriculum: activeCurriculum || preferredCurriculum.data,\n curriculumLinks: curriculumLinks || [],\n availableCurriculums: availableCurriculums.data || [],\n mappedCurriculums: mappedCurriculums.data || [],\n updateCurriculum,\n hasCompleted: hasCompleted(),\n isFetching\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t}from"./ImQRQGZr.chunk.js";import{C as n,c as r,dt as i,l as a,lt as o,ut as s}from"./Dun43GrB.chunk.js";import{t as c}from"./B-OL6Vs7.chunk.js";import{l}from"./BQ5XMoHG.chunk.js";import{n as u}from"./C9ET3pjZ.chunk.js";import{t as d}from"./DeldjYRc.chunk.js";import"./CEsevkum.chunk.js";import{t as f}from"./BYYiNmLB.chunk.js";import"./BYFGYmGx2.chunk.js";import{t as p}from"./X4vTaPlk.chunk.js";import{M as m,X as h}from"./app-
|
|
1
|
+
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t}from"./ImQRQGZr.chunk.js";import{C as n,c as r,dt as i,l as a,lt as o,ut as s}from"./Dun43GrB.chunk.js";import{t as c}from"./B-OL6Vs7.chunk.js";import{l}from"./BQ5XMoHG.chunk.js";import{n as u}from"./C9ET3pjZ.chunk.js";import{t as d}from"./DeldjYRc.chunk.js";import"./CEsevkum.chunk.js";import{t as f}from"./BYYiNmLB.chunk.js";import"./BYFGYmGx2.chunk.js";import{t as p}from"./X4vTaPlk.chunk.js";import{M as m,X as h}from"./app-BIigh9wv.js";import{t as g}from"./DDKwae_D2.chunk.js";import{r as _}from"./BoeUzfPw2.chunk.js";import{t as v}from"./C9tPKnK22.chunk.js";import{i as y}from"./DobKejA8.chunk.js";var b=e(s()),x=o();function S(e){let t=`d-flex align-items-center badge-list ${_.minHeight}`;return e.className&&(t+=` ${e.className}`),(0,x.jsx)(`div`,{className:t,children:e.children})}var C={padNumber(e,t){let n=e.toString();if(n.length>=t)return n;for(t-=n.length;t>0;)n=`0`+n,t--;return n}},w={isSeries(e){return e?.typeId===p.Series},buildSeriesSeasonEpisodeText(e,t,n){if(!e)return``;if(!t||!n)return e.toUpperCase();let r=C.padNumber(t,2),i=C.padNumber(n,2);return`${e.toUpperCase()} S${r} • E${i}`},getRating(e){return e._rating?.value}},T={appLink:`_appLink_1owb0_1`,hoverUnderline:`_hoverUnderline_1owb0_4`},E=t.encloseNamespace(`shared.videoSubText`);function D(e){let{video:t}=e,{season:n}=t;if(!t.episodeNumber||!n)return(0,x.jsx)(x.Fragment,{});let r=C.padNumber(n.number,2),i=C.padNumber(t.episodeNumber,2);return(0,x.jsxs)(`span`,{className:`d-inline-block ${e.appLink?T.hoverUnderline:``}`,children:[e.withSeriesTitle&&(0,x.jsx)(x.Fragment,{children:`\xA0`}),!!r&&`S${r} \u2022 `,`E`,i]})}function O(e){let t=g.getReleaseDate(e.video);return t?g.hasSeries(e.video)?(0,x.jsx)(x.Fragment,{children:` \u2022 ${t}`}):(0,x.jsx)(x.Fragment,{children:t}):(0,x.jsx)(x.Fragment,{})}function k(e){let{appLink:t,video:o,className:s=``}=e,c=o?.series,l=g.getReleaseDate(e.video);if(!c?.id&&!l)return(0,x.jsx)(x.Fragment,{});let u=c?.id&&t&&{...t,args:t.args?t.args:[c.id,i.slugify(c.name)]},d={...e.analyticsData,id:c?.id,name:c?.name,videoId:o?.id,videoName:o?.name},f={...e.analyticsOptions,entity:a.Series,actionType:n.Click,descriptor:r.Title},p=w.buildSeriesSeasonEpisodeText(c?.name,o.season?.number,o.episodeNumber);return(0,x.jsxs)(y,{appLink:u,className:`d-block ${T.appLink} ${s}`,analyticsData:d,analyticsOptions:f,title:p,ariaLabel:`${E(`ariaSeries`)} ${p}`,children:[c?.name&&c.name,(0,x.jsx)(D,{...e,withSeriesTitle:!0}),(0,x.jsx)(O,{...e})]})}function A(e){let{appLink:t,video:o,className:s=``}=e,c=o?.productionCompanies?.data?.[0];if(!c?.id)return(0,x.jsx)(x.Fragment,{});let l=c?.id&&t&&{...t,args:t.args?t.args:[c.id,i.slugify(c.name)]},u={...e.analyticsData,id:c?.id,name:c?.name,videoId:o?.id,videoName:o?.name},d={...e.analyticsOptions,entity:a.Company,actionType:n.Click,descriptor:r.Title};return(0,x.jsx)(y,{appLink:l,className:`d-block ${T.appLink} ${s}`,analyticsData:u,analyticsOptions:d,title:c.name,ariaLabel:`${E(`ariaCompany`)} ${c.name}`,children:c.name})}function j(e){let{type:t=`series`}=e;return t===`none`?(0,x.jsx)(x.Fragment,{}):t===`series`?(0,x.jsx)(k,{...e}):(0,x.jsx)(A,{...e})}var M=b.createContext({hasProvider:!1});function N(){return b.useContext(M)}function P(e){return(0,x.jsx)(`svg`,{...e,children:(0,x.jsx)(`path`,{fillRule:`evenodd`,d:`M0 12C0 5.373 5.373 0 12 0s12 5.373 12 12-5.373 12-12 12S0 18.627 0 12m23 0c0-6.075-4.925-11-11-11S1 5.925 1 12s4.925 11 11 11 11-4.925 11-11M9 7.498c0-.551.387-.756.847-.469l7.306 4.567c.468.292.46.77 0 1.058l-7.306 4.567c-.468.292-.847.074-.847-.47z`,fill:`currentColor`})})}function F(e){return e.audience?(0,x.jsx)(`div`,{className:`audience-label border rounded-pill d-inline-block px-2 text-nowrap
|
|
2
2
|
${`border-`+e.border} ${e.className?e.className:``}`,children:e.audience.name}):(0,x.jsx)(x.Fragment,{})}function I(e,t){let n=b.useMemo(()=>!e?.length||!t||!v.shouldShowAudiences(t)?null:v.getSortedPresentationAudiences(e,t),[e]);return b.useMemo(()=>n?.length?v.getMergedPresentationAudienceString(n):null,[n])}function L(){let e=l(h.config()),{hasPermissions:t,isLoaded:n}=m();function r(e){if(!(`productionCompanies`in e))return null;let t=e.productionCompanies?.data?.[0];return t?.id?{application:c.DASHBOARD,action:d.Dashboard.COMPANY_DASHBOARD,args:[t.id,i.slugify(t.name)]}:null}function a(e){return{application:c.VIDEOS,action:d.Videos.CLASSROOM_GUIDE,args:[e]}}function o(e){return{application:c.VIDEOS,action:d.Videos.RESOURCE_GUIDANCE,args:[e]}}return{hasCommonVideoPropsCompleted:e.hasCompleted&&n,commonVideoProps:{subTextType:`productionCompany`,getSubTextAppLink:r,isPlugin:!1,canFavourite:null,setFavourite:null,imageCdnUrl:e.data?.imageCdnUrl,yearGroups:null,getInteractiveGuidanceAppLink:()=>null,getClassroomGuideAppLink:a,getResourceGuidanceAppLink:o,showNewVideoIndicator:!1,getCompanyLogoFallbackUrl:()=>f.StreamableLearning.LOGO,hasStudentExperience:t(u.StudentExperience),hasGuestExperience:!1,features:{showClassroomGuide:e=>g.canViewCurriculumLinks(t,e)}}}}export{N as a,w as c,P as i,S as l,I as n,D as o,F as r,j as s,L as t};
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=DIavEegC.chunk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CeI-LCE-.chunk.js","names":[],"sources":["../../../../libs/shared/src/components/badges/BadgeListContainer.tsx","../../../../libs/shared/src/utils/NumberHelper.ts","../../../../libs/shared/src/utils/SeriesHelper.ts","../../../../libs/shared/src/components/video-sub-text/video-sub-text.module.scss","../../../../libs/shared/src/components/video-sub-text/VideoSubText.tsx","../../../../libs/shared/src/context/player-context/PlayerContext.tsx","../../../../libs/shared/src/images/svg/actions/PlayCircleSvg.tsx","../../../../libs/shared/src/components/audience-label/AudienceLabel.tsx","../../../../libs/shared/src/hooks/UseMergeAudiences.ts","../../src/shared/hooks/useCommonVideoProps.ts"],"sourcesContent":["import * as React from 'react';\n\nimport styles from './badge.module.scss';\n\ninterface BadgeListContainerProps {\n className?: string;\n}\n\nexport function BadgeListContainer(props: React.PropsWithChildren<BadgeListContainerProps>): JSX.Element {\n let className = `d-flex align-items-center badge-list ${styles.minHeight}`;\n\n if (props.className)\n className += ` ${props.className}`;\n\n return (\n <div className={className}>\n {props.children}\n </div>\n );\n}\n","export const NumberHelper = {\n padNumber(num: number, padLength: number): string {\n let numberString = num.toString();\n\n if (numberString.length >= padLength)\n return numberString;\n\n padLength = padLength - numberString.length;\n\n while (padLength > 0) {\n numberString = '0' + numberString;\n padLength--;\n }\n return numberString;\n }\n};\n","import { MasterType } from 'libs/shared/enums/MasterType';\nimport { BaseObject, Rating, Series } from 'libs/shared/interfaces';\n\nimport { NumberHelper } from './NumberHelper';\n\nexport const SeriesHelper = {\n isSeries(obj: BaseObject): obj is Series {\n return obj?.typeId === MasterType.Series;\n },\n\n buildSeriesSeasonEpisodeText(seriesName: string, season?: number, episode?: number): string {\n if (!seriesName)\n return '';\n\n if (!season || !episode)\n return seriesName.toUpperCase();\n\n const seasonNum = NumberHelper.padNumber(season, 2);\n const episodeNum = NumberHelper.padNumber(episode, 2);\n\n return `${seriesName.toUpperCase()} S${seasonNum} • E${episodeNum}`;\n },\n\n getRating(series: Series): Rating {\n return series._rating?.value;\n }\n};\n",":local {\n .appLink {\n color: inherit;\n\n &:hover {\n .hoverUnderline {\n text-decoration: underline;\n }\n }\n }\n}","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { AnalyticsOptions, ClickDescriptor, EntityType, UserAction } from 'libs/analytics/interfaces/AnalyticsTypes';\n\nimport { Video } from 'libs/shared/interfaces';\nimport { NumberHelper } from 'libs/shared/utils/NumberHelper';\nimport { SeriesHelper } from 'libs/shared/utils/SeriesHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { TitleSubText } from '../title-sub-text/TitleSubText';\n\nconst namespace = 'shared.videoSubText';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './video-sub-text.module.scss';\n\nexport type VideoSubTextType = 'series' | 'productionCompany' | 'none';\n\ninterface SeriesLinkProps {\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n withSeriesTitle?: boolean;\n size?: 'sm' | 'lg';\n}\n\nexport function SeasonEpisode(props: Omit<SeriesLinkProps, 'analyticsOptions' | 'analyticsData'>): JSX.Element {\n const { video } = props;\n const { season } = video;\n\n if (!video.episodeNumber || !season)\n return <></>;\n\n const seasonNumber = NumberHelper.padNumber(season.number, 2);\n const episodeNumber = NumberHelper.padNumber(video.episodeNumber, 2);\n\n /* \\u2022 is the unicode number for • */\n return (\n <span className={`d-inline-block ${props.appLink ? styles.hoverUnderline : ''}`}>\n {props.withSeriesTitle && <> </>}\n {!!seasonNumber && `S${seasonNumber} \\u2022 `}\n E{episodeNumber}\n </span>\n );\n}\n\nfunction ReleaseDate(props: SeriesLinkProps): JSX.Element {\n const releaseDate = VideoHelper.getReleaseDate(props.video);\n\n if (!releaseDate)\n return <></>;\n\n if (VideoHelper.hasSeries(props.video))\n return <>{` \\u2022 ${releaseDate}`}</>;\n\n return <>{releaseDate}</>;\n}\n\nfunction SeriesLink(props: SeriesLinkProps): JSX.Element {\n const { appLink, video, className = '' } = props;\n\n const series = video?.series;\n const releaseDate = VideoHelper.getReleaseDate(props.video);\n\n if ((!series?.id) && !releaseDate)\n return <></>;\n\n const seriesAppLink: Core.AppLink = series?.id && appLink && {\n ...appLink,\n args: appLink.args ? appLink.args : [ series.id, TextHelper.slugify(series.name) ]\n };\n\n const analyticsData = { ...props.analyticsData,\n id: series?.id,\n name: series?.name,\n videoId: video?.id,\n videoName: video?.name\n };\n\n const analyticsOptions = {\n ...props.analyticsOptions,\n entity: EntityType.Series,\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Title\n };\n\n const seriesTitle = SeriesHelper.buildSeriesSeasonEpisodeText(\n series?.name,\n video.season?.number,\n video.episodeNumber\n );\n\n return (\n <TitleSubText\n appLink={seriesAppLink}\n className={`d-block ${styles.appLink} ${className}`}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n title={seriesTitle}\n ariaLabel={`${getPhrase('ariaSeries')} ${seriesTitle}`}\n >\n {series?.name && series.name}\n <SeasonEpisode {...props} withSeriesTitle />\n <ReleaseDate {...props} />\n </TitleSubText>\n );\n}\n\ninterface ProductionCompanyLinkProps {\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n size?: 'sm' | 'lg';\n}\n\nfunction ProductionCompanyLink(props: ProductionCompanyLinkProps): JSX.Element {\n const { appLink, video, className = '' } = props;\n\n const productionCompany = video?.productionCompanies?.data?.[0];\n\n if (!productionCompany?.id)\n return <></>;\n\n const companyAppLink: Core.AppLink = productionCompany?.id && appLink && {\n ...appLink,\n args: appLink.args ? appLink.args : [ productionCompany.id, TextHelper.slugify(productionCompany.name) ]\n };\n\n const analyticsData = { ...props.analyticsData,\n id: productionCompany?.id,\n name: productionCompany?.name,\n videoId: video?.id,\n videoName: video?.name\n };\n\n const analyticsOptions = {\n ...props.analyticsOptions,\n entity: EntityType.Company,\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Title\n };\n\n return (\n <TitleSubText\n appLink={companyAppLink}\n className={`d-block ${styles.appLink} ${className}`}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n title={productionCompany.name}\n ariaLabel={`${getPhrase('ariaCompany')} ${productionCompany.name}`}\n >\n {productionCompany.name}\n </TitleSubText>\n );\n}\n\ninterface VideoSubTextProps {\n type: VideoSubTextType;\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n size?: 'sm' | 'lg';\n}\n\nexport function VideoSubText(props: VideoSubTextProps): JSX.Element {\n const { type = 'series' } = props;\n\n if (type === 'none')\n return <></>;\n\n if (type === 'series')\n return <SeriesLink {...props} />;\n\n return <ProductionCompanyLink {...props} />;\n}\n\n","import React from 'react';\nimport { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal';\n\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { DefaultDisplayMode, PlayerInitializationData } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerContextState } from 'libs/shared/context/player-context/interfaces/PlayerContextState';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { playerContextReducer } from 'libs/shared/context/player-context/reducer/PlayerContextReducer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\nconst _THEATRE_MODE = 'play-page-theatre-mode';\n\nexport interface PlayerContextValues extends PlayerContextState {\n playerRef?: React.MutableRefObject<PlayerReference>;\n portalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n\n useInitialize?: (initializeData: PlayerInitializationData) => void;\n dispose?: () => void;\n setPlayerRef?: (player: any) => void;\n setPlayerMode?: (mode: PlayerMode) => void;\n setDefaultDisplayMode?: (displayMode: DefaultDisplayMode) => void;\n setStarted?: (started: boolean) => void;\n setPersist?: () => void;\n\n /**\n * Tells components if an instance of <PlayerContextProvider /> exists\n * above them in the tree. I.e. When this is used in curator.\n */\n hasProvider: boolean;\n}\n\nconst PlayerContext = React.createContext<PlayerContextValues>({ hasProvider: false });\n\nexport function usePlayerContext() {\n return React.useContext(PlayerContext);\n}\n\nfunction getInitialState(): PlayerContextState {\n const hasSavedTheatreMode = LocalStorageHelper.get(_THEATRE_MODE);\n\n return {\n defaultDisplayMode: hasSavedTheatreMode ? 'theatre' : 'normal'\n };\n}\n\nexport function PlayerContextProvider(props: React.PropsWithChildren) {\n const [ state, dispatch ] = React.useReducer(playerContextReducer, getInitialState());\n const { hasPreviewVideos } = useSettings(null);\n\n const playerRef = React.useRef<any>(null);\n\n const portalNode = React.useMemo(() => createHtmlPortalNode(\n { attributes: { class: 'cv-theatre-mode-video-container' } }\n ), []);\n\n const questionListPortalNode = React.useMemo(createHtmlPortalNode, []);\n\n function setPlayerRef(player: PlayerReference) {\n playerRef.current = player;\n }\n\n function useInitialize(initializeData: PlayerInitializationData) {\n const enabled = hasPreviewVideos || initializeData.mode !== 'hover';\n\n React.useEffect(() => {\n if (!enabled)\n return;\n\n /**\n * Cannot initialize a hover player if we already have a player elsewhere.\n */\n if (initializeData.mode === 'hover' && state.mode)\n return;\n\n /**\n * No hover to play on interactives. This feature is ComingSoon™️ - Sha\n */\n if (initializeData.mode === 'hover' && initializeData.objectTypeId === MasterType.Interactive)\n return;\n\n dispatch({\n type: 'initialize',\n data: initializeData\n });\n\n return disposeInternal;\n }, []);\n }\n\n function setPlayerMode(mode: PlayerMode) {\n dispatch({ type: 'mode', data: { mode } });\n }\n\n function setDefaultDisplayMode(defaultDisplayMode: DefaultDisplayMode) {\n LocalStorageHelper.set(_THEATRE_MODE, defaultDisplayMode === 'theatre');\n\n dispatch({ type: 'defaultDisplayMode', data: { defaultDisplayMode } });\n }\n\n function setStarted(): void {\n dispatch({ type: 'started' });\n }\n\n function disposeInternal(force: boolean = false): void {\n if (force) {\n playerRef.current = null;\n }\n\n dispatch({ type: 'dispose', data: { force: force } });\n }\n\n function setPersist(): void {\n dispatch({ type: 'persist' });\n }\n\n /**\n * If anything external calls dispose, we ignore the persist flag and force a disposal\n */\n function dispose(): void {\n disposeInternal(true);\n }\n\n const playerContextValues: PlayerContextValues = {\n ...state,\n playerRef,\n setPlayerRef,\n portalNode,\n questionListPortalNode,\n useInitialize,\n setPlayerMode,\n setDefaultDisplayMode,\n setStarted,\n dispose,\n setPersist,\n hasProvider: true\n };\n\n return (\n <PlayerContext.Provider value={playerContextValues}>\n {props.children}\n </PlayerContext.Provider>\n );\n}\n","import React from 'react';\n\nexport function PlayCircleSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fillRule='evenodd'\n d='M0 12C0 5.373 5.373 0 12 0s12 5.373 12 12-5.373 12-12 12S0 18.627 0 12m23 0c0-6.075-4.925-11-11-11S1 5.925 1 12s4.925 11 11 11 11-4.925 11-11M9 7.498c0-.551.387-.756.847-.469l7.306 4.567c.468.292.46.77 0 1.058l-7.306 4.567c-.468.292-.847.074-.847-.47z'\n fill='currentColor'\n />\n </svg>\n );\n}\n","import * as React from 'react';\n\nimport { Audience } from 'libs/shared/interfaces';\n\nimport styles from './audience-label.module.scss';\n\ntype AudienceBorderColour = 'dark' | 'white';\n\ninterface AudienceLabelProps {\n audience: Audience;\n border: AudienceBorderColour;\n className?: string;\n}\n\nexport function AudienceLabel(props: AudienceLabelProps): JSX.Element {\n if (!props.audience)\n return <></>;\n\n // Note: the audience-label class is applied so that parent components can override styling, and Online can style this component\n return (\n <div\n className={`audience-label border rounded-pill d-inline-block px-2 text-nowrap \n ${'border-' + props.border} ${props.className ? props.className : ''}`}\n >\n {props.audience.name}\n </div>\n );\n}\n\ninterface AudienceLabelListProps {\n audiences: Audience[];\n border: AudienceBorderColour;\n}\n\nexport function AudienceLabelList(props: AudienceLabelListProps): JSX.Element {\n if (!props.audiences || !props.audiences.length)\n return <></>;\n\n return (\n <>\n {props.audiences.map((a, idx) => (\n <span key={idx} className={styles.audienceLabelListItem}>\n <AudienceLabel audience={a} border={props.border} />\n </span>\n ))}\n </>\n );\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}\n","import { Flight } from 'libs/common/react/index';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Config, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/StreamableActions';\nimport { AppChannels } from 'shared/constants/StreamableRadioChannels';\n\ninterface UseCommonVideoPropsResult {\n hasCommonVideoPropsCompleted: boolean;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function useCommonVideoProps(): UseCommonVideoPropsResult {\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const { hasPermissions, isLoaded: hasLoadedPermissions } = usePermissions();\n\n function getSubTextAppLink(video: VideoTypes) {\n if (!('productionCompanies' in video))\n return null;\n\n const productionCompany = video.productionCompanies?.data?.[0];\n\n if (!productionCompany?.id)\n return null;\n\n return {\n application: AppChannels.DASHBOARD,\n action: Actions.Dashboard.COMPANY_DASHBOARD,\n args: [ productionCompany.id, TextHelper.slugify(productionCompany.name) ]\n };\n }\n\n function getClassroomGuideAppLink(id: string) {\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.CLASSROOM_GUIDE,\n args: [id]\n };\n }\n\n function getResourceGuidanceAppLink(id: string) {\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.RESOURCE_GUIDANCE,\n args: [id]\n };\n }\n\n const hasCommonVideoPropsCompleted = (\n config.hasCompleted &&\n hasLoadedPermissions\n );\n\n return {\n hasCommonVideoPropsCompleted,\n commonVideoProps: {\n subTextType: 'productionCompany',\n getSubTextAppLink,\n isPlugin: false,\n canFavourite: null,\n setFavourite: null,\n imageCdnUrl: config.data?.imageCdnUrl,\n yearGroups: null,\n getInteractiveGuidanceAppLink: () => null,\n getClassroomGuideAppLink,\n getResourceGuidanceAppLink,\n showNewVideoIndicator: false,\n getCompanyLogoFallbackUrl: () => ImageUrls.StreamableLearning.LOGO,\n hasStudentExperience: hasPermissions(PermissionName.StudentExperience),\n hasGuestExperience: false,\n features: {\n showClassroomGuide: (video: VideoTypes) => VideoHelper.canViewCurriculumLinks(hasPermissions, video)\n }\n }\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DIavEegC.chunk.js","names":[],"sources":["../../../../libs/shared/src/components/badges/BadgeListContainer.tsx","../../../../libs/shared/src/utils/NumberHelper.ts","../../../../libs/shared/src/utils/SeriesHelper.ts","../../../../libs/shared/src/components/video-sub-text/video-sub-text.module.scss","../../../../libs/shared/src/components/video-sub-text/VideoSubText.tsx","../../../../libs/shared/src/context/player-context/PlayerContext.tsx","../../../../libs/shared/src/images/svg/actions/PlayCircleSvg.tsx","../../../../libs/shared/src/components/audience-label/AudienceLabel.tsx","../../../../libs/shared/src/hooks/UseMergeAudiences.ts","../../src/shared/hooks/useCommonVideoProps.ts"],"sourcesContent":["import * as React from 'react';\n\nimport styles from './badge.module.scss';\n\ninterface BadgeListContainerProps {\n className?: string;\n}\n\nexport function BadgeListContainer(props: React.PropsWithChildren<BadgeListContainerProps>): JSX.Element {\n let className = `d-flex align-items-center badge-list ${styles.minHeight}`;\n\n if (props.className)\n className += ` ${props.className}`;\n\n return (\n <div className={className}>\n {props.children}\n </div>\n );\n}\n","export const NumberHelper = {\n padNumber(num: number, padLength: number): string {\n let numberString = num.toString();\n\n if (numberString.length >= padLength)\n return numberString;\n\n padLength = padLength - numberString.length;\n\n while (padLength > 0) {\n numberString = '0' + numberString;\n padLength--;\n }\n return numberString;\n }\n};\n","import { MasterType } from 'libs/shared/enums/MasterType';\nimport { BaseObject, Rating, Series } from 'libs/shared/interfaces';\n\nimport { NumberHelper } from './NumberHelper';\n\nexport const SeriesHelper = {\n isSeries(obj: BaseObject): obj is Series {\n return obj?.typeId === MasterType.Series;\n },\n\n buildSeriesSeasonEpisodeText(seriesName: string, season?: number, episode?: number): string {\n if (!seriesName)\n return '';\n\n if (!season || !episode)\n return seriesName.toUpperCase();\n\n const seasonNum = NumberHelper.padNumber(season, 2);\n const episodeNum = NumberHelper.padNumber(episode, 2);\n\n return `${seriesName.toUpperCase()} S${seasonNum} • E${episodeNum}`;\n },\n\n getRating(series: Series): Rating {\n return series._rating?.value;\n }\n};\n",":local {\n .appLink {\n color: inherit;\n\n &:hover {\n .hoverUnderline {\n text-decoration: underline;\n }\n }\n }\n}","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { AnalyticsOptions, ClickDescriptor, EntityType, UserAction } from 'libs/analytics/interfaces/AnalyticsTypes';\n\nimport { Video } from 'libs/shared/interfaces';\nimport { NumberHelper } from 'libs/shared/utils/NumberHelper';\nimport { SeriesHelper } from 'libs/shared/utils/SeriesHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { TitleSubText } from '../title-sub-text/TitleSubText';\n\nconst namespace = 'shared.videoSubText';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './video-sub-text.module.scss';\n\nexport type VideoSubTextType = 'series' | 'productionCompany' | 'none';\n\ninterface SeriesLinkProps {\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n withSeriesTitle?: boolean;\n size?: 'sm' | 'lg';\n}\n\nexport function SeasonEpisode(props: Omit<SeriesLinkProps, 'analyticsOptions' | 'analyticsData'>): JSX.Element {\n const { video } = props;\n const { season } = video;\n\n if (!video.episodeNumber || !season)\n return <></>;\n\n const seasonNumber = NumberHelper.padNumber(season.number, 2);\n const episodeNumber = NumberHelper.padNumber(video.episodeNumber, 2);\n\n /* \\u2022 is the unicode number for • */\n return (\n <span className={`d-inline-block ${props.appLink ? styles.hoverUnderline : ''}`}>\n {props.withSeriesTitle && <> </>}\n {!!seasonNumber && `S${seasonNumber} \\u2022 `}\n E{episodeNumber}\n </span>\n );\n}\n\nfunction ReleaseDate(props: SeriesLinkProps): JSX.Element {\n const releaseDate = VideoHelper.getReleaseDate(props.video);\n\n if (!releaseDate)\n return <></>;\n\n if (VideoHelper.hasSeries(props.video))\n return <>{` \\u2022 ${releaseDate}`}</>;\n\n return <>{releaseDate}</>;\n}\n\nfunction SeriesLink(props: SeriesLinkProps): JSX.Element {\n const { appLink, video, className = '' } = props;\n\n const series = video?.series;\n const releaseDate = VideoHelper.getReleaseDate(props.video);\n\n if ((!series?.id) && !releaseDate)\n return <></>;\n\n const seriesAppLink: Core.AppLink = series?.id && appLink && {\n ...appLink,\n args: appLink.args ? appLink.args : [ series.id, TextHelper.slugify(series.name) ]\n };\n\n const analyticsData = { ...props.analyticsData,\n id: series?.id,\n name: series?.name,\n videoId: video?.id,\n videoName: video?.name\n };\n\n const analyticsOptions = {\n ...props.analyticsOptions,\n entity: EntityType.Series,\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Title\n };\n\n const seriesTitle = SeriesHelper.buildSeriesSeasonEpisodeText(\n series?.name,\n video.season?.number,\n video.episodeNumber\n );\n\n return (\n <TitleSubText\n appLink={seriesAppLink}\n className={`d-block ${styles.appLink} ${className}`}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n title={seriesTitle}\n ariaLabel={`${getPhrase('ariaSeries')} ${seriesTitle}`}\n >\n {series?.name && series.name}\n <SeasonEpisode {...props} withSeriesTitle />\n <ReleaseDate {...props} />\n </TitleSubText>\n );\n}\n\ninterface ProductionCompanyLinkProps {\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n size?: 'sm' | 'lg';\n}\n\nfunction ProductionCompanyLink(props: ProductionCompanyLinkProps): JSX.Element {\n const { appLink, video, className = '' } = props;\n\n const productionCompany = video?.productionCompanies?.data?.[0];\n\n if (!productionCompany?.id)\n return <></>;\n\n const companyAppLink: Core.AppLink = productionCompany?.id && appLink && {\n ...appLink,\n args: appLink.args ? appLink.args : [ productionCompany.id, TextHelper.slugify(productionCompany.name) ]\n };\n\n const analyticsData = { ...props.analyticsData,\n id: productionCompany?.id,\n name: productionCompany?.name,\n videoId: video?.id,\n videoName: video?.name\n };\n\n const analyticsOptions = {\n ...props.analyticsOptions,\n entity: EntityType.Company,\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Title\n };\n\n return (\n <TitleSubText\n appLink={companyAppLink}\n className={`d-block ${styles.appLink} ${className}`}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n title={productionCompany.name}\n ariaLabel={`${getPhrase('ariaCompany')} ${productionCompany.name}`}\n >\n {productionCompany.name}\n </TitleSubText>\n );\n}\n\ninterface VideoSubTextProps {\n type: VideoSubTextType;\n video: Video;\n appLink?: Core.AppLink;\n className?: string;\n analyticsData?: HashObject;\n analyticsOptions: AnalyticsOptions; // Required as `location` needs to be supplied\n size?: 'sm' | 'lg';\n}\n\nexport function VideoSubText(props: VideoSubTextProps): JSX.Element {\n const { type = 'series' } = props;\n\n if (type === 'none')\n return <></>;\n\n if (type === 'series')\n return <SeriesLink {...props} />;\n\n return <ProductionCompanyLink {...props} />;\n}\n\n","import React from 'react';\nimport { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal';\n\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { DefaultDisplayMode, PlayerInitializationData } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerContextState } from 'libs/shared/context/player-context/interfaces/PlayerContextState';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { playerContextReducer } from 'libs/shared/context/player-context/reducer/PlayerContextReducer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\nconst _THEATRE_MODE = 'play-page-theatre-mode';\n\nexport interface PlayerContextValues extends PlayerContextState {\n playerRef?: React.MutableRefObject<PlayerReference>;\n portalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n\n useInitialize?: (initializeData: PlayerInitializationData) => void;\n dispose?: () => void;\n setPlayerRef?: (player: any) => void;\n setPlayerMode?: (mode: PlayerMode) => void;\n setDefaultDisplayMode?: (displayMode: DefaultDisplayMode) => void;\n setStarted?: (started: boolean) => void;\n setPersist?: () => void;\n\n /**\n * Tells components if an instance of <PlayerContextProvider /> exists\n * above them in the tree. I.e. When this is used in curator.\n */\n hasProvider: boolean;\n}\n\nconst PlayerContext = React.createContext<PlayerContextValues>({ hasProvider: false });\n\nexport function usePlayerContext() {\n return React.useContext(PlayerContext);\n}\n\nfunction getInitialState(): PlayerContextState {\n const hasSavedTheatreMode = LocalStorageHelper.get(_THEATRE_MODE);\n\n return {\n defaultDisplayMode: hasSavedTheatreMode ? 'theatre' : 'normal'\n };\n}\n\nexport function PlayerContextProvider(props: React.PropsWithChildren) {\n const [ state, dispatch ] = React.useReducer(playerContextReducer, getInitialState());\n const { hasPreviewVideos } = useSettings(null);\n\n const playerRef = React.useRef<any>(null);\n\n const portalNode = React.useMemo(() => createHtmlPortalNode(\n { attributes: { class: 'cv-theatre-mode-video-container' } }\n ), []);\n\n const questionListPortalNode = React.useMemo(createHtmlPortalNode, []);\n\n function setPlayerRef(player: PlayerReference) {\n playerRef.current = player;\n }\n\n function useInitialize(initializeData: PlayerInitializationData) {\n const enabled = hasPreviewVideos || initializeData.mode !== 'hover';\n\n React.useEffect(() => {\n if (!enabled)\n return;\n\n /**\n * Cannot initialize a hover player if we already have a player elsewhere.\n */\n if (initializeData.mode === 'hover' && state.mode)\n return;\n\n /**\n * No hover to play on interactives. This feature is ComingSoon™️ - Sha\n */\n if (initializeData.mode === 'hover' && initializeData.objectTypeId === MasterType.Interactive)\n return;\n\n dispatch({\n type: 'initialize',\n data: initializeData\n });\n\n return disposeInternal;\n }, []);\n }\n\n function setPlayerMode(mode: PlayerMode) {\n dispatch({ type: 'mode', data: { mode } });\n }\n\n function setDefaultDisplayMode(defaultDisplayMode: DefaultDisplayMode) {\n LocalStorageHelper.set(_THEATRE_MODE, defaultDisplayMode === 'theatre');\n\n dispatch({ type: 'defaultDisplayMode', data: { defaultDisplayMode } });\n }\n\n function setStarted(): void {\n dispatch({ type: 'started' });\n }\n\n function disposeInternal(force: boolean = false): void {\n if (force) {\n playerRef.current = null;\n }\n\n dispatch({ type: 'dispose', data: { force: force } });\n }\n\n function setPersist(): void {\n dispatch({ type: 'persist' });\n }\n\n /**\n * If anything external calls dispose, we ignore the persist flag and force a disposal\n */\n function dispose(): void {\n disposeInternal(true);\n }\n\n const playerContextValues: PlayerContextValues = {\n ...state,\n playerRef,\n setPlayerRef,\n portalNode,\n questionListPortalNode,\n useInitialize,\n setPlayerMode,\n setDefaultDisplayMode,\n setStarted,\n dispose,\n setPersist,\n hasProvider: true\n };\n\n return (\n <PlayerContext.Provider value={playerContextValues}>\n {props.children}\n </PlayerContext.Provider>\n );\n}\n","import React from 'react';\n\nexport function PlayCircleSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fillRule='evenodd'\n d='M0 12C0 5.373 5.373 0 12 0s12 5.373 12 12-5.373 12-12 12S0 18.627 0 12m23 0c0-6.075-4.925-11-11-11S1 5.925 1 12s4.925 11 11 11 11-4.925 11-11M9 7.498c0-.551.387-.756.847-.469l7.306 4.567c.468.292.46.77 0 1.058l-7.306 4.567c-.468.292-.847.074-.847-.47z'\n fill='currentColor'\n />\n </svg>\n );\n}\n","import * as React from 'react';\n\nimport { Audience } from 'libs/shared/interfaces';\n\nimport styles from './audience-label.module.scss';\n\ntype AudienceBorderColour = 'dark' | 'white';\n\ninterface AudienceLabelProps {\n audience: Audience;\n border: AudienceBorderColour;\n className?: string;\n}\n\nexport function AudienceLabel(props: AudienceLabelProps): JSX.Element {\n if (!props.audience)\n return <></>;\n\n // Note: the audience-label class is applied so that parent components can override styling, and Online can style this component\n return (\n <div\n className={`audience-label border rounded-pill d-inline-block px-2 text-nowrap \n ${'border-' + props.border} ${props.className ? props.className : ''}`}\n >\n {props.audience.name}\n </div>\n );\n}\n\ninterface AudienceLabelListProps {\n audiences: Audience[];\n border: AudienceBorderColour;\n}\n\nexport function AudienceLabelList(props: AudienceLabelListProps): JSX.Element {\n if (!props.audiences || !props.audiences.length)\n return <></>;\n\n return (\n <>\n {props.audiences.map((a, idx) => (\n <span key={idx} className={styles.audienceLabelListItem}>\n <AudienceLabel audience={a} border={props.border} />\n </span>\n ))}\n </>\n );\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}\n","import { Flight } from 'libs/common/react/index';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Config, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/StreamableActions';\nimport { AppChannels } from 'shared/constants/StreamableRadioChannels';\n\ninterface UseCommonVideoPropsResult {\n hasCommonVideoPropsCompleted: boolean;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function useCommonVideoProps(): UseCommonVideoPropsResult {\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const { hasPermissions, isLoaded: hasLoadedPermissions } = usePermissions();\n\n function getSubTextAppLink(video: VideoTypes) {\n if (!('productionCompanies' in video))\n return null;\n\n const productionCompany = video.productionCompanies?.data?.[0];\n\n if (!productionCompany?.id)\n return null;\n\n return {\n application: AppChannels.DASHBOARD,\n action: Actions.Dashboard.COMPANY_DASHBOARD,\n args: [ productionCompany.id, TextHelper.slugify(productionCompany.name) ]\n };\n }\n\n function getClassroomGuideAppLink(id: string) {\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.CLASSROOM_GUIDE,\n args: [id]\n };\n }\n\n function getResourceGuidanceAppLink(id: string) {\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.RESOURCE_GUIDANCE,\n args: [id]\n };\n }\n\n const hasCommonVideoPropsCompleted = (\n config.hasCompleted &&\n hasLoadedPermissions\n );\n\n return {\n hasCommonVideoPropsCompleted,\n commonVideoProps: {\n subTextType: 'productionCompany',\n getSubTextAppLink,\n isPlugin: false,\n canFavourite: null,\n setFavourite: null,\n imageCdnUrl: config.data?.imageCdnUrl,\n yearGroups: null,\n getInteractiveGuidanceAppLink: () => null,\n getClassroomGuideAppLink,\n getResourceGuidanceAppLink,\n showNewVideoIndicator: false,\n getCompanyLogoFallbackUrl: () => ImageUrls.StreamableLearning.LOGO,\n hasStudentExperience: hasPermissions(PermissionName.StudentExperience),\n hasGuestExperience: false,\n features: {\n showClassroomGuide: (video: VideoTypes) => VideoHelper.canViewCurriculumLinks(hasPermissions, video)\n }\n }\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t,v as n}from"./BJvPfCvt.chunk.js";import{t as r}from"./ImQRQGZr.chunk.js";import{c as i,lt as a,m as o,ut as s}from"./Dun43GrB.chunk.js";import{t as c}from"./B20k2DA32.chunk.js";import{t as l}from"./Ca1QPe-q2.chunk.js";import{n as u,t as d}from"./B8R4YVaF2.chunk.js";import{i as f}from"./app-
|
|
2
|
-
//# sourceMappingURL=
|
|
1
|
+
import{gt as e}from"./Dp9qJj1C.chunk.js";import{t,v as n}from"./BJvPfCvt.chunk.js";import{t as r}from"./ImQRQGZr.chunk.js";import{c as i,lt as a,m as o,ut as s}from"./Dun43GrB.chunk.js";import{t as c}from"./B20k2DA32.chunk.js";import{t as l}from"./Ca1QPe-q2.chunk.js";import{n as u,t as d}from"./B8R4YVaF2.chunk.js";import{i as f}from"./app-BIigh9wv.js";var p=e(s()),m=a();function h(e){return(0,m.jsx)(`svg`,{...e,children:(0,m.jsx)(`path`,{d:`m13.026 4.377 8.5 14A1.2 1.2 0 0 1 20.5 20.2h-17a1.2 1.2 0 0 1-1.026-1.823l8.5-14a1.2 1.2 0 0 1 2.052 0M12 5 3.5 19h17zm0 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2m.75-3.677a.69.69 0 0 1-.7.677.69.69 0 0 1-.7-.677V8.677c0-.374.313-.677.7-.677s.7.303.7.677z`,fill:`currentColor`})})}var g={widgetTextButton:`_widgetTextButton_em1zx_1`},_=r.encloseNamespace(`shared.widgetHeader`);function v(e){return(0,m.jsx)(`div`,{className:`ms-3 ${g.widgetTextButton}`,children:(0,m.jsx)(l,{appLink:e.appLink,analyticsData:e.analyticsData,analyticsOptions:{location:o.SlidingList,...e.analyticsOptions,descriptor:i.SeeMore},className:`text-decoration-none ${e.appLink?`curated-widget-link`:``}`,children:(0,m.jsx)(`p`,{className:`hover-text-underline text-dark curated-widget-heading`,children:_(`seeAll`)})})})}function y(e){return(0,m.jsx)(`div`,{className:`ms-3 ${g.widgetTextButton} text-decoration-none cursor-pointer`,onClick:e.onClose,children:(0,m.jsx)(`p`,{className:`hover-text-underline text-dark curated-widget-heading`,children:_(`hide`)})})}function b(e){return(0,m.jsx)(`div`,{className:`ms-3 ${g.widgetTextButton} text-decoration-none`,children:e.showFollowSpinner?(0,m.jsx)(c,{as:`span`,animation:`border`,role:`status`,size:`sm`}):(0,m.jsx)(`p`,{className:`hover-text-underline text-dark curated-widget-heading cursor-pointer`,onClick:()=>e.onFollow(!e.isFollowing),children:_(e.isFollowing?`unfollow`:`follow`)})})}function x(e){let r=!!e.description;if(!e.name&&!e.description)return(0,m.jsx)(m.Fragment,{});let i=d.isBelowContentMinimum(e.content,e.widgetTypeId),a=u[e.widgetTypeId]?.minContent??0;return(0,m.jsxs)(`div`,{className:`curated-widget-header`,children:[(0,m.jsxs)(`div`,{className:`d-flex justify-content-between`,children:[!!e.name&&(0,m.jsxs)(`div`,{className:`d-flex align-items-center`,children:[(0,m.jsx)(l,{appLink:e.appLink,analyticsData:e.analyticsData,className:`text-decoration-none ${e.appLink?`curated-widget-link text-reset`:``}`,onClick:e.onAppLinkClick,children:(0,m.jsxs)(`h2`,{className:`h4 curated-widget-heading`,children:[e.isPreviewing&&i&&(0,m.jsx)(t,{svg:h,title:`Widget is below the minimum content threshold of ${a} and won't be displayed.`,tooltipSpanHack:!0,tooltipSpanHackClassName:`d-inline text-danger me-1`}),e.name]})}),!!p.isValidElement(e.badgeComponent)&&e.badgeComponent]}),(0,m.jsxs)(`div`,{className:`d-flex justify-content-between align-items-center gap-2`,children:[!!e.appLink&&!r&&!!e.showSeeMoreLink&&(0,m.jsx)(v,{...e}),n.isFunction(e.onFollow)&&(0,m.jsx)(b,{isFollowing:e.isFollowing,onFollow:e.onFollow,showFollowSpinner:e.showFollowSpinner}),n.isFunction(e.onClose)&&(0,m.jsx)(y,{onClose:e.onClose})]})]}),r&&(0,m.jsxs)(`div`,{className:`d-flex justify-content-between align-items-end`,children:[(0,m.jsx)(`p`,{className:`description curated-widget-description`,children:(0,m.jsx)(`span`,{children:e.description})}),!!e.appLink&&!!e.showSeeMoreLink&&(0,m.jsx)(v,{...e})]})]})}var S=400;function C(e){let{type:t,state:n,containerRef:r,mediaQuery:i}=e,[a,o]=p.useState(!1),[s,c]=p.useState({}),[l,u]=p.useState(null),d=p.useMemo(()=>f.isTouchScreen(),[]);p.useEffect(()=>{t!==`dynamic`||!r.current||!n.containerLeftPosition||d||setTimeout(()=>m(),S+50)},[r.current,i,n.offset,n.containerLeftPosition]);function m(){let e=n;r.current?.children&&c(Array.from(r.current.children).reduce((t,n)=>{let r=n?.getBoundingClientRect(),i=r.left<e.containerRightPosition&&r.right>e.containerLeftPosition;return{...t,[n.id]:i?{"aria-hidden":!1}:{"aria-hidden":!0,inert:`true`}}},{}))}function h(e){let t=n;return d||e>=t.offset-t.viewableItems&&e<t.offset?{"aria-hidden":!1}:{inert:`true`,"aria-hidden":!0}}function g(){setTimeout(()=>{if(!r.current)return;let e=r.current.querySelectorAll(`li[aria-hidden]`),t=null;for(let n=l+1;n<e.length&&!t;n++)t=e[n].querySelector(`a[tabindex="0"]`);t&&t.focus()},S+100)}function _(){setTimeout(()=>{if(!r.current)return;let e=r.current.querySelectorAll(`li[aria-hidden]`),t=null;for(let n=l-1;n>=0&&!t;n--)t=e[n].querySelector(`a[tabindex="0"]`);t&&t.focus()},S+100)}function v(e){document.querySelector(`.user-is-tabbing`)&&(o(!0),u(e))}function y(){document.querySelector(`.user-is-tabbing`)||(o(!1),u(null))}return{isTabbing:a,onFocusWidget:v,onBlurWidget:y,getFixedAttributes:h,dynamicAttributes:s,focusNext:g,focusPrev:_}}var w=function(e){return e.Percentage=`%`,e.Pixels=`px`,e}({}),T=new Image;T.src=`data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=`;var E={hideDragImage(e){!e.dataTransfer.setDragImage||!n.isFunction(e.dataTransfer.setDragImage)||e.dataTransfer.setDragImage(T,0,0)}},D=f.isTouchScreen(),O=(e,t,n)=>(t===w.Percentage&&n&&(e-=n),{transform:`translate3d(${e}${t}, 0px, 0px)`,transition:`transform .4s ease-in-out`}),k=p.forwardRef((e,t)=>{let{children:n,positionType:r,onDrag:i,onDragEnd:a,onTouchMove:o,onTouchEnd:s,percentageDragged:c,position:l=0}=e;function u(){let e={};return i&&a&&(e.draggable=!0,e.onDragEnd=a,e.onDragStart=E.hideDragImage,e.onDragOver=i),o&&s&&D&&(e.onTouchMoveCapture=o,e.onTouchEndCapture=s),e}return(0,m.jsx)(`ul`,{className:`list-unstyled d-flex flex-nowrap position-relative w-100 mb-0`,style:O(l,r,c),ref:t,...u(),children:n})}),A=function(e){return e.Init=`init`,e.Next=`next`,e.Previous=`previous`,e.Resize=`resize`,e.Drag=`drag`,e.Update=`update`,e.JumpToIndex=`jump-to-index`,e}({});export{x as a,C as i,k as n,w as r,A as t};
|
|
2
|
+
//# sourceMappingURL=DK3xia1t.chunk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BKbKu9Rp.chunk.js","names":[],"sources":["../../../../libs/shared/src/images/svg/status/WarningOutlineSvg.tsx","../../../../libs/shared/src/components/widgets/curated-widgets/components/header/widget-header.module.scss","../../../../libs/shared/src/components/widgets/curated-widgets/components/header/WidgetHeader.tsx","../../../../libs/shared/src/components/widgets/hooks/useWidgetKeyboard.ts","../../../../libs/shared/src/enums/CssMeasurement.ts","../../../../libs/shared/src/utils/DragHelper.ts","../../../../libs/shared/src/components/widgets/sliding-list/SlidingListContainer.tsx","../../../../libs/shared/src/enums/WidgetInteraction.ts"],"sourcesContent":["import React from 'react';\n\nexport function WarningOutlineSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n d='m13.026 4.377 8.5 14A1.2 1.2 0 0 1 20.5 20.2h-17a1.2 1.2 0 0 1-1.026-1.823l8.5-14a1.2 1.2 0 0 1 2.052 0M12 5 3.5 19h17zm0 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2m.75-3.677a.69.69 0 0 1-.7.677.69.69 0 0 1-.7-.677V8.677c0-.374.313-.677.7-.677s.7.303.7.677z'\n fill='currentColor'\n />\n </svg>\n );\n}\n",":local {\n .widgetTextButton {\n margin-top: 0.1rem;\n flex-shrink: 0;\n }\n}","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsOptions, ClickDescriptor, LocationContext } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { WarningOutlineSvg } from 'libs/shared/images/svg/status/WarningOutlineSvg';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport styles from './widget-header.module.scss';\n\nconst namespace = 'shared.widgetHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface WidgetHeaderProps {\n name: string;\n description?: string | JSX.Element;\n isPreviewing?: boolean;\n content?: any[];\n widgetTypeId?: WidgetTypeId;\n badgeComponent?: JSX.Element;\n\n appLink?: Core.AppLink;\n onAppLinkClick?: () => void;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n \n showSeeMoreLink?: boolean;\n onClose?: () => void;\n onFollow?: (shouldFollow: boolean) => void;\n isFollowing?: boolean;\n showFollowSpinner?: boolean;\n}\n\nfunction SeeMore(props: WidgetHeaderProps) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton}`}>\n <AppLink\n appLink={props.appLink}\n analyticsData={props.analyticsData }\n analyticsOptions={{\n location: LocationContext.SlidingList,\n ...props.analyticsOptions,\n descriptor: ClickDescriptor.SeeMore\n }}\n className={`text-decoration-none ${props.appLink ? 'curated-widget-link' : ''}`}\n >\n <p className='hover-text-underline text-dark curated-widget-heading'>{getPhrase('seeAll')}</p>\n </AppLink>\n </div>\n );\n}\n\nfunction CloseWidgetButton(props: { onClose: () => void }) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton} text-decoration-none cursor-pointer`} onClick={props.onClose}>\n <p className='hover-text-underline text-dark curated-widget-heading'>{getPhrase('hide')}</p>\n </div>\n );\n}\n\nfunction FollowWidgetButton(props: {\n isFollowing: boolean,\n onFollow: (shouldFollow: boolean) => void,\n showFollowSpinner: boolean\n}) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton} text-decoration-none`}>\n {\n props.showFollowSpinner ?\n <Spinner as='span' animation='border' role='status' size='sm' /> :\n <p className='hover-text-underline text-dark curated-widget-heading cursor-pointer' onClick={() => props.onFollow(!props.isFollowing)}>\n {getPhrase(props.isFollowing ? 'unfollow' : 'follow')}\n </p>\n }\n </div>\n );\n}\n\nexport function WidgetHeader(props: WidgetHeaderProps): JSX.Element {\n const hasDescription = !!props.description;\n\n if (!props.name && !props.description)\n return <></>;\n\n const isBelowMinimum = WidgetHelper.isBelowContentMinimum(props.content, props.widgetTypeId);\n const minContent = WidgetTypeIdConfig[props.widgetTypeId]?.minContent ?? 0;\n\n return (\n <div className='curated-widget-header'>\n <div className='d-flex justify-content-between'>\n {!!props.name && (\n <div className='d-flex align-items-center'>\n <AppLink\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n className={`text-decoration-none ${props.appLink ? 'curated-widget-link text-reset' : ''}`}\n onClick={props.onAppLinkClick}\n >\n <h2 className='h4 curated-widget-heading'>\n {props.isPreviewing && isBelowMinimum && (\n <SvgContainer\n svg={WarningOutlineSvg}\n title={`Widget is below the minimum content threshold of ${minContent} and won't be displayed.`}\n tooltipSpanHack\n tooltipSpanHackClassName='d-inline text-danger me-1'\n />\n )}\n {props.name}\n </h2>\n </AppLink>\n {!!React.isValidElement(props.badgeComponent) && props.badgeComponent}\n </div>\n )}\n <div className='d-flex justify-content-between align-items-center gap-2'>\n {!!props.appLink && !hasDescription && !!props.showSeeMoreLink && <SeeMore {...props}/>}\n {FunctionHelper.isFunction(props.onFollow) &&\n <FollowWidgetButton\n isFollowing={props.isFollowing}\n onFollow={props.onFollow}\n showFollowSpinner={props.showFollowSpinner}\n />\n }\n {FunctionHelper.isFunction(props.onClose) && <CloseWidgetButton onClose={props.onClose}/>}\n </div>\n </div>\n \n {hasDescription && (\n <div className='d-flex justify-content-between align-items-end'>\n <p className='description curated-widget-description'>\n <span>{props.description}</span>\n </p>\n {!!props.appLink && !!props.showSeeMoreLink && <SeeMore {...props}/> }\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { DynamicWidgetState } from 'libs/shared/components/widgets/dynamic-widget';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\n\n// Sync with transition time in SlidingListContainer.tsx\nconst SLIDER_ANIMATION_TIME = 400;\n\ntype FixedWidgetKeyboardOptions = {\n type: 'fixed',\n state: FixedWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery?: never\n};\n\ntype DynamicWidgetKeyboardOptions = {\n type: 'dynamic',\n state: DynamicWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery: string\n};\n\ntype UseWidgetKeyboard = FixedWidgetKeyboardOptions | DynamicWidgetKeyboardOptions;\n\nexport function useWidgetKeyboard(options: UseWidgetKeyboard) {\n const { type, state, containerRef, mediaQuery } = options;\n\n const [ isTabbing, setIsTabbing ] = React.useState(false);\n const [ dynamicAttributes, setDynamicAttributes ] = React.useState<HashObject>({});\n const [ focusedWidgetIndex, setFocusedWidgetIndex ] = React.useState(null);\n\n const isTouch = React.useMemo(() => UserAgentHelper.isTouchScreen(), []);\n\n /**\n * Get accessibility attributes for dynamic widget items\n * */\n React.useEffect(() => {\n if (type !== 'dynamic' || !containerRef.current || !(state as DynamicWidgetState).containerLeftPosition || isTouch) return;\n\n setTimeout(() => getDynamicAttributes(), SLIDER_ANIMATION_TIME + 50);\n }, [\n containerRef.current,\n mediaQuery,\n (state as DynamicWidgetState).offset,\n (state as DynamicWidgetState).containerLeftPosition\n ]);\n\n function getDynamicAttributes() {\n const dynamicWidgetState = state as DynamicWidgetState;\n\n if (!containerRef.current?.children)\n return;\n\n const focusableItems = Array.from(containerRef.current.children).reduce((acc, item) => {\n const rect = item?.getBoundingClientRect();\n\n /**\n * When any part of the widget item is visible it should be focusable,\n * otherwise prevent interaction and the slider should be the next focusable element\n * */\n const isItemVisable =\n rect.left < dynamicWidgetState.containerRightPosition &&\n rect.right > dynamicWidgetState.containerLeftPosition;\n\n return {\n ...acc,\n [item.id]: isItemVisable ?\n {\n 'aria-hidden': false\n } : {\n 'aria-hidden': true,\n 'inert': 'true'\n }\n };\n }, {});\n\n setDynamicAttributes(focusableItems);\n }\n\n /**\n * Get accessibility attributes for fixed widget items\n * */\n function getFixedAttributes(index?: number) {\n const fixedWidgetState = state as FixedWidgetState;\n\n const isItemVisible =\n isTouch ||\n index >= (fixedWidgetState.offset - fixedWidgetState.viewableItems) &&\n index < fixedWidgetState.offset;\n if (isItemVisible) {\n return {\n 'aria-hidden': false\n };\n }\n\n return {\n 'inert': 'true',\n 'aria-hidden': true\n };\n }\n\n /**\n * When the user is not signed in, there may be videos which are not focusable.\n * setTimeout is required because the transition time is 400ms\n */\n function focusNext() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let nextFocusableElement: HTMLElement = null;\n\n for (let i = (focusedWidgetIndex + 1); i < items.length; i++) {\n if (nextFocusableElement)\n break;\n\n nextFocusableElement = items[i].querySelector('a[tabindex=\"0\"]');\n }\n\n if (nextFocusableElement)\n nextFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function focusPrev() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let prevFocusableElement: HTMLElement = null;\n for (let i = focusedWidgetIndex - 1; i >= 0; i--) {\n if (prevFocusableElement) break;\n\n const item = items[i];\n prevFocusableElement = item.querySelector('a[tabindex=\"0\"]');\n }\n\n if (prevFocusableElement)\n prevFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function onFocusWidget(index: number) {\n if (document.querySelector('.user-is-tabbing')) {\n setIsTabbing(true);\n setFocusedWidgetIndex(index);\n }\n }\n\n function onBlurWidget() {\n if (!document.querySelector('.user-is-tabbing')) {\n setIsTabbing(false);\n setFocusedWidgetIndex(null);\n }\n }\n\n return {\n isTabbing,\n onFocusWidget,\n onBlurWidget,\n getFixedAttributes,\n dynamicAttributes,\n focusNext,\n focusPrev\n };\n}\n","export enum CssMeasurement {\n Percentage = '%',\n Pixels = 'px'\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst blankImage = new Image();\nblankImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';\n\nexport const DragHelper = {\n // This removes the image that appears when you drag a draggable HTML element\n hideDragImage(event: React.DragEvent<HTMLElement>): void {\n if (!event.dataTransfer.setDragImage || !FunctionHelper.isFunction(event.dataTransfer.setDragImage))\n return;\n\n event.dataTransfer.setDragImage(blankImage, 0, 0);\n }\n};\n","import * as React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { DragHelper } from 'libs/shared/utils/DragHelper';\n\nconst isTouchScreen = UserAgentHelper.isTouchScreen();\n\nconst getPositionStyling = (xPosition: number, measurement: CssMeasurement, dragPercentage?: number) => {\n // Used in situations where a touch screen user is dragging the `<FixedWidget />`\n if (measurement === CssMeasurement.Percentage && dragPercentage)\n xPosition = xPosition - dragPercentage;\n \n return {\n transform: `translate3d(${xPosition}${measurement}, 0px, 0px)`,\n // Sync with transition time in useWidgetKeyboard.ts\n transition: 'transform .4s ease-in-out'\n };\n};\n\ninterface SlidingListContainerProps extends React.PropsWithChildren<unknown> {\n position: number;\n positionType: CssMeasurement;\n\n onDrag?: (event: React.DragEvent<HTMLUListElement>) => void;\n onDragEnd?: () => void;\n\n onTouchMove?: (event: React.TouchEvent<HTMLUListElement>) => void;\n onTouchEnd?: () => void;\n\n percentageDragged?: number;\n}\n\nexport const SlidingListContainer = React.forwardRef((\n props: SlidingListContainerProps,\n ref: React.MutableRefObject<HTMLUListElement>\n): JSX.Element => {\n const { children, positionType, onDrag, onDragEnd, onTouchMove, onTouchEnd, percentageDragged, position = 0 } = props;\n\n function getEventListeners(): HashObject {\n const listenerProps: HashObject = {};\n\n if (onDrag && onDragEnd) {\n listenerProps.draggable = true;\n listenerProps.onDragEnd = onDragEnd;\n listenerProps.onDragStart = DragHelper.hideDragImage;\n listenerProps.onDragOver = onDrag;\n }\n\n if (onTouchMove && onTouchEnd && isTouchScreen) {\n listenerProps.onTouchMoveCapture = onTouchMove;\n listenerProps.onTouchEndCapture = onTouchEnd;\n }\n\n return listenerProps;\n }\n\n return (\n <ul\n className='list-unstyled d-flex flex-nowrap position-relative w-100 mb-0'\n style={getPositionStyling(position, positionType, percentageDragged)}\n ref={ref}\n {...getEventListeners()}\n >\n {children}\n </ul>\n );\n});\n","export enum WidgetInteraction {\n Init = 'init',\n Next = 'next',\n Previous = 'previous',\n Resize = 'resize',\n Drag = 'drag',\n Update = 'update',\n JumpToIndex = 'jump-to-index'\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DK3xia1t.chunk.js","names":[],"sources":["../../../../libs/shared/src/images/svg/status/WarningOutlineSvg.tsx","../../../../libs/shared/src/components/widgets/curated-widgets/components/header/widget-header.module.scss","../../../../libs/shared/src/components/widgets/curated-widgets/components/header/WidgetHeader.tsx","../../../../libs/shared/src/components/widgets/hooks/useWidgetKeyboard.ts","../../../../libs/shared/src/enums/CssMeasurement.ts","../../../../libs/shared/src/utils/DragHelper.ts","../../../../libs/shared/src/components/widgets/sliding-list/SlidingListContainer.tsx","../../../../libs/shared/src/enums/WidgetInteraction.ts"],"sourcesContent":["import React from 'react';\n\nexport function WarningOutlineSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n d='m13.026 4.377 8.5 14A1.2 1.2 0 0 1 20.5 20.2h-17a1.2 1.2 0 0 1-1.026-1.823l8.5-14a1.2 1.2 0 0 1 2.052 0M12 5 3.5 19h17zm0 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2m.75-3.677a.69.69 0 0 1-.7.677.69.69 0 0 1-.7-.677V8.677c0-.374.313-.677.7-.677s.7.303.7.677z'\n fill='currentColor'\n />\n </svg>\n );\n}\n",":local {\n .widgetTextButton {\n margin-top: 0.1rem;\n flex-shrink: 0;\n }\n}","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsOptions, ClickDescriptor, LocationContext } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeIdConfig } from 'libs/shared/constants/WidgetTypeIdConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { WarningOutlineSvg } from 'libs/shared/images/svg/status/WarningOutlineSvg';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport styles from './widget-header.module.scss';\n\nconst namespace = 'shared.widgetHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface WidgetHeaderProps {\n name: string;\n description?: string | JSX.Element;\n isPreviewing?: boolean;\n content?: any[];\n widgetTypeId?: WidgetTypeId;\n badgeComponent?: JSX.Element;\n\n appLink?: Core.AppLink;\n onAppLinkClick?: () => void;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n \n showSeeMoreLink?: boolean;\n onClose?: () => void;\n onFollow?: (shouldFollow: boolean) => void;\n isFollowing?: boolean;\n showFollowSpinner?: boolean;\n}\n\nfunction SeeMore(props: WidgetHeaderProps) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton}`}>\n <AppLink\n appLink={props.appLink}\n analyticsData={props.analyticsData }\n analyticsOptions={{\n location: LocationContext.SlidingList,\n ...props.analyticsOptions,\n descriptor: ClickDescriptor.SeeMore\n }}\n className={`text-decoration-none ${props.appLink ? 'curated-widget-link' : ''}`}\n >\n <p className='hover-text-underline text-dark curated-widget-heading'>{getPhrase('seeAll')}</p>\n </AppLink>\n </div>\n );\n}\n\nfunction CloseWidgetButton(props: { onClose: () => void }) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton} text-decoration-none cursor-pointer`} onClick={props.onClose}>\n <p className='hover-text-underline text-dark curated-widget-heading'>{getPhrase('hide')}</p>\n </div>\n );\n}\n\nfunction FollowWidgetButton(props: {\n isFollowing: boolean,\n onFollow: (shouldFollow: boolean) => void,\n showFollowSpinner: boolean\n}) {\n return (\n <div className={`ms-3 ${styles.widgetTextButton} text-decoration-none`}>\n {\n props.showFollowSpinner ?\n <Spinner as='span' animation='border' role='status' size='sm' /> :\n <p className='hover-text-underline text-dark curated-widget-heading cursor-pointer' onClick={() => props.onFollow(!props.isFollowing)}>\n {getPhrase(props.isFollowing ? 'unfollow' : 'follow')}\n </p>\n }\n </div>\n );\n}\n\nexport function WidgetHeader(props: WidgetHeaderProps): JSX.Element {\n const hasDescription = !!props.description;\n\n if (!props.name && !props.description)\n return <></>;\n\n const isBelowMinimum = WidgetHelper.isBelowContentMinimum(props.content, props.widgetTypeId);\n const minContent = WidgetTypeIdConfig[props.widgetTypeId]?.minContent ?? 0;\n\n return (\n <div className='curated-widget-header'>\n <div className='d-flex justify-content-between'>\n {!!props.name && (\n <div className='d-flex align-items-center'>\n <AppLink\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n className={`text-decoration-none ${props.appLink ? 'curated-widget-link text-reset' : ''}`}\n onClick={props.onAppLinkClick}\n >\n <h2 className='h4 curated-widget-heading'>\n {props.isPreviewing && isBelowMinimum && (\n <SvgContainer\n svg={WarningOutlineSvg}\n title={`Widget is below the minimum content threshold of ${minContent} and won't be displayed.`}\n tooltipSpanHack\n tooltipSpanHackClassName='d-inline text-danger me-1'\n />\n )}\n {props.name}\n </h2>\n </AppLink>\n {!!React.isValidElement(props.badgeComponent) && props.badgeComponent}\n </div>\n )}\n <div className='d-flex justify-content-between align-items-center gap-2'>\n {!!props.appLink && !hasDescription && !!props.showSeeMoreLink && <SeeMore {...props}/>}\n {FunctionHelper.isFunction(props.onFollow) &&\n <FollowWidgetButton\n isFollowing={props.isFollowing}\n onFollow={props.onFollow}\n showFollowSpinner={props.showFollowSpinner}\n />\n }\n {FunctionHelper.isFunction(props.onClose) && <CloseWidgetButton onClose={props.onClose}/>}\n </div>\n </div>\n \n {hasDescription && (\n <div className='d-flex justify-content-between align-items-end'>\n <p className='description curated-widget-description'>\n <span>{props.description}</span>\n </p>\n {!!props.appLink && !!props.showSeeMoreLink && <SeeMore {...props}/> }\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { DynamicWidgetState } from 'libs/shared/components/widgets/dynamic-widget';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\n\n// Sync with transition time in SlidingListContainer.tsx\nconst SLIDER_ANIMATION_TIME = 400;\n\ntype FixedWidgetKeyboardOptions = {\n type: 'fixed',\n state: FixedWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery?: never\n};\n\ntype DynamicWidgetKeyboardOptions = {\n type: 'dynamic',\n state: DynamicWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery: string\n};\n\ntype UseWidgetKeyboard = FixedWidgetKeyboardOptions | DynamicWidgetKeyboardOptions;\n\nexport function useWidgetKeyboard(options: UseWidgetKeyboard) {\n const { type, state, containerRef, mediaQuery } = options;\n\n const [ isTabbing, setIsTabbing ] = React.useState(false);\n const [ dynamicAttributes, setDynamicAttributes ] = React.useState<HashObject>({});\n const [ focusedWidgetIndex, setFocusedWidgetIndex ] = React.useState(null);\n\n const isTouch = React.useMemo(() => UserAgentHelper.isTouchScreen(), []);\n\n /**\n * Get accessibility attributes for dynamic widget items\n * */\n React.useEffect(() => {\n if (type !== 'dynamic' || !containerRef.current || !(state as DynamicWidgetState).containerLeftPosition || isTouch) return;\n\n setTimeout(() => getDynamicAttributes(), SLIDER_ANIMATION_TIME + 50);\n }, [\n containerRef.current,\n mediaQuery,\n (state as DynamicWidgetState).offset,\n (state as DynamicWidgetState).containerLeftPosition\n ]);\n\n function getDynamicAttributes() {\n const dynamicWidgetState = state as DynamicWidgetState;\n\n if (!containerRef.current?.children)\n return;\n\n const focusableItems = Array.from(containerRef.current.children).reduce((acc, item) => {\n const rect = item?.getBoundingClientRect();\n\n /**\n * When any part of the widget item is visible it should be focusable,\n * otherwise prevent interaction and the slider should be the next focusable element\n * */\n const isItemVisable =\n rect.left < dynamicWidgetState.containerRightPosition &&\n rect.right > dynamicWidgetState.containerLeftPosition;\n\n return {\n ...acc,\n [item.id]: isItemVisable ?\n {\n 'aria-hidden': false\n } : {\n 'aria-hidden': true,\n 'inert': 'true'\n }\n };\n }, {});\n\n setDynamicAttributes(focusableItems);\n }\n\n /**\n * Get accessibility attributes for fixed widget items\n * */\n function getFixedAttributes(index?: number) {\n const fixedWidgetState = state as FixedWidgetState;\n\n const isItemVisible =\n isTouch ||\n index >= (fixedWidgetState.offset - fixedWidgetState.viewableItems) &&\n index < fixedWidgetState.offset;\n if (isItemVisible) {\n return {\n 'aria-hidden': false\n };\n }\n\n return {\n 'inert': 'true',\n 'aria-hidden': true\n };\n }\n\n /**\n * When the user is not signed in, there may be videos which are not focusable.\n * setTimeout is required because the transition time is 400ms\n */\n function focusNext() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let nextFocusableElement: HTMLElement = null;\n\n for (let i = (focusedWidgetIndex + 1); i < items.length; i++) {\n if (nextFocusableElement)\n break;\n\n nextFocusableElement = items[i].querySelector('a[tabindex=\"0\"]');\n }\n\n if (nextFocusableElement)\n nextFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function focusPrev() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let prevFocusableElement: HTMLElement = null;\n for (let i = focusedWidgetIndex - 1; i >= 0; i--) {\n if (prevFocusableElement) break;\n\n const item = items[i];\n prevFocusableElement = item.querySelector('a[tabindex=\"0\"]');\n }\n\n if (prevFocusableElement)\n prevFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function onFocusWidget(index: number) {\n if (document.querySelector('.user-is-tabbing')) {\n setIsTabbing(true);\n setFocusedWidgetIndex(index);\n }\n }\n\n function onBlurWidget() {\n if (!document.querySelector('.user-is-tabbing')) {\n setIsTabbing(false);\n setFocusedWidgetIndex(null);\n }\n }\n\n return {\n isTabbing,\n onFocusWidget,\n onBlurWidget,\n getFixedAttributes,\n dynamicAttributes,\n focusNext,\n focusPrev\n };\n}\n","export enum CssMeasurement {\n Percentage = '%',\n Pixels = 'px'\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst blankImage = new Image();\nblankImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';\n\nexport const DragHelper = {\n // This removes the image that appears when you drag a draggable HTML element\n hideDragImage(event: React.DragEvent<HTMLElement>): void {\n if (!event.dataTransfer.setDragImage || !FunctionHelper.isFunction(event.dataTransfer.setDragImage))\n return;\n\n event.dataTransfer.setDragImage(blankImage, 0, 0);\n }\n};\n","import * as React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { DragHelper } from 'libs/shared/utils/DragHelper';\n\nconst isTouchScreen = UserAgentHelper.isTouchScreen();\n\nconst getPositionStyling = (xPosition: number, measurement: CssMeasurement, dragPercentage?: number) => {\n // Used in situations where a touch screen user is dragging the `<FixedWidget />`\n if (measurement === CssMeasurement.Percentage && dragPercentage)\n xPosition = xPosition - dragPercentage;\n \n return {\n transform: `translate3d(${xPosition}${measurement}, 0px, 0px)`,\n // Sync with transition time in useWidgetKeyboard.ts\n transition: 'transform .4s ease-in-out'\n };\n};\n\ninterface SlidingListContainerProps extends React.PropsWithChildren<unknown> {\n position: number;\n positionType: CssMeasurement;\n\n onDrag?: (event: React.DragEvent<HTMLUListElement>) => void;\n onDragEnd?: () => void;\n\n onTouchMove?: (event: React.TouchEvent<HTMLUListElement>) => void;\n onTouchEnd?: () => void;\n\n percentageDragged?: number;\n}\n\nexport const SlidingListContainer = React.forwardRef((\n props: SlidingListContainerProps,\n ref: React.MutableRefObject<HTMLUListElement>\n): JSX.Element => {\n const { children, positionType, onDrag, onDragEnd, onTouchMove, onTouchEnd, percentageDragged, position = 0 } = props;\n\n function getEventListeners(): HashObject {\n const listenerProps: HashObject = {};\n\n if (onDrag && onDragEnd) {\n listenerProps.draggable = true;\n listenerProps.onDragEnd = onDragEnd;\n listenerProps.onDragStart = DragHelper.hideDragImage;\n listenerProps.onDragOver = onDrag;\n }\n\n if (onTouchMove && onTouchEnd && isTouchScreen) {\n listenerProps.onTouchMoveCapture = onTouchMove;\n listenerProps.onTouchEndCapture = onTouchEnd;\n }\n\n return listenerProps;\n }\n\n return (\n <ul\n className='list-unstyled d-flex flex-nowrap position-relative w-100 mb-0'\n style={getPositionStyling(position, positionType, percentageDragged)}\n ref={ref}\n {...getEventListeners()}\n >\n {children}\n </ul>\n );\n});\n","export enum WidgetInteraction {\n Init = 'init',\n Next = 'next',\n Previous = 'previous',\n Resize = 'resize',\n Drag = 'drag',\n Update = 'update',\n JumpToIndex = 'jump-to-index'\n}\n"],"mappings":"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"}
|